I am displaying controls dynamically. I am able to display all controls with appropriate values except for radio button. The radio button list is rendering correctly but the its value is not being checked.
foreach (var radio in item.RadioButtonList)
{
//Option 1
#Html.RadioButton(radio.Text, radio.Checked) #: #radio.Text
//Option 2
#Html.RadioButton(name: radio.Text, value: radio.Checked, isChecked: radio.Checked)*#
//Option 3
<input type="radio" value="radio.Text" checked="#radio.Checked"/> #: #radio.Text
}
My model is
public class FromElement
{
public List<CBRBControl> RadioButtonList { get; set; }
}
public class CBRBControl
{
public string Text { get; set; }
public bool Checked { get; set; }
public string IsRadioChecked { get; set; }
}
My controller
public ActionResult FormDetails(int formID)
{
if (form.Field_Type_Name == "Radio Button")
{
radioList = new List<CBRBControl>();
// For option 1 and 2
radioList.Add(new CBRBControl
{
Checked = true,
Text = "Radio Test 1"
});
radioList.Add(new CBRBControl
{
Checked = false,
Text = "Radio Test 2"
});
// For option 3
radioList.Add(new CBRBControl
{
IsRadioChecked = "checked",
Text = "Radio Test 1"
});
radioList.Add(new CBRBControl
{
Text = "Radio Test 2"
});
form.RadioButtonList = radioList;
}
I tried working this using there method. In option 1 and 2 none of the radio button in the list is getting checked and in option 3 all the radio button is getting selected.
For option 1 the html generated is
<input id="Radio_Test_1" name="Radio Test 1" type="radio" value="True"> Radio Test 1
<input id="Radio_Test_2" name="Radio Test 2" type="radio" value="False"> Radio Test 2
For option 2 the html generated is
<input checked="checked" id="Radio_Test_1" name="Radio Test 1" type="radio" value="True"> Radio Test 1
<input id="Radio_Test_2" name="Radio Test 2" type="radio" value="False"> Radio Test 2
For option 3 the html generated is
<input type="radio" value="radio.Text" checked="checked"> Radio Test 1
<input type="radio" value="radio.Text" checked=""> Radio Test 2
You are using the wrong overload from RadioButton. And you should provide the Value for this control as well.
Change your model to something like this:
public class CBRBControl
{
//
// Name should be unique, given that the HTML.RaadioButton,
// will use this to generate the input attribute id, that
// must be unique in the sabe HTML document
//
public string Name { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public bool IsChecked { get; set; }
}
And use the correct overload from Html.RadioButton like this:
#foreach (var radio in Model.RadioButtonList)
{
#Html.RadioButton(radio.Name, radio.Value, radio.IsChecked) #: #radio.Text
}
The HTML generated will looks like:
<input id="radio_0" name="radio_0" type="radio" value="1" /> Radio Test 1
<input checked="checked" id="radio_1" name="radio_1" type="radio" value="2" /> Radio Test 2
Related
I'm implementing asp.net core 3.1. I have three radio buttons in my razor view and with the following code, I want to send the selected radio button value to Index action in controller in order to show its related data. My problem is, I can't set one of those radio buttons to be checked by default.
#model CSD.ChartObjects
<form method="post">
#foreach (var year in Model.Years)
{
<input type="radio" asp-for="Year" value="#year" />#year<br />
}
<input type="submit" asp-action="Index" />
</form>
Here is my model object that is read in razor
public class ChartObjects
{
public List<ChartModel> Percent { get; set; }
public List<ChartModel> Time { get; set; }
public List<ChartModel> Avg { get; set; }
public List<ChartModel> Total { get; set; }
public string Year { get; set; }
public string[] Years = new[] { "1398", "1399", "1400" };
}
And here is the body of my HomeController:
[HttpGet]
public IActionResult Index()
{
return (BuildIndexModel("1399"));
}
[HttpPost]
public IActionResult Index([FromForm] string currentYear)
{
return (BuildIndexModel(currentYear));
}
public IActionResult BuildIndexModel(string currentYear)
{
...
}
I think this will work:
#foreach (var year in Model.Years)
{
var fi = (year == Model.Years[0]) ? true : false ;
<input type="radio" asp-for="Year" value="#year" checked="#fi" />#year<br />
}
My problem is, I can't set one of those radio buttons to be checked by default.
To set a default checked radio button, you can try following code snippet.
<form method="post">
#foreach (var year in Model.Years)
{
<input type="radio" asp-for="Year" value="#year" checked="#(year == Model.Years.FirstOrDefault() ? "checked" : null)"/>#year<br />
}
<input type="submit" asp-action="Index" />
</form>
Update:
my data by default is for 1399
You can pass default year through ViewData, like below.
In controller action
ViewData["defaultyear"] = "1399";
In view page
<input type="radio" asp-for="Year" value="#year" checked="#(year == ViewData["defaultyear"].ToString() ? "checked" : null)"/>#year<br />
I don't know how to use asp.net, but In JS, I just simply have to access the attributes of the HTML Input tag so you can then assign the attribute "checked" to true.
I guess is something like this:
HtmlElement Input1 = webBrowser1.Document.GetElementById("ID"); // consider adding an ID
Input1.Attributes.Add("checked", "true");
Check this two links:
How to: Set HTML Attributes for Controls in ASP.NET Web Pages
HtmlDocument.GetElementById(String) Method
I'm using a kendo-dropdownlist tag helper from the Telerik UI for ASP.NET Core library. So far I have been able to bind the values that can be selected, but I can't figure out how to get the selected item when a post request is sent.
I have a login form:
#page
#model PITS.Areas.Authentication.Pages.Login2Model
#{
}
<form method="post">
<input class="form-control k-textbox" asp-for="UserName" type="text" />
<input class="form-control k-textbox" asp-for="Password" type="password" />
<kendo-dropdownlist name="administraties"
filter="FilterType.Contains"
placeholder="Selecteer Administratie"
style="width: 100%;"
bind-to="Model.Organizations">
</kendo-dropdownlist>
<input type="submit" class="btn btn-primary pull-right" value="Login">
</form>
and a PageModel
public class Login2Model : PageModel
{
[BindProperty]
public string UserName { get; set; }
[BindProperty]
public string Password { get; set; }
[BindProperty]
public IEnumerable<SelectListItem> Organizations { get; set; }
public void OnGet()
{
this.Organizations = _getOrganizations();
}
private IList<SelectListItem> _getOrganizations()
{
return new List<SelectListItem>
{
new SelectListItem {Value = Guid.NewGuid().ToString(), Text = "Google"},
new SelectListItem {Value = Guid.NewGuid().ToString(), Text = "Apple"},
new SelectListItem {Value = Guid.NewGuid().ToString(), Text = "Microsoft"}
};
}
}
I would expect an attribute on the kendo-dropdownlist taghelper but I haven't found it yet. Could someone tell me how to get the selected item?
This assumes you are using Razor.
Use the "for" property to bind the kendo-dropdownlist to a page model property.
for="MySelection"
Then in your page model.
public string MySelection { get; set; }
I have a form with 2 fields a dropdownlist and a checkbox. I have everything working correctly but i can not for some reason obtain the value of a checkbox if it is checked this is my code..
[HttpPost]
public ActionResult view(string pick)
{
switch (pick)
{
case "Deny":
// capture checkbox value here
break;
case "Accept":
// capture checkbox value here
break;
}
return View();
}
This is my view
#using (Html.BeginForm("view", "grouprequest", FormMethod.Post, new {}))
{
#Html.DropDownList("pick", new SelectList(new List<Object>{
new{ Text ="Accept", Value= "Accept"},new{ Text ="Deny", Value= "Deny"}}, "Value", "Text"), new {})
<input type="submit" name="work" id="work" value="Update" style="font-size:16px" />
foreach (var item in Model)
{
<input type="checkbox" id="#item.grouprequestID" name="#item.grouprequestID" value="#item.grouprequestID" />
}
}
Basically the dropdownlist has 2 options which are Accept and Deny I can capture which one the user chooses via the SWITCH-case in the controller now how can I capture the value of the checkboxes? If you notice the Checkboxes have a variable to them named #groupRequestID so every checkbox has a different unique value like 1,2,3 etc.. any help would be greatly appreciated !!
The Model
public class grouprequest
{
[Key]
public int grouprequestID { get; set; }
public int? profileID { get; set; }
public int? registrationID { get; set; }
public DateTime expires { get; set; }
public int? Grouplink { get; set; }
}
Check boxes when posted to the server act a little strange.
If a box is checked the browser will send name=value as in
<input type="checkbox" name="name" value="value" />
But if the checkbox is not checked the server doesn't send anything.
<input type="checkbox" name="Check1" id="Checks1" value="Hello" checked="checked"/>
<input type="checkbox" name="Check1" id="Checks1" value="Hello1" />
<input type="checkbox" name="Check1" id="Checks1" value="Hello2" />
Will result in Check1 = Hello
What this means is if all your check boxes are related, naming them the same will populate the same attribute of your ActionMethod. If that attribute is an enumeration it will contain only the ones that are checked.
If you have this in your view:
<input type="checkbox" name="MyValues" value="1" checked="checked"/>
<input type="checkbox" name="MyValues" value="2" />
<input type="checkbox" name="MyValues" value="3" />
and this as your controller action method:
public ActionMethod MyAction(IEumerable<int> myValues)
The myValues variable will look like this:
myValues[0] == 1
You should also note that if you are using the Html helper extension:
#Html.CheckBoxFor(m => m.MyValue)
Where MyValue is a bool the extension will create a checkbox input tag and also a hidden input tag with the same name, meaning a value will always be passed into the controller method.
Hope this helps.
I have a weird problem.
I'm making dynamic form in Razor. I'm using dictionary to store dynamically added inputs.
I generate code like that:
<input type="hidden" value="96" name="Inputs[0].Key">
<input type="text" name="Inputs[0].Value">
I receive in my controller this dictionary. It always has as many elements that I added, but all of them are empty.
This is part of my model:
public class MetriceModelTaskSchedule
{
public IEnumerable<KeyValuePair<long, string>> Inputs { get; set; }
}
What can be wrong here?
What can be wrong here?
The fact that the KeyValuePair<TKey, TValue> class has the Key and Value properties which are readonly. They do not have a setter meaning that the model binder simply cannot set their value.
So as always start by defining a view model:
public class InputViewModel
{
public long Key { get; set; }
public string Value { get; set; }
}
and then:
public class MetriceModelTaskSchedule
{
public IEnumerable<InputViewModel> Inputs { get; set; }
}
Alternatively you could use a Dictionary:
public class MetriceModelTaskSchedule
{
public IDictionary<long, string> Inputs { get; set; }
}
Also make sure that you have respected the standard naming convention for your input fields in the view so that the model binder can successfully bind them to your model:
<div>
<input type="text" name="Inputs[0].Key" value="1" />
<input type="text" name="Inputs[0].Value" value="value 1" />
</div>
<div>
<input type="text" name="Inputs[1].Key" value="2" />
<input type="text" name="Inputs[1].Value" value="value 2" />
</div>
...
I have a List<Task> in my model. This list contains 2 tasks(say) in it
public List<Task> Tasks { get; set; }
public class Task {
public Task()
{
Title="";
Total= 0;
}
public string Title{ get; set; }
public int Total{ get; set; }
}
Now in my razor view, I want render 2 text boxes for each of the Tasks in the List<Tasks> of my model.
I didn't loop, just placed direct text boxes like:
#Html.TextBoxFor(m => m.Tasks[0].Title, new { #maxlength = "50"})
#Html.TextBoxFor(m => m.Tasks[0].Total, new { #maxlength = "2"})
<br>
#Html.TextBoxFor(m => m.Tasks[1].Title, new { #maxlength = "50"})
#Html.TextBoxFor(m => m.Tasks[1].Total, new { #maxlength = "2"})
This renders the form fine, but clicking the submit button doesn't do anything in FF.
However it posts fine in IE9.
View source shows this html generated like this:
<input id="Tasks_0__Title" maxlength="50" name="Tasks[0].Title" type="text" value="" />
<input data-val="true" data-val-number="The field Total must be a number." data-val-required="The Total field is required." id="Tasks_0__Total" maxlength="2" name="Tasks[0].Total" type="text" value="" />
This HTML doesn't look right. It has name="Tasks[0].Total" which seems odd.
How should I do this so that I can access the text box values from List<> in my controller after post?
Thanks
EDIT:
I just kept one row for test. This is the html I see in FF.
<input id="Tasks_0__Title" type="text" value="" name="Tasks[0].Title" maxlength="50">
<input id="Tasks_0__Total" type="text" value="" name="Tasks[0].Total" maxlength="2" data-val-required="The Total field is required." data-val-number="The field Total must be a number." data-val="true">
This doesn't post when I click the submit button.
Now if I change name="Tasks[0].Title" to name="Tasks_0__Title" and name="Tasks_0__Total"
in FIREBUG it posts fine.
If I delete name completely it also posts fine in FF
You should use Tasks[0].Total and Tasks[1].Total instead of Items:
#Html.TextBoxFor(m => m.Tasks[0].Title, new { #maxlength = "50"})
#Html.TextBoxFor(m => m.Tasks[0].Total, new { #maxlength = "2"})
<br/>
#Html.TextBoxFor(m => m.Tasks[1].Title, new { #maxlength = "50"})
#Html.TextBoxFor(m => m.Tasks[1].Total, new { #maxlength = "2"})
name="Tasks[0].Total" is not odd. That's exactly how the input should be named in order for the model binder to fetch the value back in the POST action. See this blog post for the wire format used by the default model binder when dealing with lists and dictionaries.
This being said I would recommend you using editor templates => instead of writing those 5 lines of code in your view replace them with:
#Html.EditorFor(x => x.Tasks)
and then inside the corresponding editor template (~/View/Shared/EditorTemplates/Task.cshtml) which will be automatically rendered for each element in the Tasks collection:
#model Task
#Html.TextBoxFor(m => m.Title, new { #maxlength = "50"})
#Html.TextBoxFor(m => m.Total, new { #maxlength = "2"})
<br/>
Now you can leave the editor templates worry about proper naming convention, etc...
As far as your POST action is concerned:
[HttpPost]
public ActionResult Foo(MyViewModel model)
{
// model.Tasks should be correctly bound here
...
}
In case you want to have multiple elements with textboxes.
for (int i = 0; i < Model.Students.Count; i++)
{
#Html.HiddenFor(modelIem => Model.Students[i].StudentId)
<tr>
<td>
#Html.DisplayFor(modelItem => Model.Students[i].Student.FirstNames)
</td>
<td>
#Html.DisplayFor(modelItem => Model.Students[i].Student.LastNames)
</td>
<td>
#Html.TextBoxFor(modelItem => Model.Students[i].Score, new { #type = "number" })
</td>
</tr> }
This is the ViewModel
public class MyModel
{
public List<StudentGrade> Students { get; set; }
}
public class StudentGrade {
public ApplicationUser Student { get; set; }
[Range(1, 100)]
public int? Score { get; set; } = null;
public string Description { get; set; } = null;
public string StudentId { get; set; }
}
At the End it will look like this.