0

I am trying to submit a form which has dynamically added elements in it but when I am receiving it in my controller the formCollection is empty:

My html markup looks like this:

…
<form id="submitCart" name="submitCart" action="submitCart" method="POST" enctype="multipart/form-data">
            <button class="major" value="Done, Proceed to checkout!" id="formSubmitCart" type="submit">Done, Proceed to checkout!</button>
    </div>

    <div class="infosheet">
        <table>
            <thead>
                <tr>
                    <th style="width: 60px">Qty.</th>
                    <th style="width: 240px">Product Name</th>
                    <th style="width: 60px">Price</th>
                </tr>
            </thead>

            <tbody id="cardList">
            </tbody>
            </form>

        </table>
…

Elements are added into it from here in jQuery:

$('#addtocart').click(function () {
    var itmCnt = parseInt($('#itemCnt').val());
    itmCnt = itmCnt + 1;

    $('#itemCnt').val(itmCnt);
    //var htmlStr = "<tr><td style='width: 60px'><input type='text' name='qntty" + itmCnt + "'  disabled=disabled value='" + $('#qntty').val() + "' style='width: 60px'/></td><td style='width: 240px'><input type='text' name='prdNme" + itmCnt + "'  disabled=disabled value='" + $('#prdNme').val() + "'  style='width: 200px'/></td><td style='width: 60px'><input type='text' name='ttlprce" + itmCnt + "' disabled=disabled value='" + $('#ttlPrce').val() + "'  style='width: 60px'/></td></tr>";

    var htmlStr = "<tr><td style='width: 60px'><input type='text' name='qntty" + itmCnt + "'  readonly=readonly value='" + $('#qntty').val() + "' style='width: 60px'/></td><td style='width: 240px'><input type='text' name='prdNme" + itmCnt + "'  readonly=readonly value='" + $('#prdNme').val() + "'  style='width: 200px'/></td><td style='width: 60px'><input type='text' name='ttlprce" + itmCnt + "' readonly=readonly value='" + $('#ttlPrce').val() + "'  style='width: 60px'/></td></tr>";

    ...
    ...
    $('#cardList').prepend(htmlStr);

});

After few additions this markup looks like this (from inspect)

<tbody id="cardList">
<tr>
    <td style="width: 60px">
        <input type="text" name="qntty4" value="53" style="width: 60px">
    </td>
    <td style="width: 240px">
        <input type="text" name="prdNme4" value="Rice" style="width: 200px">
    </td>
    <td style="width: 60px">
        <input type="text" name="ttlprce4" value="2480.4" style="width: 60px">
    </td>
</tr>
<tr>
    <td style="width: 60px">
        <input type="text" name="qntty3" value="53" style="width: 60px">
    </td>
    <td style="width: 240px">
        <input type="text" name="prdNme3" value="Rice" style="width: 200px">
    </td>
    <td style="width: 60px">
        <input type="text" name="ttlprce3" value="2480.4" style="width: 60px">
    </td>
</tr>
</tbody>

And then I am submitting it through this:

$('#submitCart').on('submit', function (e) {
        console.log($(this).serialize()); // still empty
    $.post('submitCart', $(this).serialize(), function (result) {
        $('#msg').val(result);
        console.log(result);
        console.log($(this).serialize()); //Empty Nothing here..
    });
    e.preventDefault();
});

I have route in place like this:

routes.MapRoute(name: "submitCart", url: "submitCart", defaults: new { controller = "Inventory", action = "SubmitCart" });

But in my controller when I am trying to read from formCollection there nothing

    public bool SubmitCart(FormCollection submitCart)
    {
        var b = submitCart.Count;

        foreach (var key in submitCart.AllKeys)
        {
            var value = submitCart[key];
            // etc.
        }

        var a = submitCart;
        return true;

    }

The routes are ok as the action is hit, i ahve checked it through setting a breakpoint. Can anyone please guide me with this that why I can't receive my forms collection. thankyou

Maven
  • 14,587
  • 42
  • 113
  • 174
  • Did you inspect the Chrome Console for JS errors? Checkout for the request as well! Looks like nothing is getting post to the server! – Fals Jul 16 '13 at 21:10
  • I did and its fine, its even showing the correct result value through `console.log(result);` – Maven Jul 17 '13 at 04:03

1 Answers1

2

The FormCollection is empty because you are disabling the elements after you add them and disabled elements are not submitted in the request.

You can achieve the disabled appearance via css in combination with the readonly attribute.

Twitter Boostrap does it like this:

input[disabled],
select[disabled],
textarea[disabled],
input[readonly],
select[readonly],
textarea[readonly] {
  cursor: not-allowed;
  background-color: #eeeeee;
}

You can use a similar approach.

Addendum: Here's a link to another question regarding disabled elements: Disabled form inputs do not appear in the request

Community
  • 1
  • 1
Icarus
  • 63,293
  • 14
  • 100
  • 115
  • I did as you suggested as you can see in my edited code, but nothing has changed, still no items in the form collection. – Maven Jul 17 '13 at 04:07
  • The fact that you had the elements disabled was definitely one problem. If still doesn't work, then you have an additional issue. One thing that looks suspicious is the `submitCart` action. Isn't this action in a Controller with some name? I would expect to see something like `/Home/submitCart`, also make sure that `$(this).serialize()` is working as expected. Do `console.log($(this).serialize());` and double check that all elements are being serialized properly. – Icarus Jul 17 '13 at 10:39
  • `console.log($(this).serialize());` is returning empty.. nothing in there.. :/ – Maven Jul 17 '13 at 13:38
  • I have also updated my question with the `route` matching `submitCart` however controller is being hit but still you can verify if everyhting is fine – Maven Jul 17 '13 at 14:00
  • if `$(this).serialize()` is empty, then that's the issue. Now that you posted sample markup, I will work on a fiddle to figure out the issue. Stay tuned... – Icarus Jul 17 '13 at 14:20
  • Wait a second... the second `$(this).serialize()` returns empty because you are on a different context. You are inside the `$.post` now... do `console.log($(this).serialize());` BEFORE you call `$.post` – Icarus Jul 17 '13 at 14:27
  • did as you suggested, its still empty.. any idea why? :/ – Maven Jul 17 '13 at 16:38
  • I don't see anything else wrong to be honest. I encourage you to look at this jsfiddle: http://jsfiddle.net/3avHL/1/ In there I referenced jQuery 1.9.1 and it works fine. – Icarus Jul 17 '13 at 16:44
  • I am working with `jquery-1.7.1` can that be a problem? And yeah thank you for help so far. :) – Maven Jul 17 '13 at 16:49
  • jsfiddle doesn't have `jQuery-1.7.1` as available option so I can't really tell you but testing with `jQuery-1.7.1.2` which IS available, does work. Testing with the previous version available `jQuery-1.6.4` DOES NOT work so your version of jQuery may be the issue now... – Icarus Jul 17 '13 at 17:02
  • `$(this).serialize()` still prints nothing after switching to 1.10? At this point I am out of ideas. I would have to run the whole project to be able to help you. Good luck! – Icarus Jul 17 '13 at 17:12
  • oh gosh problem solved. the issue was with the markup. instead of keep `form` tag inside `table` i wrapped `table` inside `form` and now it all works fine. I dont have any technical explanation of this and why it worked but its all working all good. still Thankyou for all your help. :) – Maven Jul 17 '13 at 17:14
  • Glad you figured it out. – Icarus Jul 17 '13 at 17:28