Vue.js- Render A price comparison on a table - html

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.

Related

Create Angular2 Table Header with *ngFor loop

So, my problem is so basic but i cant solve it.
I'm trying to create dynamic table header with *ngFor.
<table>
<tr>
<th>Entry Warehouse</th>
<th colspan="2" *ngFor="let data of datas">
SomeText
</th>
</tr>
<tr>
<th>More Text</th>
<div *ngFor="let data of datas">
<th>A little text again</th>
<th>A little text again</th>
</div>
</tr>
</table>
Anyway, this solution suicide themself at that point. If datas length more than 1, div tag is underscoring th tag in same cell.
If i try another solution like this;
<table>
<tr>
<th>Entry Warehouse</th>
<th colspan="2" *ngFor="let data of datas">
SomeText
</th>
</tr>
<tr>
<th>More Text</th>
<th *ngFor="let data of datas">A little text again</th>
<th *ngFor="let data of datas">A little text again</th>
</tr>
</table>
it looks like works but actually not. Because at this time the next th tag doesnt start before the previous loop ends.
In angular 2+ you can use<ng-container> tags
<ng-conatiner *ngFor="let i of items">
<th>i</th>
</ng-conatiner>

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.

Uikit Progress bar on Uikit Table

I have problem putting a uikit progress bar inside a uikit table cell, i have searched for getuikit for progress bar and table documentation I googled everything but found no any good community or resources out there.
Here is my simplified html file for table:
<table class="uk-table uk-table-hover uk-overflow-container">
<thead>
<tr>
<th>
Employee
</th>
<th>
<label class="uk-form-label" for="name" style="font-weight: lighter;">
Contact
</label>
</th>
<th>
Workplace/Position
</th>
<th>
Status
</th>
<th>
Work Completed (%)
</th>
</thead>
<tbody>
<tr>
<td>Luigi Lascuña</td>
<td>Igi#skyes8.com</td>
<td>Main Office/General Manager</td>
<td>Regular</td>
<td class="uk-progress">
<div class="uk-progress-bar" style="width: 40%;">40%</div>
</td>
</tr>
</tbody>
</table>
Here is my output:
There result will only display the 40% text inside a table cell but
not just like in the documentation.
I just include the components/progress.css to my styles block in the head of the main html file. This solved my problem!

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

MVC Razor View Engine, add logic between quotemarks

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)">