Angular ASP.NET MVC Binding - c#

In our MVC 5 project we use Angular. The following Razor works nicely:
#Html.EditorFor(x => x.FirstName,
new { required = "required", ng_model = "FirstName" })
However, if the MVC Model.FirstName is set to "Bob" when the page is rendered, the Input field is still blank.
If I set this in the Angular controller:
$scope.FirstName = "#(Model.FirstName)";
Then "Bob" appears.
My question is: Do I have to set the $scope.VARIABLE=MODEL.VARIABLE for every field in the UI, or can I tell Angular to respect what came over from ASP.NET MVC.
Angular is appearing to over write the [input value="Bob"] that MVC writes.

There is no need to separate the model into individual fields when you bind to scope. Instead you should bind the entire model:
$scope.model = #Html.Raw(Json.Encode(Model));
This would render to the client as:
$scope.model = { FirstName: 'John', LastName:'Doe', etc };
Then you can bind your input fields as:
#Html.EditorFor(x => x.FirstName,
new { required = "required", ng_model = "model.FirstName" })
Personally, I think its cleaner not to use #Html, in favor of simple HTML:
<input ng-model="model.FirstName" required />
In Angular, you don't really need an id anymore.

Related

Id with RadioButtonFor

I'm trying to deal with radiobutton ids in asp MVC 5
I'm working like this
Example model
class A
{
public bool? radio { get; set; }
}
and in razor view
#Html.RadioButtonFor(x => x.NeutroBT, Model.NeutroBT, new { #id = "True"})
#Html.RadioButtonFor(x => x.NeutroBT, !Model.NeutroBT, new { #id = "False})
It doesn't cause problem, but I'm working in an editortemplate, and I want it to have generated id, to access in some way like #Html.IdFor(x => x.NeutroBT, true) and #Html.IdFor(x => x.NeutroBT, false) from the other views, just preventing changes in the future
Is some like this possible? I pass a lot of time searching and I didn't get anything similar
If is not possible, what is the best way to deal with it?
thanks!
There is no need to use an id attribute. Instead you can just use the name attribute to select or set the value via javascript (and in any case, #Html.IdFor() will only ever returnNeutroBT, not theidthat you override in theRadioButtonFor()` method so it cannot be used in your case)
In addition, the 2nd parameter of RadioButtonFor() should be true or false (not Model.NeutroBT and !Model.NeutroBT).
And to associate a label with the button, you can wrap it in a <label>, for example
<label>
#Html.RadioButtonFor(x => x.NeutroBT, true, new { id = ""})
<span>Yes</span>
</label>
<label>
#Html.RadioButtonFor(x => x.NeutroBT, false, new { id = ""})
<span>No</span>
</label>
Note that new { id = "" } removes the id attribute and prevents invalid html due to duplicate id attributes.
Then to access the selected value using jQuery
var selectedValue = $('input[name="' + #Html.NameFor(x => x.NeutroBT) + '"]:checked').val();

Using .NET MVC HTMLHelper .For methods doesn't generate correct ID/Name when casting viewmodel field

I got a ViewModel graph with some sub-objects.
This code:
#Html.DropDownListFor(model => model.JobTypeParams.ContactCatalogId, new SelectList(paramz.ContactCatalogues, "Id", "Description"), new { #class = "select2 input-default " })
Generates a Request.Form key/value item with the key of: JobTypeParams.ContactCatalogId.
That's great because that means the MVC Model Binder can correctly map the key/value item to the corresponding field in the view model.
However! This code (using casts)
#Html.DropDownListFor(model => ((AdSyncJobSpecificParameters)model.JobTypeParams).ContactCatalogId, new SelectList(paramz.ContactCatalogues, "Id", "Description"), new { #class = "select2 input-default " })
Generates a Request.Form key/value item with key ContactCatalogId. It loses the JobTypeParams prefix somewhere.
This leads to the modelbinder being unable to bind correct key to correct viewmodel field, and hence the problem.
I do not want to hard-code the ID because of many reasons. So how do you get the HTML Helper to correctly generate they name of the Name/Id attribute ?
It doesn't get them wrong, it's not supposed to do that. You have an incorrect expectation of how lambda's work. You are effectively replacing the old expression, model.JobTypeParams with a single expression of type AdSyncJobSpecificParameters.
What you should be doing is using an editor template.
#Html.EditorFor(model => model.JobTypeParams)
Then, create a AdSyncJobSpecificParameters.cshtml in your EditorTemplates folder and do this:
#model AdSyncJobSpecificParameters
#Html.DropDownListFor(model => model.ContactCatalogId,
new SelectList(paramz.ContactCatalogues, "Id", "Description"),
new { #class = "select2 input-default " })
You'll need to figure out a solution for the SelectList, since it doesn't seem to be part of your model. Maybe as a ViewBag item.
You can also create one for your superclass as well in YourSuperclass.cshtml
#model YourSuperclass
// etc...

pass extra attribute in #html.textboxFor - ASP.NET

I am trying to pass extra attribute 'data_id 'in #HTML.TextBoxFor... but I am getting no result
what I am missing in following code...
#Html.TextBoxFor(model => model._MarkScheme.MarkSchemeId, new { id = "_MarkSchemeId_Input", #class = "ElementMarkingSchemeTitle k1-grid-input k-textbox_3", data_id = #item.ElementID + "EMST"})
Many Thanks
Underscores aren't valid in HTML attribute names so Razor converts it to a hyphen. This will render with a data-id attribute.
HTML 5 data-* attributes are expected to be data_* in ASP.Net MVC view engine to render it.
HTML syntax
<input type="text" data-my-id="5" value="something" />
MVC syntax
#Html.TextBoxFor(model => model.Name, new {data_my_id=#item.ID})
Your case it is data-id

how to update the name attribute of a HTML helper

I am using MVC4, just wondering, is it possible to update the name attribute of a html helper. I am updating this as the action method is expecting a particular name. I know I can just write raw html, but just want to know if there is an overide in the html helper
I tried this
#Html.TextAreaFor(m => m.noteDetail.NotesDetails, new { #class = "k-textbox", #cols = 100, #rows = 5, id="NotesDetails", name= "NotesDetails" })
but when I look at the generated html
<textarea class="k-textbox" cols="100" data-val="true" data-val-required="The details are required" id="NotesDetails" name="noteDetail.NotesDetails" rows="5"></textarea>
Thanks
You just need a # symbol in front of your name property.
One technique I've found when a submodel is the model that your POST action accepts is to put the HTML that renders the submodel in a partial view that's included in the main view. Have this partial by strongly typed by the submodel and pass the value of the submodel into it. This way, the prefixes won't be generated on the submodel.
#Html.Partial("_NoteDetails", Model.noteDetail)
Then in _NoteDetails.cshtml
#model NoteDetail
#Html.TextAreaFor(m => m.NoteDetails,
new { #class = "k-textbox", cols = 100, rows = 5 });
Hi I think as you pass a viewModel as it contains maybe 2 models that is why you have this name. It does like this for the Binder to construct objects from your Post or Get.
If you change the name then you will maybe perform some custom codes for your binder if you want to pass it again to the controller.

Disabling EditorFor

I have a EditorFor HTML helper like this:
<td>#Html.EditorFor(m => m.Name, belowLevel ? disabledHtmlOptions : null)</td>
-
object disabledHtmlOptions = new { disabled = "disabled" };
I wanna make this disabled at every time. How do I do that? I dont want to do data annotations because this property is being used in other views too. Only on this view I want to disable it.
MVC 5.1 now allows passing in HTML attributes in EditorFor (see this answer). So you could do this:
#Html.EditorFor(model => m.Name, new { htmlAttributes = new { disabled = "disabled" } })
if you're stuck on using EditorFor you could set the disabled attribute via jQuery on page load. I know it's not ideal, but it's the only way unless you create an overload for EditorFor that accepts an htmlAttributes collection
$(document).ready(function() {
$('#Name').attr('disabled', 'disabled');
});
You could just render HTML for the view. If it's meant to be "read-only" just render the text. Otherwise you could render an <input> element.
For example, instead of
<td>#Html.EditorFor( m => m.Name )</td>
do
<td>#Model.Name</td>
or
<td><input type="text">#Model.Name</input></td>
I don't believe the signature of the EditorFor method allows you to specify any HTML attributes. You can if you change it to TextBoxFor however.
<td>#Html.TextBoxFor(m => m.Name, belowLevel ? disabledHtmlOptions : null)</td>

Categories

Resources