Question

I've been able to piece together the following code that "builds" a checkbox list in Sharepoint 2016. That was step one. Now, I'm trying to figure out how to loop thru the whole list of Departments and determine which Departments have been selected. (There are about 10 departments in the list so far).

Here's the code I got to work for getting the data..

$.ajax({
                url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + listName + "')/Fields?$filter=Title eq 'Departments'",
                method: "GET",
                headers: { "Accept": "application/json; odata=verbose" },
                success: function (data) {
                    var results = data.d.results;
                    var itemhtml = "";
                        $.each(results, function (index, dataRec) {
                        var choices = dataRec.Choices.results;
                        $.each(choices, function (index, optVal) {

                            // add options to select here
                            $("#ckDepartments").append('<div class="form-check"><label class="form-check-label"><input type="checkbox" class="form-check-input" value="' + optVal + '" />' + optVal + '</label></div>');

                        });
                    });
                },
                error: function (data) { }
            });

And here's what i "tried" to get if the checkbox was checked.

function insertDepartments() 
            {
            var item = {
            "__metadata": { "type": "SP.Data.NewSiteRequestListItem" },
            "Departments": $('ckDepartments').prop('checked'),
            };
            }

Appreciate any suggestions/help you might have.

Was it helpful?

Solution

While harshal's answer is on the right track, there is a problem in the code posted there (at least at the time of my writing this). But maybe it would help to understand a bit more what is going on.

When you loop through your results and do $(#ckDepartments).append(), you are inserting HTML into a wrapping container (presumably a div?) with the id of ckDepartments. So your HTML is going to look something like this:

<div id="ckDepartments"> <!-- this is your outer container -->

    <!-- as you loop through your results, you are creating mini structures as below -->
    <div class="form-check">
        <label class="form-check-label">
            <input type="checkbox" class="form-check-input" value="Accounting" />
            Accounting
        </label>
    </div>

    <div class="form-check">
        <label class="form-check-label">
            <input type="checkbox" class="form-check-input" value="Marketing" />
            Marketing
        </label>
    </div>

</div>

But then when you try to get which checkboxes are checked, you do

$('ckDepartments').prop('checked')

But, the selector you are giving to jQuery (which actually should have a # at the beginning to indicate that it is an id selector) of $('#ckDepartments') is actually selecting the wrapping container, not the checkboxes, so when you then add on .prop('checked'), you won't get the result you want because it doesn't have a "checked" property, because it's the wrapping div, not the checkboxes themselves.

harshal is on the right track, except that the selector in that code:

$("ckDepartments > input[type='checkbox']:checked")

has a >, which actually means "direct child", so that's not going to work, because all of your checkbox input elements are not direct children of your #ckDepartments element, they are actually inside labels that are inside divs that are inside the #ckDepartments element.

So what you could do is just take out the > so that the selector is choosing a child at any depth (and don't forget the # for the ckDepartments element):

$("#ckDepartments input[type='checkbox']:checked")

or, as Rob suggested, use a selector that targets the checkboxes directly, like the one he has in his example which uses their class to get directly to them.

Now, regarding the difference between $('selector').prop('checked') and $('selector:checked'), you would use the first to select a single, specific checkbox element and see if it is checked or not, but you would use the second to select a group of checkbox elements that match the selector and happen to be checked.

I'm not sure why harshal and Rob decided on the $.each($('selector'), function (){ }) type of construction, I personally would have just chained the each off of the selector, like

function insertDepartments() {
    var selectedDepartments = [];
    $('#ckDepartments input.form-check-input:checked').each(function() {
        // inside this function, $(this) represents each individual checkbox
        selectedDepartments.push($(this).value);
    })
    var item = {
        "__metadata": { "type": "SP.Data.NewSiteRequestListItem" },
        "Departments": selectedDepartments
    };
}

OTHER TIPS

Try the below code provided your Departments field is a choice field.

    function insertDepartments() 
    {
        var selectedArray = [];
        $.each($("ckDepartments > input[type='checkbox']:checked"), function(){            
            selectedArray.push($(this).val());
        });

        var item = {
        "__metadata": { "type": "SP.Data.NewSiteRequestListItem" },
        "Departments": selectedArray,
        };
    }

The value of the departments field should be any array of the names of the selected departments.

function insertDepartments() {
    var selectedDepartmentNames = [];
    var selectedCheckboxes = jQuery(".form-check-input:checked");
    $.each(selectedCheckboxes, function (index, checkbox) {
        selectedDepartmentNames.push(checkbox.value);
    });

    var item = {
        "__metadata": { "type": "SP.Data.NewSiteRequestListItem" },
        "Departments": selectedDepartmentNames
    };
}

I go into more detail on how to update multiSelect choice field values using the REST API in this YouTube video: Update MultiSelect Choice and Lookup Field Values from JavaScript CSOM and REST API

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top