How to skip rendering images in Jsf - jsf

I have a html string which contains images and text. While rendering, I only want to render the text and not the images.
I tried to do this :
<h:outputText escape="false" value="#{fn:replace(answerBlock.content,'<img>','')}" />
but this returned a malformed html which then rendered on the screen .
How can I skip the img tags and just render the text in jsf ?

Do not use string or regex functions to manipulate user-controlled HTML. The risk for a XSS attack hole is in this particular example very big as not all aspects are covered (e.g. <script>, onclick, etc). Just use a real HTML parser which is aware of XSS implications. For example Jsoup which has also a whitelist sanitizer feature.
String sanitizedHtml = Jsoup.clean(dirtyHtml, Whitelist.basic());
Then display that instead:
<h:outputText value="#{bean.sanitizedHtml}" escape="false" />
To improve performance, consider parsing it only once and saving in DB along with raw data.
See also:
How to implement a possibility for user to post some html-formatted data in a safe way?
CSRF, XSS and SQL Injection attack prevention in JSF

I would add code to your answerBlock bean. Something like:
public String imageStrippedContent() {
return stripImgTags( content() );
}
private String stripImgTags( String html ) {
// strip img tag using dom parser like jtidy, or maybe regex
...
}
Then modify your facelet to:
<h:outputText escape="false" value="#{answerBlock.imageStrippedContent} />

Related

create links dynamically

