DropdownList without a name attribute - c#

I'm building a form in my project, but because I'm using AJAX to post the form values and multiple instances of a certain dropdown (class attribute instead of id), I'm not in need of a name attribute on my form controls.
Is there a way to create a dropdown list dynamically but explicitly omitting the name attribute without getting an exception?
#Html.DropDownList(string.Empty, Model, new { #class = "year" })
Gives me this exception:
Value cannot be null or empty.
Parameter name: name
because first argument is empty.

You can do it like following.
#Html.DropDownList("aName", Model, new { Name=string.Empty, #class = "year" })

Related

How to get DropDownList selected Text in MVC controller

I have this DropDownList in html where i can select the Texts.Text = Project, Value = ID
#Html.DropDownList("Project", new SelectList(Model.dropConfig, "Project", "ID"), "-- Select LineID --", new { required = true, #class = "form-control" })
On click submit button in the controller I can see that the Value (ID) is passed on to be posted back to DB. I want the Text to be post into DB.
Controller side code line:
detailsConfig.Project = Convert.ToString(form["Project"]);
For example:
If the dropdownlist values are
Project ID
test 1
testagain 2
In controller I should get test, not 1. Please help
You use that drop-down change event and store that name in hidden filed and get that value to controller.
View:-
#Html.DropDownList("Project", new SelectList(Model.dropConfig, "Project", "ID"), "-- Select LineID --", new { required = true, #class = "form-control",#id="ddlProject" })
<input type="hidden" id = "hdnProjectName" name="ProjectName" />
Jquery:-
$("#ddlProject").on("change", function () {
$("#hdnProjectName").val($(this).find("option:selected").text());
});
Controller:-
public ActionResult Save(FormCollection formcollection)
{
var projectName = formcollection["ProjectName"];
}
new SelectList(Model.dropConfig, "Project", "Project")
The above change solves my problem. Thanks #StephenMuecke :)
First, you should definitely strongly-type your dropdownlist to your model.
What I mean is this...
In the controller is where I would create the selectlist to be used in the view.
Controller
ViewBag.ProjectSelection = new SelectList(/* your data source */, "Project", "Project");
Disclaimer:
Submitting the Text value is not preferred because typically the Text value of the select element is not unique. Submitting the ID to the server is the best practice.. and then you can simply query the database based on the ID you submitted to get the values you want. This is the best way to get the most accurate and reliable data.
Then in your view, strongly-type your ProjectSelection selectlist to the Project property in your model.
View
#Html.DropDownListFor(model => model.Project, (IEnumerable<SelectListItem>)ViewBag.ProjectSelection, "-- Select LineID --", new { required = true, #class = "form-control" })
Why are you declaring required in the dropdownlist? That should be declared in your model.
Explanation
In MVC, when it comes to HTML elements where the user can select options to be submitted to the server (dropdownlist, listbox, etc).. only the Value will be submitted (which in your case was the ID). The Text portion of the element is just for the user to see to make their selection's easier.
Let me know if this helps!

Set default for dropdownlist in view

