Is it possible to check if a message property exists?
Example: I would like to remove a collapsable div-Element in a loop containing only a message property.
<div th:each="payment : ${paymentList}">
<input type="radio" data-toggle="radio-collapse" data-target="#collapse1" [...] /> [...]
<div id="collapse1" th:utext="#{|payment.${payment.id}.additionalInfo|}" [...]>
Hello, world!
</div>
</div>
If there is no additional info for the payment the element is not necessary.
Lets say we have the IDs DIRECT_DEBIT, PAYPAL and SAFERPAY and the following message properties:
payment.DIRECT_DEBIT=Direct debit
payment.DIRECT_DEBIT.additionalInfo=Direct debit info text...
payment.PAYPAL=PayPal
payment.PAYPAL.additionalInfo=PayPal info text...
payment.SAFERPAY=Saferpay
As you can see there is no additionInfo message property for SAFERPAY.
You should use the #messages object to check if a message exists. For example:
th:if="${#messages.msgOrNull('payment.' + payment.id + '.additionalInfo') != null}"
<div id="collapse1" th:if="${#messages.msgOrNull('payment.' + payment.id + '.additionalInfo') != null}" th:utext="#{|payment.${payment.id}.additionalInfo|}" [...]>
Hello, world!
</div>
You can use th:if to add the element only if it isn't null and isn't equal to a empty string (I don't know how you implemented the object).
<div id="collapse1"
th:if="${payment.${payment.id}.additionalInfo != null && payment.${payment.id}.additionalInfo != ''}"
th:utext="#{|payment.${payment.id}.additionalInfo|}" [...]
>
Hello, world!
</div>
... and you should also change the id property. In your impelementation there could be more than one element with id "collapse1".
If you also don't want to show the input field use a th:block element and place the th:if attribute there:
<div th:each="payment : ${paymentList}">
<th:block
th:if="${ ... && ... }"
>
<input ...>
<div ...>
</div>
</th:block>
</div>
Related
<div class="ty-company-fields">
<div class="apply_for_vendor_account">
<h1 class="tygh-top-panel ty-dropdown-box__title ty-mainbox-simple-title ty-mainbox-simple-container clearfix ty-homepage-vendors">Calculator</h1>
<form action="" method="post" name="calculator" id="calculator">
<div class="ty-control-group">
<label for="contact_form" class="ty-control-group__title cm-required ty-input-text cm-focus" >Please Enter First Number</label>
<input type="text" name="cal[value1]" id="contact_form" size="32" value="{$cal.value1}" class="ty-input-text cm-focus ty-control-group_title cm-required" />
</div>
<div class="ty-control-group">
<label for="contact_form_number" class="ty-control-group__title cm-required">Please Enter Second Number</label>
<input type="text" name="cal[value2]" id="contact_form_number" class="ty-input-text cm-focus ty-control-group_title cm-required" size="32" value="{$cal.value2}" />
</div>
{if $result }
<p>The Result is: {$result}</p>
{/if}
<div class="buttons-container">
{include file="buttons/button.tpl" but_text=__("submit") but_name="dispatch[calculator2.add]" but_id="contact" but_meta="ty-btn__primary" value = "+" data-ca-target-form="calculator" data-ca-dispatch="dispatch[calculator.calculator]"}
{include file="buttons/button.tpl" but_text=__("submit") but_name="dispatch[calculator.add]" but_id="contact" but_meta="ty-btn__primary" value = "+"}
{include file="buttons/button.tpl" but_text=__("submit") but_name="dispatch[calculator.add]" but_id="contact" but_meta="ty-btn__primary" value = "+"}
{include file="buttons/button.tpl" but_text=__("submit") but_name="dispatch[calculator.add]" but_id="contact" but_meta="ty-btn__primary" value = "+"}
</div>
</form>
</div>
</div>
you can use the normal form and normal submit button, Normal way is also works fine in cs cart.
In this case, when you press the button the whole values are post to controller calculator.add and take the actions.
Inside form tag in action attribute, you need this:
<form action="{""|fn_url}" method="post" name="calculator" id="calculator">
...
</form>
In the first parameter you could also insert a specific dispatch value, for example calculator.manage if you want to navigate to specific page of yours or leave it empty.
Moreover, inside your tpl file add this at the bottom (and inside capture smarty tag):
{capture name="buttons"}
{include file="buttons/save.tpl" but_name="dispatch[calculator.manage]" but_role="submit-link" but_target_form="calculator"}
{/capture}
this capture smarty tag, will add the general Save button of cs-cart, at the right top corner.
Now, you probably have a controller file named calculator.php which also contain code like that:
if($mode == "manage") {
//your code here
}
I am new to nokogiri and so far most familiar with CSS selectors, I am trying to parse information from a table, below is a sample of the table and the code I'm using, I'm stuck on the appropriate if statement, as it seems to return the whole contents of the table.
Table:
<div class="holder">
<div class ="row">
<div class="c1">
<!-- Content I Don't need -->
</div>
<div class="c2">
<span class="data">
<!-- Content I Don't Need -->
<span class="data">
</div>
</div>
...
<div class="row">
<div class="c1">
SPECIFIC TEXT
</div>
<div class="c2">
<span class="data">
What I want
</span>
</div>
</div>
</div>
My Script: (if SPECIFIC TEXT is found in the table it returns every "div.c2 span.data" variable - so I've either screwed up my knowledge of do loops or if statements)
data = []
page.agent.get(url)
page.search('div.row').each do |row_data|
if (row_data.search('div.c1:contains("/SPECIFIC TEXT/")').text.strip
temp = row_data.search('div.c2 span.data').text.strip
data << temp
end
end
There's no need to stop and insert ruby logic when you can extract what you need in a single CSS selector.
data = page.search('div.row > div.c1:contains("SPECIFIC TEXT") + div.c2 span.data')
This will include only those that match the selector (e.g. follow the SPECIFIC TEXT).
Here's where your logic may have gone wrong:
This code
if (row_data.search('div.c1:contains("SPECIFIC TEXT")'...
temp = row_data.search('div.c2 span.data')...
first searches the row for the specific text, then if it matches, returns ALL rows matching the second query, which has the same starting point. The key is the + in the CSS selector above which will return elements immediately following (e.g. the next sibling element). I'm making an assumption, of course, that the next element is always what you want.
I'd do
require 'nokogiri'
html = <<_
<div class="holder">
<div class ="row">
<div class="c1">
<!-- Content I Don't need -->
</div>
<div class="c2">
<span class="data">
<!-- Content I Don't Need -->
<span class="data">
</div>
</div>
<div class="row">
<div class="c1">
SPECIFIC TEXT
</div>
<div class="c2">
<span class="data">
What I want
</span>
</div>
</div>
</div>
_
doc = Nokogiri::HTML(html)
css_string = 'div.row > div.c1[text()*="SPECIFIC TEXT"] + div.c2 span.data'
doc.at(css_string).text.strip
# => "What I want"
How those selectors would work here -
[name*="value"] - Selects elements that have the specified attribute with a value containing the a given substring.
Child Selector (“parent > child”) - Selects all direct child elements specified by "child" of elements specified by "parent".
Next Adjacent Selector (“prev + next”) - Selects all next elements matching "next" that are immediately preceded by a sibling "prev".
Class Selector (“.class”) - Selects all elements with the given class.
Descendant Selector (“ancestor descendant”) - Selects all elements that are descendants of a given ancestor.
I am using validatious-custom-0.9.1.js framework in my project and I am trying to validate required fields for radio buttons. But it is not validating the radio buttons in IE8. I am getting the following error in console
Message: 'tagName' is null or not an object
Line: 7
Char: 9921
Code: 0
URI: http://validatious.org/design/js/validatious.0.9.1.min.js?1256063644
HTML code used.
<div>
<label for="_button_880">Radio List
<div>
<p>some text</p>
</div>
</label>
<div>
<ul>
<li>
<div>
<div>
<input type="radio" name="radio1" id="radio1" value="Radio1" class="required" title="Required."/>
<label for="radio1">Radio1</label>
</div>
</div>
</div>
</div>
JS where it is failing - First 2 are the examples that are given in the framework file. So you will get to know how it is implemented
/* A radio button field is assumed to be either a list - ordered or unordered -
with some element in front that acts as a label. This may be any element.
If it is not in a list (ie the element does not have "li" parent elements),
the label is assumed to be the element before the first input element.
Example1 (list approach):
<h2>Favourite food:</h2>
<ul>
<li>
<input type="radio" name="food" value="hamburger" id="food_hamburger" />
<label for="food_hamburger">Haburger</label>
</li>
<li>
<input type="radio" name="food" value="pizza" id="food_pizza" />
<label for="food_pizza">Pizza</label>
</li>
</ul>
getLabel() will in this case return the h2 element.
Example2 (no list).
<label class="groupLabel">Favourite food:</label>
<input type="radio" name="food" value="hamburger" id="food_hamburger" />
<label for="food_hamburger">Hamburger</label>
<input type="radio" name="food" value="pizza" id="food_pizza" />
<label for="food_pizza">Pizza</label>
getLabel() will in this case return the first label element
*/
Actual code
getLabel: function() {
var parent = this.__elements[0].parentNode;
//alert(parent1.nodeName); --- Gives 'nodeName' is null or not an object IN Ie8
if (parent1.tagName.toLowerCase() === 'li') { ---Gives 'tagName' is null or not an object
return v2.$(parent1.parentNode).previous();
}
var element = v2.$(this.__elements[0]).previous();
return element || this.base();
}
Required field validation in the js file
v.reg('required', function(field, value, params) {
return !v2.empty(value) && !(typeof value.length !== 'undefined' && value.length == 0);
}, null, null, 'not-empty', false);
It works fine in firefox, IE7 and IE9. But in Ie8, I get message tagName is null or not an object.
Can somebody please help me in this. If this is solved, then this framework will be very useful to avoid all the hardships in validating.
Thanks in advance..
In ruby when I try mytext.include?(">Model number<") is returning false.
But mytext.include?("Model number") is returning true
What is wrong in the first condition?
mytext contains the string "Model number" inside ">" and "<"
This is relevant HTML:
<div class="bucket"> <div class="h1"><strong>Product Specifications</strong></div> <div class="content"> <div class="tsSectionHeader">Product Information</div> <div class="tsTable"> <div class="tsRow"><span class="tsLabel">Model number</span><span>516C</span></div> <div class="tsRow"><span class="tsLabel">Maximum weight recommendation</span><span>35 Pounds</span></div> <div class="tsRow"><span class="tsLabel">Material Type</span><span>Wood</span></div> </div> </div> </div>
You have to learn some HTML. > and < are part of span tag: <span></span>.
This is where the text appears:
<span class="tsLabel">Model number</span>
So a span has text Model number. You can get the text using Watir with this:
browser.span(:class => "tsLabel").text
For debug purposes, I'm trying to display the current content inside a foreach loop like this, but I'm getting an "Unable to parse bindings" error. You can see my atteping inside the 'pre' tag at the bottom of the item. Any suggestions for how to properly display this?
<!-- ko foreach: criteria -->
<div>
<span data-bind="text: myVal"></span>
<label><input type="radio" value="AND" data-bind="checked: logicGate">AND</label>
<label><input type="radio" value="OR" data-bind="checked: logicGate">OR</label>
Remove
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
</div>
<!-- /ko -->
The problem was that I was passing elements into the object's constructor and they can't be serialized by the ko.toJSON method.