WebObjects: Using WOConditional inside <div> - java

I am in a situation where the "class" attribute of a div tag should be dependent on the value of a java binding. This can be easily done by moving the associated logic to the java class, but at this moment we are not allowed to change anything at the Java component.
I am trying out the following to resolve the problem (using WOOGNL):
<div class="<wo:WOConditional condition = \"[cssClassDecider]\">classToUse</wo:WOConditiona>" >
HTML Static Content
</div>
As it can be seen, i am trying to use value of "cssClassDecider" to set the class.
Can anybody tell if any has solved a similar problem or one is available at WO.

It's not clear to me whether cssClassDecider is providing the string content for the class attribute, or a boolean to drive a conditional. In any case, the usual pattern would be:
<wo:WOGenericContainer elementName="div" class="$methodReturningClassNames">
...
</wo:WOGenericContainer>
If cssClassDecider returns a conditional, you could do something like this:
<wo:WOConditional condition="$cssClassDecider">
<div class="classWhenTrue">
...
</div>
</wo:WOConditional>
<wo:WOConditional condition="$cssClassDecider" negate="$true">
<div class="classWhenFalse">
...
</div>
</wo:WOConditional>
If neither of those solve your problem, provide some more information.

Related

I was able to run my program till morning. But suddenly getting this error " Driver info: driver.version: unknown [duplicate]

