Razor syntax inside attributes of html elements (ASP MVC 3) - asp.net-mvc

I have a table with repeating customer rows, I would like to add the customer ID to the ID attribute of my table rows like this:
<tr id="row<customer id>"></tr>
I try adding this code:
#foreach(var c in Model) {
<tr id="row#c.id"></tr>
}
Which gives me the following output:
<tr id="row#c.id"></tr>
<tr id="row#c.id"></tr>
etc.
But I would like it to be:
<tr id="row1"></tr>
<tr id="row2"></tr>
etc.
I also tried to add <tr>row#{c.id}</tr> but it did not work..

have you tried <tr>row#(c.id)</tr>?
The actual reason why this doesn't work is because your row#c.id matches the regex for an email address. So the parser assumes it's an email and not actually an attempt to call code. The reason row#{c.id} doesn't work is because the #{} doesn't output and is meant to contain blocks of code.
When in doubt you should use #() as it will force what's contained between the () to be parsed as code.

Related

How to send number with country code to url of browser from mvc application

I Wrote this code in view
#foreach (var item in Model.CDR)
{
<tr>
<th>
<a class="facebook" rel="nofollow" target="_blank" href="https://www.facebook.com/search/top/?q=#item.BNumber">Facebook</a>
<a class="facebook" rel="nofollow" target="_blank" href="https://www.truecaller.com/pk/#item.BNumber">True Caller</a>
</th>
When I click on this number,
it gets automatically send to url and
url automatically identify this number's country code ...
My Problem :
When I send the number Url is not identifying its country code.
Tell me how is it possible ?
The first few things to check would be the standards, how are you passing this modal. In the controller or do you have a separate ViewModel class?
Something you might want to add is a check
Assuming Model.CDR is a List or Enumerable
Another thing you should do is have the type of CDR.
Easiest way to do this if you are struggling is (If using Visual Studio) put a break point in at the #foreach line and in your watch, call Model.CDR to see what type it is passing back.
That will allow you to strongly type it in your foreach statement, makes the whole thing a heap easier.
#if (Model.CDR.Length != 0)
{
#foreach (object //CHANGE OBJECT TO YOUR TYPE// item in Model.CDR){
}
}
If you send in a little more info on what your Model looks like, how the CDR object is constructed I could help you a little more.

Grails pass parameter from loop to controller

In Grails I'm trying to delete a record from a (HTML) table, I want to achieve this by passing the ID of the object to the controller. So there is a table in HTML and the user clicks "delete" and the item is deleted from the database. (This logic works according to the unit tests, the problem is passing the ID from view -> controller)
I have tried several solutions found on here such as
<g:each in="${recipe}" var="item">
<tr>
<td>
${item.recipeName}
</td>
<td>
${item.people}
</td>
<td>
<g:link controller="UserRecipe" action="delete" params="[id: '${item.id}']" class="class">Info to Display</g:link></tr>
</g:each>
Which doesn't crash but calls the controller correctly, though the value of the id = null. When I manually edit the url and add /4 for example, the ID will be four. Several solutions on here showed how to pass parameters, but the error arrises when I try to pass a parameter which I access using the ${} notation with these solutions, e.g. using createLink and a params list, it will crash the application because it's a nested ${${}} it seems.
You need to change your params to:
params="[id: item.id]"

Refactor a C# loop to Knockout Mapping Plugin

