How can I set id using Html.EditorFor with MVC3 - asp.net-mvc

I am trying to set a field id as follows:
#Html.EditorFor(x => x.Order, new { id = string.Format("Order_{0}", Model.Row) })
but this results in the following and it seems my id is not being set:
<input type="text" value="334" name="item.Order" id="item_Order" class="text-box single-line">
Does anyone have an idea what I am doing wrong. I checked the allowable formats for EditorFor and looked on google for examples but I could not see anything that matched what I need.

You should change to
#Html.TextBoxFor(x => x.Order, new { id = string.Format("Order_{0}", Model.Row) })
The second parameter of #Html.EditorFor is for view data, not for html attributes

#Html.EditorFor(x => x.Order, null, string.Format("Order_{0}", Model.Row))

I know this question is pretty old, but all I needed to do was the following:
#Html.EditorFor(modelItem => item.EndDate,
new { htmlAttributes = new { #class = "form-control", #id = #endID } })
You can give it whatever classes or id that you want/need. I have this earlier in my page as well to create a different ID for each item:
string endID = "end-" + #item.ID;
Hopefully this helps someone in the future.

have you tried creating an editor template for your x.Order?
have this on your editor template:
<input type="text" id="#ViewData["id"]">
and use this on your view page:
#Html.EditorFor(x => x.Order, new { id = string.Format("Order_{0}", Model.Row) })

I'm not sure if you can override the ID attribute when using the strongly typed helpers. But you can use the other non-model type:
#Html.Editor(string.Format("Order_{0}", Model.Row), Model.Order)
This will use the first parameter as the ID and the second as the default value.

If you want to use EditorFor, you can do this:
#Html.EditorFor(model => model.Order, new { htmlAttributes = new { #id = "YOUR_ID_HERE"})
For the above example it would be:
#Html.EditorFor(model => model.Order, new { htmlAttributes = new { #id = $"Order_{0}" } })
Svetlosav's answer looks good but it will mess up your data binding. If you use that answer, check to see if your model is populating as expected and not with a default value (null, false, 0, etc..).

Related

Razor EditorFor with Onclick Event

I have nullable Boolean value that is being presented as a checkbox using the following code:
#Html.EditorFor(m => m.IsInitialStatus, new { htmlAttributes = new { #onclick = "InitialOrStarting()" } })
however the #onclick attribute is not being added to the HTML when the page is loaded. Am I missing something here? I had taken the example from an answer on this page.
I have also looked at changing this to a CheckBoxFor but keep getting an issue with the nullable Bool datatypes.
Any help on this would be appreciated! I just want a nullable bool checkbox with an onClick event firing to a Javascript function... I am not the most advanced user but this seems to be more difficult for me to do than maybe it should!?
EDIT
There appears to be an EditorTemplate for Boolean which contains:
#model bool?
#Html.CheckBox("", Model.GetValueOrDefault())
You are using the overload of EditorFor() where the 2nd parameter is additionalViewData. If you did not have a specific EditorTemplate for bool?, the method would generate the default template, which is a <select> with 3 values for null, true and false, and include the attributes.
But because you have an EditorTemplate, you need to add the attributes yourself by reading the value from the ViewDataDictionary (typically, an EditorTemplate includes multiple html elements, so the method cannot know which element you want to apply the attributes to).
Your template would need to be
#model bool?
#{ var attributes = ViewData["htmlAttributes"]; }
#Html.CheckBox("", Model.GetValueOrDefault(), attributes)
Having said that, your should not be doing this. A bool? has 3 states (null, true or false) but a checkbox has only 2 states - on or off (translates to true or false) so your EditorTemplate does not represent the possible values of your property.
If you only want to allow true or false, then your property should not be nullable. Alternatively, use the default template that does allow a null selection (or if you want an alternative UI, create a template that renders 3 radio buttons for example)
In addition, I recommend you stop polluting you markup with behavior and use Unobtrusive JavaScript - i.e. your script will be
$(yourCheckBox).click(function() {
... // do something
});
Onclick Event does not working for #HtmlEditorFor. But you can use class attribute.
<script>
$(".single-checkbox").on("change", function () {
if ($(".single-checkbox:checked").length > 2) {
this.checked = false;
alert ("Only 2 choice")
}
});
</script>
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })
#Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { #class = "single-checkbox" } })

Custom EditorFor Template and htmlAttributes

I'm trying to use EditorFor custom templates.
I want to create a Int32 and decimal templates to render the inputs with some validations.
This is what I'm trying
#model int?
#Html.TextBoxFor(model => model, null, new { #type="text", #oninput = "this.value=this.value.replace(/[^0-9]/g,'')" } )
And I call it like
#Html.EditorFor(x => x.ExampleIntField)
It renders an <input type="text", oninput="this.value=this.value.replace(/[^0-9]/g,'')"
To here everything works, but when I try to pass extra htmlAttributes like readonly I don't understand how I must receive it in EditorFor template.
Example
#Html.EditorFor(x => x.ExampleIntField, new { htmlAttributes = new { #readonly = "readonly" } } )
I tried this I got the exact same <input type="text", oninput="this.value=this.value.replace(/[^0-9]/g,'')" rendered without readonly attribute
You are using the overload of EditorFor() that passes the object as additionalViewData. You can read that within the template from the ViewDataDictionary
#model int?
#{ var attributes = ViewData["htmlAttributes"]; } // returns { #readonly = "readonly" }
which you could then merge with your existing attributes and use in the TextBoxFor() method.
#{
var htmlAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(attributes);
htmlAttributes.Add("oninput", "this.value=this.value.replace(/[^0-9]/g,'')";
}
#Html.TextBoxFor(model => model, htmlAttributes)
Note that TextBoxFor() generates type="text" so there is no need to add it again. In addition, you do not need the leading # unless its a reserved keyword (for example #class = "...")

