I have this code
<div class="result correct"><%# Eval("QandAID") %></div>
and I am wondering how I can set conditions on the value, I.e if the eval value is 2 change div class to "result incorrect" else leave as "result correct". That's also part of the question if anyone knows how to do that (change the div class based on the condition), then that would be a bonus.
Oh and I have that code inside a repeater bound to a dataset.
Define a property in the Page class:
public int MyValue { get; set; }
Then access it in the page this way:
<div style='width: <%=MyValue %>px'></div>
This example should answer indirectly your question and open up some more possibilities on how to put values into HTML that may or may not be bound to a DataRow.
Another example:
<%# Eval("QandAid") == 2 ? "result incorrect" : "result correct" %>
Or:
<div class='<%# Eval("QandAid") == 2 ? "class1" : "class2" %>'>
This should happen outside of the markup. Make the class a property of your model and set it based on your condition:
class YourModel {
public int QandAID { get; set; }
public string ValidityClass {
get {
return QandAID == 1 ? "correct" : "incorrect";
}
}
}
Then your repeater template becomes something like this:
<div class='result <%# Eval("ValidityClass") %>'><%# Eval("QandAID") %></div>
Related
I am using asp.net webform 4.5.1 code first with entity framework. I used one repeater and bind it to my entity class. I want use if statement to decide show one DIV in this repeater or not. my code is :
<asp:Repeater ID="ProductRepeater" runat="server"
ItemType="Models.Product"
SelectMethod="ProductRepeate_GetData">
<ItemTemplate>
<% if(Item.Rank > 5 && Item.X != null && Item.Y != null){%>
<div>I want show this div just if my if statement is True</div>
<%}%>
<div >
<%# Item.Name%>
</div>
</ItemTemplate>
</asp:Repeater>
I want show the first div just when the result of if statement is True. the error is : The name 'Item' does not exist in the current context
This isn't the kind of calculation that you would want to include inline; not only will it be very difficult to read, it will also be very difficult to debug.
Instead, create a label <asp:Label ID="outputLabel" runat="server" ></asp:Label> and set the value of the label from the ItemDataBound Event on the repeater.
protected void ProductRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Label output = (Label)item.FindControl("outputLabel");
Product product = (Product)item.DataItem;
if (product.Rank > 5 && product.X != null && product.Y != null)
{
output = "I want show this div just if my if statement is True";
}
else
{
output = product.Name;
}
}
I know you already got an answer, you can do it in markup also like this:
<%# (Item.Rank > 5 && Item.X != null && Item.Y != null)? "<div>I want show this div just if my if statement is True</div>" : "" %>
I have a simple field in one of my views that shows a sum for one of my columns using this code:
<p class="points-total" >#Html.Encode(ViewData["pointsTotal"])</p>
This is my controller code regarding pointsTotal:
pointsTotal = occurrences.Sum(o => o.Points);
ViewData["pointsTotal"] = pointsTotal.ToString();
I would like to assign a different class to this line based on the value of pointsTotal. For example if the total is over 50 points I'd like to assign it to class points-total-fifty.
I know I can do this on other HTML helpers like DisplayFor by doing this:
<p class="#(item.Total > 50 ? "points-total-fifty" :
"points-total")">#Html.DisplayFor(modelItem => item.Total)</p>
Is there a way to do the same thing with the Html.Encode helper?
Actually the code you put for your second example will work also with the Html.Encode helper as you are styling the <p> element. One way to do it for example:
#{
string cssClass = "points-total";
int? total = ViewData["pointsTotal"] as int?;
if (total.HasValue && total > 50)
{
cssClass = "points-total-fifty";
}
}
<p class="#cssClass" >#Html.Encode(ViewData["pointsTotal"])</p>
I am re-opening my question as it has been set as duplicate while it is not - or people who tagged it as duplicate should explain me why it is a duplicate..........
https://stackoverflow.com/questions/13227988/html-displayfor-result
How can I get the result of the method Html.DisplayFor() in a C# Class, like in a View model or even in a Controller ? And not in the View Aspx or Razor.
[Edit]
In fact I have a table to display and depending on the number of record I use a Telerik table or a simple HTLM table.
For the moment I have a function in my view to get the string to display for each column so I use the same format for both tables.
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ViewModels.OrderViewModel>" %>
<script runat="server" type="text/C#">
public string GetCellValue (String columnName, Order order)
{
string value = "";
switch (columnName)
{
case "Ref":
value = order.order.Reference.ToString(); break;
case "Etc":
value = Html.DisplayFor(p => order.order.Etc).ToHtmlString();break;
case "Payment date":
foreach (Executions ex in order.executions)
{
value += ex.Date.Date.ToString("yyyy-MM-dd") + " ";
}
break;
I want to move this function out of my view in the ViewModel for example, but I do not know how I can call the function Html.DisplayFor() out of a view.
Don't understand why would you want to do it, but...
using System.Web.Mvc;
using System.Web.Mvc.Html;
class Example {
void Method()
{
HtmlHelper<TModel> Html = new HtmlHelper<TModel>();
MvcHtmlString result = Html.DisplayFor(prop => Model.Prop);
}
}
After your edit, if you move GetCellValue to another place, maybe you will only need to do
MvcHtmlString result = new MvcHtmlString(order.order.Etc);
as, it should only display its value as string (unless you have set up a template for it).
I have method that is returning IQuerable given below:
internal IQueryable<TradeLeads> GetLeadsByCategory(int categoryId)
{
return
_context.BuySells.Where(bs => bs.CategoryId == categoryId).OrderBy(bs => bs.CreationDate).Select(
bs => new TradeLeads
{
Id = bs.Id,
BuySellTypeId = Convert.ToInt32(bs.BuySellTypeId.ToString()) ,
Description = bs.Description,
Flag = bs.Company.Country1.Flag,
MembershipType = bs.Company.MembershipType,
IsUsingSmsNotifications = bs.Company.IsUsingSMSNotifications,
IsVerified = bs.Company.IsVerified,
ProductImagePath = bs.ProductImagePath,
ProductName = bs.ProductName,
CompanyName = bs.Company.CompanyName,
CompanyId = Convert.ToInt32(bs.CompanyId.ToString()),
PostedDate = bs.CreationDate
});
}
All fields are having values. I am binding BuySellTypeId in the header template of the repeater control. ASPX is given below, which is in Usercontrol.
<HeaderTemplate>
<div class="grdheader">
<div class="hdrText">
<h3 id="h3TypeName">
</h3> <asp:HiddenField runat="server" ID="HidTypeId" Value='<%#Eval("BuySellTypeId") %>'/>
</div>
<div class="hdrMore">
<a href='<%#string.Format("ViewAll.aspx?t={0}",Eval("BuySellTypeId"))%>'>
<img src="cdn/images/more.png" />
View More </a>
</div>
</div>
</HeaderTemplate>
I am binding repeater from its parent page something like this. First I changed the protection level of the repeater from protected to public, so that I can access it from any where, without casting or finding from parent page.
private void BindAllBuyAndSellLeads(int categoryId)
{
var repo = new LeadsRepository();
var list = repo.GetLeadsByCategory(categoryId);
BindGrid(1, Leads1.LeadsGrid, list);
BindGrid(2, Leads2.LeadsGrid, list);
}
private static void BindGrid(int leadTypeId, Repeater gv, IQueryable<Core.Helper.TradeLeads> list)
{
var query = (from p in list
where p.BuySellTypeId == leadTypeId
select p).ToList();
Common.BindGrid(query, gv);
}
here Leads1 and Leads2 are the user control Leads.ascx. That is same usercontrol is placed at two places on page. But i am getting empty while binding. Please help , where and what i am doing wrong.
Binding in a header will never work. Binding is for ItemTemplate only; you can programmably set the value in the header, but realize the repeater is for binding multiple rows of data; there are multiple items, but only one header. Which BuySellTypeId should be used? The first one? The last one? There is no way for the repeater to tell, so you would have to programmably set the value.
I have a table in my database with a one to many relationship to another table, which has a relationship to a third table:
ParentObject
ID
Name
Description
ChildObject
ID
Name
Description
ParentObjectID
AnotherObjectID
AnotherObject
ID
Name
The objects are mapped into Entity Framework and exposed through a data access class.
It seemed like ViewModels are recommended when the data to be displayed greatly differs from the domain object, so I created a ViewModel as follows:
public class ViewModel {
public IList<ParentObject> ParentObjects { get; set; }
public ParentObject selectedObject { get; set; }
public IList<ChildObject> ChildObjects { get; set; }
}
I have a view that displays a list of ParentObjects and when clicked will allow a ChildObject to be modified saved.
<% using (Html.BeginForm()) { %>
<table>
<% foreach (var parent in Model.ParentObjects) { %>
<tr>
<td>
ObjectID [<%= Html.Encode(parent.ID)%>]
</td>
<td>
<%= Html.Encode(parent.Name)%>
</td>
<td>
<%= Html.Encode(parent.Description)%>
</td>
</tr>
<% } %>
</table>
<% if (Model.ParentObject != null) { %>
<div>
Name:<br />
<%= Html.TextBoxFor(model => model.ParentObject.Name) %>
<%= Html.ValidationMessageFor(model => model.ParentObject.Name, "*")%>
</div>
<div>
Description:<br />
<%= Html.TextBoxFor(model => model.ParentObject.Description) %>
<%= Html.ValidationMessageFor(model => model.ParentObject.Description, "*")%>
</div>
<div>
Child Objects
</div>
<% for (int i = 0; i < Model.ParentObject.ChildObjects.Count(); i++) { %>
<div>
<%= Html.DisplayTextFor(sd => sd.ChildObjects[i].Name) %>
</div>
<div>
<%= Html.HiddenFor(sd => sd.ChildObjects[i].ID )%>
<%= Html.TextBoxFor( sd => sd.ChildObjects[i].Description) %>
<%= Html.ValidationMessageFor(sd => sd.ChildObjects[i].Description, "*") %>
</div>
<% }
}
} %>
This all works fine. My question is around the best way to update the EF objects and persist the changes back to the database. I initially tried:
[HttpPost]
public ActionResult Edit(ViewModel viewModel) {
ParentObject parent = myRepository.GetParentObjectByID(viewModel.SelectedObject.ID);
if ((!ModelState.IsValid)
|| !TryUpdateModel(parent, "SelectedObject", new[] { "Name", "Description" })) {
|| !TryUpdateModel(parent.ChildObjects, "ChildObjects", new[] { "Name", "Description" })) {
//Code to handle failure and return the current model snipped
return View(viewModel);
}
myRepository.Save();
return RedirectToAction("Edit");
}
When I try to save a change to the child object, I get this exception: Entities in 'MyEntities.ChildObject' participate in the 'FK_ChildObject_AnotherObject' relationship. 0 related 'AnotherObject' were found. 1 'AnotherObject' is expected.
Investigation on StackOverflow and general googling led me to this blog post that seems to describe my problem: TryUpdateModel() does not correctly handle nested collections. Apparently, (and stepping through the debugger confirms this) it creates a new ChildObject instead of associating with the EF objects from my instantiated context.
My hacky work around is this:
if (viewModel.ChildObjects.Count > 0) {
foreach (ChildObject modelChildObject in viewModel.ChildObjects) {
ChildObject childToUpdate = ParentObject.ChildObject.Where(a => a.ID == modelChildObject.ID).First();
childToUpdate.Name = modelChildObject.Name;
}
}
This seems to work fine. My question to you good folks: Is there a correct way to do this? I tried following the suggestion for making a custom model binder per the blog link I posted above but it didn't work (there was an issue with reflection, the code expected certain properties to exist) and I needed to get something going ASAP.
PS - I tried to cleanup the code to hide specific information, so beware I may have hosed something up. I mainly just want to know if other people have solved this problem.
Just briefly looking at the error mentioning FK_ChildObject_AnotherObject... are you sure everything is wired up correctly in your EF data model concerning AnotherObject?
In your question you only list two tables, but this error is indicating that the ChildObject is participating in a 1 to * relationship with AnotherObject and there is not one present in the entity on save causing an error.
Try removing AnotherObject from the situation in order to test any assumed problems between ParentObject and ChildObject, or try changing the FK_ChildObject_AnotherObject relationship to 0..1 to * briefly for testing.
You could look at using Omu ValueInjector instead of tryupdate. It can be configured to be much smarter although I prefer to use it by convention.
tbh not entirely clear on the original question here. I'm not sure why the childobjects in the viewmodel are being detached form the parent in the first place?