SomeObject record = new SomeObject();
record.value1 = 1;
record.value2 = "hello";
<td><input type="checkbox" id="indicator_#record.value1_#record.value2" /><td>
What is the proper razor syntax to create a checkbox with an id of "indicator_1_hello"?
When attempting this way, it says the object doesn't contain a definition for value1_ (understandable) and when I tried "indicator_#record.value1#_#record.value2" if had a runtime error about something named _ not existing in the context (again, understandable).
edit:
As a temporary solution I've done:
SomeObject record = new SomeObject();
record.value1 = 1;
record.value2 = "hello";
var combined = String.Format("{0}_{1}", record.value1, record.value2);
<td><input type="checkbox" id="indicator_#combined" /><td>
I am still curious if you can do it all inline though.
#{
// just for testing
var record = new { value1 = "foo", value2 = "bar" };
}
<input type="checkbox" id="indicator_#( record.value1 + "_" + record.value2 )">
Gives: <input type="checkbox" id="indicator_foo_bar">
Just make sure that you aren't building an ID which would be better auto-generated by the natural hierarchy of your view model. Most of the time, you shouldn't need to manually construct IDs in your view.
If you need something like this, I'd suggest adding that field (i.e. CheckboxID) to your model and populate it on the server side, before passing it to the view.
Related
I have an Index (List) View in MVC5, that is populated from a model (Table ICS_Supplies).
I have added a textbox to add search filter for the users, on field ItemDescription (varchar). This works perfectly fine as follows:
View
<form asp-controller="Movies" asp-action="Index">
<p>
Search Supplies: <input type="text" name="SearchString">
<input type="submit" value="Filter" />
</p>
</form>
Controller
public ActionResult Index(string searchString, string SType, int? page, string YourRadioButton)
{
// Add SearchBox Filter
var catalogs = supplies.Where(s => s.ItemDescription.Contains(searchString ?? string.Empty));
// Add paging to the search results
var pageNumber = page ?? 1;
return View(catalogs.ToPagedList(pageNumber, 10));
}
This works perfectly. If the searchString is null, it brings back ALL results. IF the searchSring has a value, it brings back any results where ItemDescription Cotain the searchString Value.
I am trying to add a radiobutton to the index view so that the user can also filter on the field InvType, which is a char(1) field. It can be F (for Forms) or S (for supplies). So, I set the value of YourRadioButton to F or S depending on which is selected. . . as follows (with new code)
Index
<form asp-controller="Movies" asp-action="Index">
<div>
Supplies: #Html.RadioButton("YourRadioButton", "S")
Forms: #Html.RadioButton("YourRadioButton", "F")
</div>
<p>
Search Supplies: <input type="text" name="SearchString">
<input type="submit" value="Filter" />
</p>
</form>
And I update the Controller with additional code, as follows:
public ActionResult Index(string searchString, string SType, int? page, string YourRadioButton)
{
var supplies = db.ICS_Supplies.OrderBy(g => g.ItemDescription).ToList();
//var supplies2 = supplies.Where(s => s.InvType.Equals(mychoice));
var supplies2 = supplies.Where(s => s.InvType.Contains(YourRadioButton ?? string.Empty));
// Add SearchBox Filter
var catalogs = supplies2.Where(s => s.ItemDescription.Contains(searchString ?? string.Empty));
// Add paging to the search results
var pageNumber = page ?? 1;
return View(supplies2.ToPagedList(pageNumber, 10));
}
Now, I receive The following error
System.NullReferenceException
And it is referring to the following line of code (which I added)
var supplies2 = supplies.Where(s => s.InvType.Contains(YourRadioButton ?? string.Empty));
My question(s) are . . . Why does that kick out a NullReferenceException, but the other line works perfectly fine if it is null? And how do I resolve the issue - or is there a better way to add this second filter to my code?
This line works fine, null or not. They are both identical in how they are written, other than the Value of YourRadioButton is used, instead of searchString, and I am using InvType field instead of ItemDescription.
var catalogs = supplies2.Where(s => s.ItemDescription.Contains(searchString ?? string.Empty));
Keep in mind that I am VERY new to both MVC5 and C#, and so explaining why would help me a great deal to progress.
There does not seem to be a lot of information out there, in regards to using radio buttons in MVC5 . . . a rather simple concept in old Asp.net forms.
It seems that some entries of suppliers doesn't have an InvType. That property is sometimes null, therefore you receive a NullReferenceException because you are calling Contains() method on a null value property.
The problem doesn't occur in your first example, because you were using Linq to Entities.
In the second example you are calling ToList() after the first query. After that, everything will continue to work in memory (Linq to Objects). Then you have to check for null in any where condition:
var supplies2 = supplies.Where(s => s.InvType != null && s.InvType.Contains(YourRadioButton ?? string.Empty));
I think it is better to remove ToList() from the first query. Add your where conditions to it and let the PagedList execute the query for you:
public ActionResult Index(string searchString, string SType, int? page, string YourRadioButton)
{
var supplies = db.ICS_Supplies.AsQueryable();
if (!String.IsNullOrWhiteSpace(YourRadioButton))
{
supplies = supplies.Where(s => s.InvType.Contains(YourRadioButton));
}
if (!String.IsNullOrWhiteSpace(searchString))
{
supplies = supplies.Where(s => s.ItemDescription.Contains(searchString));
}
supplies = supplies.OrderBy(g => g.ItemDescription)
// Add paging to the search results
var pageNumber = page ?? 1;
return View(supplies.ToPagedList(pageNumber, 10));
}
I can't find anything to solve my problem in search, and here is my problem:
I'm using ASP.NET MVC 4 and EF 5, I'm trying to get a value from my db, but this db field depends on other var.
In Controller:
public ActionResult Products()
{
ViewBag.lang = "ENG";
DataEntities db = new DataEntities();
ViewBag.Categories = db.Categories;
return View();
}
In Template View:
<ul>
#{
if (ViewBag.Categories != null)
{
foreach (var cat in ViewBag.Categories )
{
<!-- we need in this case "Name_ENG" -->
var title = "Name_" + #ViewBag.lang;
<li>#cat.(title)</li>
<!-- out: cat.ToString() + "(title)" -->
<li>#cat.(#title)</li>
<!-- out: cat.ToString() + "(" + title.ToString() + ")" -->
<li>#cat.#title</li>
<!-- out: cat.ToString() + title.ToString() -->
}
}
}
</ul>
is there a way to get property "Name_ENG" from cat object like #cat.Name_ENG using a string ?
"In this case I'm trying to list al Categories in Products page."
Thanks a lot
No, definitely not in c#. You'd have to use reflection for this to work (and the syntax would be different of course as well).
I think a better option would be to create a method that would retrieve the value based on a string input, like
public T GetValue<T>(string propertyName)
and call that from your view when needed
here is an article from msdn. You can access EF entries properties by name. But at first you need dbContext and second it is wrong to access dbContext from view.
example:
object currentName2 = context.Entry(blog).Property("Name").CurrentValue;
Also, as mentioned in another answer, reflection:
object value = typeof(YourType).GetProperty("PropertyName").GetValue(yourInstance, null);
Try this
<ul>
#{
if (ViewBag.Categories != null)
{
foreach (var cat in ViewBag.Categories )
{
// here you can do something on cat
<text>
<li>#(cat.title)</li>
</text>
}
}
}
</ul>
I personally suggest you to pass the data to the view by parameter. And use #model in the view (strong type view).
I have a date in my DB of 2014-03-03 05:00:00, which is being rendered in JSON as:
the date is /Date{(-6xxxxx)/ and I call this method to parse it:
function parseJsonDate(dateString) {
var result = new Date(+dateString.replace(/\/Date\((-?\d+)\)\//gi, "$1"));
var result = new Date(parseInt(dateString.replace('/Date(', '')));
result.format("dd-MM-yyyy");
return result;
}
when running, i comment out one of the results lines, but get the same result for both:
the method is being called from Jquery template like such:
<tr>
<td>
<span id="approvedDate"><i class="glyphicon glyphicon-time" data-toggle="tooltip"
data-original-title="approved date"></i> ${parseJsonDate(AuditDate)}</span>
</td>
</tr>
EDIT
What a muppet.. I spent so long thinking this was a JSON vconversion issue, i totally forgot to go back and check my dapper code. my ApprovalHistory objec had AuditDate, but I was asking for EnteredDate in the sql. So, it was doing as expected.
aaaaaaaarrr :-)
I am seeing something fishy there
var result = new Date(+dateString.replace(/\/Date\((-?\d+)\)\//gi, "$1"));
var result = new Date(parseInt(dateString.replace('/Date(', '')));
you are making two variables named result within the same closure, is it intentional?
what does result.format do? since result is a Date object I wouldn't assume that it would change the original type from Date to string.
Maybe
var s = result.format("dd-MM-yyyy");
return s;
is what you really want to do?
you can do this after the ajax complete, this will save you tons of trouble having to parse the Date(xxxxx) thing over and over again
data = data.replace(/\"\\\/Date\((-?\d+)\)\\\/\"/g, '$1')
this will convert "Date(xxxx)" to xxxx and then you can just call new Date(xxxx) to make new Date object.
Maybe you could use something like this:
var str = (result.getMonth() + 1) + "-" + result.getDate() + "-" + result.getFullYear();
return str;
I have a very large form that represents a month or more of data. Each day has 3 drop-downs the user can update and then i need to save the data in the form. I should mention I had to make a custom dropdown (HERE) to use a style class so it's not the standard Html.dropdown()
So what I'd like to do is something like...
View:
#{
List<string> DropdownValues = new List<string>();
}
#using(Html.BeginForm("Method","Controller",FormMethod.Post,new{ Data = DropdownValues}))
{
#Html.CustomDropdown("Name1",ListOfOptions1)
#Html.CustomDropdown("Name2",ListOfOptions2)
#Html.CustomDropdown("Name3",ListOfOptions3)
<input type="submit" value="Submit" />
#{
//Do on submit
DropdownValues.add(Name1.value);
DropdownValues.add(Name2.value);
DropdownValues.add(Name3.value);
}
}
Ideas?
Thanks!
You can access form element direct from controller code without them having to be part of the Action parameters. Maybe this is what you are looking for?...
//In controller post action
string name1 = Request.Form["Name1"];
string name2 = Request.Form["Name2"];
//etc...
You could even put it in a loop depending on what you are doing with the data...
for(int i = 1; i <= 30; i++)
{
string nameX = Request.Form["Name" + i];
}
EDIT: A bit more detailed HTML document... In short- how do I actually do the lookup and where precisely should the element.setvalue or element.value appear in the query...
Edit 2: The list of monkey id does not appear clear so I will add proper id's and add additional properties to my Lookup data object, sorry for the confusion! The reason I have used a list is bacause my datasource could be from anywhere also I have used a List object because I do not really know the proper usage of Dictionary (I am a newbie to coding hence why my question is all over the place, please bear with me)
I have an XElement which is a properly formatted HTML document, I am trying to replace only the value of a html element with a value contained in a List Object for example
<div id="pageContainer">
<p> some guy wants to <b>buy</b> a <h4><label id="monkey23">monkeyfield</label></h4> for some price that I do not have a clue about, maybe we should <i>suggest</i> a list of other monkeys he may like:
</p>
<h3>list of special monekeys you may want chappy...</h3>
<br />
<ul>
<li><label id="monkey13">monkeyfield</label></li>
<li><label id="monkey3">monkeyfield</label></li>
<li><label id="animal4">animalfield</label></li>
<li><label id="seacreature5">seacreaturefield</label></li>
<li><label id="mamal1">mamal field</label></li>
</ul>
</div>
Note: the value "monkeyfield" is a temporary value inserted onscreen for the purpose of identifying this is a field, once the values from the data source is binded the new values should appear.
public class LookupData
{
public string id{get;set;}
public string value{get;set;}
public string Type{get;set;}
public string Url{get;set;}
}
...
public void DataTransformerMethod()
{
var data = new List<LookupData>();
data.add(new LookupData{id="monkey3", value="special monkey from africa" });
data.add(new LookupData{id="monkey13", value="old monkey from china" });
data.add(new LookupData{id="seacreature5", value="sea monkey" });
data.add(new LookupData{id="animal4", value="rhino" });
data.add(new LookupData{id="mamal1", value="some mamal creature" });
//what linq query will iterate over the document and set the values from the values
//found in the list?
var answer = from x in HtmlDocAsAXelement
where x.Attributes()
.Any(a=> data.AsEnumerable().Where(f=> f.Name == a.Name) );
//somehow I should use .SetValue(a.value)???
SaveTheNewXElement(answer ); //all other original data must stay in tact...
}
Well, you need to iterate over all the XElements which need changing - and set their value by just calling the Value setter:
element.Value = "newvalue";
It would be trickier if the element had multiple text nodes and you only wanted to change one of them, but as there's no other content within the element, this should be fine for you.
EDIT: After the discussion, I would do something like this:
Dictionary<string, string> replacements = data.ToDictionary(x => x.id,
x => x.value);
foreach (XElement element in HtmlDocAsAXelement.Descendants())
{
string newValue;
string id = (string) element.Attribute("id");
if (id != null && replacements.TryGetValue(id, out newValue))
{
element.Value = newValue;
}
}
You can't do that "easily", because there is no foreach equivalent in LINQ. That's on purpose. See http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx and LINQ equivalent of foreach for IEnumerable<T>.
I would suggest you just do a normal foreach over the query results.