I have a number of radio button groups, called Properties. A property can be things like "colour", "size", "height", and so on. The properties have options. For "colour", the options could be "Red", "Blue", and so on. When I'm posting my form, I'm able to read the Id for each individual radio button, but I haven't been able to access the group-Ids.
I'm rendering the properties like this:
for (int i = 0; i < Model.Properties.Count(); i++)
{
<div class="col-lg-3 col-md-4 col-sm-6">
<strong>#Model.Properties[i].Label</strong><br />
#foreach (var option in Model.Properties[i].Options)
{
<label style="font-weight:unset;">
#Html.RadioButtonFor(m => m.Properties[i].SelectedRadioOption, option.Id, new { id = Model.Properties[i].Id })
#option.Value
#Model.Properties[i].Unit
</label>
<br />
}
#Html.ValidationMessageFor(m => m.Properties[i].SelectedRadioOption)
</div>
}
This produces HTML like this:
<div class="col-lg-3 col-md-4 col-sm-6">
<strong>Size</strong><br />
<label style="font-weight:unset;">
<input checked="checked" data-val="true" data-val-required="The Selected property field is required." id="7012" name="Properties[0].SelectedRadioOption" type="radio" value="7025" />
34 - 36
</label>
<br />
<label style="font-weight:unset;">
<input id="7012" name="Properties[0].SelectedRadioOption" type="radio" value="7026" />
37 - 39
</label>
<br />
<span class="field-validation-valid" data-valmsg-for="Properties[0].SelectedRadioOption" data-valmsg-replace="true"></span>
</div>
<div class="col-lg-3 col-md-4 col-sm-6">
<strong>Colour</strong><br />
<label style="font-weight:unset;">
<input data-val="true" data-val-required="The Selected property field is required." id="7013" name="Properties[1].SelectedRadioOption" type="radio" value="7029" />
Black
</label>
<br />
<label style="font-weight:unset;">
<input id="7013" name="Properties[1].SelectedRadioOption" type="radio" value="7036" />
Pink
</label>
<br />
<span class="field-validation-valid" data-valmsg-for="Properties[1].SelectedRadioOption" data-valmsg-replace="true"></span>
</div>
This is the section in my controller's POST-method where I iterate through the Properties:
List<PropertyOptionForProduct> propertyOptions = new List<PropertyOptionForProduct>();
if (VMProduct.Properties != null)
{
for (var i = 0; i < VMProduct.Properties.Count(); i++)
{
propertyOptions.Add(new PropertyOptionForProduct
{
ProductId = VMProduct.Id,
ProductPropertyId = VMProduct.Properties[i].Id, // <-- This is always 0!
ProductPropertyOptionId = (int)VMProduct.Properties[i].SelectedRadioOption
});
}
}
If I select "Black" on the "Colour"-property, the object looks like this:
PropertyOptionForProduct
{
ProductId = 17008,
ProductPropertyId = 0, // <-- Why not 7013?
ProductPropertyOptionId = 7025
}
The correct value for ProductPropertyId in the above example should be 7013, which is the id-value on the radio button tag.
What am I doing wrong?
The format of what is posted back from a html <form> will be (for example) name1=value1&name2=value2 this maps to the name and the value field of your checked radiobuttons. Your code might for example example generate this post Properties[0].SelectedRadioOption=7026&Properties[1].SelectedRadioOption=7036.
The server has no idea about the id attribute in your radiobutton html. The id field is not included in the post unless you alter the post (using javascript) before it is sent. So either you need to include all identifiers in the value field perhaps separated like value="1243;34534" or you need to use javascript to include the id in the post data before it is posted.
Turns out, I'm a noob.
All I needed to add to make it work was this line of razor-code in the view:
#Html.HiddenFor(m => m.Properties[i].Id)
Now I can access the value of Properties[i].Id in the controller.
Related
I have checkboxes and select options inside a form.
<label>
<input type="checkbox" name="checkedBoxes" value="Reseller"checked />
<span>Reseller</span>
</label>
<label>
<input type="checkbox" name="checkedBoxes" value="SI" checked/>
<span>SI</span>
</label> //selects
...
Checkboxes are displayed as checked.
This is what my controller looks like:
public IActionResult combinedForm(string[] checkedBoxes, string SelectOption, string SelectOptionComp, string SelectOptionSer, string SelectOptionSoft, string SelectOptionApp)
{ //viewModel=...
var deneme = viewModel.Where(x =>x.Companies.company_type.Contains(checkedBoxes[0]));
}
How can I keep the state of checkboxes, preferably with the selected select options on view when I clicked the submit button?
Used viewbags for both
#if (((string[])ViewBag.checkedBoxes).Contains("Component provider"))
{
<label>
<input type="checkbox" name="checkedBoxes" value="Component provider" checked />
<span>Component provider </span>
</label>
}
else if (!((string[])ViewBag.checkedBoxes).Contains("Component provider"))
{
<label>
<input type="checkbox" name="checkedBoxes" value="Component provider" />
<span>Component provider </span>
</label>
}
<select style="width:100px" id="SelectOption" name="SelectOption" value="a">
<option>#Html.Label("-",(string)ViewBag.Name,new {#class = "mylabel" })</option>
I have a problem with my form its not passing radio button selected value to controller but another values are passed successfully when debugging.
Please note Job.PublicSubmissionReviewed its boolean, I noticed the this Job.PublicSubmissionReviewed passed through the form at all.
What am I missing on the radio button:
Here is my form and controller, your assistance will be greatly appreciated:
<form asp-action="Review">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Job.Id" />
<div class="form-group">
<p><strong>Approve or Reject public submission</strong></p>
<div class="form-group form-check-inline">
<label class="form-check-label">
<input class="form-radio-input" name="status" value="True" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Approve
</label>
</div>
<div class="form-group form-check-inline">
<label class="form-check-label">
<input class="form-check-input" name="status" value="False" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Reject
</label>
</div>
</div>
<div class="form-row showapprove" id="True">
<div class="form-group col-md-6">
<label asp-for="Job.JobCategoryId" class="control-label"></label>
<select asp-for="Job.JobCategoryId" class="form-control" asp-items="ViewBag.JobCategoryId">
</select>
</div>
<div class="form-group col-md-6">
<label asp-for="Job.Name" class="control-label"></label>
<input asp-for="Job.Name" class="form-control" />
<span asp-validation-for="Job.Name" class="text-danger"></span>
</div>
<div class="form-group col-md-6">
<label asp-for="Job.JobNo" class="control-label"></label>
<input asp-for="Job.JobNo" class="form-control" />
<span asp-validation-for="Job.JobNo" class="text-danger"></span>
</div>
<div class="form-group col-md-6">
<label asp-for="Job.ContractorId" class="control-label"></label>
<select asp-for="Job.ContractorId" class="form-control" asp-items="ViewBag.ContractorId">
</select>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-outline-primary"><i class="fas fa-save" aria-hidden="true"></i> Submit</button>
</div>
</form>
public async Task<IActionResult> Review(int id, JobViewModel model)
{
if (id != model.Job.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
var job = _context.Jobs.Where(j => j.Id == id).SingleOrDefault();
if (model.Job.PublicSubmissionReviewed == true) // approve public submission
{
job.PublicSubmissionReviewed = true;
job.PublicSubmissionReviewDate = DateTime.Now;
job.Name = model.Job.Name;
job.New = true;
job.JobNo = model.Job.JobNo;
job.JobCategoryId = model.Job.JobCategoryId;
job.ContractorId = model.Job.ContractorId;
_context.Update(job);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Public));
}
else if (model.Job.PublicSubmissionReviewed == false) // reject public submission
{
job.PublicSubmissionReviewed = true;
job.PublicSubmissionReviewDate = DateTime.Now;
job.New = false;
job.PublicSubmissionRejected = true;
job.PublicSubmissionRejectedDate = DateTime.Now;
job.PublicSubmissionReviewRejectReason = model.Job.PublicSubmissionReviewRejectReason;
_context.Update(job);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Public));
}
}
catch (DbUpdateConcurrencyException)
{
if (!JobExists(model.Job.Id))
{
return NotFound();
}
else
{
throw;
}
}
}
return View(model);
}
The name HTML attribute in a form element is what will be sent to the server to identify that field once you submit the form. Razor's model binding expects a certain name for form fields, and asp-for automatically sets that name for you. Since you've manually specified a name instead, the model binder will not be able to recognize the field, and therefore will not set it in your model.
It looks like you're setting the name in order to group the radio buttons together. Since asp-for will use the same name for a given bound property, you do not need to worry about that; all radio buttons corresponding to a certain property will be grouped together.
Therefore, you can simply remove the name attribute and your code should then work fine:
<input class="form-radio-input" value="True" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Approve
<input class="form-check-input" value="False" type="radio" asp-for="Job.PublicSubmissionReviewed" /> Reject
This question already has answers here:
How to make Check Box List in ASP.Net MVC
(2 answers)
Closed 2 years ago.
I have a list of checkboxes and I need to tell which are checked using C#. How would I tell which individual checkboxes are checked and then add their values together? I am using Asp.Net Core, if that could be helpful
<div class="row">
<form method="post" class="offset-3 col-5 border">
<div id="Colors" class="form-group" type="checkbox">
<label class="form-check-label">Colors</label>
<div class="form-check">
<input id="Red" class="form-check-input" type="checkbox" value="1">
<label class="form-check-label">Red</label>
</div>
<div class="form-check">
<input id="Yellow" class="form-check-input" type="checkbox" value="2">
<label class="form-check-label">Yellow</label>
</div>
<div class="form-check">
<input id="Green" class="form-check-input" type="checkbox" value="4">
<label class="form-check-label">Green</label>
</div>
<div class="form-check">
<input id="Blue" class="form-check-input" type="checkbox" value="8">
<label class="form-check-label">Blue</label>
</div>
<div class="form-group">
<input type="submit" value="Post" class="btn btn-primary" />
</div>
</div>
</form>
</div>
If you are using Jquery and you want to get all checkboxses are checked then you can do what you need like below :
var selected = [];
$('.form-check-input input:checked').each(function() {
selected.push($(this).attr('name'));
});
if you are using another Javascript librarry, you should do same.
if you want to get them in your Controller, so you should follow these steps:
1- Add a name to your Checkbox like (here chose color) :
<input id="Red" class="form-check-input" name="color" type="checkbox" value="1">
2- Add a property to your Model
public class AddPostModel
{
public List<int> Color { get; set; }
}
In this way, when you post your view, you have all values from checkboxes are checked.
I am making an ASP.NET Core Mvc web app and am working on a search form. In the form, a user can be looked up by first name, last name, zip, and either ID, email, or phone. Whether a user is inputting ID, email, or phone is determined by a drop down list. I want to bind this to the User model I have but am not sure how to do it dynamically with the dropdown list. I am able to bind first name, last name, and zip just fine since they are not dynamic fields. Code for what I have so far for the form is below:
<form asp-action="Search">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label for="sel1">Search By:</label>
#* The dropdown menu to choose input type *#
<select class="form-control" id="sel1">
<option>ID</option>
<option>Email</option>
<option>Phone</option>
</select>
</div>
#* Where users would input information for the dropdown field *#
<div class="form-group">
<label for="id">Value:</label>
<input type="text" class="form-control clearable" id="id" Placeholder="0123456789">
</div>
<div class="form-group">
<label asp-for="FirstName">First Name:</label>
<input asp-for="FirstName" type="text" class="form-control clearable" id="firstName" Placeholder="Jane">
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName">Last Name:</label>
<input asp-for="LastName" type="text" class="form-control clearable" id="lastName" Placeholder="Doe">
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Zip">Zip Code:</label>
<input asp-for="Zip" type="text" class="form-control clearable" id="zipCode" Placeholder="55555">
<span asp-validation-for="Zip" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Search" class="btn btn-default" id="search" />
</div>
</form>
Then the code where the model is bound on the Search function:
public async Task<IActionResult> Search([Bind("FirstName, LastName, Zip")] Consumer consumer)
{
// Code....
}
Is there a way to dynamically bind the input for the text input with id="id" based on the dropdown menu selection? Thanks in advance.
There's two options:
Render all the fields to the page (first, last, zip, etc.), and then use JavaScript to hide/show those fields based on the selection in the drop down list. For example, if you select "First Name", then show the FirstName input and hide the others. The user then enters their keywords in that input, and when they post, it will bind to FirstName naturally.
Post the value of the drop down and a generic text input. In your action, you can then simply switch on the value of the drop down and query the right property:
IQueryable<Foo> query = db.Foos;
switch (model.MyDropDownSelection)
{
case "FirstName":
query = query.Where(x => x.FirstName.Contains(keyword));
break;
// etc.
}
Let me clarify the title a bit.
I am a model which has a collection of trailers, and in turn each collection has a list of trailers. The html looks something like this
for(int i = 0; i <Model.TrailerCollection.Count(); i++)
{
... // some html
#for(int j = 0; j < Model.TrailerCollection[i].Trailers.Count(); j++)
{
<div>
#Html.CheckBoxFor(m => m.TrailerCollection[i].Trailers[j].SelectedTrailer, new {data_id = Model.TrailerCollection[i].Trailers[j].TrailerTypeId}
</div>
}
}
Now this outputs the html as I require with a list of items with a checkbox next to each one, but the problem arises when I post the model back to the controller.
If I have a list of say 10 checkboxes and check them all, when the model is passed to the controller the first one is always false, even when checked, but the others are fine.
Below is the JS for clarity.
var data = $("#form1").seralize
$.ajax({
url: 'xxxx',
data:data,
type:'post'
success: function(result)
{...}
});
My controller snippet
public async Task<HttpResponseMessage> Update(VM model)
I am just a little confused as to why the first one is always false.
Any help would be very much appreciated.
Rendered HTML
<div class="row">
<div class="col-lg-8"> Trl_86_dd_1 </div>
<div class="col-lg-4">
<input data-id="11" id="TrailerCollection_0__Trailers_0__SelectedTrailer" name="TrailerCollection[0].Trailers[0].SelectedTrailer" value="true" type="checkbox">
<input name="TrailerCollection[0].Trailers[0].SelectedTrailer" value="false" type="hidden">
</div>
<input data-val="true" data-val-number="The field TrailerTypeId must be a number." id="TrailerCollection_0__Trailers_0__TrailerTypeId" name="TrailerCollection[0].Trailers[0].TrailerTypeId" value="11" type="hidden">
<input id="TrailerCollection_0__Trailers_0__Name" name="TrailerCollection[0].Trailers[0].Name" value="Trl_86_dd_1" type="hidden">
</div>
<div class="row">
<div class="col-lg-8">Trl_86_dd_2</div>
<div class="col-lg-4">
<input checked="checked" data-id="26" id="TrailerCollection_0__Trailers_1__SelectedTrailer" name="TrailerCollection[0].Trailers[1].SelectedTrailer" value="true" type="checkbox">
<input name="TrailerCollection[0].Trailers[1].SelectedTrailer" value="false" type="hidden">
</div>
<input data-val="true" data-val-number="The field TrailerTypeId must be a number." id="TrailerCollection_0__Trailers_1__TrailerTypeId" name="TrailerCollection[0].Trailers[1].TrailerTypeId" value="26" type="hidden">
<input id="TrailerCollection_0__Trailers_1__Name" name="TrailerCollection[0].Trailers[1].Name" value="Trl_86_dd_2" type="hidden">
</div>