Thymeleaf calling method on object - html-table

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>

Related

YADCF - customFunc and exFilterColumn

I'm trying to use a custom filter on one of my columns and to do the filtering programmatically. I have managed to call the custom filter but the filterVal prints as null. Code below:
Calling the filter:
yadcf.exFilterColumn(theTable, [[4, "Value To Filter On"]]);
The filter itself - I'm just returning true for now to test the actual calling of the filter:
function numberFilter(filterVal, columnVal, rowValues, stateVal) {
console.log(filterVal)
return true;
}
The console.log line prints out null instead of "Value to Filter On".
Am I missing something or is customFunc even supported with exFilterColumn?
It wasn't working because you tried to filter with value that is not present in the filter values, in addition notice that you have used html elements in the column which resulted in html elements in the filter itself,
Here is the modified code for filter
$("#value-filter").on('input', function () {
console.log(this.value);
yadcf.exFilterColumn(theTable, [[0, 50]]);
})
and updated column data
<tr>
<td>
500
</td>
</tr>
<tr>
<td>
200
</td>
</tr>
<tr>
<td>
50
</td>
</tr>

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

VueJS - v-for and attributes on the parent Element

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

Click on specific button based on name of the class or elements

I captured the testName by using driver.find_element_by_xpath("//td[contains(.,'%s')]" % test_name)
How can I capture class name based on testName?
I am trying to click on menu-button if it contains specific test name
<tr class="row-1">
<td>testName</td>
<td>testDes</td>
<td class="menu">
<div class="menu-button">
</div>
</td>
</tr>
This is one possible XPath expression :
//tr[td[contains(.,'testName')]]/td[#class='menu']/div[#class='menu-button']
Basically the above XPath locate tr element having child td value equals "testName", then return the corresponding div[#class='menu-button'] element.

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