Display:none fields not being posted to controller

2019-07-16 08:47发布

问题:

I have a lightbox that contains a bunch of input elements that I have set up using HTML helpers for a create action. They are optional fields, but I do apply the digit rule to them in jquery validation.

The user can open up this lightbox, and fill out the fields if they would like to, but they are not required. It is in the same form as the rest of the data, but to submit, they have to close this lightbox.

On submit, not of the values from the lightbox are posted to the controller. If I remove the inputs from the lightbox, it works fine. It must have something to do with it being hidden, but why would that happen? Is it jquery? I have 'voavi-ignore' as my ignore class, so it should still be validating these. I'm a bit confused and burnt out on this one as I've been a it for a while. Everything else on my page works fine, and I just added these new fields to the lightbox.

js:

$(document).ready(function () {
    InitTab();
    $("#caseProductions").hide();
    $(".chzn-select").chosen();
    $(".filetypes").click(OnNewVOAVIClick);
    $(".countPerCase").change(OnCaseProdChange);
    $(".caseCount").change(OnCaseProdChange);
    $(".drinkWindow").change(OnDrinkWindowChange);
    $("#lnkCaseProduction").click(OnCaseProdOpen);

    VintageUpAlert();

    $.validator.addMethod("decimalNumber", function (value, element) {
        return this.optional(element) || (!isNaN(value));
    }, "Must be a valid number");

    wineValidator = $("form").validate({
        errorPlacement: function (error, element) {
            var x = element.parent();
            error.appendTo(element.closest("td"));
        },
        ignore: ".voavignore",
        rules: {
            "Wine.VarTypeID": { min: 1 },
            "Wine.OriginID": { min: 1 },
            "Wine.AppID": { min: 1 },
            "Wine.VintageID": { min: 1 },
            "VOAVIRequest.VarType": { required: true },
            "VOAVIRequest.Origin": { required: true },
            "VOAVIRequest.App": { required: true },
            "VOAVIRequest.Vintage": { required: true },
            "Wine.CaseProduction": { digits: true },
            "Wine.AlcoholContent": { number: true,
                min: 0, max: 100
            },
            "Wine.pH": { number: true,
                min: 0, max: 7
            },
            "Wine.RS": { decimalNumber: true,
                min: 0, max: 1000
            }
        },
        messages: {
            "Wine.VarTypeID": { min: "Varietal/Type Required" },
            "Wine.OriginID": { min: "Origin Required" },
            "Wine.AppID": { min: "Appellation Required" },
            "Wine.VintageID": { min: "Vintage Required" },
            "VOAVIRequest.VarType": { required: "Varietal/Type Required" },
            "VOAVIRequest.Origin": { required: "Origin Required" },
            "VOAVIRequest.App": { required: "Appellation Required" },
            "VOAVIRequest.Vintage": { required: "Vintage Required" },
            "Wine.CaseProduction": { digits: "Please enter whole numbers only" }
        }
    });

    CaseProdValidation();
});

function CaseProdValidation() {
    $(".caseCount").rules("add", { digits: true });
}

html (This is just the lighbox as the rest quite a bit of markup):

<div class="lightbox" id="caseProductions">
    <a href="#" class="ui-icon ui-icon-circle-close closer"></a>
    <table>
        <thead>
            <tr>
                <td>
                    <h4>
                        Format</h4>
                </td>
                <td>
                    <h4>
                        Cases</h4>
                </td>
                <td>
                    <h4>
                        Bottles/Case</h4>
                </td>
                <td>
                    <h4>
                        Total Bottles</h4>
                </td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc187ml)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc187ml, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc187ml, new SelectList(Model.BottlesPerCase, "Key", "Value", 24), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc375ml)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc375ml, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc375ml, new SelectList(Model.BottlesPerCase, "Key", "Value", 12), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc500ml)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc500ml, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc500ml, new SelectList(Model.BottlesPerCase, "Key", "Value", 12), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc750ml)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc750ml, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc750ml, new SelectList(Model.BottlesPerCase, "Key", "Value", 12), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc1p5L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc1p5L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc1p5L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc3L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc3L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc3L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc5L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc5L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc5L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc6L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc6L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc6L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc9L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc9L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc9L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc12L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc12L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc12L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc15L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc15L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc15L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc18L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc18L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc18L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.cc27L)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cc27L, new { @class = "caseCount" })
                </td>
                <td>@Html.DropDownListFor(m => m.Wine.cpc27L, new SelectList(Model.BottlesPerCase, "Key", "Value", 1), new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
            <tr>
                <td>@Html.LabelFor(m => m.Wine.ccOther)
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.ccOther, new { @class = "caseCount" })
                </td>
                <td>@Html.TextBoxFor(m => m.Wine.cpcOther, new { @class = "countPerCase" })
                </td>
                <td class="totalBottleCalc">
                </td>
            </tr>
        </tbody>
    </table>
    <div style="display: inline-block">
    <input type="button" value="Save" />
    </div>
</div>

回答1:

It's actually the browser deciding that display:none fields should not be posted (except type="hidden" ones which are never displayed anyway).

One widely-used trick is to hide the field using positioning instead:

CSS:

input.hideThisField {
  position:absolute;
  top: -9999px;
  visibility:hidden;
}

But in your case, the problem is that your form fields are inside your lightbox, which is (apparently) being closed before the form is submitted. This won't work. You are going to have to keep the lightbox open while the form submits, or extract the form contents with JavaScript yourself once the lightbox is closed.

I'd probably opt for simply keeping the lightbox open until the form has been posted).