HTML editor removes FreeMarker tags inside <table> tag - html

I use FreeMarker to build various templates from email to invoice templates. Issue that i am seeking right now is related to FreeMarker code being extracted outside table tag since HTML doesn't allow other characters inside it beside tbody, thead, tr.
Would be glad if anyone has an idea how to bypass this.
Example:
<table>
<tbody>
[#assign eventDetails = []]
[#if items?? && items?has_content]
[#list items as item]
<tr>
<td style="padding: 5px;vertical-align: top;border-bottom: 1px solid #eee; text-align: center;">
${item.name}
</td>
</tr>
[/#list]
[/#if]
</tbody>
</table>
become like this after being applied to editor using element.innerHTML:
[#assign eventDetails = []]
[#if items?? && items?has_content]
[#list items as item]
[/#list]
[/#if]
<table>
<tbody>
<tr>
<td style="padding: 5px;vertical-align: top;border-bottom: 1px solid #eee; text-align: center;">
${item.name}
</td>
</tr>
</tbody>
</table>

It of course only depends on the HTML editor you are using, but you should try if same happens if, either:
You are using the <#...> syntax instead. That looks like some unknown tag for the editor, not CDATA, so maybe it doesn't react the same way.
Replace <tbody>...</tbody> with [#html.tbody]...[/#html.tbody]. Then the editor might won't be confident enough to remove stuff. Or, the same with [#html.table], etc. Quite awkward, but might be better than what you have now. (For that to actually work when running the template, you will have to define the tbody macro in the html namespace of course. It's not built in.)
Example of the last:
<#ftl output_format='HTML'>
<#macro table attrs...><#elementWithNested 'table' attrs><#nested></#></#macro>
<#macro tbody attrs...><#elementWithNested 'tbody' attrs><#nested></#></#macro>
<#macro elementWithNested elementName attrs>
<${elementName}<#if attrs?size != 0><#list attrs as k, v> ${k}="${v}"</#list></#if>>
<#nested>
</${elementName}>
</#macro>
If above template is #import-ed as html, then <#html.table foo="bar">...</#html.table> etc. will work.

Related

How to add a class and other HTML attributes on the same object on template Jinja2?

Considering this partial HTML code below:
<tr>
<td>
<label>IVA</label>
</td>
<td>
{{form.iva(class="form-control")}}
{% if form.iva.errors %}<span class="error">{{';'.join(form.iva.errors)}}</span>{%endif%}
</td>
</tr>
And this partial python code (Flask/Wtforms):
iva = SelectField(u"IVA", [validators.Required()], choices=[])
Besides of set the class "form-control" I would like to add some more style but without change the class, in other words, just add some more style in this specific object, eg: width: 150px;
So, How I can do?
You can rendering fields adding some keywords arguments which will be injected as html attributes like style, placeholder, autocomplete, etc:
<tr>
<td><label>IVA</label></td>
<td>
{{form.iva(class="form-control",style="min-width: 150px; max-width: 200px;")}}
{% if form.iva.errors %}<span class="error">{{';'.join(form.iva.errors)}}</span>{%endif%}
</td>
</tr>
See more information in the official documentation

ASP.NET 1.1 - VB.NET HTML Markup not reading variable from Code-Behind

I am trying to dynamically change the values inside my HTML markup depending on certain conditions in the code-behind.
In my code-behind in the Page_Load(), I have the following:
If Not myCheck = 1 Then
mySuffix = "_gr"
myColor = "#cccccc"
Else
mySuffix = ""
myColor = "#bdd1ec"
End If
This is used for my HTML markup to change the way the page looks on certain conditions.
<table>
...
<tr>
<td style="background-color: <%=myColor%>" colSpan="6"><IMG height="5" src="/images/corner-inner-blue-topLeft<%=mySuffix%>.gif" width="5"></td>
<td style="background-color: <%=myColor%>; text-align:right"><IMG height="5" src="/images/corner-inner-blue-topRight<%=mySuffix%>.gif" width="5"></td>
</tr>
...
</table>
Now my problem is this. It works on the suffix but not on the color.
When I run my site, navigate to the page, and I do an inspect element, I get this.
<table>
...
<tr>
<td style="background-color: <%=myColor%>" colspan="6"><img src="/images/myImg_gr.gif" height="5" width="5"></td>
<td style="background-color: <%=myColor%>; text-align:right"><img src="/images/myImg_gr.gif" height="5" width="5"></td>
</tr>
...
</table>
It's reading the <%=mySuffix%> variable from my code-behind but not the <%=myColor%>.
I tried debugging just to be sure that it does pass something to the variable and it does.
Can someone help me point out which I am doing wrong? Or is there any other better way to achieve this?
Thanks a lot!
If not using the table is an option, you might consider using a span or div element, and give it an id, instead of using a <td> element. Then you can reference the span control inside the code-behind to set the style properties. Like this:
ASPX:
<span id="spnSample" runat="server">Hello</span>
.VB:
If Not myCheck = 1 Then
mySuffix = "_gr"
spnSample.Style.Add("background-color", "#cccccc")
Else
mySuffix = ""
spnSample.Style.Add("background-color", "#bdd1ec")
End If

How to get line from table with Jsoup

I have table without any class or id (there are more tables on the page) with this structure:
<table cellpadding="2" cellspacing="2" width="100%">
...
<tr>
<td class="cell_c">...</td>
<td class="cell_c">...</td>
<td class="cell_c">...</td>
<td class="cell">SOME_ID</td>
<td class="cell_c">...</td>
</tr>
...
</table>
I want to get only one row, which contains <td class="cell">SOME_ID</td> and SOME_ID is an argument.
UPD.
Currently i am doing iy in this way:
doc = Jsoup.connect("http://www.bank.gov.ua/control/uk/curmetal/detail/currency?period=daily").get();
Elements rows = doc.select("table tr");
Pattern p = Pattern.compile("^.*(USD|EUR|RUB).*$");
for (Element trow : rows) {
Matcher m = p.matcher(trow.text());
if(m.find()){
System.out.println(m.group());
}
}
But why i need Jsoup if most of work is done by regexp ? To download HTML ?
If you have a generic HTML structure that always is the same, and you want a specific element which has no unique ID or identifier attribute that you can use, you can use the css selector syntax in Jsoup to specify where in the DOM-tree the element you are after is located.
Consider this HTML source:
<html>
<head></head>
<body>
<table cellpadding="2" cellspacing="2" width="100%">
<tbody>
<tr>
<td class="cell">I don't want this one...</td>
<td class="cell">Neither do I want this one...</td>
<td class="cell">Still not the right one..</td>
<td class="cell">BINGO!</td>
<td class="cell">Nothing further...</td>
</tr> ...
</tbody>
</table>
</body>
</html>
We want to select and parse the text from the fourth <td> element.
We specify that we want to select the <td> element that has the index 3 in the DOM-tree, by using td:eq(3). In the same way, we can select all <td> elements before index 3 by using td:lt(3). As you've probably figured out, this is equal and less than.
Without using first() you will get an Elements object, but we only want the first one so we specify that. We could use get(0) instead too.
So, the following code
Element e = doc.select("td:eq(3)").first();
System.out.println("Did I find it? " + e.text());
will output
Did I find it? BINGO!
Some good reading in the Jsoup cookbook!

How to find 2nd td in html using xpath

I have 2 occourances of same td in 2 different tables.
I am able to get the value 'Yes' for the 1st one using this:
//h:td[1][*[contains(.,'Loudspeaker')]]/../h:td[last()]/text()
but not getting the value 'Voice 75dB / Noise 66dB / Ring 75dB' for the 2nd one.
I tried:
//h:td[2][*[contains(.,'Loudspeaker')]]/../h:td[last()]/text()
I am very new to html and xpath so please bear with me.
portion of my html:
</table><table cellspacing="0">
<tr>
<th rowspan="3" scope="row">Sound</th>
<td class="ttl">Alert types</td>
<td class="nfo">Vibration; MP3, WAV ringtones</td>
</tr>
<tr>
<td class="ttl">Loudspeaker </td>
<td class="nfo">Yes</td>
</tr>
.
.
<table cellspacing="0">
<tr>
<th rowspan="5" scope="row">Tests</th>
<td class="ttl">Display</td>
<td class="nfo">
<a class="noUnd" href="http://xyz.php">Contrast ratio: Infinite (nominal) / 3.419:1 (sunlight)</a></td>
</tr><tr>
<td class="ttl">Loudspeaker</td>
<td class="nfo">
<a class="noUnd" href="http://xyz.php">Voice 75dB / Noise 66dB / Ring 75dB</a></td>
</tr><tr>
..
Thanks in Advance.
The only difference between these two snippets is that in the second one your text is nested within an a element. So it has to be
//h:td[2][*[contains(.,'Loudspeaker')]]/../h:td[last()]/h:a/text()
(I guess you have a namespace definition for h as you use it in your XPath.
What you are doing is:
//h:td[2] find each second td in the whole document (main issue here, because there is no second td with text "Loudspeaker" ).
[*[contains(.,'Loudspeaker')]] check if this (second td) has a child with text Loudspeaker in any children.
/../h:td[last()]/text() get the text of last td off parent.
But what you seem like to do is something like:
(//h:tr[h:td/*[contains(.,'Loudspeaker')]]) find all tr with has text "Loudspeaker"
[2] select the second of this trs.
/h:td[last()]/. text of any children of last td of this second found tr.
Therefor try (not tested!):
(//h:tr[h:td/*[contains(.,'Loudspeaker')]])[2]/h:td[last()]/.
public string FindElementUsingOneTrTwoTd(string tblName, string className, string searchString)
{
return "//*[#id=\"" + tblName + "\"]/tbody/tr/td[contains(normalize-space(#class), \"" + className + "\") and contains(string(),\"" + searchString + "\")]/../td[2]";
}

How to embed links (anchor tag) into HTML context from UIBINDER in gwt

I have a HTML widget in my ui.xml which I am using in Uibinder to populate data as given below:
ui.xml ->
<g:HTML ui:field="operationsDetailTableTemplate" visible="false">
<table class="{style.LAYOUT_STYLE}" width="100%" border="1">
<tr>
<td><img src="images/indent-blue.gif"/></td>
<td>
<table class="{style.DEFAULT_STYLE}">
<thead>
<tr>
<th>OperationUuid</th>
....
</tr>
</thead>
<tbody>
<tr>
<td>%s</td>
...
</tr>
</tbody>
</table>
</td>
</tr>
....
</g:html>
Uibinder.java--->
String htmlText = operationsDetailTableTemplate.getHTML()
.replaceFirst("%s", toSafeString(operation.getOperationUuid()))
....
HTML html = new HTML(htmlText);
operationsDetail.add(html);
The above is done in a for loop for each of the operation retrieved from the database.
My question is how I can embed a hyperlink or an anchor tag on one of the cell (eg. operation id ) for each of the operation set retrieved. I also wish to have a listener attached to it.
P.S. - It does not allow me to have a anchor tag in HTML in ui.xml.
You'd better use the tools in the way they've been designed to be used: use ui:field="foo" on the <td> and #UiField Element foo + foo.setInnerHTML(toSafeString(...)) instead of extracting the HTML, modifying it and reinjecting it elsewhere. You could also use a <g:Anchor> and attach an #UiHandler to handle ClickEvents.
Your way of using UiBinder makes me think of SafeHtmlTemplates, or the new UiRenderer aka UiBinder for Cells: https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder#Rendering_HTML_for_Cells