Since we can apply JQuery to any JSF rendered components, as in the following question
JSF to JQuery Component Integration
After having tried that, it did work I can successfully integrate JQuery into JSF, but the problem is that whenever I re-render the h:dataTable for instance, JQuery stops working,
-I'm using RichFaces and the a4j, by the way-.
For example, I have a data table as follows
<h:dataTable id="someDataTable" value="#{backingBean.someDataModel}" var="item" styleClass="table">
<h:column>
<h:outputText value="#{item.text}"/>
</h:column>
</h:dataTable>
and I have a button that when clicked re-renders the dataTable, and repopulate it with new data.
<a4j:commandButton value="Click" reRender="someDataTable"/>
and not to forget I have this script in the page
<script>
jQuery.noConflict();
jQuery(document).ready(function () {
jQuery('.table').dataTable({
"bSort": false});
});
</script>
Now when the page is first loaded, sorting works fine, but whenever I click the button to re-render the table, the table is successfully populated with the new data from the backing bean, but the sorting doesn't work anymore.
From what I guess, I think this might has something to do with the
jQuery(document).ready()
which applies the
jQuery.('.table').dataTable();
only when the document is ready, so I was wondering if there's some events in jQuery that I can attach to the dataTable re-render event, as I'm no guru at JQuery or JS.
Just re-execute the script when the ajax request has completed.
First refactor your script into a reuseable function.
<script>
jQuery.noConflict();
jQuery(document).ready(function() {
initDataTable();
});
function initDataTable() {
jQuery('.table').dataTable({
"bSort": false
});
}
</script>
Then invoke the same function in oncomplete of <a4j:commandButton>.
<a4j:commandButton ... oncomplete="initDataTable()" />
Related
My application is managing software, and for user convenience, I want to allow them to open multiple tabs for changing parameters of more than one record at a time. But after finishing whatever they doing, the tabs stays open, and I got some complains about that. So basically my question is:
If there's any way to close browser tab that sends a request to method in my backing bean? for example:
JSF page:
<h:commandButton value="Public score"
action="#{assignmentBean.publicSelected()}">
</h:commandButton>
Bean method:
public void publicSelected() {
application.setAssignmentStatus(done);
dataAccess.mergeEntity(application);
}
is there any way to add something after merging command and close browser tab that activated method? Thanks for help
FULL CODE FOR SOLUTION I'm bad with mixing JS and JSF, so for any of you that are also bad at this I post full code solution using Tiago Vieira Dos Santos hint.
Now my button code looks like:
<h:commandButton value="Public score"
action="#{myBean.doThings}">
<f:ajax execute="#this" onevent="pop"/>
</h:commandButton>
plus on bottom of page I added code as follows:
<script type="text/javascript">
function pop(data){
if(data.status == "success"){
window.close();
}
}
</script>
now after method does what has to be done the window closes.
I think you can be use the javascript command Window.close() then you can put it on oncomplete tag or call in you managed bean using the FacesContext.
See more in this How to close current tab in a browser window?
Using an OutputLink and Javascript
<h:outputLink onclick="window.open('popup.faces', 'popupWindowName', 'dependent=yes, menubar=no, toolbar=no'); return false;" value="#">
<h:outputText value="open popup" />
</h:outputLink>
With this solution we got control over the appearance of the new browser window. And since there is no postback, there is no validation at all. This is the easiest way to open a new browser window when no model update is needed and no action has to be executed.
In order to implement a proper action handling we need to move the decision whether to open a new window to the action listener.
<h:commandLink actionListener="#{bean.openPopupClicked}" value="open popup" />
public void openPopupClicked(ActionEvent event) {
// code to open a new browser window goes here
}
I have Javscript in my XHTML file as
<script src="test1.js"></script>
Now I have couple of other javascripts as well. They are actually themes.
I want give users flexibility to change the them (javascript name) frmo drop-down box .
I tried this way
<script src="#{testBean.jsName}</script>
Since it is going to be an Ajax update so I have update the section and I updated with
<h:panelGrid id="jsName">
<script src="#{testBean.jsName}</script>
</h:panelGrid>
This is not inside the form .
when I try
<p:commandButton value="Generate"
actionListener="#{tBean.generateGraph}" update="jsName"></p:commandButton>
It doesn't work as it says that it couldn't find jsName.
I put that gride inside the form then it wont throw the error but the script name would still remain the same.
Does anyone have better idea or any other way to achieve it?
If you try to update it from a component inside the form you have to use the absolute id of the panelGrid otherwise primefaces will try to update something with id jsName inside the form. When you want to use the absolute id you have to preced a :. So try the following for the button:
<p:commandButton value="Generate" actionListener="#{tBean.generateGraph}" update=":jsName"/>
I was browsing to find a solution for a long time, but I did not find a suitable answer.
I'm developing a JSF web appication using RichFaces library. Application supports different locales, and user is able to change them by selecting from dropdown list.
I want the items in dropdown list to have a flag icons along the locale name.
Unfortunately, I could not find the way to do it with JSF.
The xthml code for the dropdown list is:
<h:panelGroup>
<h:form id="languageForm" prependId="false">
<h:outputText value="#{usermsg['locale.select.message']}" styleClass="userMessage"/>
<h:selectOneMenu id="dropdown" value="#{localeBean.selectedLocale}" onchange="submit()">
<f:selectItems value="#{localeBean.locales}" />
</h:selectOneMenu>
</h:form>
</h:panelGroup>
Flag icons are simply done with plain HTML and JQuery, like I've found here: http://www.ixtendo.com/polyglot-language-switcher-jquery-plugin/
To put the icon in the dropdown list item, I have to apply the css for each element in list, like:
#en {
background-image: url(/resources/images/flags/gb.png);
}
#fr {
background-image: url(/resources/images/flags/fr.png);
}
The problems here are:
f:selectItems (as well as f:selectItem) does not seem to support style property.
I could apply styles to tags using javascript, but I need to have IDs for tags, which f:selectItem (seems) does not allow as well.
The other thing I thougt is to use JQuery control mentioned in the link above, but here is another problem: how to set the value of the selected option to JSF bean. In other words, can I set #{localeBean.selectedLocale} through JQuery or Javascript and plain HTML?
I have found that PrimeFaces has a selectOneMenu control, which allows adding icons http://www.primefaces.org/showcase/ui/selectOneMenu.jsf (the one named 'Content with Filter')
but I'm affraid we cannot afford to switch from RichFaces to PrimeFaces at the moment.
Any help is appreciated.
I have found a solution myself. I figured that I'm able to add ids or classes to html tags with jQuery, so what I've done, I've added the following script:
<script type="text/javascript">
$(document).ready(function() {
$('option').each(function(){
$(this).addClass(this.value);
});
});
</script>
And css:
option {
background-repeat: no-repeat;
background-position: right;
}
.en {
background-image: url(/resources/images/flags/gb.png);
}
.fr {
background-image: url(/resources/images/flags/fr.png);
}
...
I used classes because I have two menus with flags in my app, but this works with ids as well.
The script adds the class to JSF-generated tags, so there is no longer an issue to send value back to managedBean.
Thanks everyone.
I have this application written in JSF 2.0 facelets and it has the following code that supposed to display some content in an area which a jQuery slide controls, meaning that you press a button that displays that area and press it again to hide it
<f:ajax render="messageID">
<h:form id="myform" styleClass="form1" >
<h:message id="messageID" for="signinemail" class="messageforlogin"/>
<h:panelGrid styleClass="loginpanel" columns="2" cellspacing="4">
<h:outputText value="Email: "/>
<h:inputText class="textboxes" size="20" id="signinemail"
value="#{signinBean.email}"
validatorMessage="Invalid Email, Try Again">
<f:validateRegex pattern="\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
</h:inputText>
As you can see there is an error message that should be displayed if the email is not typed correctly, and as i said before this area is controlled with a jquery.slidetoggle function and button that makes it a slide to input the stuff in,
The thing is when the use presses the submit button(not shown here) the slide freezes and no error message is displayed,When i remove the "ajax" the message is displayed but the slide disappears and you have to press the toggle button again to see the slide with the error messages, i have done this in the same page but with out a slide and it wokrs very fine.
Is there away to display the slide and the error messages on it ???
The jQuery script which is responsible for setting the slides should be re-executed when the JSF ajax request completes, simply because the ajax response changes/replaces elements in the HTML DOM tree with new elements retrieved from the server which in turn of course do not contain those jQuery-initialized event handlers anymore. The jQuery script is not auto-executed everytime when the ajax request completes, but only whenever you refresh the page.
You just need to re-invoke your jQuery function in the JSF ajax event callback handler as follows:
jsf.ajax.addOnEvent(function(data) {
if (data.status == "success") {
yourjQueryFunctionWhichAddsTheSlideEvents();
}
});
An alternative is to use OmniFaces' <o:onloadScript>.
<o:onloadScript>yourjQueryFunctionWhichAddsTheSlideEvents();</o:onloadScript>
This way you also don't need a $(document).ready() anymore.
I have the following dialog inside my .xhtml page.
<p:dialog widgetVar="exampleDialog" onShow="fillTextArea()" >
<p:tabView id="tabView">
<p:tab id="exampleTab" title="Example">
<p:inputTextarea id="someInputTextArea" autoResize="false"
value="" />
</p:tab>
</p:tabView>
</p:dialog>
The dialog is shown when a button is clicked. The fillTextArea javascript function is defined inside script tags at the head of the document.
function fillTextArea() {
console.log(jQuery("textarea[id='someInputTextArea']")); // logs empty array []
console.log($("[id='someInputTextArea']")); // logs empty array []
jQuery("textarea[id='someInputTextArea']").val('xxx'); // does nothing
}
What's the problem? Why can't I retrieve the input text area?
Instead of using the onShow event of the Dialog, I tried:
exampleDialog.show();
fillTextArea();
just in case. But this didn't work neither. I'm trying to set the contents of the inputTextArea.
Any help appreciated. Thanks.
jQuery works on the JSF-generated HTML DOM tree, not on the JSF source code. JSF components do not necessarily generate the same client ID (the HTML element ID) as you have specified in the component ID. They may be prepended with IDs of the parent NamingContainer components. The <h:form> and <p:tabView> are such components.
Open the page in webbrowser, rightclick and View Source and locate the generated HTML code of the <p:inputTextarea>. It'll look something like this:
<textarea id="formId:tabViewId:textareaId">
You need to specify exactly this ID in the jQuery selector.
$("[id='formId:tabViewId:textareaId']");
See also:
How to refer to a JSF component Id in jquery?
How to select JSF components using jQuery?