MVC Razor View Engine, add logic between quotemarks - html

I'm really new at using Razor with MVC, and so far I really like it.
One little thing I want to do is write a variables value to an attribute in HTML.
For example, if I had the following:
<table style="width: 100%">
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
Value
</th>
</tr>
#foreach (var item in Model)
{
<tr id="ID#item.id">
<td>
#item.id
</td>
<td>
#item.name
</td>
<td>
#item.value
</td>
<td>
</tr>
}
</table>
I would want all the tags to have an ID equal to "ID[insert item's id]", but instead I get an ID equal to "ID#item.id".
How do I write a variable's name between HTML quote marks?
Thanks!

This pattern is recognized as an email address. Do the following to work around this behavior:
<tr id="ID#(item.id)">

Related

Vue.js- Render A price comparison on a table

I have a use case, i'm struggling to put together.I want to display prices of goods from different shops like in the picture below.
My problem is i get the following table;
The output on my table is incorrect. Price for Zimgold is only available in Spar. But here its displayed under all other shops. The same goes for Raha.Its Price is supposed to be under OK.I want other shops to have a dash or empty rows if they don't have that product.
Here is my vue.js code:
<modal ref="comparisonTable" no-close-on-backdrop no-close-on-esc hide-cancel width="600px" title="GENERATE BILL" :hide-ok="true" hide-footer centered>
<Spinner v-show="productsLoader" :message="productsLoaderMessage" size="medium"></Spinner>
<table class="table table-striped " v-show="productsTable" width="100%">
<!--Table head-->
<thead>
<tr class="table-info">
<th>Product Brands</th>
<th v-for="company in selectedCompaniesDetails" :key="company.id">
{{company.name}}
</th>
<th>Pick</th>
</tr>
</thead>
<!--Table head-->
<!--Table body-->
<tbody>
<tr v-for="product in products" :key="product.id">
<th scope="row">
{{product.name}}
</th>
<td v-for ="totalCompanies in totalSelectedCompanies" :key="totalCompanies">
<span>
{{product.price}}
</span>
</td>
<td>
<input type="checkbox" style="margin:10px;" v-model="selectedProducts" :value="product"/>
</td>
</tr>
<tr>
<th scope="row">
</th>
<td v-for ="totalCompanies in totalSelectedCompanies" :key="totalCompanies">
</td>
<th>
<button #click="generateFinalBill($event)">
GENERATE BILL
</button>
</th>
</tr>
</tbody>
</table>
</modal>
In your example you have two nested for loops, the outer one loops through products and the inner one loops through totalSelectedCompanies.
The problem is that your product.price variable only changes with each iteration of the outer loop. In order to display a different price for each iteration you would need to have the value be affected by the inner loop.
The way you do this would depend on how the price is stored or calculated but the one way to do this is to store the prices for each seller in the product object and loop through that:
<tr v-for="product in products" :key="product.id">
<th scope="row">
{{product.name}}
</th>
<td v-for ="seller in product.sellers">
<span>
{{seller.price}}
</span>
</td>
<td>
<input type="checkbox" style="margin:10px;" v-model="selectedProducts" :value="product"/>
</td>
</tr>
An issue with this is that you would have to have every seller in product.sellers regardless of if they actually sold it. Instead I would make a method that returns the price of a product from the given company, then you could do something like:
<tr v-for="product in products" :key="product.id">
<th scope="row">
{{product.name}}
</th>
<td v-for ="company in selectedCompanies">
<span>
{{calculateCompanyPrice(product, company)}}
</span>
</td>
<td>
<input type="checkbox" style="margin:10px;" v-model="selectedProducts" :value="product"/>
</td>
</tr>
calculateCompanyPrice() would then contain all the logic for returning the price you need from a given product and company, including displaying a dash if the company does not sell the given product.
Edit: It's worth noting that you can technically put any valid javascript between your {{ }}s, so I'm sure there are many other ways of outputting the proper price within the inner loop.

ASP.NET MVC table row including link on text from model

