What am I missing with the following thymeleaf markup:
<tr th:fragment="row" th:with="defaultAttrs='placeholder=\'' + ${placeholder} + '\''">
<td>
<input th:attr="${attrs ?: defaultAttrs}" />
</td>
...
</tr>
called from
<th:block th:include="row::row(attrs='value=\'*{prodName}\', minLength=\'.{2, 16}\', required, title=\'starts with an alphabet 2 and 8\' placeholder=\'Product name\'')" />
which is producing this error:
Could not parse as assignation sequence: "${attrs ?: defaultAttrs}"
On an unrelated note, had to do a double take at the exception message for the interesting usage of the word assignation instead of assignment
You are trying to pass text string to th:attr. Thymeleaf expects expression, but not string. Next example will NOT work, but this what you're trying to do:
<input th:attr="${'placeholder=\'defaultPlaceholder\''}" />
I suggest you next way:
<tr th:fragment="row" th:with="defaultPlaceholder='placeholder', defaultMaxlength=10">
<td>
<input th:attr="placeholder=${placeholder?:defaultPlaceholder},
maxlength=${maxlength?:defaultMaxlength}" />
</td>
...
</tr>
It looks longer, but gives you more control for manage attributes.
Updated: If you prefer pass all attributes in one string variable, you can use Thymeleaf's preprocessing. For example, next code, is how you going to use fragment in your page:
<div th:include="fragment :: row(attrs='value=\'*{prodName}\', minLength=\'.{2, 16}\',
required=true, title=\'starts with an alphabet 2 and 8\', placeholder=\'Product name\'')">
Then you fragment will something like this:
<div th:fragment="row">
<div th:with="defaults='placeholder=\'placeholder\', maxlength=10'" th:remove="tag">
<tr>
<td>
<input th:if="${attrs!=null}" th:attr="__${attrs}__"/>
<input th:if="${attrs==null}" th:attr="__${defaults}__"/>
</td>
...
</tr>
</div>
</div>
Explanations:
main tag of fragment will NOT be included in result page. So, don't use <tr> as main tag. Instead, wrap <tr> into <div>.
parameters passed to fragment will override all variables declared in th:with of main tag of fragment. So, if you would like to pass any parameters to fragment, don't declare th:with right in main tag of fragment. Do it the body of fragment.
if you don't need to output some tags in result page, just use th:remove attribute. This attribute allows you to remove parts of fragment. In this example we used second <div> just to declare th:with and we don't need this <div> in result page.
You have error in attr paramter of th:include. Because attribute is pair of name and value, you can't specify just required. You have to write: required=true. Another one error: you missed comma between title and placeholder. Correct string should be next:
<th:block th:include="row::row(attrs='value=\'*{prodName}\', minLength=\'.{2, 16}\',
required=true, title=\'starts with an alphabet 2 and 8\', placeholder=\'Product name\'')" />
Related
I was working with Spring and Thymeleaf when I've encountered the following problem: I need a Form object, which has a list of items (Item) as attribute; I'm using an html form to print the Name of the Item, and to generate a checkbox for each Item (any checkbox's value is the corresponding item's id).
The form works correctly, sending to the Controller a list of item's ids corresponding to the checked checkboxes.
However, now, I'm trying to check some checkbox upon the occurrence of a condition (if itemIds, which is a list, contains the current item's id). For that I'm using:
th:checked="${#lists.contains(itemIds, item.id)}"/>
But it doesn't work (checkbox are all unchecked).
I tried also with a "dummy test":
th:checked="${1 == 1 ? 'checked' : ''}"/>
But, again, all the checkbox remain unchecked; the "checked" attribute is ignored as you can see in this example of the rendered HTML:
<input type="checkbox" value="12" class="chkCheckBox" id="ids1" name="ids">
What am I doing wrong? What am I missing here?
form.html
<form th:action="#{${uriBase}+'/new/' + ${date}}"
method="POST" th:object="${form}">
<div class="table-responsive">
<table class="table">
<thead class=" text-primary">
<tr>
<th>Name</th>
<th><input type="checkbox" th:id="checkAll"/>Check</th>
</tr>
</thead>
<tbody>
<tr th:each="item : ${items}">
<td th:text="${item.name}"></td>
<td>
<input type="checkbox" th:field="*{ids}"
th:value="${item.id}" th:class="chkCheckBox"
th:checked="${#lists.contains(itemIds, item.id)}"/>
</td>
</tr>
</tbody>
</table>
<button type="submit" class="btn btn-primary pull-right">Submit</button>
<div class="clearfix"></div>
</div>
</form>
Form class
public class Form implements Serializable {
private List<Long> ids;
//getter and setter
}
Thank you in advance.
I have been struggling with this as well. If you use the th:field it will override the checked and value options, as Xaltotun mentions, because it is trying to get the value and checked option from the field/form.
If you change it to th:name it should work how you want...
But this forum seems to be helpful for doing it with th:feild.
As far as I understand there are 2 issues in your post:
The dummy example is incorrect.
th:checked="${1 == 1 ? 'checked' : ''}"
In fact the value must true or false not 'checked'. If you try with
th:checked="${1 == 1}"/>
It will work.
If you set th:field="*{ids}" then the checkbox should be trying to get the value from the field item.ids and will not use the "th:checked" or "th:value" properties. Does the item has the field ids?
I am trying to get conditional display to work properly. What I am attempting to do is:
Within a block that has been merged, if a value is empty I want to display an input box along with a few other hidden variables I need to carry along with it, but if the value is not empty I wish to simply display that value.
PHP
$cks . . some query;
$TBS->LoadTemplate("check.html") ;
$TBS->MergeBlock("cks",$cks);
$TBS->Show(TBS_NOTHING); echo($TBS->Source);
Template portion
<td width="25%" class="mod_row2">[cks.check1]</td>
<td width="25%" class="mod_row2">
[cks.value;ifempty=
<input type="text" name="value[]" value="" size="26">
<input type=hidden name="check_id[]" value="[cks.check_id]">
<input type=hidden name="equip_id[]" value="[cks.equip_id]">
]</td> "
Everything works except the values of the hidden cells are not merged. I don't know if this is the right way to do this or if this is possible . . .
TBS 3.8.0, php 5.3.3
Thanks
Peter
Your HTML part with <input> is not parsed because it is embedded in a TBS parameter (ifempty).
It is not a good practice to embed HTML/XML in the TBS fields.
The best way is to use conditional display with block. The magnet feature is nice for that.
Example for you :
<td width="25%" class="mod_row2">[cks.check1]</td>
<td width="25%" class="mod_row2">
<div>
[cks.value;ope=mok:;magnet=div]
<input type="text" name="value[]" value="" size="26">
<input type=hidden name="check_id[]" value="[cks.check_id]">
<input type=hidden name="equip_id[]" value="[cks.equip_id]">
</div>
</td>
In this example, the parameter ope=mok: means that the block is displayed if the value is empty string (''), and is deleted in other cases.
I have this HTML structure:
https://imgur.com/a/8TevWtz
<tbody>
<tr data-drupal-selector="edit-strings-996" class="odd">
<td><div id="edit-strings-996-original" class="js-form-item form-item js-form-type-item form-type-item js-form-item-strings-996-original form-item-strings-996-original form-no-label">
<label for="edit-strings-996-original" class="visually-hidden">Source string (Built-in English)</label>
Search
</div>
</span></td>
<td><div class="js-form-item form-item js-form-type-textarea form-type-textarea js-form-item-strings-996-translations-0 form-item-strings-996-translations-0 form-no-label">
<label for="edit-strings-996-translations-0" class="visually-hidden">Translated string (Español)</label>
<div class="form-textarea-wrapper">
<textarea lang="es" data-drupal-selector="edit-strings-996-translations-0" id="edit-strings-996-translations-0" name="strings[996][translations][0]" rows="1" cols="60" class="form-textarea resize-vertical">Search</textarea>
</div>
</div>
</td>
</tr>
<tr data-drupal-selector="edit-strings-1176" class="even">
<td><div id="edit-strings-1176-original" class="js-form-item form-item js-form-type-item form-type-item js-form-item-strings-1176-original form-item-strings-1176-original form-no-label">
<label for="edit-strings-1176-original" class="visually-hidden">Source string (Built-in English)</label>
Search page
</div>
I need a Xpath that I can find only the exact text "Search". I cannot use contains() because it will return all rows with this word, I need only the row with "Search" word only.
My knowledge of Xpath is not great, so I tried many things like:
//tbody/tr/td/div[.='Search']
//tbody/tr/td/div[normalize-space(.)='Search']
//tbody/tr[1]/td/div/. -> This one works but I cannot pass the tr[1] because I'll use this xpath in an automation and the text I want is not always in the first row, so I need to find by Text and not by Index.
The problem is that all texts have these whitespaces and it makes it worse for me to make it work.
Text content of target div node is not just "Search", but "Source string ... Search", so you can try
//div[normalize-space(text()[2])='Search']
Assuming you're looking for the div which has text containing the string Search, this should work:
//tbody/tr/td/div[contains(., 'Search')]
It's a bit dirty in that it would also detect Search anywhere under the div, e.g. including in the label's text, if applicable.
My HTML Code looks like this:
<html>
<body>
<div>
</div>
<div>
<table>
<tbody id=a>
<tr>
<td>
<div>
<span>
some Text
</span>
</div>
</td>
</tr>
<tr>
<td>
<div>
<span>
some Text2
</span>
</div>
</td>
</tr>
<tr>
<td>
<div>
<span>
some Text3
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
I'm trying to select each of the span elements by their text. I'm able to select the tbody by id. I Tried this:
tbody.FindElement(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
(var = somex0020Text)
but this always returns the first <span> element in my table.
I also tried:
tbody.FindElements(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
which returned a list containing every single <span> element in my table, and I don't know why.
I also don't understand why
tbody.FindElement(By.XPath(String.Format(".//span[text() = {0})]", &var)));
throws an Element not found Exception, when the contain method returns a <span> element with just the same text.
I tried by using xpath as:
.//span[contains(text(),'some Text')]
it is selecting all the 3 span.
so to this i have refer to parent element.
for 1st span: .//tbody[#id='a']//tr[1]//span[contains(text(),'some Text')]
for 2nd: .//tbody[#id='a']//tr[2]//span[contains(text(),'some Text')]
for 3rd: .//tbody[#id='a']//tr[3]//span[contains(text(),'some Text')]
through this I can select every span element individually.
You could use the jQuery to get all the span elements within "Table".
Example:
var items = $('table div span');
items.each(function (x) {
alert(items[x].innerHTML);
});
tbody.FindElement(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
(var = somex0020Text)
but this always returns the first Element in my table.
This is an expected behavior in Selenium. As i can see, there are 3 elements with the same xpath as mentioned in your code, in this case Selenium returns the first element.
tbody.FindElements(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
which returned a list containing every single Element in my table, and i dont know why.
This is also an expected behavior in Selenium. FindElements will return all the elements with the same xpath.
So change the value of var to some Text2 or some Text3 to locate the other two elements.
The following xpath will work for some Text2 :
.//span[contains(text(), 'some Text2'))]
Try with this Xpath $x("//tr//span[contains(.,'some Text')]")
For what I can see, you are having a trouble with the contains. All 3 spans are containing this 'some Text' portion.
If you want to check the entire string, you could use .//span[text()='some Text'].
Hope this helps, and have fun with web parsing!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP: “Notice: Undefined variable” and “Notice: Undefined index”
I am just learning PHP and I keep getting an Undefined Index error. The book I'm learning from has an HTML form and a PHP page that processes the form, using the following format:
<!-- The form fields are all set up something like this -->
<input type="text" id="howlong" name="howlong" /><br />
// The PHP starts with one line like this for each of the form fields in the HTML
$how_long = $_POST ['howlong'];
// And there is one line for each one like this to output the form data:
echo ' and were gone for ' . $how_long . '<br />';
The example I'm working with has about 12 form fields.
What's odd is that not all of the variables throw this error, but I can't see a pattern to it.
I've checked that all HTML fieldnames match up with the PHP $_POST variable name I entered, and I've made certain that when I fill out the form and submit it that all fields are filled in with something. Interestingly, the completed code that can be downloaded for the book also throws this error.
I realize this code may not reflect best practices, it's from the first chapter of the book and obviously I am a noob :)
In case it makes a difference, I am using PHP 5.3.5 on XAMPP 1.7.4 with Windows 7 Home Premium.
Remember to set the method to POST on the form tag...
heres the code i used to try yours, and it worked to me:
in a file named test.php:
<html>
<body>
<form method="POST" action="testProc.php">
<input type="text" id="howlong" name="howlong" /><br/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
and in testProc.php:
<?php
if (isset($_POST)) {
if (isset($_POST["howlong"])){
$howlong = $_POST['howlong'];
echo ' and were gone for ' . $howlong . '<br />';
}
}
?>
Just as an advise, to make display manipulation with stylesheets i recommend to put forms within a table, like this:
<html>
<body>
<form method="POST" action="testProc.php">
<table>
<tbody>
<tr>
<th>
<label for="howlong">How long? :</label>
</th>
<td>
<input type="text" id="howlong" name="howlong" />
</td>
</tr>
<tr>
<input type="submit" value="submit"/>
</tr>
</tbody>
</table>
</form>
</body>
</html>
Hope you can use this...
you need to check that form is submitted and then you can try to use $_POST array, so you should put this code above:
if(isset($_POST['send'])) {
where "send" is name of submit button
You can test to see if a variable is set using the isset() function.
Also, not all HTML form elements will post a value in all cases. The common example is the checkbox; an unchecked checkbox doesn't form part of the the data posted back to the server. Therefore the $_POST element you're expecting to be set won't be.