VueJS - v-for and attributes on the parent Element - vue.js

I'm working with a table display and am using vueJS to render a group of rows inside of a table. The bindings inside of the <tr> work fine, but I can't figure out how to bind say an attribute that lives on the parent <tr> that hosts the v-for directive:
<tr v-for="detailItem in itemList" data-key="{detailItem.pk}}">
<td>{{detailItem.cdesc}}</td>
<td>{{(detailItem.nnetunits * 1).toFixed(2)}}</td>
...
</tr>
In this code the inner items on the <td> bind just fine, but how would you get the data-key bound?

With Vue 2 you don't use interpolation in attributes, you use the attribute binding syntax.
<tr v-for="detailItem in itemList" v-bind:data-key="detailItem.pk">
Or the shortcut
<tr v-for="detailItem in itemList" :data-key="detailItem.pk">

Related

How to use v-show with dynamic element in Vuejs

I have a dynamic table rendering where columns and rows of the table are rendered dynamically.
So here I have two sibling <td> elements in each row:
<td :key="`td3-${index}`" :id="`show_${key}`" v-show="`show_${key}`">
<input type="text" :v-model="key" :name="key" :value="entry[key]" />
</td>
<td :key="`td4-${index}`">
Edit
</td>
In the onclick event of the link in the second <td> I have to show and hide the first <td> element. Since it's dynamic I will have multiple rows. So I declared a dynamic boolean in my data to show and hide the specific <td> based on the click of another <td> in the same row.
v-show="`show_${key}`" - this is show property with dynamic key
show_firstname: false,
show_lastname: false,
show_email: false,
show_orgname: false
I created separate boolean elements for every <td> in each row.
But whenever I change the value of v-show property with the on click of second <td> element it's not making any difference. So I could not show or hide the <td>. Maybe v-show takes "`show_${key}`" as a string value not replacing true or false correctly. Can someone help me how can I achieve this?
Why don't you try organising the show_ in an object instead of a flat list of properties?
https://codesandbox.io/embed/vue-template-csncc?fontsize=14&hidenavigation=1&theme=dark

Adding field to Qweb report

There is field account.move.line.journal_id and i want it to be displayed in report.
i'm trying by
<tr t-foreach="p.account_move_line" t-as="p">
<span t-esc="p.journal_id"/>
</tr>
or something like this.
<tr t-foreach="p.account_invoice.payment_move_line_ids" t-as="p">
<span t-esc="p.journal_id"/>
but getting error
AttributeError: 'NoneType' object has no attribute 'account_move_line'
Error to render compiling AST
AttributeError: 'NoneType' object has no attribute 'account_move_line'
Template: account.report_invoice_document
Path: /templates/t/t/div/div[4]/div[2]/table/tr[2]/td[2]/tr
Node: <tr t-foreach="p.account_move_line" t-as="p">
<span t-esc="p.journal_id"/>
</tr>
In t-foreach you must have the list you want to iterate. I think the error is that you are assigning the value to p and at the same time you are iterating by this variable.
Try changing the variable (this is taking into account that p is your account_invoice record, otherwise you can access directly without the t-foreach):
<tr t-foreach="p.account_move_line" t-as="j">
<span t-esc="j.journal_id"/>
</tr>
I hope I've helped ;)

Angular-repeat display column IF equal to a value