Where the server is sending the client a complex object and the goal is to transition from C#'s 'foreach' to KnockoutJS's 'data-bind="foreach: ' consider this code that populates a shopping cart with various pieces of info:
#{
foreach (var item in GetItems(Model))
{
<dt>
<input type="radio" id='mode_#(item.ID)' name="mode" value="#item.ID" />
#item.Label - $#item.PriceToAdd
</dt>
<dd>
#Html.Raw(item.Explanation) </dd>
}
}
}
Should the server's code be adjusted to flatten out the object before rendering the View or can KnockoutJS deal with unwrapping it? Would it get easier if the server sends JSON?
FOLLOWING UP:
It becomes clear the question boils down to mapping plugin and mfanto's first answer gets me part the way there:
self.items = ko.mapping.fromJS(#Html.Raw(JsonConvert.SerializeObject(Model.Items)));
firebug shows me output of:
self.items = ko.mapping.fromJS([{"ID":60},{"ID":62},{"ID":63},{"ID":64},{"ID":9}]);
Perhaps mapper fails because one of my Items (id=9) has different elements than the rest.
Probably I need to research one of the more advances usages of mapper?
FORMATTED OUTPUT COMPARES VALUES RETURNED BY JsonConvert vs. JavaScriptSerializer
...
self.itemsJSON = ko.mapping.fromJS(#Html.Raw(JsonConvert.SerializeObject(Model.Items)));
self.items = #Html.Raw(new JavaScriptSerializer().Serialize(Model.Items));
when the above code renders to a breakpoint in Firebug:
self.itemsJSON = ko.mapping.fromJS([{"ID":60},{"ID":62},{"ID":63},{"ID":64},{"ID":9}]);
self.items = [ //line breaks inserted for clarity
{"Explanation":"Item1's text.","Label":"Item1's Label","MsgConfirm":null,"PriceToAdd":1255,"TaxExempt":false,"PercentToAdd":0,"SortOrder":1,"ID":60},
{"Explanation":"Item2's text.","Label":"Item2's Label","MsgConfirm":null,"PriceToAdd":1255,"TaxExempt":false,"PercentToAdd":0,"SortOrder":2,"ID":62},
{"Explanation":"Item3's text.","Label":"Item3's Label","MsgConfirm":null,"PriceToAdd":295,"TaxExempt":false,"PercentToAdd":0,"SortOrder":3,"ID":63},
{"Explanation":"Item4's text.","Label":"Item4's Label","MsgConfirm":null,"PriceToAdd":395,"TaxExempt":false,"PercentToAdd":0,"SortOrder":4,"ID":64},
{"Explanation":null,"Label":"[foo]","MsgConfirm":null,"PriceToAdd":150,"TaxExempt":false,"PercentToAdd":0,"SortOrder":99,"ID":9}
];
thx
You don't need to flatten the object before you use Knockout. The ko.mapping plugin will create viewmodels with observable properties, and can handle complex nested objects.
To use it with an ASP.NET MVC model, use #Html.Raw() and a Json serializer (in this case Json.NET:
function AppViewModel() {
var self = this;
self.items = ko.mapping.fromJS(#Html.Raw(JsonConvert.SerializeObject(Model.Items)));
}
ko.applyBindings(new AppViewModel());
From there, you can use foreach:
<table>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: PriceToAdd()"></td>
</tr>
</tbody>
</table>
You can go either way with this. Render it on the server with Razor or render it on the client with knockout... The more fundamental question is where do you want to render it. There is no right or wrong answer here.
If you go with knockout, you need to deal with more than just having the server possibly flatten out your model. Knockout will require ajax requests to both read and then save your data and this is where the two solutions fundamentally differ I don't see any JavaScript as part of your solution and without that component, providing a ko solution is pretty impossible.
If you are thinking about using knockout simply as a client side templating engine, then something like jsrender is likely a better solution.

Change bound Id to separate model name

So I have two separate models, one 'items' model, the second a 'sites'
model... I'm using KO to bind this data to two separate elements on
the DOM (and working as needed), but I've found a need to replace one
of my bound columns on one of my models, with data from the other.
On my 'items' model, I have a site ID column, that I'd love to swap
with the actual 'SiteName' property on that model (simple name, value-
pair - SiteName, SiteId)... Does any one know a way to do this within
KO?
I really want to keep the model data itself in tact on the server side,
verses just creating a custom model on the server side that does it for me.
I'm sure I could give those elements a special class, and loop
through them and replace them manually with jQuery, but I thought that
KO might have an easier way of doing this.
Thanks!
I have tried something like this, but it doesn't seem to work (yes, I know div tags within a table element are not standards based, I just wanted to see if it would work, and if it did, I'd transition from the table to another formatting option)
<tbody data-bind="foreach: items">
<tr data-bind="click: updateItem">
<td data-bind="text: ItemName"></td>
<div data-bind="foreach: sites">
<div data-bind="if: items.SiteId = sites.SiteId">
<td data-bind="text: sites.SiteName"></td>
</div>
</div>
The jQuery to do this using my returned model is:
$(function () {
$('#allItems tr .siteIdCell').each(function () {
for (i in allSites) {
if (allSites[i].SiteId == $(this).html()) {
$(this).html(allSites[i].SiteName);
}
}
});
});
Where .siteIdCell is the class I applied to the columns using this value, and allSites is the object array I'm receiving via JSON.
Not sure if I'll get many responses, but I just figured I'd update this if anyone else has the same issue, and there's no ability to do this in KO.

Razor View Engine: Complex looping and HTML

I have lots of complex HTML reports in my current project where there we perform lots of conditional rendering of TRs and TDs with rowspans and colspans.
It could sometimes look like this (this is extremely simplified):
<tr>
#foreach (var ourItem in ourList) {
if (ourItem != ourList.First()) {
<tr>
}
<td></td>
</tr>
}
However, Razor claims: "The foreach loop is missing a closing "}" character". (within Visual Studio)
I've tried to wrap the <tr> in <text></text> which makes the closing } problem go away only to find this when run: "Encountered end tag "tr" with no matching start tag. Are your start/end tags properly balanced".
How would I do this kind of conditional rendering while convincing Razor not to bother about the HTML at all, cause the HTML is balanced when all the looping is done. Or at least that was the case when the ASP.NET View Engine was used.
Visual Studio Intellisense and syntax highlighting is not one of the best but in this case it warns you that if the condition is not satisfied, you might get invalid markup and you shouldn't blame it for this.
The important thing is that your project runs fine but you might consider externalizing this logic into HTML helpers because if what you are saying is true that this is a simplified version of what you have in the views I don't even want to imagine how your actual code looks.
IMHO having so much conditional logic in a view is an abuse. You definitely should consider using HTML helpers or controls such as MVCContrib Grid.
UPDATE:
You may try the following hack:
<tr>
#foreach (var ourItem in ourList) {
if (ourItem != ourList.First()) {
#:<tr>
}
#:<td></td>
#:</tr>
}
Razor depends on matching tags to determine the automatic transitions between code and markup. You cannot "disable" this feature of Razor (at least not without rewriting large parts of the Razor parser).
You can work around it by using Darin's suggestion, though I don't understand (at least not from your simplified example) why your view needs to be so convoluted. Why not write the following code instead:
#foreach (var ourItem in ourList) {
<tr>
<td>...</td>
</tr>
}
While tags might balance out in the generated markup, the source that you provided makes it very difficult to reason about its correctness.
When trying to use rowspan and trying to get a structure like
<table>
<tr>
<td rowspan=2>1:st col</td>
<td>2:nd col</td>
</tr>
<tr>
<td>2:nd col</td>
</tr>
</table>
You could try:
#{
var ourList = new List<string> { "1", "2", "3" };
}
<table border=1>
#foreach(var ourItem in ourList){
<tr>
#if (ourItem == ourList.First())
{
<td rowspan="#ourList.Count()">#ourItem</td>
}
<td>#ourItem</td>
</tr>
}
</table>
I had a similar problem - my solution Html.Raw("");
if (isTrue)
{
<text><div></text> }
...
if(isTrue) {
#Html.Raw("</div>"); // <-- closing tag!
}

Resources