locked
Pass data from the view to a controller RRS feed

  • Question

  • User-1664485818 posted

    When I select a product from the table and click the submit button.

    The ProductID and quantity from the dropdown list is passed back to the controller.

    But my controller always receives the same ProductID regardless of which product I select.

    Any pointer or help much appreciated.

     @foreach (var t in Model.TyreFittedList)
     {
       <tr>
         <td class="text-center">@t.ProductID</td>
         <td>@t.Brand @t.Pattern <br /> @t.Full_size <br /></td>
         <td>@t.Label_Roll</td>
         <td>@t.Label_Wetgrip</td>
         <td>@t.Label_Noise1<span>dB</span></td>
         <td>
            @t.ProductUnitSalePriceMailOrder.Value.ToString("C", CultureInfo.CreateSpecificCulture("en-GB"))<br />
        </td>
        <td>
           @Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Quantity, "Id", "Quantity"), "0", new { style = "width: 60px;" })
                                            
           <input type="hidden" name="ProductID" value="@t.ProductID" />
    
           <input type="submit" class="btn btn-primary btn-sm btn-Order" name="Action:Order" value="Add" />
       </td>
    </tr>
                                }
     [HttpPost]
            public ActionResult SubmitSearchResultsMailOrder(ApplicationViewModel model, FormCollection collection, int? ProductID)
            {        
                if (ModelState.IsValid)
                {
                    if (Request.Form["Action:Order"] != null)
                    {             
                        int qty = model.SelectedProductId;             
                        int? ID = ProductID;                
                    }
                }
    
                return CurrentUmbracoPage();
            }

    Sunday, March 10, 2019 1:56 PM

Answers

  • User475983607 posted

    I'm using Umbraco, trying to post form but the page just keeps reloading, not hitting the controller 

    Well... Now, the HTML markup is invalid due to nesting HTML forms.   Your original HTML design has many inputs within a single HTML form.   Every time you click a button you are submitting every input within the form.  This is how HTML forms work.

    If you want to update one record at a time, then wrap each record in a form tag.  Rather than one big form you'll have several small forms, each representing a record.  You should be able to move the BeginUmbracoForm line so it wraps each record.

    @using (Html.BeginUmbracoForm("SubmitSearchResultsMailOrder", "Home", new { }, new { @novalidate = "novalidate" }, FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    	@Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Quantity, "Id", "Quantity"), "0", new { style = "width: 60px;" })
    	<input type="hidden" name="ProductID" value="@t.ProductID" />
    	<input type="submit" class="btn btn-primary btn-sm btn-Order" name="Action:Order" value="Add" />
    }

    I assume you'll also need to re-query the data and pass it to the View so when the page refreshes the quantity is in sync. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, March 10, 2019 3:51 PM

