How to add an element to a list with condition using th:with? - conditional-statements

I'm trying to create a list of elements, but the elements may be added if they satisfy their given conditions, for example :
<\div th:with = "$list = { {[condition1] ? [value1 if true] : null, [condition2] ? [value2 if true] : null } }">
What is intended is that, the size will vary depending on each conditions for the elements, so that list could either have 2 or 1 or no element at all. However, thymeleaf treats null as an element too, so I don't know if there is a way to instruct the engine to literally 'not add' when condition is false.

I would need to see your code to evaluate your conditional statements, but perhaps you could still have the nulls, just not access them?
Spring has a safe navigation operator, which looks like this: ?.
It helps to avoid NullPointerException by directly skipping the object, if it is null, instead of trying to access its methods or properties.
Here is a Thymeleaf use case from this post:
<td th:text="${user?.address?.city}"></td>
Hope this helps you.

Related

filter and range with map are not working

my need is to go over a list but extract only the first two elements out of that list.
i wrote the following code
payload.list.*listItem filter ($.type == "supervisor") map {
// other code
}
this worked perfectly fine. Then I modified it to extract the first two elements only like this
payload.list.*listItem filter ($.type == "supervisor") [0 to 1] map {
// other code
}
and it doesnt work anymore. i am getting no error but the other code doesnt work as if the map operator has nothing to go over.
also i need to make it work for a scenario if there is only one element after the filter is applied.
how should i change my code to make this work.
The range selector must be used directly over an Array so you just need to properly do the selection:
(payload.list.*listItem filter ($.type == "supervisor"))[0 to 1] map {
// other code
}
You need to add parenthesis to ensure precedence. Also, I'm surprised it worked for you at all. I needed to put "type" in single quotes to get it to work since that is a dataweave keyword. I did this ?($$<2) instead of [0 to 1] since I wasn't sure if you were guaranteed to have at least two objects in the output of the filter. If you know, you'll have at least two, leave it the way you had it.
(payload.list.*listItem filter ($.'type' == "supervisor"))[?($$<2)] map (value, index) ->
{
"key":value
}
Here's a link to Dataweave documentation on precedence. It snags a lot of people. Safer just to use parens in most cases.

NHibernate QueryOver condition on several properties

I have this armor table, that has three fields to identify individual designs: make, model and version.
I have to implement a search feature for our software, that lets a user search armors according to various criteria, among which their design.
Now, the users' idea of a design is a single string that contains make, model and version concatenated, so the entry is that single string. Let's say they want to look up the specifications for make FH, model TT, version 27, they'll think of (and type) "FHTT27".
We use an IQueryOver object, upon which we add successive conditions according to the criteria. For the design, our code is
z_quoQuery = z_quoQuery.And(armor => armor.make + armor.model + armor.version == z_strDesign);
Which raises an InvalidOperationException, "variable 'armor' of type 'IArmor' referenced from scope '', but it is not defined".
This is described as a bug here: https://github.com/mbdavid/LiteDB/issues/637
After a lot of trial and error, it seems that syntaxs that don't use the armor variable first raise that exception.
Obviously, I have to go another route at least for now, but after searching for some time I can't seem to find how. I thought of using something like
z_quoQuery = z_quoQuery.And(armor => armor.make == z_strDesign.SubString(0, 2).
And(armor => armor.model == z_strDesign.SubString(2, 2).
And(armor => armor.version == z_strDesign.SubString(4, 2);
Unfortunately, the fields are liable to have variable lengths. For instance, another set of values for make, model, and version might be, respectively, "NGI", "928", and "RX", that the code above would parse wrong. So I can't bypass the difficulty that way. Nor can I use a RegEx.
Neither can I make up a property in my Armor class that would concatenate all three properties, since it cannot be converted to SQL by NHibernate.
Has someone an idea of how to do it?
Maybe I should use an explicit SQL condition here, but how would it mix with other conditions?
It seems you can use Projections.Concat to solve your issue:
z_quoQuery = z_quoQuery.And(armor => Projections.Concat(armor.make, armor.model, armor.version) == z_strDesign);

Build XPath using wildcard for changing strings

I am trying to build an XPath for a property that is constantly changing. The number prefix is bound to change sometimes.
Original:
//*[#id="MainContent_DXEditor3_I"]
which I can query using
$x('//*[#id="MainContent_DXEditor3_I"]
Intended use: I would like to build the string to handle any number in the sub-string. Example: if the property changes to 'MainContent_DXEditor33_I' or 'MainContent_DXEditor8_IXYZ' - I still want to be able to find the element without having to rebuild
You can try to relax the predicate by using starts-with() :
//*[#starts-with(#id, "MainContent_DXEditor")]
You should try to identify a unique parent of the element or save xpath as a string that contains a variable.
These are the 2 possible solutions.
A general selector will return multiple elements, if you identify a unique parent then you are closer and after that you can select any first, second.. last if you have a list.

Displaying dynamic kanban colors according to record state in OpenERP 7

could someone tell me in what way I can display the items in a view kanban with a specific color according to the state that is the record.
I'm trying something like this
<div t-attf-class="#{record.state=='scheduled' ? oe_kanban_color_#{kanban_getcolor(1)} : oe_kanban_color_#{kanban_getcolor(0)}">
but I looked ALL elements and not only those who are in the "scheduled".
Thanks :)
If you have copy/pasted exactly what you typed in the view definition, then your t-attf- class attribute is malformed, and all record will have the following class:
class="#{record.state=='scheduled' ? oe_kanban_color_1 : oe_kanban_color_0"
which, due to CSS class precedence, will cause them all to have the oe_kanban_color_1 style.
A few hints:
To avoid coloring some records, you can omit the oe_kanban_color_X entirely in some cases
You can use a t-att-class attribute to allow arbitrary Javascript expressions, depending on what you want to do. In contrast, t-attf-class only allows replacing placeholders.
When comparing field values with Javascript operators you normally want to use the value or raw_value of the field, rather that the Field object itself. value will only differ from raw_value when the value needs specific rendering, such as dates, numbers, etc.
The kanban_getcolor() function accepts any integer or string and returns one of the 10 default kanban color indexes.
Based on the above, the following might be closer to what you tried to do (note the t-att-class attribute:
<div t-att-class="record.state.value == 'scheduled' ?
'oe_kanban_color_1' :
'oe_kanban_color_0' ">
Alternatively, you could use t-attf-class and let kanban_getcolor() pick a color based on the state string:
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.state.value)}">
That last example is similar to what is done in many default kanban views in the official OpenERP distribution.

xPath last select element

Can someone help me to bring this code working? I have several select fields and I only want the last one in my variable.
variable = browser.elements_by_xpath('//div[#class="nested-field"]//select[last()]
Thanks!
This is a FAQ: The [] operator in XPath has higher precedence (priority) than the // pseudo-operator. This is why brackets must be used to change the default operator priorities. There are at least several similar questions with good explanations -- search for them and read and understand.
Instead of:
//div[#class="nested-field"]//select[last()]
Use:
(//div[#class="nested-field"]//select)[last()]
is the class attribute an exact match?
if the mark up is like this
<div class="nested-field other">
...
then you'll have to either match by the exact class or use xpath contains.