validationmessagefor missing "data-valmsg-for" in editorfor - html

I have a collection of objects that I'm trying to display, however the span generated by the ValidationMessageFor does not include all the validation attributes:
<span class="field-validation-error">This field is required</span>
instead of:
<span class="field-validation-error" data-valmsg-replace="true" data-valmsg-for="Questions[0].SingleAnswer"></span>
This is how I'm generating the html:
<fieldset id="dr_profileUpdates">
#Html.EditorFor(model => model.Questions)
</fieldset>
And here is my editor template:
#Html.ValidationMessageFor(model => model.SingleAnswer)
#Html.TextBoxFor(model => model.SingleAnswer, new { #class = "textBoxDefault" })
The validation works, however the span does not dissapear after filling out the textbox and focusing out of it - I would assume this is because the span does not get generated correctly
Any help is appreciated.
EDIT: Actually it appears that after posting back to the server and returning the partial view (assuming the ModelState is invalid), those attributes do not get generated again - it only seems to affect the ValidationMessage. Any ideas?
Thanks,

Try add on top of your razor file
#{
Html.EnableUnobtrusiveJavaScript();
}

Related

MVC using different text for form label

I have just created an MVC project and my view looks like this
{
#model Models.LeadModels
ViewBag.Title = "Add a Lead";
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<p>#ViewBag.SaveResult</p>
#using (Html.BeginForm("Add", "Lead"))
{
<p>#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName)</p>
<p>#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName)</p>
<p>#Html.LabelFor(m => m.Company)
#Html.TextBoxFor(m => m.Company)</p>
<p>#Html.LabelFor(m => m.Province)
#Html.TextBoxFor(m => m.Province)</p>
<p>#Html.LabelFor(m => m.Telephone)
#Html.TextBoxFor(m => m.Telephone)</p>
<p>#Html.LabelFor(m => m.EmailAddress)
#Html.TextBoxFor(m => m.EmailAddress)</p>
<p>#Html.LabelFor(m => m.LeadStatus)
#Html.TextBoxFor(m => m.LeadStatus)</p>
<p><input type="submit" value="Add Lead" /></p>
}
When this is rendered the labels are the same as my model properties, as in the text says "FirstName"
Questions.
Is there a way to put in a different label (First Name instead of FirstName) using a HTML Helper method?
Are there any neat stuff/tricks we can do to change the display? Such as set the labels to be a fixed width so they all line up?
Is there a way to use a HTML Helper method to output the submit button? Or do I need to manually write the HTML like I am doing?
Is there a way to put in a different label (First Name instead of
FirstName) using a HTML Helper method?
You can use Display attribute data annotation on your property name
public class LeadModels
{
[Display(Name = "First name")]
public string FirstName { set; get; }
}
LabelFor helper method will render the value you provided for the Name attribute
Are there any neat stuff/tricks we can do to change the display? Such
as set the labels to be a fixed width so they all line up?
You can use your css classes style the content. You may also consider using bootstrap css classes which does the alignment in a neat way
Is there a way to use a HTML Helper method to output the submit
button? Or do I need to manually write the HTML like I am doing?
No. There is no helper methods for that. You should write your html tag for the button.
Also, in the asp.net core version, tag helpers are available which allows us to write more HTML style code instead of calling the C# methods in view.

MVC 5, Razor - How to create Edit Template for one property in model

I have a question that feels like it should be easy to answer, but I am not sure where to go with it.
I have several cshtml pages that take different models. But, each of these models has a common property, called WebSiteSK, and the same razor and Kendo UI code that handles that property in each cshtml file. What I want to do is extract this common razor and Kendo UI into an EditerTemplate.
So, I have one cshtml page that takes a Model, which I'll call ModelA. Then, another that takes another model, called ModelB. Both ModelA and ModelB have an integer property called WebSiteSK, which the code that I want extract into an editor template receives.
Here is the code that I want to centralize in an editor template:
<script type="text/x-kendo-tmpl" id="site-droplist-template">
<span>#: data.WebSiteSK # - </span>
<span><b>#: data.SiteName # </b> - </span>
<span>#: data.EnvironmentNK #</span>
<br />
<span>#: data.SiteUrl #</span>
</script>
<div>
#Html.LabelFor(model => model.WebSiteSK, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#(Html.Kendo().DropDownList()
.Name("WebSiteSK_Target")
.DataTextField("SiteName")
.DataValueField("WebSiteSK")
.DataSource(d => d.Read("GetWebSiteList", "Site"))
.Height(300)
.TemplateId("site-droplist-template")
.Filter("contains")
.OptionLabel("Select a site")
.Events(d =>
{
d.DataBound("onSiteBound");
d.Change("onSiteChange");
})
)
#Html.ValidationMessageFor(model => model.WebSiteSK, string.Empty, new { #class = "text-danger" })
</div>
</div>
Does that make sense? Can anyone help me do this?
You can create a base class that contains only the property 'WebSiteSK'. All models that have have this property then should inherit from this base class. Then you can create a partial view '_WebSiteSK' with the code that you want to reuse.
Your models:
public class MyModel : WebSiteSKBaseClass
The partial view must be typed with the base class
#model MyProject.Models.WebSiteSKBaseClass
Finally you can replace the replicated code in all views with:
#Html.Partial("_WebSiteSK")