All replies

  • User475983607 posted

    When I select a product from the table and click the submit button.

    The ProductID and quantity from the dropdown list is passed back to the controller.

    But my controller always receives the same ProductID regardless of which product I select.

    Any pointer or help much appreciated.

     @foreach (var t in Model.TyreFittedList)
     {
       <tr>
         <td class="text-center">@t.ProductID</td>
         <td>@t.Brand @t.Pattern <br /> @t.Full_size <br /></td>
         <td>@t.Label_Roll</td>
         <td>@t.Label_Wetgrip</td>
         <td>@t.Label_Noise1<span>dB</span></td>
         <td>
            @t.ProductUnitSalePriceMailOrder.Value.ToString("C", CultureInfo.CreateSpecificCulture("en-GB"))<br />
        </td>
        <td>
           @Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Quantity, "Id", "Quantity"), "0", new { style = "width: 60px;" })
                                            
           <input type="hidden" name="ProductID" value="@t.ProductID" />
    
           <input type="submit" class="btn btn-primary btn-sm btn-Order" name="Action:Order" value="Add" />
       </td>
    </tr>
                                }
     [HttpPost]
            public ActionResult SubmitSearchResultsMailOrder(ApplicationViewModel model, FormCollection collection, int? ProductID)
            {        
                if (ModelState.IsValid)
                {
                    if (Request.Form["Action:Order"] != null)
                    {             
                        int qty = model.SelectedProductId;             
                        int? ID = ProductID;                
                    }
                }
    
                return CurrentUmbracoPage();
            }

    If you are trying to update a single records, then you need to warp each record in a separate <form> element.

    <td>
    	<form method="post">
    		@Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Quantity, "Id", "Quantity"), "0", new { style = "width: 60px;" })							
    		<input type="hidden" name="ProductID" value="@t.ProductID" />
    		<input type="submit" class="btn btn-primary btn-sm btn-Order" name="Action:Order" value="Add" />
    	</form>  
    </td>

    If you are trying to update several records at one time, then you'll need to fix the HTML so that the name attribute have indexes.  Otherwise, the model binder will be unable to populate the object collection on the server.

    Sunday, March 10, 2019 3:05 PM
  • User-1664485818 posted

    Thanks mgebhand, I'm using Umbraco, trying to post form but the page just keeps reloading, not hitting the controller 

    @{ Html.EnableClientValidation(false); }
    
    @using (Html.BeginUmbracoForm("SubmitSearchResultsMailOrder", "Home", new { }, new { @novalidate = "novalidate" }, FormMethod.Post))
    {
        @Html.AntiForgeryToken()
        <div class="container">
                    <div class="form-group">
                        <div class="col-sm-12 font-size">
                            <table id="SearchResultsFitted" class="table table-striped table-bordered dt-responsive" cellspacing="0">
                                <thead class="thead-dark">
                                    <tr>
                                        <th class="text-center">ID</th>
                                        <th>Tyre Model</th>
                                        <th>Fuel Efficiency</th>
                                        <th>Braking Under Wet Conditions</th>
                                        <th>External Noise Level</th>
                                        <th>Price Per Tyre<br /></th>
                                        <th>Select Quantity</th>
                                    </tr>
                                </thead>
                                @foreach (var t in Model.TyreFittedList)
                                {
                                    <tr>
                                        <td class="text-center">@t.ProductID</td>
                                        <td>@t.Brand @t.Pattern <br /> @t.Full_size <br /></td>
                                        <td>@t.Label_Roll</td>
                                        <td>@t.Label_Wetgrip</td>
                                        <td>@t.Label_Noise1<span>dB</span></td>
                                        <td>
                                            @t.ProductUnitSalePriceMailOrder.Value.ToString("C", CultureInfo.CreateSpecificCulture("en-GB"))<br />
                                        </td>
                                        <td>
                                            <form asp-action="SubmitSearchResultsMailOrder" asp-controller="Home">
                                                @Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Quantity, "Id", "Quantity"), "0", new { style = "width: 60px;" })
                                                <input type="hidden" name="ProductID" value="@t.ProductID" />
                                                <input type="submit" class="btn btn-primary btn-sm btn-Order" name="Action:Order" value="Add" />
                                            </form>
                                        </td>
                                    </tr>
                                }
                            </table>
    
                        </div>
                    </div>
                </div>

    Sunday, March 10, 2019 3:20 PM
  • User475983607 posted

    I'm using Umbraco, trying to post form but the page just keeps reloading, not hitting the controller 

    Well... Now, the HTML markup is invalid due to nesting HTML forms.   Your original HTML design has many inputs within a single HTML form.   Every time you click a button you are submitting every input within the form.  This is how HTML forms work.

    If you want to update one record at a time, then wrap each record in a form tag.  Rather than one big form you'll have several small forms, each representing a record.  You should be able to move the BeginUmbracoForm line so it wraps each record.

    @using (Html.BeginUmbracoForm("SubmitSearchResultsMailOrder", "Home", new { }, new { @novalidate = "novalidate" }, FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    	@Html.DropDownListFor(model => model.SelectedProductId, new SelectList(Model.Quantity, "Id", "Quantity"), "0", new { style = "width: 60px;" })
    	<input type="hidden" name="ProductID" value="@t.ProductID" />
    	<input type="submit" class="btn btn-primary btn-sm btn-Order" name="Action:Order" value="Add" />
    }

    I assume you'll also need to re-query the data and pass it to the View so when the page refreshes the quantity is in sync. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, March 10, 2019 3:51 PM
  • User-1664485818 posted

    Thanks mgebhard, everything is working ok now :)

    When the page refreshes all the dropdown values changes to the quantity I selected, however I would prefer only the one record i.e dropdown list change to the value selected and the remaining records (dropdown list to remain at 0) how would I achieve this?

    Sunday, March 10, 2019 4:35 PM
  • User475983607 posted

    When the page refreshes all the dropdown values changes to the quantity I selected, however I would prefer only the one record i.e dropdown list change to the value selected and the remaining records (dropdown list to remain at 0) how would I achieve this?

    This is pretty basic MVC stuff brucey... The Controller Action queries the database and fetches a Model.  The Model is passed to the View.  The View uses the Mode to render the HTML.  

    I can only see the code that you share.  I'm not sure why you are unable to get this information.

    Sunday, March 10, 2019 5:02 PM