How to get Unicode data in JSF's backing bean - jsf

I have the following code snippets which basically set a hidden field's value to the html content of a div (using jQuery) so I can process it on a backing bean:
MyPage.xhtml
function save_to_hidden()
{
document.getElementById('hidden_field').value=$('#my_div').html();
}
Further down:
<h:inputHidden id="hidden_field" value="#{myBean.divData}" />
Further down:
`<div id="my_div">
<!-- content in foreign language (spanish) -->
</div>
Further down:
<a4j:commandButton value="Save" onclick="save_to_hidden()" action="#{myBean.processDivData}" />
I receive the content on the "processDivData" method, but all the "special" characters are replaced with gibberish. Where the problem could be?
Thank you

The hidden_field is rendered as an HTML form element and as such probably encoded the data in the application/x-www-form-urlencoded MIME type before sending it to the server.
You can use the URLDecoder class to decode these Unicode characters.

Related

Popup helpful message before selecting from h:selectOneMenu in JSF

I am using JSF and I have an h:selectOneMenu which is populated using f:selectItems from a backing bean. I would like to display a helpful message for each option in the h:selectOneMenu. This message will come from a bean too and it will be different for each option. I want to do that while the user navigates between the options and before selecting the options that he wants. The idea is to help the user decide what to select. In other words I want something very similar to “title” attribute of component but more fancy and powerful than this. Specifically I want something like a small popup window which allows unlimited number of characters. Is this possible? Do you have any idea as to how to proceed? Is there any JSF library that can help me do this?
I found this link ToolTip for each SelectOneMenu Items in jsf but it is not helpful for me because first of all it uses the “title” attribute and secondly the message does not come from a backing bean.
Thanks in advance!
As BalusC mentioned, you can just use Primefaces, and here is a sample code using the PowerTip jQuery plugin:
<p:selectOneMenu id="users" converter="userConverter" var="u">
<f:selectItems value="#{userManagedBean.users}" var="user" itemLabel="#{user.firstName}" itemValue="#{user}"/>
<p:column >
<span customData="#{u.emailOrAnyOtheInfoYouWantToDisplayInTooltip}" class="aClassForTooltips">
<h:outputText value="#{u.firstName} - #{u.lastName}" />
</span>
</p:column>
And on the jQuery part:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<h:outputScript name="js/jquery.powertip.min.js" />
<script type="text/javascript">
$.noConflict();
jQuery(document).ready(function () {
jQuery('.aClassForTooltips').each(function(){
var elementToH = jQuery(this),
data = elementToH.attr('customdata').replace(/%20/g,' ');
elementToH.data('powertip', function() {
return '<div style="background-color:black;width:200px;height:25px">'+data+'.</div>';
});
///////
elementToH.powerTip({
placement: 'ne' // north-east tooltip position
});
//////
});
});
Notice the use of a custom attribute in the span element. This attribute is ignored by JSF renderers if used with any JSF component, that's why you need a span.
Finally do not forget to include at least this CSS:
#powerTip {
position: absolute;
display: none;
z-index: 2147483647;
color:red;
}
I hope this helps

Validation failed javascript callback in JSF

I have a template in which I can add a CSS error class to a div when the validation of a component has failed and it renders a pretty nice effect on the browser.
Now, I don't need to add a css class to a component (this won't help me), but rather I need to change the css of the html that surrounds it, this is pretty simple with jQuery, however I can't seem to find a javascript callback for failed validation, is this possible? I'm also using primefaces (in case they provide such capabilities).
Markup:
<div class="control-group ERROR_CLASS_GOES_HERE_IF_VALIDATION_FAILED">
<label class="control-label">Input value:</label>
<div class="controls">
<h:inputText class=" inputbox" type="text" required="true" /> <!--Component that can fail -->
</div>
</div>
if the input text is empty, I need the div that wraps the "control group" to have an extra class. I can turn it into a <h:panelGroup> so it is a JSF component but still I wouldn't know how to do it. Javascript seems easier as I can do a:
jQuery("#ID_OF_DIV").addClass("error_class")
Just let JSF/EL conditionally print the class based on FacesContext#isValidationFailed().
<div class="control-group #{facesContext.validationFailed ? 'error_class' : ''}">
You only need to ensure that this element is covered by ajax update/render.
Another way would be hooking on the oncomplete event of an arbitrary PrimeFaces ajax based component. There's an args object available in the scope which in turn has a validationFailed property. E.g. <p:commandButton oncomplete> or even <p:ajaxStatus oncomplete>.
<p:ajaxStatus ... oncomplete="if (args && args.validationFailed) $('#ID_OF_DIV').addClass('error_class')">
If you want to do everything on the client side.
<h:outputText class="samplecls" rendered="#{facesContext.validationFailed}"
value="Please enter all the required fields">
</h:outputText>
<div class="control-group ERROR_CLASS_GOES_HERE_IF_VALIDATION_FAILED">
<label class="control-label">Input value:</label>
<div class="controls">
<h:inputText class=" inputbox" type="text" required="true" /> <!--Component that can fail -->
</div>
</div>
Javascript/Jquery
This class will exist in DOM only validation fails by rendered="#{facesContext.validationFailed}"
$(window).load(function(){
if($('.samplecls').length>0){
$("#ID_OF_DIV").addClass("error_class");
}
});

How to render a custom attribute of <h:outputLink>?

I am trying to implement pinterest's pinit button using a snippet like the one below:
<h:outputLink value="http://pinterest.com/pin/create/button/" class="pin-it-button" count-layout="horizontal">
<f:param name="url" value="#{beanOne.someMethod}/sometext{prettyContext.requestURL.toURL()}"/>
<f:param name="media" value="#{beanOne.someOtherMethod}/sometext/somemoretext/#{beanTwo.someMethodTwo}-some-text.jpg"/>
<f:param name="description" value="#{beanTwo.someOtherMethodTwo}"/>
<img border="0" src="//assets.pinterest.com/images/PinExt.png" title="Pin It" />
</h:outputLink>
Here are the gotcha's:
the whole markup is created from the combination of four different methods from two different beans as well as some static text
the url parameters obviously need to be urlencoded, therefore I am using f:param inside h:outputLink so that they get urlencoded
the generated a tag needs to have the non-standard count-layout="horizontal" attribute
Now my question is either one of:
How can I inject the count-layout attribute into h:outputLink or the generated anchor tag
Otherwise if I cannot, what would be another non-invasive (I don't want to change the bean methods) way to accomplish the required pinit button markup?
The required markup can be found at http://pinterest.com/about/goodies/ down in the "pin it button for websites" section.
Either use a normal <a> element along with a custom EL function which delegates to URLEncoder#encode().
<c:set var="url" value="#{beanOne.someMethod}/sometext#{prettyContext.requestURL.toURL()}"/>
<c:set var="media" value="#{beanOne.someOtherMethod}/sometext/somemoretext/#{beanTwo.someMethodTwo}-some-text.jpg"/>
<c:set var="description" value="#{beanTwo.someOtherMethodTwo}"/>
<a href="http://pinterest.com/pin/create/button/?url=#{utils:encodeURL(url)}&media=#{utils:encodeURL(media)}&description=#{utils:encodeURL(description)}" class="pin-it-button" count-layout="horizontal">
<img border="0" src="//assets.pinterest.com/images/PinExt.png" title="Pin It" />
</a>
(note that the class attribute was invalid for <h:outputLink>, you should be using styleClass)
Or create a custom renderer for <h:outputLink> which adds support for count-layout attribute. Assuming that you're using Mojarra, simplest would be to extend its OutputLinkRenderer:
public class ExtendedLinkRenderer extends OutputLinkRenderer {
#Override
protected void writeCommonLinkAttributes(ResponseWriter writer, UIComponent component) throws IOException {
super.writeCommonLinkAttributes(writer, component);
writer.writeAttribute("count-layout", component.getAttributes().get("count-layout"), null);
}
}
To get it to run, register it as follows in faces-config.xml:
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.Link</renderer-type>
<renderer-class>com.example.ExtendedLinkRenderer</renderer-class>
</renderer>
</render-kit>

Using CKEditor instead of PrimeFaces Editor

I am trying to use CKEditor in my JSF application. How to get the content of CKEditor into backing bean..?
index.xhtml
<form action="" method="post">
<p>
My Editor:<br />
<textarea cols="90" rows="20" id="editor1" name="editor1" value="#{EditorBean.value}"></textarea>
<script type="text/javascript">
CKEDITOR.replace( 'editor1',
{
uiColor: '#85B5D9'
});
</script>
<input type="button" value="Clear" name="clear" onclick="clear1()"/>
</p>
</form>
BackingBean
#ManagedBean
public class EditorBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
System.out.println("Content: "+value);
}
}
When I tried to print the value, It is not printing. Help me on this issue. PrimeFaces Editor is not supporting "Insert Table" function. So, I want to use CKE.
As el wont be able to evaluate non-JSF component.
Add this to your page :
<h:inputHidden value="#{EditorBean.value}" id="editorValue"/>
and onblur of editor textarea assign the value to the hidden element using
document.getElementById(editorValue).value = this.value;
Since this question bumped up somehow....
There is another option:
You can use the PrimeFaces Extensions , here is the link PrimeFaces Extensions CKEditor
Here an example from the showcase
<p:growl id="growl" showDetail="true" />
<pe:ckEditor id="editor" value="#{editorController.content}" interfaceColor="#33fc14">
<p:ajax event="save" listener="#{editorController.saveListener}" update="growl"/>
</pe:ckEditor>
<p:commandButton actionListener="#{editorController.changeColor}" update="editor"
value="Change color with AJAX" style="margin-top:10px;"/>
try this:
<textarea class="ckeditor" cols="80" id="editor1" rows="10"/>
<h:inputHidden value="#{tskCtrl.selected.dsc}" id="editorValue"/>
<p:commandButton onclick="document.getElementById('editorValue').value = CKEDITOR.instances.editor1.getData();" action="#{tskCtrl.create()}" value="Post" />
The answer from niksvp was helpful and set me in the right direction, but
the problem I found was that the blur handler never fires. I had to copy
the value from the textarea to the inputHidden on the onclick handler of
the commandButton:
<textarea id="textareaValue" .../>
<a4j:commandButton execute="editorValue" onclick="document.getElementById('editorValue').value = document.getElementById('textareaValue').value;"
...
or
<a4j:commandButton execute="editorValue" onclick="jQuery('#editorValue').val(jQuery('#textareaValue').val())"
I tried using onbegin & onbeforedomupdate but they didn't work.
Another option is to use the JSF versions of form and textarea. (It is likely possible to do this with passthrough elements as well, but I didn't try that.)
<h:form id="form">
<p>
My Editor:<br />
<h:inputTextarea cols="90" rows="20" id="editor1" value="#{EditorBean.value}" />
<script type="text/javascript">
ClassicEditor.create(document.querySelector('form\\:editor1'))
.then( editor => {
console.log( editor );
} )
.catch( error => {
console.error( error );
} );
</script>
</p>
</form>
This assumes that you do not have prependId=false.
The weird \\: is an escaping issue. It won't work without that. You'd get the "is an invalid selector" error in the console.
You can ID form and editor1 with other names, but you'll need to change the selector as well. You don't want to leave it to the defaults, as those are fragile, often changing as you update the page. Now it will only change if you change the structure of where editor1 is relative to form. E.g. if you add a fieldset around editor1, that would make the ID something like form\\:fieldset\\:editor1, where fieldset is the ID of the fieldset as specified in JSF. JSF will create the long version for you.
This also requires the CKEditor script to be added to the head, e.g.:
<script src="https://cdn.ckeditor.com/ckeditor5/11.2.0/classic/ckeditor.js"></script>
This particular example is for the ClassicEditor version. If you want a different version, you'd need to change the script and the part that says ClassicEditor.
Differences between the script as called in the question and this version may be that this is the current version (as I write this) while the question is older.
Alternately, you might prefer to use h:outputScript. But then you might need to host the script in your resources folder rather than using the version from the CDN.
See also:
Is the ID generated by JSF guaranteed to be the same across different versions and implementations?
Select element with double dot in id, error: “#octo:cat” is not a valid selector
Acquire full prefix for a component clientId inside naming containers with JSF 2.0
How to find out client ID of component for ajax update/render? Cannot find component with expression “foo” referenced from “bar”
How to include JavaScript files by h:outputScript?

Jsf custom selectItems

Look the following code
<h:selectManyCheckbox layout="pageDirection" styleClass="pressReviewTable">
<f:selectItems value="#{theme.articles}" var="prArt" itemLabel="#{prArt.prLabel}" itemValue="#{prArt.id}" itemLabelEscaped="false"/>
</h:selectManyCheckbox>
I try to put some html on on the itemLabel like a <b> but i have the following error:
The value of attribute "itemLabel"
associated with an element type
"f:selectItems" must not contain the
'<' character.
I find a trick to put directly in #{prArt.prLabel} the html but i'm not satisfied with that. I use mojarra and primefaces.
I want to do something like :
<f:selectItems value="#{theme.articles}" var="prArt" itemLabel="<b>#{prArt.value1}</b> : <font>#{prArt.value2}</font>" itemValue="#{prArt.id}" itemLabelEscaped="false"/>
What's the other way? If there...
Thanks
Since each item label get printed as <label> in HTML, you can just use CSS
<h:selectManyCheckbox styleClass="foo">
with
.foo label { font-weight: bold; }

Resources