ASP.NET MVC 4 - Set input value using #Html.EditorFor

Currently i have this field on a form:
#Html.EditorFor(model => model.AmountDecimal,
new { htmlAttributes = new { #class = "form-control" } })
But:
a) i want it to have the value "100" predefined
b) don't want it to be editable
I know how to do it in raw HTML but i need it to be in razor.
Thanks
It would make sense to set this value e.g. in the constructor of your model or in the controller before you call your view
public ActionResult MyAction()
{
var model = new MyViewModel
{
AmountDecimal= 100
};
return View(model);
}
But if you really like to do it in razor, you may use HiddenFor
#Html.HiddenFor(model => model.AmountDecimal, new { #Value = "100" });
<input type="text" name = "dummy" class="form-control" value="100" readonly/>
Keep in mind to never trust a user input ;)
I think your are loooking for something like this:
#Html.EditorFor(model => model.AmountDecimal,
new { htmlAttributes = new { #class = "form-control", #Value = "100", #readonly = "readonly"} })

ng-model on hidden razor input not working

In my MVC 5 Razor view, I created a hidden field, like this:
#Html.HiddenFor(x => x.FormData.UserId,
new { ng_model = "selectedEmployee.userId" })
When I perform the necessary angular action to fill the selectedEmployee.userId property, the hidden input's value is not filled.
But, when I change it to
#Html.TextBoxFor(x => x.FormData.UserId,
new { ng_model = "selectedEmployee.userId" })
It's working and the data is posted to the server.
And
<input type="hidden" name="FormData.UserId" value="{{selectedEmployee.userId}}">
is working, but
#Html.HiddenFor(x => x.FormData.UserId,
new { value = "{{selectedEmployee.userId}}" })
is not. (which probably has to do with Razor overwriting the HTML value)
What's the reason that in Razor a hidden input with an ng-model is not working?
Please change value into ng_value
#Html.HiddenFor(x => x.FormData.UserId,
new { ng_value = "{{selectedEmployee.userId}}" })
Here is how to assign a value to Hidden field. 'V' character of value attribute must be Capital letter.
<div data-ng-controller="MyFunction">
#{Html.BeginForm("SchoolMedium", "BasicSetup", FormMethod.Post, new { });
#Html.HiddenFor(s => s.SchoolMediumId, new { Value = "{{mascotmedium.SchoolMediumId}}" });
Html.EndForm();
}
and in controller
$scope.EditWhenAdded= function(row){
$scope.mascotmedium = row.entity;
};

DropDownList Error in MVC3

After adding the class to the html.dropdownlist am facing the below error.
Error:'System.Web.Mvc.HtmlHelper' does not contain a definition for 'DropDownList' and the best extension method overload 'System.Web.Mvc.Html.SelectExtensions.DropDownList(System.Web.Mvc.HtmlHelper, string, string)' has some invalid arguments
<li>
#Html.LabelFor(m => m.BuildType)
#Html.DropDownList("BuildType", new { #class = "BuildType" })
#Html.ValidationMessageFor(m => m.BuildType)
</li>
<li>#Html.LabelFor(m => m.BuildMode)
#Html.DropDownList("BuildMode", new { #class = "BuildMode" })
#Html.ValidationMessageFor(m => m.BuildMode) </li>
<li>
Where are your list options? You need to provide a list of options via an IEnumerable<SelectListItem> object (see this overload).
So your model would have something like this:
public IEnumerable<SelectListItem> BuildModeOptions { get; set; }
And your view would pass the list into the helper:
#Html.DropDownList("BuildMode", Model.BuildModeOptions, new { #class = "BuildType" })
Or, since you're using the type-safe For versions on your other helpers, use DropDownListFor on this one as well:
#Html.DropDownListFor(m => m.BuildMode, Model.BuildModeOptions, new { #class = "BuildType" })
But keep in mind, Model.BuildMode is your selected value -- Model.BuildModeOptions is for your dropdown options.
You can use:
#Html.DropDownListFor(m => m.BuildType, (SelectList)Viewbag.YourSelectList, "Select Build type", new { #class = "BuildType" })
or
#Html.DropDownListFor(m => m.BuildType, Model.YourSelectList, "Select Build type", new { #class = "BuildType" })
When you use #Html.DropDownList, you specify a name for the dropdownlist... but you are missing the SelectList itself. I think that out of the box, the helper will try to use the name of the DropDownList (in your case "BuildType") to search in the ViewData collection for the SelectList.
When you use a #Html.DropDownListFor you don't use a name, but a lamda expression m => m.BuildType that will help you in same cases to not have harcoded names.
Your SelectList (the second parameter) can be grabbed from Viewbag or from a property in your Model.
The second parameter should be the list of items you want to show in the dropdown.
so It will look like :
#Html.DropDownListFor("BuildType", m.yourListofItems, new { #class = "BuildType" })

Resources