how to give unique name to control in mvc - asp.net-mvc

in webform we never have to think about controls ID or name for unique ness. everything webform handle automatically. so tell me when we assign name to html control's ID then how can i provide unique name ? please help me with small code snippet
just see it
#Html.DropDownListFor(x => x.Field, ModelClass.MakeSelectListUtenti(Model.Destinations), new { id="Destinations"})
here we specify the controls id name as "Destination" but how can i specify name like "UniqueID_" + "Destination" ?
someone show me a way to do it like below
#Html.DropDownListFor(x => x.Field, ModelClass.MakeSelectListUtenti(Model.Destinations), new { id= #guid.NewGuid().ToString() + "Destinations"})
i like to know is there any other way around. i heard that something new technique has been introduce in mvc4. is it true....what is that?
if possible also show me various way to generate unique client side id in mvc 3/4.
thanks

As I know,there is noway can do it on official way,so I suggest a jQuery way:
First set a custom attribute instead the id for dropdownlist like this:
#Html.DropDownListFor(x => x.Field, ModelClass.MakeSelectListUtenti(Model.Destinations), new { originalid="Destinations"})
And this can be put multi times,then write a script on your page:
$(document).ready(function () {
$("[originalid]").each(function () {
var originalid = $(this).attr("originalid");
$(this).attr("id", $("[originalid='" + originalid + "']").index($(this)) + "_" + originalid);
});
})
And the same id will be init as "0_Destinations" "1_Destinations" etc.

I can't get to VS to give you a code example, but I would do something similar to what you have been shown, but using integers.
I am assuming the ID's are an issue because you are creating dropdowns on the fly. Otherwise you would obviously just change the text.
If you are creating dropdowns on the fly from a list, you could put it within a for loop and use the current number as a pre-pend to your id. This would give a result like id= #myInt + "_Destinations" -> '0_Destinations', '1_Destinations' etc. I have used this pattern many times. It makes for easy jQuery selection and is much tidier than Guid ids.
If you are not looping through a list, you could create a method that gives you a number and then pre-pend that in an Id.

Related

MVC dynamically load a dropdown based on a selection from another

I am using MVC and I would like to have two dropdowns where ones values are dependent on another. Additionally based on the combination on the two dropdowns saved the corresponding ID.
I have a code table that consists of
I would like to have dropdown one be a list of Manufacturers then based off the selection I would like dropdown two to be any models that have that as a Manufacturer. Then when I save the record that these dropdowns are used for I would like to record the ManufacturerModelID that is assigned to that combination. Is this possible?
If I understood well, you want to apply the MVC model to your application.
If yes, there is not a matter of "if", you can implement anything. You just need to separate your model from your view and controller.
In your case, I would go for "object oriented" javascript. Having separated the Models in Objects helps understanding the MVC itself.
Programming everything under a namespace like "MANUFACTUREAPP" would be helpful too.
1)For the Model
a) You need to have an object "Manufacturer" with fields like this.id, this.description, this.models = []. Then you need the setters, getters and your magic function that would push to this.models the models it has. So in the end just one more function like getManufacturer() that will get you an object filled with eeeverything this manufacturer has.
b) You need a "ManufacturerModel" with this.model, this.modelDescription, this.manufacturerID = [], setters, getters, init and all your funky functions.
2) For the View
a) You need your "View" object with functions like:
onManufacturerClick = function(){
manufacturersModels = MANUFACTUREAPP.manufacturers.getMeWhatIwant(howIwantIt);
}
So now you can be proud that your app supports the MVC architecture.
3) For the controller just follow the same concept.
In your main you want to create your object in your init function like:
init = function(){
MANUFACTUREAPP.manufacturers = new MANUFACTUREAPP.init();
}
Two friendly advices. Study the MVC in theory because it might get tricky if you didn't understood it 100%. And my best advice would be...grab a pen and draw your models before if you want to save tiiiime and energy!
EDIT
just noticed the asp.net tag.. Anyway, I am gonna leave that here. I am not familiar with asp.net but I guess the theory should be the same..
You can do it using jQuery and ajax.
Assuming your razor view renders the markup like this.
<select name="Manufacturer" id="Manufacturer">
<option value="1">Aaaaa</option>
<option value="2">Bbbbb</option>
<option value="3">Ccccc</option>
</select>
<select name="Model" id="Model">
</select>
Now have this javascript in your page, which listens to the change event of the first select element and get the value of the selected option and send it to your server using ajax. Let your server action method returns the models belongs to the manufacturer id.
$(function(){
var urlForModesl = "/Manufacturer/Models";
$("#Manufacturer").change(function(){
var manufacturerId= $(this).val();
$.getJSON(urlForModesl,function(data){
var modelsHtml="";
$.each(data,function(a,b){
modelsHtml+="<option value='"+b.Id+"'>"+b.Name+"</option>";
});
$("#Model").html(modelsHtml);
});
});
});
Assuming your Models action method returns a list of objects with Id and Name property in JSON format.
public ActionResult Models(int id)
{
var list= db.ModelManufactors.Where(s=>s.ManufacturerId==id)
.AsEnumerable()
.Select(s=> new { Id=s.ManufacturerModelId, Name=s.Name}).ToList();
return Json(list,JsonRequestBehaviour.AllowGet);
}

