How to set data-display in razor [duplicate] - asp.net

This question already has answers here:
Hyphenated html attributes with asp.net mvc
(2 answers)
Closed 6 years ago.
I have a basic password strength indicator.
<input type="password" id="myElement1" size="40" class="left" data-display="myDisplayElement1" />
<div class="left" id="myDisplayElement1"></div>
I have the JS Script which takes care of all the logic. And the data-display div shows the message whether the password is weak or strong. But I want to convert the above code into Razor. Below is what I have till now.
<div class="form-group">
#Html.LabelFor(model => model.NewPassword, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.NewPassword, new { htmlAttributes = new { #class = "form-control", id = "myElement1" } })
<div class="left" id="myDisplayElement1"></div>
#Html.ValidationMessageFor(model => model.NewPassword, "", new { #class = "text-danger" })
</div>
</div>
Question: Everything is working fine but I am not able to put data-display attribute in razor. Where do I need to place it. But as the data-display is not set, I am not able to display the user its password strength as the div.
I want to be able to do something like below
#Html.EditorFor(model => model.NewPassword, new { htmlAttributes = new { #class = "form-control", id = "myElement1" , data-display = "myDisplayElement1"} })
But data-display gives me error.
Error
Cannot resolve symbol data the error comes at the place where I have added data-display.

Hyphenation is not valid within an anonymous object. However, knowing that it would be necessary at times to add attributes with hyphenation, the Razor helpers will auto replace underscores with hyphens in attribute names. As a result, you can accomplish what you need by using data_display rather than data-display.

Related

Why won't Bootstrap let me set margins on dropdowns in ASP.NET MVC page?

I'm having some issues with Bootstrap/CSS in my ASP.NET MVC app. I've got a ´form-group´ with a label to the left and a vertical stack of dropdowns to the right.
I've now set it up the way I want it except for the margins. Currently there are none. It seems like the margins that I'm giving are not effective. I've pretty much took this from a video tutorial on YouTube. I don't understand why this doesn't work.
I've tried all kind of things, mb-4, mt-4, my-4, ...
What am I doing wrong here? I've checked I use bootstrap v3.3.7.
This is my code:
<div class="form-group">
#Html.LabelFor(model => model.SelectedTags, htmlAttributes: new { #class = "control-label col-md-2", id = "lblSelectedTags" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Tag1, Model.AvailableTags, htmlAttributes: new { #class = "form-control mb-4", id = "ddlTag1" })
#Html.DropDownListFor(model => model.Tag2, Model.AvailableTags, htmlAttributes: new { #class = "form-control mb-4", id = "ddlTag2" })
#Html.DropDownListFor(model => model.Tag3, Model.AvailableTags, htmlAttributes: new { #class = "form-control mb-4", id = "ddlTag3" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FriendlyName, htmlAttributes: new { #class = "control-label col-md-2", id = "lblFriendlyName" })
<div class="col-md-10">
#Html.EditorFor(model => model.FriendlyName, new { htmlAttributes = new { #class = "form-control", id = "edrFriendlyName" } })
#Html.ValidationMessageFor(model => model.FriendlyName, "", new { #class = "text-danger" })
</div>
</div>
And this is the result:
After continued iterations of an endless loop of trial and error I figuered that the way ASP.NET assembles html and styles is not straightforward enough that it can be easily understood for someone who's new to the technology. Hopefully this might change after some time.
So I've stumpled upon this other post (Cant set proper margin with bootstrap css in MVC) where somebody else had issues with margins in ASP.NET. This probably isn't the right way of doing things, but for me and for now it works. I've basically avoided adding to my CSS file something like this
.mb-4 {
margin-bottom: 1.5em !important;
}
and instead added it to the htmlAttributes collection of the Html helper class for each of my controls, like this:
#Html.DropDownListFor(model => model.Tag1, Model.AvailableTags, htmlAttributes: new { #class = "form-control", style = "margin-bottom: 1.5em !important;", id = "ddlTag1" })
bootstrap 4 allows for padding and margin tags:
mt-1 (margin-top) , mb-1 (margin-bottom) , mr-1 (margin-right) , ml-1 ( margin-left) can change the number from 1-5 depending on your needs or replace M for p ( padding)
as for bootstrap 3 you will need to use css
.form-group{
margin-bottom:10px;
}
for example
You use bootstrap 3 and in this version sapcing is not available
So you can imitate the behavior of bootstrap version 4 by creating those class in css
For example I initated the behavior of mb-4 by add to css .mb-4 { margin-bottom: 1.5em; }:
NOTE!
In Razor: use the same code in HTML as you posted but add the css rule
I use em in css only to initate bootstrap but you can use px as you want
.mb-4 { margin-bottom: 1.5em; }
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="form-group">
<label class = "control-label col-md-2" id ="lblSelectedTags">drop down</label>
<div class="col-md-10">
<div class = "form-control mb-4" id = "ddlTag1">
ddlTag1
</div>
<div class = "form-control mb-4" id = "ddlTag2">
ddlTag2
</div>
<div class = "form-control mb-4" id = "ddlTag3">
ddlTag3
</div>
</div>
</div>

