Javascript Assign list to element by id not working

Viewed 37

On my project with razor view I'm struggling with the following situation:

I have the following form:

@using (Html.BeginForm("GetFilteredReport", "ServiceReport", FormMethod.Post, new { id = "serviceReportForm" }))
    {
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="card-body pt-0">
                <div class="district-container">
                    <div class="district-container">
                        @Html.LabelFor(model => model.DistrictAssigned, "Distrito", htmlAttributes: new { @class = "form-label" })
                        @Html.DropDownListFor(model => model.DistrictAssigned, Model.DistrictPool, new { @class = "form-control district-dropdown select-2 select-add-placeholder", @id = "districtId" })
                        @Html.ValidationMessageFor(model => model.DistrictAssigned, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="datepicker-container">
                    <div class="">
                        <div class="">
                            @Html.LabelFor(model => model.Date, "Fecha", htmlAttributes: new { @class = "form-label" })
                            <div class="col-md-10">
                                @Html.EditorFor(model => model.Date, new { htmlAttributes = new { @class = "form-control district-dropdown", @placeholder = "Seleccione Fecha", @id = "kt_datepicker_1" } })
                                @Html.ValidationMessageFor(model => model.Date, "", new { @class = "text-danger" })
                            </div>
                        </div>
                    </div>
                </div>
                <div class="shift-container">
                    <div class="checkbox-list">
                        <div class="checkbox">
                            <input type="checkbox" name="Mañana" class="checkbox-custom" onclick="onShiftChange('Mañana', this.checked)">
                            <span class="checkbox-label">Mañana</span>
                        </div>
                        <div class="checkbox">
                            <input type="checkbox" name="Tarde" class="checkbox-custom" onclick="onShiftChange('Tarde', this.checked)">
                            <span class="checkbox-label">Tarde</span>
                        </div>
                        <div class="checkbox">
                            <input type="checkbox" name="Noche" class="checkbox-custom" onclick="onShiftChange('Noche', this.checked)">
                            <span class="checkbox-label">Noche</span>
                        </div>
                    </div>
                    @Html.HiddenFor(model => model.Shift, new { id = "shiftCheckbox"})
                    @Html.ValidationMessageFor(model => model.Shift, "", new { @class = "text-danger" })
                </div>
            </div>
        <div class="card-footer">
                <div class="filter-button-container">
                    <input type="submit" value="Filtrar" class="btn filter-button btn-active-primary filter-button btn-filter btn-block" id="submitFilter" />
                </div>
            </div>
        } 

On the shift-container with the checkboxes I've added a hidden property to assign the values of the checkboxes to the shift property which is a string list.

The onClick method called is the following:

function onShiftChange(val, checked) {
    if (checked) {
        shift.push(val);
    } else {
        shift = shift.filter(x => x != val);
    }

    document.getElementById('shiftCheckbox').value = shift;
}

all this seems to work well but when I submit the form the server side receives the shift list as one item like:

shift = "item1, item2"

but it should be like this

shift = {"item1", "item2"}

Whats wrong here?

1 Answers

When you store a JavaScript variable inside an HTML element, it gets stored as a string, not as whatever the variable's original type was.

Here is an example that shows storing a JavaScript array inside an HTML element, and then attempting to retrieve the array from the stored value. You can see in the console output the same issue your code sample is displaying. To fix this and get back the original JS value, you have to convert the string to an array. Here, I used the .split() method with "," as the argument, meaning split the string at every comma character, and then return an array with an element for each piece of the string.

Your example uses c#, which I'm not familiar with, but it looks like there is a method similar to JavaScript's .split() you could use to convert the string back to a list. I would suggest performing this type conversion after the shift value is retrieved from the HTML but before it is sent to the server, or else after it is received by the server but before it is used.

Example:

var storeVariableInHTML = function(variable, HTML_element_id) {
    document.getElementById(HTML_element_id).innerHTML = variable;
};
    
var theArray = ['first', 'second', 'third'];
storeVariableInHTML(theArray, "testing");
    
var storedValue = document.getElementById("testing").innerHTML;
console.log(storedValue);
console.log("Stored in HTML as a(n) " + typeof(storedValue));

var afterTypeConversion = storedValue.split(",");
console.log(afterTypeConversion);
console.log("Converted back to Array: now type is " + typeof(afterTypeConversion));
// Note that the type of an Array in JavaScript is actually "object"!
body {
    background-color: lightblue;
    color: darkblue;
}
<head>
    <title>Example</title>
</head>

<body>
    <h1 id="testing"></h1>
</body>

Does this fix the problem?

Related