Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have a view where i dynamically render checkbox items with razor. User can make adjustments and then i need to send form back to controller. If i send only one item i.e. row, it works fine, but if i try to send all of them i always get null. How can i collect form data properly. This is what i have at the moment.

public void SendData(List<SomeClass> myData)
    {
        var data = myData; //always null
    }

    public class SomeClass
    {
        public int Id { get; set; }
        public int RoleId { get; set; }
        public bool R { get; set; }
        public bool W { get; set; }
        public bool E { get; set; }
        public bool D { get; set; }
    }

And view:

    <script type="text/javascript">

    $(document).ready(function () {

        var test = $("#myForm").serialize();

        console.log(test);

        test = JSON.stringify({ 'myData': test });

        console.log(test);

        $.ajax({
            contentType: 'application/json; charset=utf-8',
            type: 'POST',
            url: '/Home/SendData',
            data: test,
            success: function () {

            },
            failure: function (response) {

            }
        });
    });

    </script>


        <form id="myForm">

        <div class="row control_group">
            @Html.Hidden("Id", 1)
            @Html.Hidden("RoleId", 1)
            @Html.CheckBox("R", false)
            @Html.CheckBox("W", false)
            @Html.CheckBox("E", false)
            @Html.CheckBox("D", false)
        </div>

        <div class="row control_group">
            @Html.Hidden("Id", 2)
            @Html.Hidden("RoleId", 2)
            @Html.CheckBox("R", true)
            @Html.CheckBox("W", true)
            @Html.CheckBox("E", true)
            @Html.CheckBox("D", true)
        </div>

    </form>

EDIT:

This is how i render items with razor

    foreach (SomeObject x in items)
    {
        var menuName = someStringFromDb;
        var permissions = x.MainItem.FirstOrDefault();

            <div class="row control_group">
                <div class="col-sm-4">@menuName</div>
                <input name="Id" type="hidden" value="@permissions.Id"/>
                <input name="RoleId" type="hidden" [email protected] />
                <div class="col-sm-2">
                    @Html.CheckBox("R", @permissions.Read)
                </div>
                <div class="col-sm-2">
                    @Html.CheckBox("W", @permissions.Write)
                </div>
                <div class="col-sm-2">
                    @Html.CheckBox("E", @permissions.Edit)
                </div>
                <div class="col-sm-2">
                    @Html.CheckBox("D", @permissions.Delete)
                </div>
            </div>
    }

EDIT 2

Thank you for your answer @Avi Fatal it got me this far. Problem i am facing now is this. Checkbox elements rendered by razor have two inputs, one is hidden and other one is shown. When i collect form data i am always getting last input value (hidden one, that's always false) How can i get true value?

enter image description here

Current data sent to controller (everything is false):

{"ajaxData":[{"Id":"1","RoleId":"1","R":"false","W":"false","E":"false","D":"false"},{"Id":"2","RoleId":"2","R":"false","W":"false","E":"false","D":"false"}]}

Collecting data like this (found similar problem here on SO):

var ajaxData = $('.control_group').map(function (i, group) {
                var data = {};
                $(group).find(':input').each(function () {
                    data[this.name] = this.value;
                });
                return data;
            }).get();

            ajaxData = JSON.stringify({ 'ajaxData': ajaxData });

            console.log(ajaxData);

EDIT 3

With only .serialize() i get null as input parameter on controller, with JSON.stringify i get Count = 0, also empty. What am i missing?

HTML:

        @model List<WebApplication3.Controllers.HomeController.SomeClass>

    <form id="myForm">
        @for (int i = 0; i < Model.Count; i++)
        {
            <div>Element</div>
            @Html.HiddenFor(m => m[i].Id)
            @Html.HiddenFor(m => m[i].RoleId)
            @Html.CheckBoxFor(m => m[i].R)
            @Html.CheckBoxFor(m => m[i].W)
            @Html.CheckBoxFor(m => m[i].E)
            @Html.CheckBoxFor(m => m[i].D)
        }
    </form>

    <button id="send">SEND</button>


    <script type="text/javascript">

        $('#send').on('click', function () {

            var data = $("#myForm").serialize();
            console.log(data);

            //data = JSON.stringify({ 'ajaxData': data });

            $.ajax({
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                type: 'POST',
                url: '/Home/SendData',
                data: data,
                success: function () {

                },
                failure: function (response) {

                }
            });

        });

    </script>

Controller

public void SendData(IEnumerable<SomeClass> ajaxData)
    {
        var data = ajaxData;
    }
share|improve this question
    
You have not shown how you are dynamically generating the form controls, but the html you have shown has name attributes without indexers so will not bind to a collection. Refer the answers here and here for some options – Stephen Muecke Nov 24 '15 at 7:33
    
Unfortunately adding indexes to names didn't work (following first and second link from your comment) – azza idz Nov 24 '15 at 8:19
    
Of course it works. If its not working for you, then consider posting the code you have used so we can correct your errors – Stephen Muecke Nov 24 '15 at 10:22
1  
You cannot use a foreach loop to generate form controls in a view. You need to use for (int i = 0; i < Model.Count; i++) { @Html.HiddenFor(m => m.Id) @Html.CheckBoxFor(m -> m[i].R) .... } so that your controls are correctly named. – Stephen Muecke Nov 24 '15 at 20:38
1  
Yes, and when you post back to the method which has a parameter for your model (i.e. List<SomeClass> model), the DefaultModelBinder will correctly set the value of all the boolean properties! – Stephen Muecke Nov 25 '15 at 8:18
up vote 2 down vote accepted

It took me some time to understand the problem (-:

Anyway, I have created a small test, and it is working.

public class User
{
        public string UserName { get; set; }
}

public void TestPost(List<User> users)
{

}

you need to serialize your data to json array of objects, [{ 'UserName': "user 1" }, { 'UserName': "user 2" }] a little jquery manipulation... (see here: Convert form data to JavaScript object with jQuery)

$.ajax({
            contentType: 'application/json; charset=utf-8',
            type: 'POST',
            url: '/Home/TestPost',
            data: JSON.stringify([{ 'UserName': "user 1" }, { 'UserName': "user 2" }]),
            dataType: "json",
        });
share|improve this answer
    
Thank you for your answer @Avi Fatal it got me this far (see edit 2). Problem i am facing now is this. Checkbox elements rendered by razor have two inputs, one is hidden and other one is shown. When i collect form data i am always getting last input value (hidden one, that's always false) How can i get true value? – azza idz Nov 24 '15 at 14:33
    
Hi, please accept the anwer and open another thread, it is a different problem. it does not belong here... ill look in to it when you open a new thread. – Avi Fatal Nov 24 '15 at 14:50
    
I have, it's here stackoverflow.com/questions/33896965/… – azza idz Nov 24 '15 at 15:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.