Implementing Html.DropDownListFor() in View Only

I am completely new to Asp.Net (junior dev). I'm working on a project that requires a customer to enter data to be stored in a database. When I created the template view for the model, I get a EditorFor() textbox for the customer to enter data. Here's what it looked like:
<div class="form-group">
#Html.LabelFor(model => model.ApplicantState, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ApplicantState, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ApplicantState, "", new { #class = "text-danger" })
</div>
</div>
This works great, except I want the user to choose from a drop-down list of options rather than enter the data themselves. Here's what I want to do if I were doing the dropdown list with straight HTML:
<div class="form-group">
#Html.LabelFor(model => model.ApplicantState, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<select id="applicantState">
<option disabled selected value> -- Please Select -- </option>
<option value="OH">Ohio</option>
<option value="CA">California</option>
<option value="TX">Texas</option>
</select>
</div>
</div>
I need to get this data to store in the ApplicantState field in the model. The senior developer running this project does NOT want me to add code to the model or controller to do this; he wants me to do the drop-down list in the view only.
Here's what I have...
<div class="form-group">
#Html.LabelFor(model => model.ApplicantState, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.ApplicantState, new List<SelectListItem> {
new SelectListItem { Value = "" , Text = " -- Please Select -- " },
new SelectListItem { Value = "OH", Text = "Ohio"},
new SelectListItem { Value = "CA", Text = "California"},
new SelectListItem { Value = "TX", Text = "Texas"}
})
</div>
</div>
The code is compiling and I'm not getting any errors. For anyone who's done this before, does this look correct? Will the dropdown list option be stored in the ApplicantState field? I have no confidence in what I've written. I've only ever done a dropdown list from a MVC controller. I'm not yet able to test the code by submitting a fake application. The view is popping up correctly though. Any advice would be appreciated. Thanks!
Because of this:
The senior developer running this project does NOT want me to add code to the model or controller to do this; he wants me to do the drop-down list in the view only.
You need to instantiate at the top of your Razor view this dictionary:
var dictionary = new Dictionary<string, string>
{
{ "OH", "Ohio"},
{ "CA", "California"},
{ "TX", "Texas"}
};
Then replace your razor code with this:
#Html.DropDownListFor(m => m.ApplicantState, dictionary.Select(d => new SelectListItem { Value = d.Key, Text = d.Value }).ToList(), " -- Please Select -- ");
This is clean and should work. After that you need to tell to your co-worker that the dictionary which keep the data should belong to your model and the code should go there.

Label Inside EditorTemplate Disappears During Validation

I am using the following EditorTemplate:
<div class="form-group">
#Html.LabelFor(m => m, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, htmlAttributes)
#Html.ValidationMessageFor(m => m, null, new { #class = "help-block" })
</div>
</div>
When attempting to save the form with a deliberate error, the page refreshes and correctly shows the validation error but the label completely disappears. It is not hidden it is completely gone from the html source.
Here is my EditorFor:
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
Is this a bug, or does anyone know what might be causing this?
This problem has been fixed with the latest asp.net core.
See here:
https://github.com/aspnet/Mvc/issues/2778

