calling a Javascript function that makes a click on a (hidden) button or link - jsf

I call a javascript function that makes a click on a hidden commandButton but the click run when the page loads, not when I call the function.
this is the html code :
<p:inputText id="aa" value="#{bonBonneManagedBean.sel}" onkeyup="fnc()" />
<h:commandButton id="hh" onclick="#{bonBonneManagedBean.kk()}" style="display:none"/>
and the javaScript function :
function fnc()
{
length = document.getElementById('form:aa').value.length;
if(length == 10)
{
$("#hh").click();
document.getElementById('form:aa').value = "";
}
}

You should use the action attribute instead of onclick like this
<h:commandButton id="hh" action="#{bonBonneManagedBean.kk()}" style="display:none"/>
Note that you might have to add form prefix to the selector, like this
$("#myFormId\\:hh").click();
The same would work for a commandLink or any other 'clickable' component.

Must there be a button on this page(which I doubt, seeing as you're hiding it anyways)? You're better served using something like <p:remoteCommand/> here
Ditch the hidden button and replace with
<p:remoteCommand name="fnc" actionListener="#{bonBonneManagedBean.kk}"/>
But, if it's an absolute requirement, you can very easily emulate a button click in js with the click() method from your function you need to
Change the <h:commandButton/> to a <p:commandButton/> so you can assign the button a widgetVar attribute(to guarantee the name of the element in the DOM). The widgtetVar attribute can be set on almost all primefaces components to make your life easier
Using the widgetVar, just call the click() method in your function
<p:commandButton ajax="false" widgetVar="theButton" id="hh" action="#{bonBonneManagedBean.kk()}" style="display:none"/>
<p:inputText id="aa" widgetVar="theTextBox" value="#{bonBonneManagedBean.sel}" onkeyup="fnc()" />
and in the function:
function fnc(){
length = theTextBox.value.length;
if(length == 10){
theButton.click()
theTextBox.value = "";
}
}

If the top answers from Daniel and Kolossus doesn't help out someone: I found that characters got put in front of the id I set in my case, therefore this helped me:
$('[id$=hh]').click();
Basically the selector is saying the id ends with 'hh' but may not be the full id.
This is also helpful in SF development as the same thing happens with comandButtons, etc.

Related

PrimeFaces.current().focus Not working on commandButton

PrimeFaces.current().focus method works with inputTexts but with a commandButton I see no results, alternative I can use executeScript but the idea is to use focus for this kind of requeriment:
This works:
PrimeFaces.current().executeScript("document.getElementById('frmAperturaCajaMasiva:btnAceptarAperturaCajaMasiva').focus();");
This works on inputTexts but not working on button:
PrimeFaces.current().focus("frmAperturaCajaMasiva:btnAceptarAperturaCajaMasiva");
Any idea why? its the same thing but different in both commands
This is the code of the button on the xhtml nothing fancy :)
<p:commandButton id="btnAceptarAperturaCajaMasiva"
value="#{etiquetasMsg.cerrar_caja}" styleClass="cds-icon-button"
icon="cds-icon aprobar"
disabled="#{aperturaMasivaMB.blBtnProcesar}"
title="#{tooltipsMsg.cierrecaja_masiva_cerrar}"
onclick="if(!confirmarSeleccionTabla(PF('dtbFrmCajaWv'),null)){ return false; }"
actionListener="#{aperturaMasivaMB.validarCierreCajaMasivo}"
rendered="#{adminRestriccionMB.validarRestriccion('BTN_CERRAR_CAJAMASIVO')}" />
Yes I know why. The focus method in PrimeFaces specifically excludes buttons it was intended to focus input fields. Here is the source code.
focus: function(id, context) {
var selector = ':not(:submit):not(:button):input:visible:enabled[name]';
Notice the "not(:submit):not(:button)" in the Jquery selector.
Source code:
https://github.com/primefaces/primefaces/blob/master/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.js#L699-L728

Javascript calculator in JSF view calling server side

I need to make a calculator in a jsf view using only client-side part. No data can be passed to server-side.
I have the view splitted in a couple of <h:form> with calculator in the middle:
<h:form id="customer_form">
// view here working nice
</h:form>
<h:panelGroup layout="block" styleClass="ui-grid-col-2 offset-boxes" >
<p:panel id="calculator" header="Calculadora" styleClass="half-screen-height calculator-table">
<h:inputText id="result" widgetVar="result" styleClass="result-text"/>
<p:button value="X" widgetVar="X" ajax="false" onclick="calculate('x')" styleClass="right"></p:button>
// more calculator buttons
</p:panel>
</h:panelGroup>
<h:form id="consumption_form">
// view here working nice
</h:form>
Until here all is ok, but when I try to manage calculator with javascript:
<script type="text/javascript">
function calculate(sel){
if (sel == "x") {
document.getElementById("result").value = "";
} else {
var input = document.getElementById("result").value;
document.getElementById("result").setAttribute("value", input + sel);
}
}
</script>
Each time i change result value, server-side is called and value is reset to original value.
EDIT according to PrimeFaces documentation of p:button::onclick event
Client side callback to execute when button is clicked.
Either <h:button> tag is acting like this, so I guess problem is the way JSF or PrimeFaces are handling the javascript event...
I also tried to call and set input value by jquery with $("result").value but the result i get is a function(b7) not the value itself.
What am I doing wrong?
Thanks! ;)
J
you got to make sure you're JS code will not try to submit the form, so that will trigger a server side call, for that I suggest you return false and try using event.preventDefault() on your HTML buttons onclick calls, so you will avoid bubbling up the event to any listeners.

