vue.js when sorting grid only values is updated, not HTML - vue.js

I am new to Vue.js, and could really use som help on this one.
I am trying to put a class (success) on my table rows to give them background color depending on the value of a property (status) in each of the objects in Array (data), wich is working as intended using the v-bind:class.
The problem arises when i sort the table rows by clicking on the table headers. When this is done there is a mismatch between the colored rows and their content, as if only values of rows is updated and not the rows themselves.
Try it here : https://jsfiddle.net/Bayzter/cyv1o78s/
Does anyone know how to solve this, so colored rows again match up with the correct objects?
<script type="text/x-template" id="grid-template">
<table>
<thead>
<tr>
<th v-for="key in columns"
#click="sortBy(key)"
:class="{active: sortKey == key}">
{{key | capitalize}}
<span class="arrow"
:class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="
entry in data
| filterBy filterKey
| orderBy sortKey sortOrders[sortKey]" v-bind:class="{ 'success' : data[$index].status == 0}">
<td v-for="key in columns">
{{entry[key]}}
</td>
</tr>
</tbody>
</table>
</script>
<!-- demo root element -->
<div id="demo">
<form id="search">
Search <input name="query" v-model="searchQuery">
</form>
<demo-grid
:data="gridData"
:columns="gridColumns"
:filter-key="searchQuery">
</demo-grid>
</div>

Where you have
v-bind:class="{ 'success' : data[$index].status == 0}"
You want
v-bind:class="{ 'success' : entry.status == 0}"
$data[$index] is not going to refer to the current-order item, it's going to refer to the original-order item. entry is the current item.

Related

Fixed Column on HTML Table with Vue JS

