question

BigBear avatar image
0 Votes"
BigBear asked ZhiLv-MSFT answered

.Net 6 - Passing a radio button selected table row to a controller

I really feel like this should be easy but I’m thinking it may have changed with .Net 6. I can pass values to my controller with the input “name=’name’” but for some reason I cannot get any values from my model into my controller. I am trying to POST my row values to the controller. I am using an enumerable. I’m not sure if I should be using a or not. Another thing is how should I be populating my table row from a loop of the model. I thought using @Html. Was for older .net and tag helpers are the new way but I couldn’t get any to work populating my rows.

 <form method="post">
         <div id="tblPullParts" class="container justify-content-center mt-3">
           
             <table class="table table-striped">
               
                 <thead>
                     <tr>
                         <th></th>
                         <th >Order #</th>
                         <th >Item</th>
                         <th >Description</th>
                         <th >Quantity</th>
                     </tr>
                 </thead>
                 <tbody>
                     @foreach (var p in Model)
                     {
                         <tr>
                             <td><input type="radio" id="radio" name="radio"
                                 value="@Html.DisplayFor(item => p.PartID)" /></td>
 @*<td><input asp-for="Selected" type="radio" value="Selected" /></td>*@
                             <th scope="row">@Html.DisplayFor(item => p.PartID)</th>
                             <td>@Html.DisplayFor(item => p.Name)</td>
                             <td>@Html.DisplayFor(item => p.ItemLocation)</td>
                             <td>@Html.DisplayFor(item => p.PartGroup)</td>
                             <td>@Html.DisplayFor(item => p.Description)</td>
                             <td>
                                 <input type="text" asp-for="@p.Name" id="txtNameN" />
                             </td>
                         </tr>
                     }
                        
                 </tbody>
    
             </table>         
             @*<input type="text" id="@Model[0].Name" />*@
             <input type="text" id="txtName" name="txtName" value="" />
         </div>
         <div class="text-center">
             <button type="submit" class="btn btn-lg btn-success mt-3">Start Pick</button>
    
         </div>
      </form>
    
 [HttpPost]
         public async Task<IActionResult> Index( PartVM model, string radio, string txtName)
         {
                
             if (model?.PartID != 0)
             {
                 return View("UpdatePickQuantity", model);
             }
    
             if (!String.IsNullOrWhiteSpace(txtName))
             {
    
             }
    
             //Request.QueryString["radio"];
             var lstParts = await _ordersService.GetAllParts();
    
             return View(lstParts);
         }
dotnet-csharpdotnet-aspnet-core-general
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered

by default complex objects are bound to the body, and simple (string, int) are bound to the query string. you can override this with binding attributes, but a proper post back model is better:


 public class IndexRq
 {
      public string radio {get; set;} = "";
      public string Name {get; set;} = "";
      public string txtName {get; set;} = "";
 }  
    
  [HttpPost]
  public async Task<IActionResult> Index(IndexRq model)
 {
 }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ZhiLv-MSFT avatar image
0 Votes"
ZhiLv-MSFT answered

Hi @BigBear,

In Asp.net MVC application, the foreach statement and the @Html.DisplayFor is used to list the page model. If you are using the F12 developer Elements tools to check the rendered html resource, you can see that, it directly show the property value, without using an html element with the name attribute. Like this:

206046-image.png

So, when you click the submit button and submit this form, you can't get the page model data at the controller.

To solve this issue, you can add hidden field with the @Html.DisplayFor method. Like this:

     <td>
     @Html.DisplayFor(item => p.ItemLocation)
     <input type="hidden"  asp-for="@p.ItemLocation" name="[@i].ItemLocation">
     </td>

Or, you can try to use for statement and the Html.TextBoxFor or Html.RadioButtonFor to display the property value.

Code like this:

205983-image.png

The controller:

     public IActionResult ShoppingIndex()
     {
         var initdata = new List<ShoppingCar>()
         {
             new ShoppingCar(){ ProductID=101, Name="A", Item="Item 1", Price= 2.1, Quantity=5 },
              new ShoppingCar(){ ProductID=102, Name="B", Item="Item 2", Price= 2.2, Quantity=6 },
               new ShoppingCar(){ ProductID=103, Name="C", Item="Item 3", Price= 23, Quantity=7 },
                new ShoppingCar(){ ProductID=104, Name="D", Item="Item 4", Price= 2.4, Quantity=8 },
                 new ShoppingCar(){ ProductID=105, Name="E", Item="Item 5", Price= 2.5, Quantity=9 },
         };
         return View(initdata);
     }
     [HttpPost]
     public IActionResult ShoppingIndex(List<ShoppingCar> cars, string radio)
     {
         return View();
     }

and ShoppingCar model:

 public class ShoppingCar
 {
     public int ProductID { get; set; }
     public string Name { get; set; }
     public string Item { get; set; }
     public int Quantity { get; set; }
     public double Price { get; set; }

     //for the checkbox.
     public bool IsSelected { get; set; }
 }

Besides, about the radio button, using your code, since the radio button will use the same name, you can only select one row, and you can get the select row value via the name attribute.

But, if you want to select multiple rows, you can refer the above sample: add a IsSelected property in the page model, then use the Html.RadioButtonFor to display the radio button, and on its change event set the value to true or false. Then, you can according to the IsSelected property to get the select rows.

The result like this:

205978-1.gif

Note: when using the above code, it will use the submit button to submit the form and the page model, if you want to only submit the selected row data to the controller, you use the radio button click event, then use JQuery to get the selected row data and then use JQuery Ajax to call the controller with the selected row data.


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Best regards,
Dillion


image.png (152.6 KiB)
image.png (175.1 KiB)
1.gif (1.2 MiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.