DisplayFor showing on different line to LabelFor MVC

I created an Edit page in MVC and decided I did not want the ID to be editable, but I do want it to look like the rest, just greyed out preferably.
Here is my property:
<div class="form-group">
#Html.LabelFor(model => model.EvpId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.EvpId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EvpId, "", new { #class = "text-danger" })
</div>
</div>
After doing some reading everyone seems to suggest using the #Html.DisplayFor which makes sense, even though it does not look like the rest.
However when swapping the EditorFor for the DisplayFor I notice that the label is not on the same line:
What is the simple way of having this on the same line as the corresponding label, I am using the standard out of the box bootstrap CSS.
View Source on page:
<div class="form-group">
<label class="control-label col-md-2" for="EvpId">Id</label>
<div class="col-md-10">
2
<span class="field-validation-valid text-danger" data-valmsg-for="EvpId" data-valmsg-replace="true"></span>
</div>
</div>
I have had the same issue.
Jasen answer did not help, because span does not put an element into the same horizontal line with label, but his later comment with the link to bootstrap doc solved the problem, we should use p tag instead of span.
So my final solution was:
<p class="form-control-static">#Html.DisplayFor(model => model.Contractor.Name) </p>
Thanks to Jasen!
When you use #Html.DisplayFor() the helper is selecting markup based on the type. Here it chose to output a bare string and this breaks the Bootstrap form-horizontal styling.
<div class="col-md-10">
2 <!-- no surrounding tags for EvpId value -->
...
</div>
The easiest thing to do is just use plain html to insert your own tags
<div class="col-md-10">
<span class="form-control-static">#Model.EvpId</span>
...
</div>
If you do this a lot or you have much more markup you can create a custom helper extension. This is a very simple example:
public static class HtmlHelperExtensions
{
public static HtmlString IdSpan(this HtmlHelper helper, string id)
{
return new HtmlString(String.Format("<span class=\"form-control\">{0}</span>", id));
}
}
Usage:
<div class="col-md-10">
#Html.Idspan(Model.EvpId)
#Html.ValidationMessageFor(model => model.EvpId, "", new { #class = "text-danger" })
</div>
Using Jasen's answer I was able to achieve what I wanted by altering the width of the <span> however this seemed abit messy:
<span class="form-control" style="width:280px;">#Model.EvpId</span>
The ultimate answer to my question was this as it is what I originally was looking for:
#Html.EditorFor(model => model.EvpId, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
Hope this helps someone.
Instead of wrapping in a P tag or SPAN I just put the class directly into the exiting DIV, and that worked too.
<div class="col-md-10 form-control-static">
...
</div>

MVC5/razor - Login Password asterisks appearing on Change Password form

On my Change Password form I have asterisks appearing in the New Password field. I assume they are appearing as a leftover from the password field from the Login Form?
Change Password form (partial):
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-3 control-label" })
<div class="col-md-9">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password)
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.ConfirmPassword, new { #class = "col-md-3 control-label" })
<div class="col-md-3">
#Html.PasswordFor(m => m.ConfirmPassword, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.ConfirmPassword)
</div>
</div>
This behavior is probably browser-related due to a cookie from saving the password on login. I'm just wondering if there is anyway to overcome this without renaming the Password field?
#Html.PasswordFor (and all of the other xxxFor HtmlHelpers) will fill in the input field with whatever value the model has for the property when the page is rendered. In this case, Model.Password must already have a value, perhaps from when you fetched the user from the database. Note, if you are storing the user's password somewhere in plain text, this is bad practice.
Before the call to View in your Controller, clear out the Password property.
If that doesn't work and you've confirmed the Password property of the Model is empty when the page loads, then perhaps it is some browser autocompletion as you say. You can try adding autocomplete = "off" attribute to the input element.

Resources