I'm trying to display a table from a model. But the problem is that my model class has a string that already includes an <a> tag.
My view is:
#model MyWeb.Models.Incidente
#{
Layout = null;
ViewBag.Title = "Communication for " + Model.num.ToString();
}
<h2>#ViewBag.Title</h2>
<table class="table">
<tr>
<th> User </th>
<th> Date </th>
<th> Time </th>
<th> Message </th>
</tr>
#foreach (MyWeb.Models.Comunication item in Model.GetComunications())
{
<tr>
<td> #Html.DisplayFor(modelItem => item.user) </td>
<td> #Html.DisplayFor(modelItem => item.date) </td>
<td> #Html.DisplayFor(modelItem => item.time) </td>
<td> #Html.DisplayFor(modelItem => item.message) </td>
</tr>
}
</table>
The problem is that one item in GetComunications() has a message that include a link to Google:
You can Google it, just press Here!. Thank you!
So when the table is displayed the message shows the tag instead of creating the link in "Here!".
How can I solve this problem, and show a message that already has a link on the string?
If you are sure about the sanitation of your output, you can use Html.Raw:
#Html.Raw(Html.DisplayFor(modelItem => item.message))

How to dynamically add HTML element/content - Angular

What would be the best way to dynamically add an HTML element, such as another column onto a basic HTML table?
I want to have a button below the table, and if the user were to click the button, the event would add the same amount of rows already in the table and add another column. I would want to support about 5 extra columns being added to the table.
Here's my HTML table as of right now:
<table>
<thead>
<tr>
<th id="row-tag"></th>
<th id="option-column">Option 1</th>
</tr>
</thead>
<tbody>
<tr>
<td id="row-tag">P</td>
<td id="option-column">{{ p }}</td>
</tr>
<tr id="row-tag">
<td>
<app-a-p (saveButtonClick)="toggleAP($event)"
[modModalValues]="modModalValues">
</app-a-p>
</td>
<td id="option-column">
<div class="input-group input-group-sm">
$<input
*ngIf="toggleAP==true"
type="text"
name="aP"
size="10"
disabled
value=""
/>
<input
*ngIf="toggleAP==false"
type="text"
name="aP"
size="10"
[ngModel]="con.pA"
(ngModelChange)="con.pA = $event" appFormatP
(blur)="checkAP($event.target.value);
inputTracker.addModifiedValue('Option 1', $event.target.value)"
/>
</div>
</td>
</tr>
<tr>
<td id="row-tag">L</td>
<td id="option-column">${{l}}</td>
</tr>
<tr>
<td id="row-tag">R</td>
<td id="option-column">${{r}}</td>
</tr>
</tbody>
</table>
I think in Angular, you define table based on your data. for example, you have fields array defining columns, and data array defines the what's actually in the table.
<table >
<thead>
<tr>
<th *ngFor='let key of this.fields'>{{key}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let row of this.data ' >
<td scope="row" *ngFor='let key of this.fields'> {{row[key]}} </td>
</tr>
</tbody>
</table>
when you need a new column, just push a new field into fields. like
fields.push('newcolumn');
when you need a new row, just do:
data.push({col1: '', col2:'', newcolumn: ''});
Look into the insertRow() and insertCell() functions in JavaScript. This alongside an onClick function that you write will let you edit the table.
A good way of generating a table on UI when using angular would be to use 2D-array (row*column) use can have a button using which you can dynamically add values to this array and have another row/column to the table.

Use XPath in nodeset repeater (XForms)

I have a question about XPath and the nodeset repeater (XForms).
As you can see in the following code snippet I want to change an attribute of a specific entry of a list and additionally an attribute in the following entry in the nodeset with a trigger.
The first <xf:action> works fine but the second does not. What I want here is to leave the current nodeset of the processinstance, go to the following one and change the attribute state here. How do I realize that with XPath?
<div>
<xf:model>
<xf:instance xmlns="" id="template">
<project id="">
<name/>
...
<processinstance>
<name>
<state>
</processinstance>
</project>
</xf:instance>
</xf:model>
....
<!-- Process repeat table -->
<div>
<table class="table table-hover">
<thead>
<th width="50%">Processname</th>
<th width="50%">State</th>
<th width="50%">Action</th>
</thead>
<tbody id="process-repeat" xf:repeat-nodeset="//project[index('project-repeat')]/processinstance">
<tr>
<td>
<xf:output ref="name"/>
</td>
<td>
<xf:output ref="state"/>
</td>
<td>
<xf:group ref=".[state eq 'in processing']">
<xf:trigger appearance="minimal">
<xf:label>finish process</xf:label>
<xf:action>
<xf:setvalue ref="state">finished</xf:setvalue>
</xf:action>
<!-- THE FOLLOWING DOES NOT WORK AS I WANT! -->
<xf:action>
<xf:setvalue ref="//project[index('project-repeat')]/processinstance[index(process-repeat)+1]">in process</xf:setvalue>
</xf:action>
</xf:trigger>
</xf:group>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Best regards,
Felix
One thing is that you have a typo:
index(process-repeat)
vs.
index('process-repeat')
In addition, the index() function represents the currently selected, in the UI, repeat iteration. It does not represent the current iteration being evaluated in XPath.
The bottom line is that you cannot use index('process-repeat') to identify the current repeat iteration. It is a common misunderstanding of the index() function.
Some implementations have functions to identify the current repeat iteration. I assume you are using BetterFORM, and I don't know if it has such a function. With Orbeon Forms you could write:
//project[index('project-repeat')]/processinstance[xxf:repeat-position()]
Or better, if betterFORM supports variables, you could use that to avoid repeating yourself with:
<tbody id="process-repeat" xf:repeat-nodeset="//project[index('project-repeat')]/processinstance">
<xf:var name="current-process" value="."/>
<tr>
<td>
<xf:output ref="name"/>
</td>
<td>
<xf:output ref="state"/>
</td>
<td>
<xf:group ref=".[state eq 'in processing']">
<xf:trigger appearance="minimal">
<xf:label>finish process</xf:label>
<xf:action>
<xf:setvalue ref="state">finished</xf:setvalue>
</xf:action>
<xf:action>
<xf:setvalue ref="$current-process">in process</xf:setvalue>
</xf:action>
</xf:trigger>
</xf:group>
</td>
</tr>
</tbody>

Bind Angular with dynamic data from database

I am pretty new to Angularjs and I would like to achieve an editable table similar to this jsfiddel http://jsfiddle.net/NfPcH/93/ (retrieved from the official angular doc) however instead of hardcoded data, how can I fill the table with a List of data retrieved from the database in MVC or a ViewBag?
for example instead of this MVC table below I would like to achieve to achieve the same thing but instead using Angular to make the table editable.
#if (ViewBag.Session != null)
{
<table class="table table-hover">
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
Surname
</th>
<th>
House
</th>
<th>
Address
</th>
<th>
Locality
</th>
<th>
Contact
</th>
<th>
Contact 2
</th>
<th>
Contact 3
</th>
<th>
Reply
</th>
<th>
Edit
</th>
</tr>
#foreach (var item in ViewBag.Session)
{
<tr>
<td>
#item.ID
</td>
<td>
#item.Name
</td>
<td>
#item.Surname
</td>
<td>
#item.House
</td>
<td>
#item.Address
</td>
<td>
#item.Locality
</td>
<td>
#item.Contact1
</td>
<td>
#item.Contact2
</td>
<td>
#item.Contact3
</td>
<td>
#item.Reply
</td>
</tr>
}
</table>
Additionally, when a row is changed and saved, how can the data be sent back to the backed to be save in the database?
I think it would be a good idea for you to read a jumpstart tutorial, training, or book.
Here you have a link to get started using web api in the server side plus angularjs on the client, it just load a list of items from the server.
http://www.youtube.com/watch?v=Ja2xDrtylBw