I am using angularJS to display my result set into a table, that is filterable with totals etc. I was wondering if it would be possible to display a value based on another value if it is = to something. here is an example:
<tr ng-repeat="c in data">
<td>{{c.type}}</td> //expects either 'fixed' or 'hourly'
<td>{{c.fixed_rate}}</td>
<td>{{c.hourly_rate}}</td>
</tr>
Therfore are you able to only display the fixed value if type is fixed, and hourly if the type is hourly without using any JQuery to hide elements?
My mind is kind of stumped on this as I am just a few months in with angular.
Data is pulled from a database* so if there is an SQL option I am all for it.
You could do something like this:
<tr ng-repeat="c in data | filter: filterHourlyOrFixed">
<td>{{c.type}}</td>
<td ng-if="c.type == 'fixed'">{{c.fixed_rate}}</td>
<td ng-if="c.type == 'hourly'">{{c.hourly_rate}}</td>
</tr>
If you want to filter by only those two values, add this function to your controller:
$scope.filterHourlyOrFixed = function (item) {
return item.type === 'fixed' || item.type === 'hourly';
};
If you do not want to filter by the value, remove | filter: filterHourlyOrFixed from the ng-repeat.
Also, when you have some time, do a little reading through the docs for ngIf, ngShow, ngHide, and ngFilter. You'll probably be using these repeated. Also, pay attention to the differences in how ng-if, ng-show, and ng-hide manipulate the DOM to achieve similiar results.
The differences are subtle, but important.
Use ng-if to remove or recreate parts of the DOM based on an expression. for example:
<tr ng-repeat="c in data">
<td>{{c.type}}</td> //expects either 'fixed' or 'hourly'
<td ng-if="c.type=='fixed'">{{c.fixed_rate}}</td>
<td ng-if="c.type=='hourly'">{{c.hourly_rate}}</td>
</tr>
You could also use a filter, if you are rendering identical DOM but want to exclude certain elements.
You could try something like this:
<tr ng-repeat="c in data">
<td ng-if="c.type =='fixed'">Fixed</td>
<td ng-if="c.type =='hourly'">Hourly</td>
<td ng-if="c.type =='fixed'">{{c.fixed_rate}}</td>
<td ng-if="c.type =='hourly'">{{c.hourly_rate}}</td>
</tr>
Hope this helps!
http://embed.plnkr.co/Wes1Uf1OCCmKYa5wTP5s/preview

Thymeleaf calling method on object

Is it possible to call a method on an object in an "each" loop in Thymeleaf? I'm trying to create a dynamic table where both rows and columns can be dynamic. A Table have a list of Rows and a list of Columns. Column have a method getValue that for a given Row can get the value. But I'm not able to call this getValue(Row row) from Thymeleaf.
I have this Thymeleaf code:
<table>
<tr th:each="row : ${table.rows}">
<td th:each="column : ${table.columns}">
<span th:text="${column.value(row)}"/>
</td>
</tr>
</table>
This causes an exception:
Exception evaluating SpringEL expression: "column.value(row)"
Is it even possible to do this in Thymeleaf, e.g. pass variables to methods on other variables?
I found the problem, since I'm passing in something to this method it's not a getter method so I have to provide the full method name: getValue not just value:
<table>
<tr th:each="row : ${table.rows}">
<td th:each="column : ${table.columns}">
<span th:text="${column.getValue(row)}"/>
</td>
</tr>
</table>

Angularjs - How to apply different class in <tr> conditionally to repeat directive

I need to apply a different class to a <tr> according to the $index of the repeat directive. For example
<table>
<tr ng-repeat="model in list" class="xxx">
<td>...</td>
<tr>
</table>
I need to apply a different style to <tr> depending on whether the index is even and odd.
How could I solve this?
Normally you would use ngClassOdd (http://docs.angularjs.org/api/ng.directive:ngClassOdd) and ngClassEven (http://docs.angularjs.org/api/ng.directive:ngClassEven) directives like this:
<tr ng-repeat="item in items" ng-class-odd="'class1'" ng-class-even="'class2'">
Here is the jsFiddle: http://jsfiddle.net/pkozlowski_opensource/hNHJ4/1/
Unfortunately there is an issue where the mentioned directives are not working correctly when rows are removed: https://github.com/angular/angular.js/issues/1076
As a work around you can use the ngClass directive (http://docs.angularjs.org/api/ng.directive:ngClass) with the $index variable exposed by a repeater:
<tr ng-repeat="item in items" ng-class="{class1 : $index%2==0, class2 : !($index%2==0)}">
Here is the jsFiddle: http://jsfiddle.net/pkozlowski_opensource/am7xs/
It is not super-clean, but could be improved (for example, by exposing a function in a root scope, something like:
ng-class="getClass($index,'class1','class2')"
till the mentioned bug is fixed
If this is just for styling you can just use CSS
tr:nth-child(odd) { ... }
tr:nth-child(even) {...}
see http://jsfiddle.net/5MSDC/ for an example