how to get selected records count in rich data table having multiple pages rich:datascroller

I am facing a problem where i want to test that whether a user has selected any record or not from the multiple page in rich:dataTable. These pages are created through rich:datascroller. Related code is given below.
<rich:datascroller id="dataScroller" selectedStyleClass="myClass" renderIfSinglePage="false"
align="center" for="dataList" maxPages="10"
pageIndexVar="currentPage" pagesVar="totalPages" reRender="pageNum,dataList" ajaxSingle="false">
<f:facet name="first"><h:outputText value="First" /></f:facet>
<f:facet name="last"><h:outputText value="Last" /></f:facet>
</rich:datascroller>
<h:inputHidden id="pageNum" value="#{currentPage}"></h:inputHidden>
<h:inputHidden id="numOfRows" value="10"></h:inputHidden>
The problem is that if user selects a record (say on 3rd page) and after that he moves to page one. Now in this case when i try to iterate through the table in Java Script to know that whether he has selected any record or not than it always allows me to iterate till the current page on which i am and hence i am unable to give user the proper alert message for selecting a record first on pressing of submit button. All i want is to know that user has checked the check box against a record on any page from the available pages , irrespective of the fact that on which page is currently opened. Any ideas?
Try it via the Richfaces Javascript API.
For every component you have in your page, there's a representing Javascript object, named as next:
Richfaces_componentId (small 'f' for faces).
Using that and to understand it live, go to the ScrollableDatatable Live Demo, open your chrome browser console, and execute this:
Richfaces_ScrollableGrid_j_id353_carList.selectionManager.selection.ranges
This will print out an empty javascript array.
Try selecting some rows, and running that line again, you'll have an array containing the indexes of your selected rows.
So to put that in a function:
<script>
function tableHasSelection() {
return Richfaces_ScrollableGrid_j_id353_carList.selectionManager.selection.ranges.length != 0;
}
</script>
Now you call this function via onclick of your submit button, and return false in case of no selection to prevent submission.
Of course you would replace Richfaces_ScrollableGrid_j_id353_carList with your component's javascript representing object.
Hopefully this will help.
[UPDATE]
According to our discussion in the comments, here is an update that might be helpful.
Your data table would be like this:
<rich:extendedDataTable value="..." var="element" id="table" selectionMode="..." selection="...">
<rich:column>
<h:selectBooleanCheckbox value="..." onclick="toggleSelection(this, #{element.id});" />
</rich:column>
</rich:extendedDataTable>
<h:commandButton value="Submit" action="#{...}" onclick="return tableHasSelection();" />
And your script would have these functions:
<script>
var selectedElements = [];
function toggleSelection(checkbox, id) {
if ($(checkbox).is(':checked')) {
//add selected row if checkbox is checked
selectedElements.push(id);
} else {
//or find it in the array and remove it
var index = selectedElements.indexOf(id);
if (index > -1) {
array.splice(index, 1);
}
}
}
function tableHasSelection() {
return selectedElements.length != 0;
}
</script>
(<rich:extendedDataTable> has selectable rows, you may want to look at that)
One thing you can do is to submit the selection when the user clicks it. E.g.
<h:selectBooleanCheckbox onclick="saveSelection(#{rowId})">
…
<a4j:jsFunction name="saveSelection">
<a4j:param name="id" assignTo="#{bean.selectedId}">
</a4j:jsFunction>
But if the user will only be choosing one row then simply say if the selected row is not on the current page the user didn't select anything, I don't think that's a wrong approach.

how to call Cufon.refresh after user click on <h:commandButton>

In my project i have a <h:datatabel> that contains details of polls that defined in the system. I will use pagination in my page, then create use a next command with the following code:
<h:commandLink value="<" action="#{PollSearchControler.next}" >
<f:ajax render="checkall" />
</h:commandLink>
my button work good and when i click in it my table refresh and load new data. but i have a problem with Cufon. I use Cufon in my project for use non standard font. when my date changed, i must call Cufon.refresh(). this function render new data and show my data with my font. now i have a question:
How can i say to <f:ajax> that call Cufon.refresh() after it load new data?
thanks.
You can use the onevent attribute to call a javascript function, this function will be called three times during the request lifetime: begin, complete, success. for example <f:ajax render="checkall" onevent="refreshCuffon"/>
and the function will be
function refreshCuffon(data) {
if(data.status == "success") {
Cufon.refresh()
}
}

Call an action listener via ajax when user presses enter on a h:form input field

I have this form
<h:form id="formId" prependId="false">
Descrizione <h:inputTextvalue="#{bean.description}" />
Prezzo: <h:inputText value="#{optionalManaged.price}" />
<a4j:commandLink styleClass="button smallButton" actionListener="#{bean.method}"
execute="formId" render="otherDiv">
+
</a4j:commandLink>
</h:form>
At the moment, pressing the a4j:commandLink stores the two input filelds' values inside my bean and calls my action listener correctly.
What I'd like to happen is that pressing enter on the second inputText does the same.
I made a naive try by calling the a4j:commandLink click() via jquery from inside the inputText. This, obviously, didn't work.
Any idea on how I could do this?
You need to detect if Enter key was pressed and click the command link programmatically. Just don't forget to set its id, as well as id of input component. The piece of JavaScript you need to add when the page has finished loading is:
document.getElementById('input').onkeypress = function(e) {
var event = e || window.event;
var code = event.which || event.keyCode;
if (code == 13) {
document.getElementById('link').click();
return false;
}
}

Resources