I'm having a problem with my table when I scroll to the right
this is my code
TableComponent.vue
<div id="main-container">
<table class="maint-table">
<thead id="table-header">
<tr>
<th class="dates"> </th>
<th v-for="data in dateHeader">{{data}}</th>
</tr>
<tr>
<th class="title"> </th>
<th v-for="data in dayOfWeek">{{data}}</th>
</tr>
</thead>
<tbody id="table-body" #scroll="fixedScroll">
<table_block :table_data="dataHeader"></table_block>
<table_block :table_data="allData"></table_block>
</tbody>
</table>
</div>
...
...
...
<script>
components: {
table_block
},
methods: {
fixedScroll() {
fixedScroll(event) {
var thead = document.getElementById("table-header");
var tbodyScroll = document.getElementById("table-body").scrollLeft;
thead.scrollLeft = tbodyScroll;
}
</script>
I made a props to pass the data to my TableBlock to loop through the data and display it on the table. This is my TableBlock Code.
TableBlock.vue
<template>
<div>
<tr v-for="row in table_data">
<td>
<div class="drop-down-container"><span class="drop-down-controller"">{{ row.title }}</span></div>
</td>
<td v-for="cel in row.data" class="group-header">{{ cel }}</td>
</tr>
</div>
</template>
When I scroll it to the right, the first column must freeze but it's not.
I tried to create a dummy data inside TableComponent.vue with a normal HTML Table without passing the data to another component using props, it works perfectly. But when I use these codes, it doesn't work correctly.
Scenario
Let say I have 10 columns in the table, when I scroll it to the right, the 1st column will stick which is normal but when the 10th column reach to 1st column, the 1st column will scroll away together with the 10th column.
I'm trying my best to illustrate the scenario but this is the best that I can do. If someone can help, please help me.

Does vue.js have something like AngularJS' `ng-repeat-start`

Parsing vue.js' docs I can't see any hint that vue.js has something like a ng-repeat-start / ng-repeat-end
Is there a way to archive something like
<table>
<tr class="weather_warning top" ng-repeat-start="warning in dwd_warnings">
<td {{warning.valid_from}} → {{warning.valid_to}}</td>
<td><div style='background:{{warning.color}};'>{{warning.message}}</div></td>
</tr>
<tr class="weather_warning bottom" ng-repeat-end>
<td colspan="2">
{{warning.description}}<br/>
<span>Issued on the {{warning.effective}} ({{warning.headline}}). {{warning.ascertain}}</span>
</td>
</tr>
</table>
Each warning consists of 2 TRs which go together. One is the top half of the message in the iteration, the other one the lower half. It must be this way, because of some very weird formatting stuff, so there's no way around using 2 TRs for one item. Maybe some tags are off in this example, this is because I had to delete a ton of stuff in order to post it here. Note the colspan="2" in the TD of the second TR, which might give a bit of a hint of the problem which is tackled here.
Closest thing I can think of is to use a <template>, eg
<template v-for="item in items">
<header>
Header {{ item }}
</header>
<div class="body">
Body {{ item }}
</div>
<footer>
Footer {{ item }}
</footer>
</template
See https://v2.vuejs.org/v2/guide/list.html#v-for-on-a-lt-template-gt
... you can also use a <template> tag with v-for to render a block of multiple elements
Nothing changes with your edit, you just wrap your two <tr> elements in
<template v-for="warning in dwd_warnings">
<tr class="weather_warning top">
<!-- etc -->
</tr>
<tr class="weather_warning bottom">
<!-- etc -->
</tr>
</template>

xpath with following-sibling

I want to access the table with classname 'table table-hover' that should be under the class=='box-title' that contains the text 'OODR Items for next 20 Days'. Can any one please help me out to get the xpath for this ? I tried with following-sibling but no luck. Thanks in advance.
<?xml version="1.0" encoding="UTF-8"?>
<div id="topTenSellers" class="box box-solid box-primary frontpageWidget">
<div class="box-header">
<i class="fa fa-group" />
<h3 class="box-title">OODR Items for next 20 Days</h3>
<div class="box-tools pull-right">
<button class="btn btn-primary btn-sm" data-widget="collapse">
<i class="fa fa-minus" />
</button>
</div>
</div>
<!-- /.box-header -->
<div class="box-body no-padding">
<table class="table table-hover">
<tbody>
<tr>
<th style="width: 10px">#</th>
<th>Booking</th>
<th>Item Start Date</th>
<th>Site</th>
<th>Supplier</th>
</tr>
<tr>
<td>
<strong>1</strong>
</td>
<td>
(642143)
</td>
<td>21/10/2017 00:00:00</td>
<td>Ski</td>
<td>OODR - Out of Date Range</td>
</tr>
</tbody>
</table>
</div>
<!-- /.box-body -->
</div>
You can try following instead of following-sibling as mentioned h3 and table nodes are not siblings:
//div[#id="topTenSellers"]//h3[#class="box-title" and .="OODR Items for next 20 Days"]/following::table[#class="table table-hover"]
If there is only one element of that class name then either of these will work. One thing to note though, selenium can struggle with spaces in class names depending on the version and browser. If you find that is the case, then use multiple contains to handle the spaces.
//table[contains(#class,'table table-hover')]
//table[#class = 'table table-hover']
If you need that the element as a child of that OODR Items for the next 20 days
//h3[contains(text(),'OODR Items for the next 20 days')]/parent::div/following-sibling::div/table[#class ='table table-hover']
This path uses your anchor point, "OODR Items..", then goes to the parent, then sibling, then to the item with the specified class name. Good luck!

Table cell validation in vuejs and laravel 5.4

I’m very new to VUE and trying loop through dynamically created tables from unique arrays. I have the table creation complete and dynamic table id’s based off a value from the array. I’m trying to validate that either cell[0] in each row contains a specific string or if the last cell[?] which has a select dropdown has been selected and is said string.
I’ve done something similar before in JS like this.
$("#" + t_node + " :selected").each(function (i,sel) { .....///code }
and like this
$("table#"+t_node+" > tbody > tr").each(function(row, tr) { .....///code }
I don’t know how to replicate with VUE.
I have a onclick event that I want to loop through the table and for any row that has p2vg01 already created sum its size along with any select option of p2vg01. In the below table I’d want to find that SDB was selected at 107GB. Not shown but it could be that SDB was already p2vg01 but if I selected SDC as well as p2vg01 I’d sum 32GB + 107GB.
<div v-for="storageResult in storageValidationResults" >
<h3 class="panel-title">{{ storageResult.node_name }}</h3>
<table :ref="storageResult.node_name" v-bind:id="storageResult.node_name" class="table table-bordered table-striped table-hover" >
<thead>
<th v-for="(value, key, index) in storageResult.table_head">
{{ value }}
</th>
<th>Select</th>
</thead>
<tbody>
<tr v-for="(value, key, index) in storageResult.disk_data">
<td v-for="v in value">
{{ v }}
</td>
<td v-if="checkAvailable(value)">
<select>
<option value="">--Select VG--</option>
<option value="p2vg00">p2vg00</option>
</select>
</td>
<td v-else=""></td>
</tr>
</tbody>
</table>
</div>

Dynamic Interpolation in Angular2

I am learning Angular-2 and try to build data-grid component and run into a problem with dynamic interpolation.
Assume, the other component will consume the data-grid like the following:
<data-grid [model] = 'users'>
<column header='Last Name' value="lastName" ></column>
<column header='First Name' value='firstName' ></column>
<column header='Address' value='address' ></column>
</data-grid>
The data-grid component holds a collection of columns. From the data-gird, I try to loop through the columns collection to build the column header then show all data. The headers for the table is easy but I don't know how to do the nested interpolation for row and columns.
<div class="container" >
<table class="table table-hover">
<thead class="thead-default">
<tr>
<th template="ngFor let col of columns">
{{ col.header}}
<th>
</tr>
</thead>
<tbody>
<tr template="ngFor let row of model">
<td template="ngFor let col of columns">
<!-- want to loop though the columns
{{row.{{col.value}}}} //How to make this statement works? -->
</td>
</tr>
</tbody>
</table>
</div>
Any idea how to solve this problem?
thanks,
Austin
You do not need the additional evaluation brackets. Use square brackets for array indexing.
<tr *ngFor="let row of model">
<td *ngFor="let col of columns">
{{row[col.value]}}
</td>
</tr>
http://plnkr.co/edit/DVwolRDu0JNcsXTaTrir