How to make grey text on a textbox that disapears in MVC

I am searching for the same answer that was given here:
HTML/CSS Making a textbox with text that is grayed out, and disappears when I click to enter info, how?
But I want to do this in MVC4.
I got the following view:
#using (Html.BeginForm("Kompetens", "KumaAdmin"))
{
<div class="three columns" style="margin-right: 627px;">
<h6>Kompetens</h6>
<div style="width:456px;"> #Html.ListBox("kompetensId", (SelectList)ViewBag.KomId)</div><br/>
<h6>Lägg till kompetens</h6>
<div class="focus">
#Html.EditorFor(mm => mm.KompetensTest)
</div>
<input type="submit" style="margin-right: 205px;" value="Skapa"/><br/><br/>
</div>
}
Since this is my textbox:
#Html.EditorFor(mm => mm.KompetensTest)
I don't know how to apply the "onfocus" & onblur attributes on it like in the link above.
You need to create an Editor Template. Because the Html.EditorFor does not have the "object htmlattributes" parameter to do "new { onfocus = "js here" }".
Over the Views>Shared,
Create a folder called EditorTemplates
Then, you create a view using #model string/whathever this object is. Name the file as you want.
When you put the #model on a view you are specifying that it only accepts this type mas a model.
Inside this view, you create a Html.TextBox (not TextBoxFor) and voila.
On the Html.EditorFor method there is also a way to set which editor template you want to use. Choose the one you created by typing its name like this:
#Html.EditorFor(mm => mm.KompetensTest, "GreyedTemplate")
Code for the View I named as: GreyedTemplate.cshtml
#model string
#Html.TextBox("", Model, new { onfocus = "", onclick="" })
Note that the first parameter is empty. This was done on purpose, because when you use EditorFor(mm => mm.KompetensTest,"GreyedTemplate") it uses KompetensTest as the name of the field automatically.
You want to use the placeholder html attribute (http://www.w3schools.com/tags/att_input_placeholder.asp)
Something like #Html.EditorFor(mm => mm.KompetensTest, new { placeholder = "Text" })
#Gmoliv It worked finaly! I googeld arround and found that the "Editfor" does not have access to html attributes. Although I found "TextBoxFor" which has access to them, so the soloution is:
#Html.TextBoxFor(mm => mm.Profile, new { placeholder = "Ange Profil" })
#Pedro I really tried hard to make it work but the problem was that i could not get the value to be set so it was alwasy empty, i treid setting it in the view and in the templateView and it simply did not take. If you could i would appreciate a full code sample
Thanks alot!

override the "id" attribute of Html.EditorFor - not working

Trying to override the "id" attribute of Html.TextBoxFor (MVC 3) so that it should look like:
<input type="text" name="Password" id="#idPasswordTextBox" value="#Model.Password" />
where "idPasswordTextBox" is defined as:
string idPasswordTextBox = "passwordText_"+#Model.Key; in the same cshtml file.
This is working fine if I use as :
<input type="text" name="Password" id="#idPasswordTextBox" value="#Model.Password" />
but not working if I do it this way:
#Html.TextBoxFor(model => model.Password, new { id = "#idPasswordTextBox" })
Looks like the "id" attribute is getting messed up. What am I missing? Can anybody help? I am new bee in ASP.net.
Thanks in advance.
Sorry, i should've looked more carefully. You don't want quotes around #idPasswordTextBox in your TextBoxFor method. That is run on the server, so when you put quotes around the name it is being treated as a literal string. Remove the quotes, and remove the # sign in front of id, and it will work.
Its important to always remember what is running on the server, and what is running on the client.
#Html.TextBoxFor(model => model.Password, new { id = #idPasswordTextBox })

Tab index for dynamically added elements

I have a jsp page with three text boxes and a ADD button beside it. Now I have to set the tabindex for the dynamically added elements. How can I do it?
[As you may have figured out by now, posting code allows someone else to give a more definite answer. Without an example to work from, I can only imagine what your code and environment is...from ASP.NET MVC3 + jQuery]
[I used the information from this stackoverflow post and modified a lit bit.]
I use jQuery to modify the tabindex value. I have multiple forms that are dynamically added by jQuery. The forms use div and style="display: table" to organize the text fields into columns.
[The relevant CSS styles]
.tb-table
{
display: table;
}
.tb-row
{
display: table-row;
}
.tb-cell
{
display: table-cell;
}
[A chunk of my ASP.NET MVC3 Razor cshtml that produces html for the browser--should be readable]
<div class="tb-table">
<div id="namerow1" class="tb-row">
<div class="tb-label tb-cell" id="l_firstname1">
#Html.LabelFor(model => model.firstname1)
</div>
<div class="tb-field tb-cell" id="firstname1">
#Html.TextBoxFor(model => model.firstname1, new { tabindex = "1" })
#Html.ValidationMessageFor(model => model.firstname1)
</div>
<div class="tb-label tb-cell" id="l_firstname2">
#Html.LabelFor(model => model.firstname2)
</div>
<div class="tb-field tb-cell" id="firstname2">
#Html.TextBoxFor(model => model.firstname2, new { tabindex = "2" })
#Html.ValidationMessageFor(model => model.firstname2)
</div>
</div>
<div id="namerow2" class="tb-row">
<div class="tb-label tb-cell">
#Html.LabelFor(model => model.lastname1)
</div>
<div class="tb-field tb-cell">
#Html.TextBoxFor(model => model.lastname1, new { tabindex = "1" })
#Html.ValidationMessageFor(model => model.lastname1)
</div>
<div class="tb-label tb-cell">
#Html.LabelFor(model => model.lastname2)
</div>
<div class="tb-field tb-cell">
#Html.TextBoxFor(model => model.lastname2, new { tabindex = "2" })
#Html.ValidationMessageFor(model => model.lastname2)
</div>
</div>
</div>
I use tabindex for all values in a column; not just a unique order. For the browsers I tested in, when there are multiple text fields with the same tabindex, the text field encountered first in the html code will be selected first by tab-navigation.
Therefore, for each form that I have, I use a tab value from 0-9 to group them. Once I have the tab order for an individual form working the way I want, I use the following jQuery to INCREMENT the tabindex value by 10 (or 20, or 30, or 40) for each form that I dynamically add. the first decimal, 0-9, organizes the tabs within that form, and incrementing the factors of 10 keeps the subsequent form tabs following along.
$('.createtab-form [tabindex]').each(function () {$(this).attr('tabindex', parseInt($(this).attr('tabindex'))+10)})
This is my first attempt at this myself--I'm sure someone else will have a better method. Let me know what you think.