I have a dropdownlist that I want to set a default value for but the way I have it set up does not work with all the examples I have seen on the web. Here is my controller code for getting the string:
ViewBag.RoleId = new SelectList(db.Roles, "RoleId", "RoleDescription");
Then here is the code of my dropdownlist in the view:
#Html.DropDownList("RoleId", null, "Select Role", htmlAttributes: new { #class = "form-control" })
I want to set that dropdownlist to be defaulted to a User Role but I cannot figure it out.
Here is the code for my roleID in my model trying to set the default value:
[Display(Name = "Role")]
[Required]
[DefaultValue('B2323674-45DC-45E7-91D2-E635CF63C04A')]
[ForeignKey("Role")]
public Guid RoleID { get; set; }
problem is I am getting an error on the Guid Default saying that it is too long for a string literal.
You can use this overload of the SelectList that accepts default value:
ViewBag.RoleId = new SelectList(db.Roles, "RoleId", "RoleDescription", selectedValue);
Where selectedValue is an object of whatever type is in your list.
Initializes a new instance of the SelectList class by using the
specified items for the list, the data value field, the data text
field, and a selected value.
public SelectList(
IEnumerable items,
string dataValueField,
string dataTextField,
object selectedValue
)
So in your case:
ViewBag.RoleId = new SelectList(db.Roles, "RoleId", "RoleDescription", "B2323674-45DC-45E7-91D2-E635CF63C04A");
more info.
Also there's another solution that personally I recommand you that, Using jQuery in view for selection for example the first item of the drop down list:
$("#target").val($("#target option:first").val());
The problem is that your ViewBag property and your model property are named the same. When Razor renders the values for your fields it uses the data from ModelState. ModelState is composed from values from ViewBag, ViewData, Request and Model as a last resort. In other words, since the name of the ViewBag property and Model property are the same, you're essentially saying that the selected value of RoleId is the entire SelectList, which obviously is not what you want.
The simplest solution is to simply name your ViewBag property something else, like ViewBag.RoleIdChoices. Then, you'll be fine.
There's a couple things going on here.
You won't be able to bind a dropDownList to a ViewBag collection "Extension methods cannot be dynamically dispatched." Meaning, you need to include your SelectList into your Model.
You can set a SelectedValue in your SelectList
ViewBag.RoleId = new SelectList(db.Roles, "RoleId", "RoleDescription", <DefaultRoleObj>);
You need to include the reference to you selectList in your DropDownList
#Html.DropDownList("RoleId", <Model.SelectList>)

Add prefix to control id and still have it bind MVC Razor

I have a case where I have a page displaying an order and tabs that display the order details. The order details are quite complex and since they are the same layout, I want to use a partial view or editor template that will generate the form.
The problem is the result is multiple duplicate form input id's are generated (one for each order detail. For example, I have:
foreach (var orderDetail in Model.OrderDetils)
{
#Html.EditorFor(model => orderDetail, "WorkOrder", orderDetail)
}
I've read much about this and see solutions where it is recommended to use an editortemplate, but that solution only works when you have the same form to render, but passing it different model properties so the control id's prefixes will differ...ie. like this solution.
In my case, this won't work as the model property I am passing is always the same.
So how else can I create unique Id's in the partial or editor template that will also bind.
I know instead of:
#Html.EditorFor(model => model.WOHdr.Attribute1)
I could do:
#Html.TextBoxFor(model => model.WOHdr.Attribute1, new { id = Model.Id + "_Attribute1" })
But then it won't bind when it passes to the controller.
Thoughts?
Try this
#Html.TextBoxFor(model => model.WOHdr.Attribute1, new { #id = #Model.Id + "_Attribute1" })
Use "#"+dynamic value. Now You will get unique Id's
In EditorFor you can use like this
#Html.EditorFor(model => model.WOHdr.Attribute1, null, "id=" + #Model.Id + "" )
the id will generate like this
id="id_1", id="id_2" and so on..
<input id="Checkbox1_#(test.TestId)" type="checkbox" />
i hope upper code will help you

DropDownListFor Unobtrusive validation shows on empty form

