Create select list with first option text with mvccontrib? - asp.net

Trying to create a select list with a first option text set to an empty string. As a data source I have a List of a GenericKeyValue class with properties "Key" & "Value". My current code is as follows.
<%= this.Select(x => x.State).Options(ViewData[Constants.StateCountry.STATES] as IList<GenericKeyValue>, "Value", "Key").Selected(Model.State) %>
This gets fills the select list with states, however I am unsure at this point of an elegant way to get a first option text of empty string.

"Trying to create a select list with a first option text set to an empty string." The standard way isn't fluent but feels like less work:
ViewData[Constants.StateCountry.STATES] = SelectList(myList, "Key", "Value");
in the controller and in the view:
<%= Html.DropDownList(Constants.StateCountry.STATES, "")%>

Sure you can, but you add it to your list that you bind to the dropdown...
List<State> list = _coreSqlRep.GetStateCollection().OrderBy(x => x.StateName).ToList();
list.Insert(0, new State { Code = "Select", Id = 0 });
ViewData["States"] = new SelectList(list, "Id", "StateName", index);

Or this...
Your view;
<%=Html.DropDownList("selectedState", Model.States)%>
Your controller;
public class MyFormViewModel
{
public SelectList States;
}
public ActionResult Index()
{
MyFormViewModel fvm = new MyFormViewModel();
fvm.States = new SelectList(Enumerations.EnumToList<Enumerations.AustralianStates>(), "Value", "Key", "vic");
return(fvm);
}

Without extending anything - you can't.
Here's what author says:
One final point. The goal of MvcFluentHtml was to leave the opinions to you. We did this by allowing you to define your own behaviors. However, it is not without opinions regarding practices. For example the Select object does not have any “first option” functionality. That’s because in my opinion adding options to selects is not a view concern.
Edit:
On the other hand - there is 'FirstOption' method for Select in newest source code.
Download MvcContrib via svn, build and use.

Related

Umbraco: x.GetPropertyValue("myProp") vs x.myProp

I use Umbraco v4, but think this should be a common problem.
I have a generic property "myNode" of "Content Picker", that should obtain a DynamicNode...
so doying myObj.myNode I obtain the node itself... so can use myObj.myNode.Url
But doying the myObj.GetPropertyValue("myNode") I obtain the ... string ID value of the node... so can't anymore do myObj.GetPropertyValue("myNode").Url (string does not have Url property)
I can't use directly myObj.myNode, because the name is "dynamic" (the same function should use "your"+"Node" or "their"+"Node" upon conditions - the example is very aproximative, but hope the idea is clear)...
I even did myObj.GetPropertyValue<DynamicNode>("myNode"), but the result was the same: "8124" (the node id)
So, how to obtain the real property value, not just string representation of it?
Your content picker does not contain a node, it contains an id of a node.
myObj.GetPropertyValue("myNode") does exactly what is says, gets the value of a property called myNode on the instantiated DynamicNode object. It is not designed to return the node itself.
If you want to return the node whose ID your 'myNode' property contains then you have to use that value in a call to instantiate another DynamicNode
DynamicNode myNewNode = new DynamicNode(myObj.GetPropertyValue("myNode"))
or
Model.NodeById(myObj.GetPropertyValue("myNode"))
Use somethings like: mynode = Umbraco.Content(CurrentPage.myNode).Url (for Umbraco 6 and 7) For Umbraco 4 i use this Model.NodeById(Model.myNode).Url; in a script file. (I think it need at least Umbraco 4.7.x)
See also https://our.umbraco.org/documentation/Using-Umbraco/Backoffice-Overview/Property-Editors/Built-in-Property-Editors/Content-Picker
A not so elegant solution, but at least a solution that work:
var linkNode = image.GetPropertyValue("imgLinkNode" + model._lang.ToUpper());
if (linkNode is string)
{
string id = linkNode;
linkNode = model.NodeById(id);
}
var linkNodeUrl = linkNode.Url;

ASP.NET MVC 3 - #Html.DropDownList - How do I change the description?

The following code in a cshtml file creates a dropdown with a list of Contacts, but the field it uses for the description of values, is not the one I want to display.
How do I force it to choose data from a different field in the Contact object?
#Html.DropDownList("ContactId", String.Empty)
#Html.DropDownListFor(a => a.OtherContactId,
new SelectList(Model.ContactList, "ContactId", "ContactValue",
Model.OtherContactId), "-- Select --")
where, Model.ContactList is populated in your controller action.
p.s. I'm not entirely certain whether you mean change the title of the select option text or the property that is updated, so have presented a kind of hybrid offering
You can try something like this on the server side(controller):
ViewBag.ContactList = new SelectList(iContactRepository.GetAllContacts(),
"ContactId", "Name", contactDefault.ContactId);
//Here the method GetAllContacts returns Iqueryable<Contact>.
And this on the view:
#Html.DropDownList("ContactIdSelect", ViewBag.ContactList as SelectList)
This is the SelectList documentation.
Hope it helps.

