I have a jsf datatable inside my form like this.
<h:form id="personId">
<h:dataTable id="hdatatable" value="#{Person.personList}"
border="0" cellpadding="10" cellspacing="5"
var="per" styleClass="order-table"
headerClass="order-table-header"
rowClass="order-table-odd-row,order-table-even-row"
syle="width: 950px" >
<h:column id="tcoulm">
<f:facet name="header">Action</f:facet>
<h:commandLink id="editLink" value="Edit" action="#{person.editAction(per)}"/>
<h:commandLink id="cancelLink" value="Undo" action="#{person.undoAction()}"/>
</h:column>
</h:datatable>
</h:form>
In the above table i am trying to access Edit and Undo actions using javascript.So, I assigned them Ids.But when I see Id of those elements in the html source it's like this.Here there mean i guess third row of the table. I am able to see column Id in the source.
personId:hdatatable:3:editLink
If i give only Id to command Link and give 'prependId="false" in form still I am seeing Id of the commdndLink as below
j_id1267631877_14a2c285:editLink
If i use only form Id and commandLink Id
formId:j_id1267631877_14a2c285:editLink
How to exactly access the elements inside the datatatble column?
Just use
var editLink = document.getElementById("personId:hdatatable:3:editLink");
?
If you don't want to access them individually, but you want to access them all, then much easier is to give them a style class
<h:commandLink ... styleClass="editLink" />
so that you can select them by class name instead (assuming jQuery)
var $editLinks = $(".editLink");
Related
Problem: Sometimes you will want to access a component from javascript with
getElementById, but id's are generated dynamically in JSF, so you
need a method of getting an objects id. I answer below on how you can do this.
Original Question:
I want to use some code like below. How can I reference the inputText JSF component in my Javascript?
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Input Name Page</title>
<script type="javascript" >
function myFunc() {
// how can I get the contents of the inputText component below
alert("Your email address is: " + document.getElementById("emailAddress").value);
}
</script>
</head>
<h:body>
<f:view>
<h:form>
Please enter your email address:<br/>
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
</h:form>
</f:view>
</h:body>
</html>
Update: this post Client Identifiers in JSF2.0 discusses using a technique like:
<script type="javascript" >
function myFunc() {
alert("Your email address is: " + document.getElementById("#{myInptTxtId.clientId}").value);
}
</script>
<h:inputText id="myInptTxtId" value="backingBean.emailAddress"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
Suggesting that the attribute id on the inputText component
creates an object that can be accessed with EL using #{myInptTxtId},
in the above example. The article goes on to state that JSF 2.0 adds
the zero-argument getClientId() method to the UIComponent class.
Thereby allowing the #{myInptTxtId.clientId} construct suggested
above to get the actual generated id of the component.
Though in my tests this doesn't work. Can anyone else confirm/deny.
The answers suggested below suffer from drawback that the above
technique doesn't. So it would be good to know if the above technique
actually works.
You need to use exactly the ID as JSF has assigned in the generated HTML output. Rightclick the page in your webbrowser and choose View Source. That's exactly the HTML code which JS sees (you know, JS runs in webbrowser and intercepts on HTML DOM tree).
Given a
<h:form>
<h:inputText id="emailAddresses" ... />
It'll look something like this:
<form id="j_id0">
<input type="text" id="j_id0:emailAddress" ... />
Where j_id0 is the generated ID of the generated HTML <form> element.
You'd rather give all JSF NamingContainer components a fixed id so that JSF don't autogenerate them. The <h:form> is one of them.
<h:form id="formId">
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
This way the form won't get an autogenerated ID like j_id0 and the input field will get a fixed ID of formId:emailAddress. You can then just reference it as such in JS.
var input = document.getElementById('formId:emailAddress');
From that point on you can continue using JS code as usual. E.g. getting value via input.value.
See also:
How to select JSF components using jQuery?
Update as per your update: you misunderstood the blog article. The special #{component} reference refers to the current component where the EL expression is been evaluated and this works only inside any of the attributes of the component itself. Whatever you want can also be achieved as follows:
var input = document.getElementById('#{emailAddress.clientId}');
with (note the binding to the view, you should absolutely not bind it to a bean)
<h:inputText binding="#{emailAddress}" />
but that's plain ugly. Better use the following approach wherein you pass the generated HTML DOM element as JavaScript this reference to the function
<h:inputText onclick="show(this)" />
with
function show(input) {
alert(input.value);
}
If you're using jQuery, you can even go a step further by abstracting them using a style class as marker interface
<h:inputText styleClass="someMarkerClass" />
with
$(document).on("click", ".someMarkerClass", function() {
var $input = $(this);
alert($input.val());
});
Answer: So this is the technique I'm happiest with. Doesn't require doing too much weird stuff to figure out the id of a component. Remember the whole point of this is so you can know the id of a component from anywhere on your page, not just from the actual component itself. This is key. I press a button, launch javascript function, and it should be able to access any other component, not just the one that launched it.
This solution doesn't require any 'right-click' and see what the id is. That type of solution is brittle, as the id is dynamically generated and if I change the page I'll have to go through that nonsense each time.
Bind the component to a backing bean.
Reference the bound component wherever you want.
So here is a sample of how that can be done.
Assumptions: I have an *.xhtml page (could be *.jsp) and I have defined a backing bean. I'm also using JSF 2.0.
*.xhtml page
<script>
function myFunc() {
var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}")
alert("The email address is: " + inputText.value );
}
</script>
<h:inputText binding="#{backBean.emailAddyInputText}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
BackBean.java
UIInput emailAddyInputText;
Make sure to create your getter/setter for this property too.
Id is dynamically generated, so you should define names for all parent elements to avoid j_id123-like ids.
Note that if you use jQuery to select element - than you should use double slash before colon:
jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
instead of:
jQuery("my-form-id:my-text-input-block:my-input-id")
In case of Richfaces you can use el expression on jsf page:
#{rich:element('native-jsf-input-id')}
to select javascript element, for example:
#{rich:element('native-jsf-input-id')}.value = "Enter something here";
You can view the HTML source when this is generated and see what the id is set to, so you can use that in your JavaScript. As it's in a form it is probably prepending the form id to it.
I know this is not the JSF way but if you want to avoid the ID pain you can set a special CSS class for the selector. Just make sure to use a good name so that when someone reads the class name it is clear that it was used for this purpose.
<h:inputText id="emailAddresses" class="emailAddressesForSelector"...
In your JavaScript:
jQuery('.emailAddressesForSelector');
Of course you would still have to manually manage class name uniqueness.
I do think this is maintainable as long as you do not use this in reusable components. In that case you could generate the class names using a convention.
<h:form id="myform">
<h:inputText id="name" value="#{beanClass.name}"
a:placeholder="Enter Client Title"> </h:inputText>
</h:form>
This is a small example of jsf. Now I will write javascript code to get the value of the above jsf component:
var x = document.getElementById('myform:name').value; //here x will be of string type
var y= parseInt(x,10); //here we converted x into Integer type and can do the
//arithmetic operations as well
I am currently trying to setup an editable data table that uses ajax to maintain focus when a user edits a cell using either JavaScript or a backing bean, because when a cell edit occurs data in other parts of the table will need to be updated, thus the table should be redrawn, unfocusing the focused element. Currently I'm trying to do this using a p:focus, using a CellEditEvent listener to get the component id. Unfortunately, assigning to the variable for the focused component id is not changing which element is focused on the page.
Here is the relevant HTML:
<h:form id="addForm">
<p:focus id="focusID" for="#{beanView.focus}" />
<h:panelGroup id="entrypg">
<p:commandButton id="updateButton" widgetVar="updateButton" update="addForm:myDT" />
<p:dataTable id="myDT" widgetVar="myDT" var="iter" value="#{beanView.valList}"
editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{beanView.onCellEdit}" oncomplete="$('#addForm\\\:updateButton').click();"/>
<p:column headerText="X">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{iter.x}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{iter.x}" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</h:panelGroup>
</h:form>
And the cell edit handler in the view:
public void onCellEdit(CellEditEvent edit) {
if(edit.getNewValue() != null) {
focus = edit.getColumn().getChildren().get(0).getClientId();
}
}
I am also open to better ways one could do this, as I'm unsureif p:focus is designed for this purpose.
Thanks!
Ok I've gotten it to work using widgets:
function forceFocus(index) {
var widget = PF('myDT');
widget.showCellEditor($('[role="gridcell"].ui-editable-column:eq(' + index + ')'));
}
The showCellEditor does pretty much exactly what I need, it highlights a cell and focuses it allowing immediate editing. It also seems to preserve focus between ajax calls.
More logic would be needed if you wanted to do this to a table with more than 1 editable column.
Edit: Ok it seems like its not storing the focus between table redraws, but it should be doable to grab the focus before the table is redrawn and restore it after its redrawn with the above function
Problem: Sometimes you will want to access a component from javascript with
getElementById, but id's are generated dynamically in JSF, so you
need a method of getting an objects id. I answer below on how you can do this.
Original Question:
I want to use some code like below. How can I reference the inputText JSF component in my Javascript?
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Input Name Page</title>
<script type="javascript" >
function myFunc() {
// how can I get the contents of the inputText component below
alert("Your email address is: " + document.getElementById("emailAddress").value);
}
</script>
</head>
<h:body>
<f:view>
<h:form>
Please enter your email address:<br/>
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
</h:form>
</f:view>
</h:body>
</html>
Update: this post Client Identifiers in JSF2.0 discusses using a technique like:
<script type="javascript" >
function myFunc() {
alert("Your email address is: " + document.getElementById("#{myInptTxtId.clientId}").value);
}
</script>
<h:inputText id="myInptTxtId" value="backingBean.emailAddress"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
Suggesting that the attribute id on the inputText component
creates an object that can be accessed with EL using #{myInptTxtId},
in the above example. The article goes on to state that JSF 2.0 adds
the zero-argument getClientId() method to the UIComponent class.
Thereby allowing the #{myInptTxtId.clientId} construct suggested
above to get the actual generated id of the component.
Though in my tests this doesn't work. Can anyone else confirm/deny.
The answers suggested below suffer from drawback that the above
technique doesn't. So it would be good to know if the above technique
actually works.
You need to use exactly the ID as JSF has assigned in the generated HTML output. Rightclick the page in your webbrowser and choose View Source. That's exactly the HTML code which JS sees (you know, JS runs in webbrowser and intercepts on HTML DOM tree).
Given a
<h:form>
<h:inputText id="emailAddresses" ... />
It'll look something like this:
<form id="j_id0">
<input type="text" id="j_id0:emailAddress" ... />
Where j_id0 is the generated ID of the generated HTML <form> element.
You'd rather give all JSF NamingContainer components a fixed id so that JSF don't autogenerate them. The <h:form> is one of them.
<h:form id="formId">
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
This way the form won't get an autogenerated ID like j_id0 and the input field will get a fixed ID of formId:emailAddress. You can then just reference it as such in JS.
var input = document.getElementById('formId:emailAddress');
From that point on you can continue using JS code as usual. E.g. getting value via input.value.
See also:
How to select JSF components using jQuery?
Update as per your update: you misunderstood the blog article. The special #{component} reference refers to the current component where the EL expression is been evaluated and this works only inside any of the attributes of the component itself. Whatever you want can also be achieved as follows:
var input = document.getElementById('#{emailAddress.clientId}');
with (note the binding to the view, you should absolutely not bind it to a bean)
<h:inputText binding="#{emailAddress}" />
but that's plain ugly. Better use the following approach wherein you pass the generated HTML DOM element as JavaScript this reference to the function
<h:inputText onclick="show(this)" />
with
function show(input) {
alert(input.value);
}
If you're using jQuery, you can even go a step further by abstracting them using a style class as marker interface
<h:inputText styleClass="someMarkerClass" />
with
$(document).on("click", ".someMarkerClass", function() {
var $input = $(this);
alert($input.val());
});
Answer: So this is the technique I'm happiest with. Doesn't require doing too much weird stuff to figure out the id of a component. Remember the whole point of this is so you can know the id of a component from anywhere on your page, not just from the actual component itself. This is key. I press a button, launch javascript function, and it should be able to access any other component, not just the one that launched it.
This solution doesn't require any 'right-click' and see what the id is. That type of solution is brittle, as the id is dynamically generated and if I change the page I'll have to go through that nonsense each time.
Bind the component to a backing bean.
Reference the bound component wherever you want.
So here is a sample of how that can be done.
Assumptions: I have an *.xhtml page (could be *.jsp) and I have defined a backing bean. I'm also using JSF 2.0.
*.xhtml page
<script>
function myFunc() {
var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}")
alert("The email address is: " + inputText.value );
}
</script>
<h:inputText binding="#{backBean.emailAddyInputText}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
BackBean.java
UIInput emailAddyInputText;
Make sure to create your getter/setter for this property too.
Id is dynamically generated, so you should define names for all parent elements to avoid j_id123-like ids.
Note that if you use jQuery to select element - than you should use double slash before colon:
jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
instead of:
jQuery("my-form-id:my-text-input-block:my-input-id")
In case of Richfaces you can use el expression on jsf page:
#{rich:element('native-jsf-input-id')}
to select javascript element, for example:
#{rich:element('native-jsf-input-id')}.value = "Enter something here";
You can view the HTML source when this is generated and see what the id is set to, so you can use that in your JavaScript. As it's in a form it is probably prepending the form id to it.
I know this is not the JSF way but if you want to avoid the ID pain you can set a special CSS class for the selector. Just make sure to use a good name so that when someone reads the class name it is clear that it was used for this purpose.
<h:inputText id="emailAddresses" class="emailAddressesForSelector"...
In your JavaScript:
jQuery('.emailAddressesForSelector');
Of course you would still have to manually manage class name uniqueness.
I do think this is maintainable as long as you do not use this in reusable components. In that case you could generate the class names using a convention.
<h:form id="myform">
<h:inputText id="name" value="#{beanClass.name}"
a:placeholder="Enter Client Title"> </h:inputText>
</h:form>
This is a small example of jsf. Now I will write javascript code to get the value of the above jsf component:
var x = document.getElementById('myform:name').value; //here x will be of string type
var y= parseInt(x,10); //here we converted x into Integer type and can do the
//arithmetic operations as well
I'm using a dropdown list inside tag
<td id="tdStatus" runat="server">
<asp:DropDownList ID="ddlStatus" runat="server" AutoPostBack="false">
</asp:DropDownList>
</td>
Now I need to select a particular item based on value returned from database.
I stored the value in variable ddl.
How can I identify this dropdown and select value using jQuery..?
I used the following code also, but not working..
$('#dropdownID').val("Value to be selected");
You should try this one:
$('#<%=ddlStatus.ClientID%>').val("Value to be selected");
The id of the dropdown in the markup that is generated by asp.net's view engine differs from the id you define in your markup, in order to access your server side control in your code behind class.
You are having ID attribute for td element. you can use:
$('#tdStatus select').val('set new val');
I am having issue with my js function within a ADF Faces af:interator. I have 3 controls within an af:iterator (af:ouputText, af:inputText, af:selectBooleanCheckBox) and I would like to have a js function on the checkbox so that when checking the checkbox, the text of the outputText will be copied into the inputText.
The issue here is that within the af:iterator, ADF will generate its own id or append a weird number for the ids and I am not sure if I should rely on those generated ids to write my js function. I know that I should be using PPR for this, but I can't.
You can use a combination of <af:clientAttribute/> and <af:clientListener/> and some javascript to achieve this behavior.
You will also need to set clientComponent to true on the <af:inputText/>.
This works in my test program.
<af:document id="d1">
<af:resource type="javascript">
function copyFromTo(evt) {
fromValue = evt.getSource().getProperty('fromValue');
fromIndex = evt.getSource().getProperty('fromIndex');
// iterator ID, then fromIndex, then inputText ID
id = 'i1:'+fromIndex+':it1';
inputComponent = AdfPage.PAGE.findComponentByAbsoluteId(id);
inputComponent.setValue(fromValue);
}
</af:resource>
<af:form id="f1">
<af:panelStretchLayout id="psl1">
<f:facet name="center">
<af:iterator id="i1" value="#{PageBean.outputTextValues}" var="row" varStatus="rowStatus">
<af:panelGroupLayout id="pgl1" layout="horizontal">
<af:selectBooleanCheckbox label="Copy" id="sbc1">
<af:clientAttribute name="fromValue" value="#{row}"/>
<af:clientAttribute name="fromIndex" value="#{rowStatus.index}"/>
<af:clientListener method="copyFromTo" type="click"/>
</af:selectBooleanCheckbox>
<af:spacer width="10" height="10" id="s1"/>
<af:outputText value="#{row}" id="ot1"/>
<af:spacer width="10" height="10" id="s2"/>
<af:inputText label="Label 1" id="it1" value="none" clientComponent="true"/>
</af:panelGroupLayout>
</af:iterator>
<!-- id="af_one_column_stretched" -->
</f:facet>
</af:panelStretchLayout>
</af:form>
</af:document>
Why cant you use PPR? The js IDs should not be relied upon at all, and they will change when lets say you decide to put your taskflow in a region or inside a portlet.
The field values should be based on VO attributes, if they are not DB backed, you can create a transient VO. then update the values on the VO and call
AdfFacesContext.getCurrentInstance().addPartialTarget(JSFUtils.findComponent("<comp_id of parent component>"));