I am getting the following error:
"Compound class names not permitted"
While trying to access web element where-in the element's class name have spaces in between. The page source for the web element is as below.
driver.findElement(By.className("alert alert-success"));
<div class="alert alert-success" alert-dismissable"="" id="58417" style="display: none;">
<button type="button" class="close hide-panel close-icon-58417" data-dismiss="alert" aria-hidden="true" style="display: inline-block;">×</button><span id="caret-58417" class="notification-caret caret-58417"></span>
<div class="hide-panel close-icon-58417" id="58417" style="display: block;">
<span class="glyphicon glyphicon-ok-sign"></span><strong>Success</strong> KeyLinks Updated Successfully
<div class="notification-panel-body panel-body-58417">REST Invocation Success</div>
</div>
</div>
I tried to find the element by CSS path as below. But the element is not searchable with this.
driver.findElement(By.cssSelector(".alert alert-success"));
This was the workaround given in the Link but still no success. your help will be much appreciated.
You can access the element if it has multiple classes using "By":
from selenium.webdriver.common.by import By
driver.findElement(By.cssSelector(".alert.alert-success"));
You can use
driver.findElement(By.className("alert-success"));
or
driver.findElement(By.className("alert"));
As right now selenium doesn't support multiple class name.If your class name includes a space, WebDriver will see it as a "compound selector".
You can use cssSelector or id for selecting the webelement.
If usage of class name is must you can use the following ways:
1) css selectors:
driver.findElement(By.cssSelector(".alert.alert-success");
2) using xpath
driver.findElement(By.xpath("//div[#class='alert alert-success']"))
Try avoiding xpath and use css selectors instead.
The issue is because of the way find by Class name works.
in your code class name is class="alert alert-success"
If the class name has space you'll get the above error. You can simply get rid of the issue by using Id, CSS, Xpath, regular expression or any other element finder method.
Do you need to use Class Name or can you use another method? Let me know if you need to use class name.
It can also be done using class name like:
driver.find_element_by_class_name("alert")
or
driver.find_element_by_class_name("alert-success")
you can select anyone class name from two or more class names separated by spaces it'll work just fine.
Most of the time class name attribute of any element has groups of classes names.
like class = 'alert alert-success another class name'
if you are using css selector ,then just remove spaces between the class names and create you clas name like below :
driver.findElement(By.cssSelector(".alert.alert-success.another.class.name")
. => represent class
=> represent ID
for CSS selector.

Thymeleaf - output variable without a tag

I use Thymeleaf as a templating engine and I usually output variable value like this:
in Java I set:
ctx.setVariable("tester", "hello");
and in html template I output:
<span th:text="${tester}"></span>
This works great, but I would like to output a variable without the need of a tag. Something following would be great:
${tester}
Unfortunately it does not work. My goal is to avoid unnecessary tag to output the variable value. Is this possible to do with Thymeleaf?
My goal is to avoid unnecessary tag to output the variable value. Is this possible to do with Thymeleaf?
Yes this is possible. You can use the Thymeleaf synthetic th:block tag (see here).
Example template excerpt:
<body>
<th:block th:text="${tester}"></th:block>
</body>
This renders the following HTML:
<body>
hello
</body>
Only the variable is displayed.
Use Thymeleaf expression inlining (docs) using either [[...]] or [(...)]. With expression inlining, you do not need to use synthetic tags.
Example:
<body>
The value of tester is [[${tester}]].
</body>
Thymeleaf triggers on the "th:" tag and as far as I know thats the only way.
The behaviour you describe works with JSF.
Best regards
Ben
I also managed to figure out some workaround:
<span th:text="${tester}" th:remove="tag"></span>
th:remove removes span tag, but preserves content.

Thymeleaf unable to evaluate internationalized expression

I am trying to achieve internationalization and I have the following html markup.
<p th:text= "${your_amount(${it.vm.getAmount})}"></p>
which generates html as
<p>Your Amount is: $</p>
Your Amount is: $ is exactly what my internationalized string is.
Ideally the result should be.
<p>Your Amount is: $123.24</p>
The it.vm.getAmount sort of doesn't get executed. I have checked that there is a value present inside getAmount with the following
<p th:text="${it.vm.getAmount}"></p>
Which gives me a result as
<p>123.24</p>
Does thymeleaf consider "$" to be a special character while rendering and is there a way to work around that?
This expression:
<p th:text= "${your_amount(${it.vm.getAmount})}"></p>
is not valid syntax -- for many reasons.
${} expressions are never nested inside other ${} expressions -- unless you are preprocessing.
If your_amount is a string, you cannot use it as a function your_amount(...).
it.vm.getAmount shouldn't work -- unless you really have named your getter method getGetAmount(). It should either be it.vm.amount or it.vm.getAmount().
When I try your expression, I get this error:
Method your_amount(java.lang.String) cannot be found on org.thymeleaf.spring4.expression.SPELContextMapWrapper
If you just want to append different strings together, you should really be doing something like:
<p th:text= "${your_amount + it.vm.getAmount}"></p>
or
<p>
<span th:text="${your_amount}"><span th:text="${it.vm.getAmount}">
</p>
or
<span th:text="|${your_amount}${it.vm.getAmount}|" />

Nested Thymeleaf Templates in Spring

Short version
How is one supposed to make nested templates in Thymeleaf when using Spring? It appears asterisk notation is not supported ("*{mailingAddress}") inside th:object attributes in Spring. Is there a work-around / different tag to use?
Long version
For example, let's say I have these classes:
class Address { String street; }
class Person { Address mailingAddress; Address shippingAddress; }
class Order { int orderNo; Person customer; }
So I make an address.html Thymeleaf template:
<span th:text="*{street}"></span>
We test it with a sample Address. Looks good.
and I make a person.html Thymeleaf template that references the address like so:
<span th:text="*{firstName}"></span>
<span th:object="${person.shippingAddress}">
<span th:include="fragments/address :: address"></span>
</span>
And we test it with an example person. I could even reference the same template and set the context to be the ${person.mailingAddress}. So far so good.
Now let's make our Order template. Only, hey, wait. Earlier, in our person.html file we said ${person.shippingAddress} but now we need it to say ${order.customer.shippingAddress}. If I were not using Spring I'd put the following into person.html:
<span th:text="*{firstName}"></span>
<span th:object="*{shippingAddress}">
<span th:include="fragments/address :: address"></span>
</span>
That way, no matter what my path to getting here all I have to care about is that my current context has a shippingAddress. I could then use person.html directly as well as within my order.html template.
Unfortunately I am in Spring, so I get the following exception:
org.thymeleaf.exceptions.TemplateProcessingException:
The expression used for object selection is *{shippingAddress},
which is not valid: only variable expressions (${...}) are
allowed in 'th:object' attributes in Spring-enabled environments.
(include:510)
at org.thymeleaf.spring4.processor.attr.SpringObjectAttrProcessor.validateSelectionValue(SpringObjectAttrProcessor.java:73)
at org.thymeleaf.standard.processor.attr.AbstractStandardSelectionAttrProcessor.getNewSelectionTarget(AbstractStandardSelectionAttrProcessor.java:69)
at org.thymeleaf.processor.attr.AbstractSelectionTargetAttrProcessor.processAttribute(AbstractSelectionTargetAttrProcessor.java:61)
To move forward I must duplicate all my nested templates. In this example, I would have one person.html with th:object="${person.mailingAddress}" calling to address.html, and a duplicate of person.html called orderCustomer.html where we change the line to th:object="${order.customer.mailingAddress}", but is otherwise identical.
Is there a work-around out there that would let me re-use templates?
You can report a bug to the thymeleaf developers in github, or fork the project to add this functionality and convince the Daniel Fernández to accept it.
https://github.com/thymeleaf/thymeleaf/issues
Or else, he is available in StackOverflow. You can simply send him a message about the posibility of integrating this functionality
https://stackoverflow.com/users/550664/daniel-fern%C3%A1ndez
apart from that there is nothing much we can do rather to stick with the approach of putting th:object="${person.mailingAddress}" and th:object="${order.customer.mailingAddress}" outside each import.

Angularjs UI Bootstrap Popover Prevents input submit

I have used Angularjs with ui.bootstrap popover feature in following manner,
<form name="frm1" role="form" ng-submit='myFunc()' novalidate="novalidate">
.... other inputs go here...
<input type="number" ng-pattern="/^[0-9]+$/" name="testNo" ng-model='testNo' required popover="Locate number here" popover-trigger="focus">
<input type="submit" ng-model='funcBtn' value="Submit" ng-click="submitted = true" ng-disabled="value.length=0">
</form>
The issue is because of popover="Locate number here" popover-trigger="focus" code when I check after submitting the form the value for the input testNo is not passed to controller.
The Controller is as follows,
app.controller('myCtrl', ['$scope','$location','$log', function($scope,$location,$log)
{
$log.log('testNo', $scope.testNo);
}]);
And If I remove the popover code from this input it works fine. I like to know whether there's a specific way in using popover into inputs.
Used resource ui.bootstrap example, input trigger: http://angular-ui.github.io/bootstrap/
The problem is that the current version of AngularJS can only have one scope for a given DOM element, and the popover creates a child scope that then gets inherited by the other directives. Fortunately, the solution is simple. Just refer to $parent.my_var in the directive, in your case ng-model="$parent.$model".
Here is the popover FAQ on this problem.
I ran into this problem in the bowels of my own custom directive, but fortunately the solution is simple there as well: rather than refer to $scope.var, refer to $scope.parent.var. Simple solution, but hours of debugging!

Categories