Using Html.DropDownListFor() with a SelectList

What is the correct way to populate a SelectList when using the Html.DropDownListFor helper in ASP.Net MVC 3?
I basically have a "Create" form which I want to specify the entry values on for a particular field. For example, it is a movie database and I want the ability to enter a Genre, but I don't want users to be able to enter what they like, so I assume a SelectList to be the best answer?
A way that works is to create a new class with a static method to return the SelectList:
public class Genres
{
public static List<string> GetGenres()
{
List<string> myGenres = new List<string>();
myGenres.Add("Comedy");
myGenres.Add("Romantic Comedy");
myGenres.Add("Sci-Fi");
myGenres.Add("Horror");
return myGenres;
}
}
Which can then be used like this:
<div class="editor-field">
#Html.DropDownListFor(model => model.Genre, new SelectList(OLL.Models.Genres.GetGenres()))
</div>
It just doesn't seem like the right/easiest way to do it? I think I'm missing something obvious here...
Thanks for any assistance you can provide.
This is a simple selectList style I use for drop downs all the time, hopefully you find this helpeful.
ViewBag.AlbumListDD = from c in db.Query<DatabaseEntities.VenuePhotoAlbum>("WHERE VenueId = #0", VenueId)
select new SelectListItem
{
Text = c.Name,
Value = c.Id.ToString()
};
Inside my view:
#Html.DropDownList("AlbumId", (IEnumerable<SelectListItem>)ViewBag.AlbumListDD, new { id = "ChangeAlbum" })
Hopefully you can find this useful as this is a database route to go. I typically like to have all of that sort of information in a database and that way users can dynamically add/remove and change these dropdown items at will. There is a bit of SQL work behind the scenes required when removing a type but it has proven to be very successful and fast for me at this point.
var og = (from s in DB.Products
select new SelectListItem
{
Text = s.ProductName,
Value = s.ProductID.ToString()
});
ViewBag.lstProducts = new SelectList(getproductname, "ProductID", "ProductName");
<p>
#Html.DropDownList("AlbumId", (IEnumerable<SelectListItem>)ViewBag.lstProducts, new { #id = "drp" });
</p>

avoiding the use of the viewdata enumerable object in controller - reg

I have 2 points for today
I. I have a controller in which i have a public static method for getting the details for a checkbox like
public static List<country> GetCountryLists()
{
List<country> countries = new List<country>();
country _country = new country() { countryname = "Select a country", value = "0" };
country _country1 = new country() { countryname = "India", value = "India" };
country _country2 = new country() { countryname = "USA", value = "USA" };
countries.Add(_country);
countries.Add(_country1);
countries.Add(_country2);
return countries;
}
Currently , i am using this function via
ViewData["country"] = GetCountryLists();
is it ok for me to use this same function like this one in the view, so that I do not need to use the viewdata object,
<%: Html.DropDownList("country", new SelectList(UserController.GetCountryLists(), "value", "countryname", "0"))%>
Kindly suggest me the best practice.
II. Also i have another query, when i use the same id & name for the radiobuttons, validation at the client side is working fine.
If I use the same condition for a group of checkboxes, i get do not get the checkboxes highlighted during client validation and only during server validation, i get the error message, but the controls [checkboxes] do not have a red border indicating the error.
I have used my own html helper to generate the checkboxlist as per http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs
Kindly let me know if there is any possible solution for this problem too. As i am new to asp.net mvc2, i am not sure of using these.. kindly suggest me accordingly.
is it ok for me to use this same function like this one in the view, so that I do not need to use the viewdata object
No, this is not good practice and violation of the MVC pattern for various reasons. Views shouldn't pull information. They should only use the information that it is being passed in the view model. It is the controller's responsibility to invoke various methods to fetch data and then construct a view model containing all the necessary information needed for the view and then pass this view model to the view. So here's the suggested way:
<%= Html.DropDownListFor(
x => x.Country,
new SelectList(Model.Countries, "value", "countryname")
) %>
or with the ugly/weakly typed/avoid to use/requiring magic strings ViewData:
<%= Html.DropDownList(
"Country",
new SelectList((IEnumerable)ViewData["Countries"], "value", "countryname")
) %>
and it is the responsibility of the control to populate either the view model properties or the ugly ViewData.
As far as your second question is concerned you will need to show your code in order to see what is wrong with it. From your description what I can say is that you cannot have two elements with the same id in the DOM or you get invalid markup.