I get validation message always when I open this page (even first time), even if I choose value in one of dropdown lists, message doesn't go away. If I choose values in both I can submit form but messages still doesn't go away.
Snippet is Linq to sql class and LanguageID and SnippetTypeID are ints, I assume this happens because I pass empty model to View so LanguageID and SnippetTypeID are null and AFAIK Linq to Sql classes have required on non-nullable ints.
How can I fix this so validation messages doesn't appear before user tries to submit form, and if one of dropdown lists get selected to remove validation message.
View
#model Data.Snippet
#using (Html.BeginForm("Save", "Submit", FormMethod.Post))
{
<h1 class="subtitle">Submit new snippet</h1>
<h4>Title</h4>
#Html.TextBoxFor(snippet => snippet.Title, new { #class = "form-field" })
<h4>Language</h4>
#Html.DropDownListFor(snippet => snippet.LanguageID, new SelectList(#ViewBag.Input.Languages, "ID", "Name", #Model.LanguageID), "Choose Language", new { #class = "form-select" })
<p>#Html.ValidationMessageFor(snippet => snippet.LanguageID , "You must choose language", new { #class= "validation-message"})</p>
<h4>Snipet type</h4>
#Html.DropDownListFor(snippet => snippet.SnippetTypeID, new SelectList(#ViewBag.Input.SnippetTypes, "ID", "Name", #Model.SnippetType), "Choose snippet type", new { #class = "form-select" })
<p>#Html.ValidationMessageFor(snippet => snippet.SnippetTypeID,"You must choose snippet type", new { #class= "validation-message"})</p>
<h4>Text</h4>
#Html.TextAreaFor(snippet => snippet.Text, new { cols = "20", rows = "10", #class = "form-field" })
<input type="submit" value="Submit Snippet" />
}
Controller
//Controllers are not finished Save() should have
//code to actually insert to db after I fix validation
// GET: /Submit/
//
public ActionResult Index()
{
Snippet model = new Snippet();
SubmitModel input = new SubmitModel();
ViewBag.Input = input;
return View(model);
}
public ActionResult Save(Snippet snippet)
{
return View();
}
Model
Model is Linq to Sql class.
Snippet
ID (int, identifier)
Title (string)
SnippetType (int, FK on table SnippetTypes)
LanguageID (int, FK on table Languages)
Text (string)
Alright,
So I think the reason it is failing is because of the custom CSS that you are adding. ValidationMessageFor will put a hidden class when the validation is successful.
if you want to add custom colors or something like that with you CSS i would consider applying the style to the wrapping p tag or adding a wrapping div/span and adding it to that.
You could probably define your messages on the view using only #Html.ValidationMessageFor(snippet => snippet.SnippetTypeID, "ErrorMessage"); However a more proper way is to take your Model and create Data Annotations for it.
Take a look at this article http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validation-with-the-data-annotation-validators-cs for more information about how to do model validation with Data Annotations.
Also I would consider passing in custom classes instead of your linq to sql class so that you can do custom validation based on the view. These custom classes are often refereed to as ViewModels.

Dynamically set Text and Value of TextBoxFor

I'm having a bit of an issue that I'd appreciate some help with.
I have a User object with properties ID and NAME that I need to display in a Readonly textbox. I'd like to populate the texbox's value with ID and Text with Name.
When submitted to Formcollection I need to retrieve entered data with:
collection.Get("User")
I know this is not the correct syntax but I'm trying to achieve the following:
#Html.TextBoxFor(model => model.User, new { #readonly="readonly",#Value = model.Id , #Text=model.Name })
What do I need to do to correct this ? In the textbox how can I display the user Name, when submitted return the user ID with collection.Get("User") ?
Thank you in advance.
p.s.
Standard
#Html.TextBoxFor(model => model.User.Name)
doesn't work for me as it doesn't store the value and
#Html.TextBoxFor(model => model.User, new { #readonly="readonly",#Value = Model.User.Id})
fails for obvious reason when User.Id is empty (in my case it's possible ).
You need to store the Id in a hidden input field.
#Html.HiddenFor(x => x.User.Id)
#Html.TextBoxFor(x => x.User.Name, new { #readonly = "readonly" })
Keep in mind that as long as you use readonly, the value will be model-binded. But as soon as the field is disabled, it won't. So you will receive null values in your Controller.
In the Controller you can use Modelbinding instead of accessing the FormCollection.
public ActionResult Whatever(User user)
{
// user.Id
// user.Name
// should be filled.
}
Update:
Why do you wan't to have those values in the view in the first place?
If you need them for modelbinding you should be aware that people are still able to manipulate them even though they are readonly (Firebug, POST requests from other scripts).
If you require them for your model to be valid I would recommend using hidden input fields. And on the server side make sure that you only save values that the user is actually supposed to change.

Categories