Why is form returning null value for a checked radiobutton instead of true or false? - radio-button

I have a Boolean field in my model that I'm using an Editor template for in order to display the radio buttons for Yes and No.
#Html.EditorFor(model => model.Disruption)
#{
Dictionary<string, object> yesAttrs = new Dictionary<string, object>();
Dictionary<string, object> noAttrs = new Dictionary<string, object>();
yesAttrs.Add("id", ViewData.TemplateInfo.GetFullHtmlFieldId("") + "Yes");
noAttrs.Add("id", ViewData.TemplateInfo.GetFullHtmlFieldId("") + "No");
if (Model.HasValue && Model.Value)
{
yesAttrs.Add("checked", "checked");
}
else if (Model.HasValue && !Model.Value)
{
noAttrs.Add("checked", "checked");
}
}
#Html.RadioButtonFor(x => x, "true", yesAttrs)
<label for="#(ViewData.TemplateInfo.GetFullHtmlFieldId(""))Yes">Yes</label>
#Html.RadioButtonFor(x => x, "false", noAttrs)
<label for="#(ViewData.TemplateInfo.GetFullHtmlFieldId(""))No">No</label>
Using the console viewer in developer tools on the browser I can see that when I check Yes the value is true and when I check No the value is false, yet when I click Submit the insert fails as the column cannot contain a NULL value. Why is the true or false value not being passed correctly in this case when the same code seems to work on other fields?

Related

How can I pass Dictionary<string, dynamic> to a blazor component?

I am trying to pass a dictionary as a parameter to a blazor component. The dictionary needs to store <string, dynamic>, <string, List>, and <string, Dictionary<string, dynamic>> key-value pairs.
I tried to do this, but get the error, "'EventCallbackFactory' has no applicable method named 'CreateBinder' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched."
Is what I am trying to do valid, and if not, why? Is there another way I should approach this?
Here is the code for my blazor component, for reference:
#page "/dictitemcomponent"
#using System.Collections.Generic;
<ul>
#foreach (KeyValuePair<string, dynamic> item in thisDict)
{
#if(item.Value.GetType() == typeof(Dictionary<string, dynamic>))
{
<li>#item.Key.ToString() : </li>
#foreach (var dict in item.Value)
{
<DictItemComponent thisDict=dict/>
}
}
#if(item.Value.GetType() == typeof(List<dynamic>))
{
<li>#item.Key.ToString() : </li>
#foreach (var value in item.Value)
{
<li>#value</li>
}
}
#if(item.Value.GetType() != typeof(List<dynamic>) && item.Value.GetType() != typeof(Dictionary<dynamic, dynamic>))
{
<li>#item.Key.ToString() : <input #bind="item.Value"/></li>
}
}
</ul>
#code
{
public KeyValuePair<string, dynamic> newProperty = new KeyValuePair<string, dynamic>();
[Parameter] public Dictionary<string,dynamic> thisDict {get; set;}= new Dictionary<string, dynamic>();
//convert the value of a KVP to a dictionary
public void ValueToProperty(KeyValuePair<string,dynamic> property)
{
string key = property.Key;
property = new KeyValuePair<string, dynamic>(key, new Dictionary<string, dynamic>());
}
public void ValueToList(KeyValuePair<string,dynamic> property)
{
string key = property.Key;
property = new KeyValuePair<string, dynamic>(key, new List<dynamic>());
}
}
May I know what you are trying to achieve?
Based on your first if statement, why would you have a dictionary inside a dictionary?
By reading your exception and your 3rd conditional statement, it seems that you are trying to bind the input to your dictionary value. However, this is not how you should use a dictionary. Unless you are binding to the usual "type" property (e.g. string), you may use #bind=someVariable. Otherwise, in a dictionary, each value should tie to their respective key and therefore, #bind=_dict[key] ("shorthand" syntax for #bind-value and #bind-value:event) instead of binding input to the item.value. For easier understanding, I've scoped out the aforementioned conditional statement and simulated a solution to the problem in the following lines. It should render value in the <label> next to the input during onchange:
#page "/dict"
#foreach (var kvp in _dict)
{
<div>
<label>#kvp.Key</label>
<input #bind=_dict[kvp.Key] />
<label>Key:#kvp.Key|Value:#kvp.Value</label>
}
#code {
private Dictionary<string, string> _dict = new()
{
["1"] = "One",
["2"] = "Two",
["3"] = "Three",
["4"] = "Four",
["5"] = "Five",
};
}
Meanwhile, you should simplify your if statements as follow:
#if(item.Value.GetType() == typeof(Dictionary<string, dynamic>))
{
//dowork
}
else if(item.Value.GetType() == typeof(List<dynamic>))
{
//do more work
}
else
{
//do other work
}
Screenshot for my Input fields rendered based on Key Value Pair and value entered

StateHasChange dont want to rerender Select with new seleted