Eval versus DataField in ASP:Datagrid

I have this really random problem with is bugging me. It works at the end of the day but the problem took some time to figure out and was wondering why this happens so if anyone shed some light on the subject I would be really grateful. Here is the problem
I have the following two columns on my datagrid
<asp:boundcolumn
datafield="contentsection.Id"
headerstyle-cssclass="dgHead"
headertext="Section"
itemstyle-cssclass="dgItem" />
and
<asp:templatecolumn>
<itemtemplate><%#Eval("contentsection.Id") %></itemtemplate>
</asp:templatecolumn>
The first column gives me the error of:
A field or property with the name 'contentsection.Id' was not found on the selected data source
but the second on runs fine. Any ideas or theories as to why this is happening ?
The way that I call and bind my data is like so:
Page Load Code Behind
ContentList.DataSource = ContentBlockManager.GetList();
ContentList.DataBind();
The GetList() function it is overloaded and by default passed a 0
public static List<ContentBlockMini> GetList(int SectionId)
{
List<ContentBlockMini> myList = null;
SqlParameter[] parameters = { new SqlParameter("#ContentSectionId", SectionId) };
using (DataTableReader DataReader = DataAccess.GetDataTableReader("dbo.contentblock_get", parameters))
{
if (DataReader.HasRows)
{
myList = new List<ContentBlockMini>();
}
while (DataReader.Read())
{
myList.Add(FillMiniDataRecord(DataReader));
}
}
return myList;
}
and my filling of the data record. The ContentSection is another Object Which is a property of the ContentBlock object
private static ContentBlockMini FillMiniDataRecord(IDataRecord DataRecord)
{
ContentBlockMini contentblock = new ContentBlockMini();
contentblock.Id = DataRecord.GetInt32(DataRecord.GetOrdinal("Id"));
contentblock.Name = DataRecord.GetString(DataRecord.GetOrdinal("Name"));
contentblock.SEOKeywords = DataRecord.IsDBNull(DataRecord.GetOrdinal("SEOKeywords")) ? string.Empty : DataRecord.GetString(DataRecord.GetOrdinal("SEOKeywords"));
contentblock.SEODescription = DataRecord.IsDBNull(DataRecord.GetOrdinal("SEODescription")) ? string.Empty : DataRecord.GetString(DataRecord.GetOrdinal("SEODescription"));
if (DataRecord.GetInt32(DataRecord.GetOrdinal("ContentSectionId")) > 0)
{
ContentSection cs = new ContentSection();
cs.Id = DataRecord.GetInt32(DataRecord.GetOrdinal("ContentSectionId"));
cs.Name = DataRecord.IsDBNull(DataRecord.GetOrdinal("ContentSectionName")) ? string.Empty : DataRecord.GetString(DataRecord.GetOrdinal("ContentSectionName"));
contentblock.contentsection = cs;
}
return contentblock;
}
There you go that is pretty much the start to end.
Databinding can only access "top level" properties on an object. For example, if my object is
Company with simple properties CompanyId and Name and a child object for Address, databinding can only access CompanyId and Name, not Company.Address.City.
Eval can access child object properties if you import the namespace using an #Import page directive.
The "Bind" marker is a two-way bind and is made using the default namespace attached to the datasource of the object. This can't be overridden, and because of this tightly coupled connection the namespace should be left off as assumed (since it's dynamically pulled from the datasource).
Eval is a one-way binding that can be used with any namespace that will fulfill a proper evaluation. Dates, strings, method calls, etc. The namespace provided in your example just provides eval with a marker on where to get the data relevant.
The key here is the nature of the binding. Eval is a "fire and forget" sort of binding where as Bind is more rigid to facilitate the two-way.
The DataField property approach isn't complicated enough to support dot notation; it expects a direct reference in your underlying data source; it takes that field and checks the data source, which it can't find it by the exact string.
The second approach, eval, is more dynamic, but actually I wasn't sure if it supported dot notation... learn something everyday.
HTH.
It's necessary take a look to your DataSource, but you can do a simple test: convert the first column to a template column a try to Run.
In EntityFramework is possible Eval Properties using code like this: <%#Eval("Customer.Address.PostalCode") %>.
I dont know if it is your case, but if you provide more details about how to retrieve the DataSource we can help you.

Resources