I have a user-defined text, such as
#SessionScoped
public class MyBean {
private String text = "Life’s but a walking shadow, a poor player
that struts and frets his hour upon the stage and
then is heard no more.";
public String getText() {
return text;
}
}
Of course the text is not static, but will be loaded from somewhere else. I want the text to be displayed one the page, as in
<h:form id="myForm">
<h:outputText value="#{myBean.text}" />
</h:form>
Now have a logic in the bean which marks certain words, e.g. every noun, in the text. These words should be rendered as links, as if they were commandLinks.
That is, the form should be submitted and I should be able to find out which link was clicked.
Something similar was already asked here, here and here, but I am not sure if the solutions given there suit my case.
My best guess right now is to split the text at the marked words into a list of snippets in the bean, e.g.
List<TextSnippet> textSnippets;
class TextSnippet {
private String precedingText;
private String markedWord;
...
}
such that each text snippet ends with a marked word. Then I would be able to iterate over the list in the xhtml, e.g.
<h:form id="myForm">
<ui:repeat var="snippet" value="#{myBean.textSnippets}">
<h:outputText value="#{snippet.precedingText}" />
<h:commandLink action="#{myBean.clickedOn(snippet.markedWord)}">
<h:outputText value="#{snippet.markedWord}">
</h:commandLink>
</ui:repeat>
</h:form>
However, I feel that this tightly couples the bean (logic of splitting) to the view. Any better ideas?
What I would personally do is try to keep the jsf tree small and implement something like the lines below that I think is more performant (disclamer: no full code coming )
Prepare the text serverside in a bean as This is a <div class="linkedWord">specific</div> word that needs a link and so is <div="linkedWord">this</div>
Output this in plain html via an <h:outputText value="#{myBean.text}"> (for escaping!)
Add a jquery dynamic eventhandler on the class="linkedWord" (so it works for each link) and call a javascript function
In that javascript function read the content of the div (or maybe add the text as a data- attribute aas well (like <div class="linkedWord" data-word="specific">specific</div>
and call a <h:commandScript> (JSF 2.3 and up) or a o:commandScript for previous JSF versions (or the `p:remoteCommand) and pass the content of the div (or the value of the attribute) as a parameter to a serverside method.
Keep in mind that there is no explicit reason to do everything in a 'JSF' way. Using client-side features and some small integration with JSF is very valid usage. People not doing this often 'blame' JSF but they themselves are effectively the cause of the less optimal behaviour)
See also:
Event binding on dynamically created elements?
http://omnifaces.org/docs/javadoc/2.6/org/omnifaces/component/script/CommandScript.html
https://javaserverfaces.github.io/docs/2.3/vdldocs/facelets/h/commandScript.html
You seem to go the right way, but I think I can suggest you some improvements. Don't know your exact requirements, but your current structure limits the marked word (which I guess acts as a mere link) to be at the end of the paragraph. What would happen if you have text after it? What about having two marked words? This class might suit better:
class TextSnippet {
private String text;
private String linkUrl;
...
}
You'll need to build the List<TextSnippet> the way you do, but evaluate the links before, so ui:repeat can access them.
Then, iterate over it. Instead of performing a POST to evaluate where to go, you've got it already, so you can use a h:link if you want to point to somewhere in your application or h:outputLink if it's outside it:
<ui:repeat var="snippet" value="#{myBean.textSnippets}">
<h:outputText value="#{snippet.text}" rendered="#{empty snippet.linkUrl}" />
<h:link outcome="#{snippet.linkUrl}" rendered="#{not empty snippet.linkUrl}">
<h:outputText value="#{snippet.text}">
</h:link>
</ui:repeat>

How to input HTML code by Servlet in JSF page [duplicate]

I'm using PrimeFaces with JSF 2.0 to build one application. I'm using PrimeFaces <p:editor> component to enable user to create rich text. But the output of this component is HTML source which look like this:
String text = "<p>This text <i>contains</i> some <b>HTML</b> code.</p>";
When I show this in a <h:outputText> as below:
<h:outputText value="#{bean.text}" />
Then it shows the HTML code as plain text:
<p>This text <i>contains</i> some <b>HTML</b> code.</p>
Is there any component which can interpret the HTML source so that e.g. <i> is actually shown as italics and <b> as bold?
This text contains some HTML code.
JSF by default escapes HTML from backing bean properties in order to prevent XSS attack holes. To disable this, just set the escape attribute of the <h:outputText> to false.
<h:outputText ... escape="false" />
This way the HTML won't be escaped and will thus be interpreted by the webbrowser.
Unrelated to the concrete problem, beware of XSS attacks as you're here basically redisplaying user-controlled input unescaped. You might want to sanitize it beforehand.
What is the general concept behind XSS?
CSRF, XSS and SQL Injection attack prevention in JSF
Server side HTML sanitizer/cleanup for JSF
Escape everything but linebreaks in h:outputText

Button do not work jsf [duplicate]

I am trying to implement jQuery with PrimeFaces and JSF components, but it's not working properly. When I tried to do the same with HTML tags it;s working properly.
Here is the code with HTML tags which works properly with jQuery:
<input type="checkbox" id="check2"></input>
<h:outputText value="Check the box, if your permanent address is as same as current address."></h:outputText>
<h:message for="checkbox" style="color:red" />
with
$("#check2").change(function() {
if ($("#check2").is(":checked")) {
$("#p2").hide();
} else {
$("#p2").show();
}
});
Here is the code with PrimeFaces/JSF which doesn't work properly with jQuery:
<p:selectManyCheckbox >
<f:selectItem itemLabel="1" value="one" id="rad" ></f:selectItem>
</p:selectManyCheckbox>
with
$("#rad").change(function() {
if ($("#rad:checked").val() == "one") {
$("#p2").hide();
} else {
$("#p2").show();
}
});
You should realize that jQuery works with the HTML DOM tree in the client side. jQuery doesn't work directly on JSF components as you've written in the JSF source code, but jQuery works directly with the HTML DOM tree which is generated by those JSF components. You need to open the page in webbrowser and rightclick and then View Source. You'll see that JSF prepends the ID of the generated HTML input elements with the IDs of all parent NamingContainer components (such as <h:form>, <h:dataTable>, etc) with : as default separator character. So for example
<h:form id="foo">
<p:selectManyCheckbox id="bar" />
...
will end up in generated HTML as
<form id="foo" name="foo">
<input type="checkbox" id="foo:bar" name="foo:bar" />
...
You need to select elements by exactly that ID instead. The : is however a special character in CSS identifiers representing a pseudo selector. To select an element with a : in the ID using CSS selectors in jQuery, you need to either escape it by backslash or to use the [id=...] attribute selector or just use the old getElementById():
var $element1 = $("#foo\\:bar");
// or
var $element2 = $("[id='foo:bar']");
// or
var $element3 = $(document.getElementById("foo:bar"));
If you see an autogenerated j_idXXX part in the ID where XXX represents an incremental number, then you must give the particular component a fixed ID, because the incremental number is dynamic and is subject to changes depending on component's physical position in the tree.
As an alternative, you can also just use a class name:
<x:someInputComponent styleClass="someClassName" />
which ends up in HTML as
<input type="..." class="someClassName" />
so that you can get it as
var $elements = $(".someClassName");
This allows for better abstraction and reusability. Surely those kind of elements are not unique. Only the main layout elements like header, menu, content and footer are really unique, but they are in turn usually not in a NamingContainer already.
As again another alternative, you could just pass the HTML DOM element itself into the function:
<x:someComponent onclick="someFunction(this)" />
function someFunction(element) {
var $element = $(element);
// ...
}
See also:
How can I know the id of a JSF component so I can use in Javascript
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable IDs, which are incompatible with the CSS part of web standards
Integrate JavaScript in JSF composite component, the clean way
You also can use the jQuery "Attribute Contains Selector" (here is the url http://api.jquery.com/attribute-contains-selector/)
For example If you have a
<p:spinner id="quantity" value="#{toBuyBean.quantityToAdd}" min="0"/>
and you want to do something on its object you can select it with
jQuery('input[id*="quantity"]')
and if you want to print its value you can do this
alert(jQuery('input[id*="quantity"]').val());
In order to know the real html tag of the element you can always look at the real html element (in this case spinner was translated into input) using firebug or ie developer tools or view source...
Daniel.
If you're using RichFaces you can check rich:jQuery comonent. It allows you to specify server side id for jQuery component. For example, you have component with specified server id, then you can apply any jQuery related stuff to in next way:
<rich:jQuery selector="#<server-side-component-id>" query="find('.some-child').removeProp('style')"/>
For more info, please check doumentation.
Hope it helps.
look this will help you when i select experience=Yes my dialoguebox which id is dlg3 is popup.and if value is No it will not open

jsf output html-formatted text

I have what it seems to be a very trivial question for you jsf expert out there...
I'm working in a JSF 2.0 application. Said that I have managed bean with a property containing an html portion to display to the user, which faces control should I use to emit that html directly on the page, without encoding it?
Did you try that:
<h:outputText value="#{myBean.myProperty}" escape="false"/>
By default, escape attribute is set to true in order to escape the HTML / XML characters.

how to display rich content using jsf component?

I used the rich: editor component to enter rich content and I save it in a database. When I tried to display it in outputText field , rich tags are not interpreted and are displayed as simple text.
So my question is: how can I make the jsf component (or Richfaces) interpret this rich content and display it properly??
The h:outputText indeed by default escapes predefined XML/HTML entities to avoid XSS attacks. If you want to display user-controlled input unescaped, then just set the escape attribute to false.
<h:outputText value="#{bean.text}" escape="false" />
However, keep potential XSS attacks in mind. If the rich:editor isn't already sanitizing user input from XSS, then you can do this with help of among others Jsoup.

Resources