I have this macro in velocity trying to convert it to a freeMarker template:
#macro(headerRow $yard $yardName)
<tr><td class="header" colspan="6">Call List - $yard - $yardName</td></tr>
#end
In freeMaker, I had:
<#macro(headerRow ${yard} ${yardName})>
<tr><td class="header" colspan="6">Call List - ${yard} - ${yardName}</td></tr>
</#macro>
At the first line it will not like it, not sure where the close tag has to be.
Freemarker macro first line shouldn't have special characters (as $).
In your case:
<#macro headerRow yard yardName>
<tr><td class="header" colspan="6">Call List - ${yard} - ${yardName}</td></tr>
for example <#macro "foo~bar">.... Note that this string literal does not expand interpolations (as "${foo}").
Related
Is there any way directly get the parent element to find its attributes?
In my situation, I have a
DOMElement img,I have to use functions
img.getparent().getparent().findElement(By.tagName("a")).getAttribute("href"));
and the result is not accuarate since a parent node can find many same type of elements
<td>
<img></img>
<a></a>
<a></a>
<a></a>
<a></a>
</td>
Cast DOMNode to DOMElement and use it's .getAttribute(String attr):
String href = ((DOMElement)(img.getparent())).getAttribute("href");
<tr>
<td width="70"><strong>Director:</strong></td>
<td><a href="/?&director=Zhangke Jia">Zhangke Jia</td>
</tr>
I try to do this parser but not working
foreach($html->find('strong.Director:') as $titlu) {
echo $titlu->find('a', 0)->plaintext;
}
In need some help please
It is not working because 'Director' is not a class name, It's just a text inside 'td > strong' tag.
These are the ways you can find html dom elements:
Finding HTML elements by id
Finding HTML elements by tag name
Finding HTML elements by class name
Finding HTML elements by HTML object collections
try this:
foreach($html->find('td a') as $titlu) {
echo $titlu->plaintext;
}
I'am trying to have auto complete and onBlur functionality attached to the same input field using Liftweb framework.
I have them working independently.
What I'am trying to do is have an auto complete input field and on selecting the value from the suggestion, some business logic is to be performed and another input field needs to be updated.
But only the auto complete feature is working.
This is the form
<form class="lift:CapitalOnBlur">
Country : <input id="countryNameOnBlur" type="text" name="countryNameOnBlur"/><br />
Capital: <input id="capitalNameOnBlur" type="text" name="capital"/>
</form>
This is the snippet
object CapitalOnBlur {
val capitals: Map[String, String] = Map(
"india" -> "New Delhi",
"uganda" -> "Kampala",
"japan" -> "Tokyo")
def render = {
def callback(countryName: String): JsCmd = {
val capital = capitals.getOrElse(countryName.toLowerCase, "Not Found")
SetValById("capitalNameOnBlur", capital)
}
val default = ""
def suggest(value: String, limit: Int) = capitals.filter(_._1.startsWith(value.toLowerCase)).keys.toSeq
def submit(value: String) = Unit
"#countryNameOnBlur" #> AutoComplete(default, suggest, submit) &
"#countryNameOnBlur [onBlur]" #> SHtml.onEvent(callback)
}
}
This is what I actually want to do. I tried this and only onBlur event is triggered.
According to my needs, When I start typing the country name in the first input field, it should show me the suggestions and on selecting the suggestion i.e.; onBlur from that input field, the corresponding capital should be rendered in the next input field.
And also is there a way to trigger an action on selecting a suggestion using the inbuilt Auto complete feature of lift.
I am adding this as a separate answer since the edit is essentially a separate question. The AutoComplete widget from Lift does not modify an existing element on the page, but rather replaces it with the following NodeSeq, as per the source.
<span>
<head>
<link rel="stylesheet" href={"/" + LiftRules.resourceServerPath +"/autocomplete/jquery.autocomplete.css"} type="text/css" />
<script type="text/javascript" src={"/" + LiftRules.resourceServerPath +"/autocomplete/jquery.autocomplete.js"} />
{Script(onLoad)}
</head>
<input type="text" id={id} value={default.openOr("")} />
<input type="hidden" name={hidden} id={hidden} value={defaultNonce.openOr("")} />
</span>
Since that has now replaced the original HTML, the second line where you add an onBlur handler is not applied to anything useful. However, the AutoComplete constructor does take an optional parameter for attributes and you can probably use that to add an onBlur attribute to the input tag.
You can try something like this:
"#countryNameOnBlur" #> AutoComplete(default, suggest, submit,
("onBlur", SHtml.onEvent(callback).cmd.toJsCmd))
The above should pass in a tuple which specifies the attribute name, and the string representation of the Javascript you want executed. This should accomplish what you are looking for as long as the AutoComplete library doesn't also rely on the onBlur event. That case is doable too, but a bit more work.
One other thing to note is that onBlur is fired when the input loses focus, ie: the user moves the cursor to another field. If you want it to fire any time the text changes, regardless of cursor position, you may prefer the onChange event.
If you are looking to bind to different events on the same element, so that you end up with something like: <input onblur="getCapitalName" onchange="autoComplete">, you can try using SHtml.onEvent. Something like this in your snippet should do the trick:
object CapitalOnBlur {
def render =
"* [onblur]" #> SHtml.onEvent(e => CapitalOnBlur.getCapitalName(e)) &
"* [onchange]" #> SHtml.onEvent(e => CapitalOnBlur.autoComplete(e)) &
...
}
And then call the snippet from your input, like this:
<form>
Country : <input id="countryNameOnBlur" data-lift="CapitalOnBlur" type="text" name="countryNameOnBlur"/><br />
</form>
I am not sure what any of the arguments your code takes, so the above is mostly illustrative - but will hopefully get you on your way.
I have this in my template:
<v:iterator.explode content="<f:format.nl2br>{artnumbers.qualitynumber.certificates}</f:format.nl2br>" glue="<br />" as="expCertificates">
if artnumbers.qualitynumber.certificates is empty, it returns teh string "array".
Is that a bug?
v:iterator.explode when used with the as argument implies the variable assigned to as is only available inside the tag content:
<v:iterator.explode content="1,2,3" as="numbers">
{numbers} is an array
</v:iterator.explode>
{numbers} is no longer defined.
This behaviour changed from VHS 1.7 to 1.8 (from memory).
Alternatively, do:
{artnumbers.qualitynumber.certificates
-> f:format.nl2br()
-> v:iterator.explode(glue: '<br />')
-> v:var.set(name: 'extractedCertificates')}
<f:for each="{extractedCertificates}" as="certificate">
{certificate}
</f:for>
Or better, but assumes your lines are ONLY separated by a single line break:
{artnumbers.qualitynumber.certificates
-> v:iterator.explode(glue: 'constant:LF')
-> v:var.set(name: 'extractedCertificates')}
<f:for each="{extractedCertificates}" as="certificate">
{certificate}
</f:for>
Which of course lets you skip the nl2br step.
Even more compacted:
<f:for each="{artnumbers.qualitynumber.certificates -> v:iterator.explode(glue: 'constant:LF')}" as="certificate">
{certificate}
</f:for>
You are using the <f:format.nl2br> ViewHelper. This ViewHelper replaces newlines in a string (!) with tags. You cannot use it for an array and that's why it returns "array".
I don't know why you need the explode viewHelper. Why don't you just iterate through your certificates?
<f:for each="{artnumbers.qualitynumber.certificates}" as="certificate">
{certificate}<br />
</f:for>
EDIT: If certificates is a string containing newlines, use the newline as glue for explode:
<v:iterator.explode content="{artnumbers.qualitynumber.certificates}" glue="\n" as="expCertificates">
You could also try to use CONSTANT:LF in glue as suggested in the documentation of the ViewHelper.
I wanna know how can I get a value of a child of a child. I have this...
<table id="table4">
<tr>
<td>Id:</td>
<td>Name:</td>
</tr>
<tr>
<td>1515</td>
<td>Thiago</td>
</tr>
</table>
In Jquery, I wanna do something like this...
var id = $("#table4:nth-child(2) tr:nth-child(1)").val();
How can I do this work? The first <td> of the second <tr>. I know that I can use "class" and "id" to make it easier, but in this case I can't do that for others reasons.
PS. Sorry about the bad English, I'm a noob in this language.
Thanks.
Like this:
var id = $("#table4 tr:nth-child(2) td:nth-child(1)").text();
You can test it out here. The :nth-child selector applies to the child, for instance the first is saying "a <tr> that is a second child of its parent", rather than your attempted version, which would mean "the second child of this <tr>".
Also, use .text() to get an elements text, rather than .val() which is for input type elements.
This isn't a fully jQuery solution, but just thought I'd point out that you could do this:
var txt = $("#table4")[0].rows[1].cells[0].innerHTML;
Or if there will be any HTML markup you want to avoid, you could do this:
var cell = $("#table4")[0].rows[1].cells[0];
var txt = cell.innerText || cell.textContent;