I'm having troubles getting drop-down-menus in MVC to return data

I am very new to MVC as a whole, and I was sent to create a web application that would give the user options then change the view based on these options. First I created a simple "select" html drop down menu but I am under the assumption that this won't work.
I can supply all the actual code I currently have, I just don't know what would be important to see and what would just be bothersome to wade through.
When I had created a constructor for the model, it wouldn't go through that constructor or else it would be easier.
Sorry since this all sounds probably bad, but any help would be amazing.
There are couple ways to do that , here's what i do :
create the function in your controller (The one that returns the list of items you want to include in the dropdownmenu) . let's name it getNames();
Then return that to the view using #viwbag.Names;
In the view you can declare a variable , something like:
#{
SelectListItem[] Names = ViewBag.Name;
}
and the dropdown menu code should be something like this:
#Html.DropDownList("Names", Names)
Finally, here is sample code for the controller:
IEnumerable<SelectListItem> Names =
(from names in YourDB.students.ToArray()
select new SelectListItem
{
Text = names.Name,
Value = names.Id
}).ToArray();
var Templist = names.ToList();
ViewBag.Roles = Templist.ToArray();

ASP.NET MVC 5 Creating multiple DropDownLists from a single source on the client side

I am wondering if there is a way to create multiple DropDownLists on the client side from one source in the model.
The background is I need to create a view that contains about 30 DropDownLists. The DropDownLists are identical to one another, and each contains about 400 entries. My model contains one
List<SelectListItem> StandardProductTypes
to hold all entries for each DropDownList.
Here is what is in my current view:
#for (int i = 0; i < Model.Mappings.Count; i++)
{
#Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey,
new SelectList(Model.StandardProductTypes, "Value", "Text", Model.Mappings[i].SelectedStandardProductTypeKey))
}
As you can see, this is returning 30 x 400 = 12000 entries from the sever, and the page loads rather slowly.
All that is really required is only 400 entries transferred and they are replicated 30 times on the client side in the browser. Is there a way to achieve that? Any reference to reading materials or tutorials will be good.
Thanks in advance.
Nay
how about copy with jQuery?
$('#myDropDownlist1 option').clone().appendTo('#myDropDownlist2');
Ok firstly you have no need to create a new SelectList for every DropDownList as the source. The DropDownListFor method just requires an IEnumerable<SelectListItem> as a source, which you already have (and the selected value is determined by the property value it is for normally, so you don't need to pass this in explicitly for the selected value.
Ie given "StandardProductTypes" is already IEnumberable<SelectListItem> you can simplify your DropDownListFor from
#Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey,
new SelectList(Model.StandardProductTypes, "Value", "Text", Model.Mappings[i].SelectedStandardProductTypeKey))
To
#Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey,
Model.StandardProductTypes)
Also I would generally NOT put stuff like a List<SelectListItem> in the model, because you don't need to pass it back after postback. Having it in the Viewbag is fine.
However that's just good practice, and besides the point, as the HTML here will still include all the options for all the dropdowns. TO solve your issue you want to return it only once, and then use some client side jQuery/javascript to replicate it
EG:
use
#Html.DropDownListFor(model => model.Mappings[i].SelectedStandardProductTypeKey, new List<SelectListItem>())
#Html.Hidden(String.Format("Mappings[{0}].SelectedStandardProductTypeKey_Initial",i), Model.Mappings[i].SelectedStandardProductTypeKey)
in place of the dropdown (so you have the correct initial value)
Then a bit of script at the end to fill the dropdownlists:
<script>
var ddlVals= new Array();
#foreach(var item in Model.StandardProductTypes) // get all the select list items into a javascript array
{
#Html.Raw(String.Format("ddlVals.push(['{0}','{1}']);", item.Key, item.Value))
}
$('input[type="select"][name$="SelectedStandardProductTypeKey"]').each(function()
{
var initValue $("name='" + $(this).attr("name") + "_Initial'").val();
foreach(var item in ddlVals)
{
var html = '<option value="' + item[0] + '"'
if (item[0] == initValue){ html = html + ' selected="selected"'}
html = html + '>' + item[1] + '</option>';
$(this).append(html);
}
}
</script>
EDIT
May be quicker using the idea in Edi G's answer
But you'd still need to select the correct initial value.
So keep the hidden fields and dropdowns above, but instead of the previous script how about:
<!-- a template dropdownlist - hidden from view -->
#Html.DropdownList("ddlTemplate", Model.StandardProductTypes, new {id = "ddlTemplate", style="display:none;"})
<script>
$('input[type="select"][name$="SelectedStandardProductTypeKey"]').each(function()
{
$('#ddlTemplate option').clone().appendTo($(this));
var initValue $("name='" + $(this).attr("name") + "_Initial'").val();
$(this).val(initValue);
}
</script>
EDIT 2
If you still find the page to be unresponsive when the javascript is populating the dropdowns after trying the script in the edit above then I have another possible solution.
You would basically need to populate each dropdown with a source as a new List<SelectListItem> - each containing just the single selected option.
Populate an array of values (as per the original script), but then instead of immediately populating all the dropdowns have some javascript that populates the remaining values from the array when you drop the dropdownlist for the first time.
That way you only load the full list of 400 items once, and client side javascript only needs to do work when you click a dropdown, rather than all 30 dropdowns at page load time.

Set HtmlFieldPrefix for id but not name

Setting ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix will prepend all name and id attributes.
I'm wondering if there is a way to prefix just the id and leave the name alone.
The scenario is this: A partial view is being loaded by AJAX multiple times on a page. A JavaScript library we are using requires the use of ids but we also want to be able to post the forms (so the names need to match the server model).
Our current solution is to generate a unique number for each time the partial view is loaded, set the HtmlFieldPrefix to items[n] (where n is the generated number) and for our action to recieve an array of items (where we only need to receive one). This gives us a globally unique id and a name which can be parsed by the model binder.
This feels ugly, though. Any suggestions?
I had the same issue as yourself.
#{ ViewData.TemplateInfo.HtmlFieldPrefix = "Prefix"; }
#using(Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.TextBoxFor(m => m.MerchantAccount.MerchantName, new { maxlength = 29, size = 35 })<br />
#Html.ValidationMessageFor(m => m.MerchantAccount.MerchantName)
}
Firstly, my bad idea: Use jQuery on page load to remove undesired prefix to all names.
$('[id*="Prefix_']).each(function(i, e) {...
What we actually ended up doing was suggested here: https://stackoverflow.com/a/1318342/4946681
Basically, on the controller you state what prefix to strip (by specifying a bind prefix in the method signature) and it's done for you automatically.
Now we can have our ID prefixes cake, and eat (bind) them, too!

MVC4 EF cannot get saved value to display in dropdown on page load

I have never asked a question on StackOverflow before, and never wanted to, but I am desperate, so here we go: I cannot get a saved value to show up as the default value/display in a dropdown.
I set up the list in my controller:
public ActionResult Index()
{
//User Dropdown List
var users = Roles.GetUsersInRole("Manager");
SelectList list = new SelectList(users);
ViewBag.Users = list;
return View();
}
Then in the view an admin can then select one of these users and save it to my database via EF:
#Html.DropDownList("Users", ViewBag.Users as SelectList, "--Select Manager--")
This all works great, however, when you edit this entry, I want the dropdown list to show the current saved manager, not the first name in the list. I was hoping on my edit action that I could pull the current manager out of the database and pass it back into the dropdown as the default selected item, but no go:
public ActionResult Edit(int id = 0)
{
var theOwner = (from v in _db.Location where v.LocationID == id select v.Owner).FirstOrDefault();
var users = Roles.GetUsersInRole("Manager");
SelectList list = new SelectList(users, theOwner);
ViewBag.Users = list;
From all the examples I have read over the last 2 weeks, everyone has had 3 different values to work within their dropdowns, making it possible to use all the overloads in the SelectList method. However, my problem is that I just have this string list with only one item in it, so I can't utilize the overloads as I want.
So does anyone have an idea on how I can get this to work? Thanks a lot in advance for your time on this!
I'm pretty sure that if you modify the second parameter on the line where you create your SelectList, it should work -- it does for me.
Here is what I think the trouble is: Currently you are specifying the second parameter as 'theOwner', which is an object reference from the earlier Linq statement. But the SelectList contains a bunch of strings (the UserNames of the users which match the specified rolename). As a result, the SelectList doesn't 'know' how to match what you specified as the SelectedItem to something in the list of strings it contains.
But if you refine that second parameter so it specifies the USERNAME of the Owner that you just looked up, it should work. However I do not know what the correct property name is from your Location table. If the field you are currently selecting (v.Owner) contains the UserName itself rather than some Key then the syntax would be:
SelectList list = new SelectList(users, theOwner.Owner);
If that column actually contains a key for the User like an int or a Guid then you will have query for the UserName using the key, but the nature of the fix is the same.
Hope that helps.
A quick workaround is not to use #Html.DropDownList but plain html code.
As an example for your case, use the following html code in your View instead of Html.DropDownList helper:
<!-- NOTE: the ID and name attributes of "select" tag should be the same as
the name of the corresponding property in your Model in order for ASP.NET MVC
to edit your Model correctly! -->
<select id="User" name="User">
#foreach (var user in (SelectList)ViewBag.Users)
{
if (user == ViewBag.TheOwner)
{
<option value="#user" text="#user" selected = "selected" />
}
else
{
<option value="#user" text="#user" />
}
}
</select>
Also , for this to work you need to add one more line to your Edit method:
ViewBag.TheOwner = theOwner;
Another solution is also possible using #Html.DropDownListFor() however you haven't shown your model so I can't tell you what exactly to use. When DropDownListFor is used, ASP.NET MVC will select an option automatically based on the value in your model.

Resources