Implementing Html.DropDownListFor() in View Only - asp.net

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.

Related

How to filter dropdownlistfor according to what has selected in first dropdownlist in asp mvc?

I am working on a asp.net mvc project and I need to filter dropdownlist according to what user has selected first dropdownlist
This is my first dropdownlist in view:
<div class="form-group">
#Html.LabelFor(m => m.BuildDefinitionName, "Build Definition name", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.BuildDefinitionName, new SelectList(Model.BuildData.Select(x => x.Key), "BuildInfo"), "select", new { #class = "form-control" })
</div>
</div>
and this is my second dropdownlist:
<div class="form-group">
#Html.LabelFor(m => m.CurrentBuildNumber, "Current Build", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.CurrentBuildNumber, new SelectList(Model.BuildData
.Where(x=>x.Key == "#BuildDefinitionName")
.Select(y => y.Value), "BuildInfo"), "select", new { #class = "form-control" })
</div>
</div>
I have a dictionary that key is string (what the user should chose first dropdown ) and value is IEnumerable ( what it should be filtered by the first dropdown selection).
I am so thanksful for solving my problem.
after applying the answer :
You need to use jquery to modify the second dropdown list.
In your 2nd dropdown list, you need to put all the data of Model.BuildData. So, in your controller, be sure to provide all the records because we will be filtering on client-side.
public ActionResult ControllerName(){
var yourModel = new yourModel();
// Add all the entries to Build Data, we're going to filter it with jquery
yourModel.BuildData = db.BuildData.ToList();
return View(yourModel);
}
In your 2nd dropdown list, we need to put a data attribute on the html. For this example, we're rendering it manually, replace your 2nd dropdown list with the HTML below.
<div class="form-group">
#Html.LabelFor(m => m.CurrentBuildNumber, "Current Build", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<select id="CurrentBuildNumber" name="CurrentBuildNumber" class="form-control">
#foreach(var selectItem in Model.BuildData){
<option data-filter="#selectItem.Key" value="#selectItem.Value">
#selectITEM.Value
</option>
}
</select>
</div>
</div>
Lastly, we need to add an onchange script to the 1st dropdown list that would filter the 2nd dropdownlist.
The code below will loop through all the options in the 2nd dropdown list, and if its data-attribute doesn't match with the selected value, it will hide it.
<script>
$(document).ready(function(){
$(document).on("change","#BuildDefinitionName",function(){
var selected = $(this).val();
$("#CurrentBuildNumber").find("options").each(function(){
if($(this).data("filter")==selected){
// if data-filter is the same as the selected value, show it
$(this).show();
}else{
// if it doesn't match, hide
$(this).hide();
}
});
});
});
</script>

How to set data-display in razor [duplicate]

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.

How to move JQuery DatePickers ahead of other form elements

I am new to CSS and JQuery. I have a C# MVC application that has several forms and I want to use the JQuery datepicker control. What I am seeing is that the datepicker is there, but it is hard to see and is obscured by the other boxes in the form.
All I can do is really describe it, since the site will not allow me to upload images in this question (I keep getting a "Service Unavailable" error). When I click on the editor in the view, I can see the datepicker calendar appear, but it is basically getting all mashed up with the other form boxes below it (to the point where it obscures parts of the calendar).
My markup code is here:
#section Scripts
{
#Scripts.Render("~/bundles/jqueryui")
#Styles.Render("~/Content/cssjqryUi")
<script type="text/javascript">
$(document).ready(function () {
$('input[type=datetime]').datepicker({
dateFormat: "dd/M/yy",
changeMonth: true,
changeYear: true,
yearRange: "-60:+5",
});
});
</script>
}
<div class="form-group">
<div class="col-md-10">
#Html.LabelFor(model =>
model.ExpiryDate,
"Expiry Date",
htmlAttributes: new { #class = "control-label col-md-2" })
#Html.EditorFor(m => m.ExpiryDate, new { #class = "datepicker"})
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.LabelFor(model =>
model.IssuanceFeeValue,
"Issuance Fee Value",
htmlAttributes: new { #class = "control-label col-md-2" })
#Html.EditorFor(m => m.IssuanceFeeValue)
#Html.ValidationMessageFor(m => m.IssuanceFeeValue, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.LabelFor(model =>
model.Tenor,
"Tenor",
htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownListFor(m => m.SelectedTenor, Model.TenorList)
#Html.ValidationMessageFor(m => m.SelectedTenor, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.LabelFor(model =>
model.Tranche,
"Tranche",
htmlAttributes: new { #class = "control-label col-md-2" })
#Html.DropDownListFor(m => m.SelectedTranche,Model.TrancheList)
</div>
</div>
I have tried tinkering with the z-index and that did nothing. Note sure what I am missing here.
Any advice would be greatly appreciated.
UPDATE
I have a picture that I can upload of what the markup looks like:
I had the same exact issue a few days ago, this problem is because you are probably missing a jquery-ui.css file.
try adding this file to your page:
http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/base/jquery-ui.css

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

Bootstrap3 ASP.NET Validation display validation to right of control

I would like the validation error text to appear to the right form controls, but instead it appears under. In Bootstrap 2 there was a style called help-inline that appeared to do this, but it has been removed from version 3.
The solution I have right now is ok -- at medium and large resolution it looks the way I want it:
<div class="form-group">
#Html.LabelFor(model => model.FirstName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-4">
#Html.TextBoxFor(model => model.FirstName, htmlAttributes: new { #class = "form-control", maxlength = "40" })
</div>
#Html.ValidationMessageFor(model => model.FirstName, "", new { #class = "text-danger col-md-6 form-control-static" })
</div>
This produces:
The problem is that when the screen width is reduced, the ValidationMessage span takes up an extra line even when hidden -- which grows the height of the form. Which you can see if you look at the spacing after the first and last names which use the above syntax, opposed to City which uses the more common syntax:
Is there way of updating the more common syntax of:
<div class="form-group">
#Html.LabelFor(model => model.City, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
</div>
Here is the rendered HTML from the example above:
<div class="form-group">
<label class="control-label col-md-2" for="Address_City">City</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="Address_City" name="Address.City" type="text" value="RCQXNEZMTBSURAX" />
<span class="field-validation-valid text-danger" data-valmsg-for="Address.City" data-valmsg-replace="true"></span>
</div>
</div>
So there a way to have the validation appear to the right of the control (inline) without creating that extra line at reduced width?

Resources