I have this dropdown that generates a couple of dropdowns.
it shows fine at first render. then i change a value that gives me back some new selected items for all the dropdowns.
problem is my StateHasChanged does not want to rerender correctly.
#foreach (Parameter parameter in #group.Parameters)
{
#parameter.Description
if (parameter.IsList == true)
{
//Create Dropdown List
<select class="form-control" #onchange="#((ChangeEventArgs args) => SelectValueChange(args, parameter.Name))">
#foreach (Element element in parameter.Domain.Elements)
{
<option selected=#element.IsSelected style="color:white; background-color:#element.State;" value=#element.Name>#element.Description</option>
}
</select>
}
<br />
}
SelectValueChange is what i call when a new option is selected.
private void SelectValueChange(ChangeEventArgs args, string selectName)
{
var selectedName = args.Value.ToString();
ValueChange(selectName, selectedName);
}
ValuChange is where im trying to force the rerender.
public void ValueChange(string param, string value)
{
Result newResult = config.Commit(param, value);
SetupPage(newResult);
//TODO: find a way to change these values newResult.Response.Changed or newResult.Response.AllChanged
ShowNotification(newResult.Response);
InvokeAsync(() => StateHasChanged());
InvokeAsync(StateHasChanged);
}
SetupPage is where im just settings the new values from my result. maybe i can set these in a different way?
private void SetupPage(Result result)
{
CurrentStep = null;
Headline = null;
Groups = null;
PrevSteps = null;
NextSteps = null;
CurrentStep = result.CurrentStep;
Headline = result.RootGroup.Description;
Groups = result.RootGroup.SubGroups;
PrevSteps = result.PreviousSteps;
NextSteps = result.NextSteps;
StateHasChanged();
}

Can I set value=1 item in dropdown as default item

ViewBag.UserStatusList = new List<SelectListItem>
{
new SelectListItem{Text = "Active", Value = "1",Selected=true},
new SelectListItem { Text = "Inactive", Value = "0",Selected=false }
};
the above shows the viewbag which i am binding to dropdown list . So here I want to fix Active as default item in the view page. How can I do that please give some suggestions
#Html.DropDownListFor(m => m.UserStatus, (IEnumerable<SelectListItem>)ViewBag.UserStatusList, new { #id = "ddlCustomerStatusList", #class = "form-control", #selected = "selected" })
This is my view
You need to set the value of your model property in the GET method before you return the view
model.UserStatus = 1;
return View(model);
You can delete setting the Selected property of SelectListItem because its ignored by the DropDownListFor() method (internally the method builds a new IEnumerable<SelectListItem> based on the value of the property your binding to)
Note also you should delete new { #selected = "selected" }(that is not a valid attribute for a <select> element) and there is no need to use new { #id = "ddlCustomerStatusList" } as the helper already creates an id attribute (its id="UserStatus")

RadioButton list Binding in MVC4

I have a radiobuttonList which is binding data from Enum Class and its working correctly in the view.
But my concern is how can I set inital value of radiobutton to CROCount.ONE.I have tried to set the initial value in the following way but couldnot get the desired result.
public enum CROCount
{
ONE = 1,
TWO = 2
}
ViewModel is
public class RegistraionVM
{
....
public EnumClass.CROCount CROCount { get; set; }
}
I generated the radio button list as follows.
<div>
#foreach (var count in Enum.GetValues(typeof(SMS.Models.EnumClass.CROCount)))
{
<label style="width:75px">
#Html.RadioButtonFor(m => m.RegistrationVenue, (int)count,
new { #class = "minimal single" })
#count.ToString()
</label>
}
</div>
Binding performed in the Controller is
public ActionResult Index(int walkInnId)
{
try
{
var _studentReg = new RegistraionVM
{
CROCount=EnumClass.CROCount.ONE
};
return View(_studentReg);
}
catch (Exception ex)
{
return View("Error");
}
}
Your binding your radio button to property CROCount (not RegistrationVenue) so your code should be
#Html.RadioButtonFor(m => m.CROCount, count, new { id = "", #class = "minimal single" })
Note that the 2nd parameter is count (not (int)count) so that you generate value="ONE" and value="TWO". Note also the new { id = "", removes the id attribute which would otherwise result in duplicate id attributes which is invalid html.

How do I get the value of my drop down list

I am trying to return the selected item and when i debug my code, the view data track list is always null.
How can I assign the value to the view data?
public ActionResult EditParcel(int id)
{
Parcel parc = _abcSearchService.GetAbcParcel(id);
List<SelectListItem> TrackList = new List<SelectListItem>
{
new SelectListItem { Text = "Processing", Value = "Processing", Selected = true},
new SelectListItem { Text = "Out for delivery", Value = "Out for delivery"},
new SelectListItem { Text = "Delivered", Value = "Delivered"},
};
ViewData["TrackList"] = TrackList.AsEnumerable();
}
it all depends on how you are setting up the drop down. I would recommend not using viewbag/data for sending the information. Put it in your viewmodel build the list how you are building it but save it to the view model
viewModel.TrackList = TrackList;
then on your view
#Html.DropDownListFor(x => x.Track, Model.TrackList)
the for helper will override the selected property. In this case to set the selected value you would need to set viewModel.Track to the value you want selected and the for helper would then be set accordingly. Let me know if you have any questions.