I'm setting an input component from my bean
In my bean
public void InicializarCronometro(ComponentSystemEvent e) {
HtmlForm form = (HtmlForm) e.getComponent();
UIInput input = new HtmlInputText();
input.setId("cronoInput"); // Must be unique!
input.setValueExpression("value", createValueExpression("#{jugarPartidoAdmBean.labelCrono}", String.class));
form.getChildren().add(input);
}
private ValueExpression createValueExpression(String valueExpression, Class<?> valueType) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getExpressionFactory()
.createValueExpression(context.getELContext(), valueExpression, valueType);
}
In my xhtml file:
<b:navBar brandHref="indexAdm.xhtml" inverse="true" fixed="bottom" sticky="false">
<b:navbarLinks>
<h:form id="footForm" styleClass="navbar-form navbar-right">
<f:event type="postAddToView" listener="#{jugarPartidoAdmBean.InicializarCronometro}" />
<b:row>
<b:column col-xs="12" col-sm="3" col-md="4" />
<b:column col-xs="12" col-sm="3" col-md="8" offset="12">
<b:commandButton value="Comensar" look="success" action="#{jugarPartidoAdmBean.ComensarPartido()}" style="margin-left: 10%;" />
</b:column>
</b:row>
</h:form>
</b:navbarLinks>
</b:navBar>
When I press the button I call this method to start the crono
public void ComensarPartido() {
Cronometro crono = new Cronometro(0, 0);
crono.addObserver(this);
Thread t = new Thread(crono);
t.start();
}
The crono class works fine and in my beAN I implemente Observer and in the update method I have this:
#Override
public void update(Observable o, Object arg) {
this.setLabelCrono((String) arg);
//InicializarCronometro(new HtmlInputText());
System.out.println(this.getLabelCrono());
}
in the line this. setLbaelCrono((String) arg) I'm setting the counter 00:00, 00:01, 00:02... etc.
I want to update my input component to show the crono but I don't getting that result the input component remain in 00:00 that it's tha value of "labelCrono" by default.
What do I need to do to update the component in my view.??
Related
I am trying to highlight an p:inputText (used to hold an email address) if this value doesn't match the value which came from the database. Here is my java code :
private UIInput gUiInputemailAdd; //global variable
public void validateCredentials(ComponentSystemEvent event) {
UIComponent components = event.getComponent();
UIInput uiInputemailAdd = (UIInput) components.findComponent("emailAdd");//ID of textbox
gUiInputemailAdd = uiInputemailAdd;
// uiInputemailAdd.setValid(false);//works fine here(it highlights this particular textBox)
}
public boolean forgotPasswordValidator(UserDetailTO userDetailTO)
throws MessagingException {
if (!gEmailAddress.equalsIgnoreCase(userDetailTO.getEmailAddress())) {
System.out.println(gUiInputemailAdd.getValue().toString()); //works fine and print value
gUiInputemailAdd.setValid(false);//doesn't work here
}
}
Xhtml code:-
<p:outputLabel for="emailAdd" value="EmilAddresss" />
<p:inputText value="#{loginTo.emailAddress}" id="emailAdd"/>
Please help me on this I have been stuck here for so long.
so I have an extendedDataTables as follows(Code is shortened to keep it straightforward).
<rich:extendedDataTable value="#{package.packageList}" var="o"
styleClass="listStyle" selection="#{package.selection}"
selectionMode="single">
<a4j:ajax execute="#form" event="selectionchange"
listener="#{package.selectionListener}" render=":res" />
<rich:column>
<f:facet name="header">Package ID</f:facet>
#{o.packageID}
</rich:column>
</rich:extendedDataTable>
So when the user clicks on this it outputs the details of it to another table inside the a4j:outputPanel that follows.
<a4j:outputPanel id="res">
<rich:panel header="Selected Package"
rendered="#{not empty package.selectionPackage}">
</rich:panel>
</a4j:outputPanel>
This part works. However this new detail now contains several variables and also an arrayList of objects with which I need to also be able to select. So this arrayList generates its own extendedDataTable which I need to then select and retrieve its information. This part is where it is breaking. What I have attempted so far looks as follows.
<a4j:outputPanel id="res">
<rich:panel header="Selected Package"
rendered="#{not empty package.selectionPackage}">
<rich:dataTable value="#{package.selectionPackage}"
var="extensionTable" styleClass="listStyle" selectionMode="single">
<rich:column>
<rich:extendedDataTable value="# {extensionTable.extensionList}"
var="selectedExtension" styleClass="listStyle" style="height:200px;"
selection="#{package.extensionSelection}" selectionMode="single">
<a4j:ajax execute="#form" event="selectionchange"
listener="#{package.selectionExtensionListener}" render=":extensions" />
<rich:column>
<f:facet name="header">Extension Add on list</f:facet>
#{selectedExtension.extensionName}"
</rich:column>
</rich:extendedDataTable>
</rich:column>
</rich:dataTable>
</rich:panel>
</a4j:outputPanel>
I have another a4j panel to handle the new extensions selected object. The problem is that my selectedExtensionListener is not being called. I do not know why, is what I am trying even possible. The selection is working as the rows are changing colour however the selectionExtensionListener is never being called. I have some system.out.printlnts in just to check and whereas the first listener is being called the second one is not. Forgive me if this is obvious or not even possible but I am relatively new to jsf. Any help would be greatly appreciated.
I will copy and paste my bean below to show you the backend of the code. I will exclude declaring all of my variables and populating my lists and objects etc as it will just clog up the code, if you need them just let me know and I will edit them in. (Sorry for formatting, I do not know if you can format code here?)
public class Package implements Serializable{
public void selectionListener(AjaxBehaviorEvent event) {
System.out.println("In selection listener");
UIExtendedDataTable dataTable = (UIExtendedDataTable) event.getComponent();
Object originalKey = dataTable.getRowKey();
selectionPackage.clear();
for (Object selectionKey : selection) {
dataTable.setRowKey(selectionKey);
if (dataTable.isRowAvailable()) {
selectionPackage.add((PackageClass) dataTable.getRowData());
}
}
dataTable.setRowKey(originalKey);
}
public void selectionExtensionListener(AjaxBehaviorEvent event) {
System.out.println("Testing 1");
UIExtendedDataTable dataTable = (UIExtendedDataTable) event.getComponent();
Object originalKey = dataTable.getRowKey();
selectionExtension.clear();
for (Object selectionKey : extensionSelection) {
dataTable.setRowKey(selectionKey);
if (dataTable.isRowAvailable()) {
System.out.println("Testing 2");
selectionExtension.add((ExtensionClass) dataTable.getRowData());
}
}
dataTable.setRowKey(originalKey);
}
public Collection<Object> getSelection() {
return selection;
}
public void setSelection(Collection<Object> selection) {
this.selection = selection;
}
public Collection<Object> getExtensionSelection() {
return extensionSelection;
}
public void setExtensionSelection(Collection<Object> extensionSelection) {
this.extensionSelection = extensionSelection;
}
public List<PackageClass> getPackageList() {
return packageList;
}
public void setPackageList(ArrayList<PackageClass> packageList) {
this.packageList = packageList;
}
public PackageClass getSelectionPackage() {
if (selectionPackage == null || selectionPackage.isEmpty()) {
return null;
}
return selectionPackage.get(0);
}
public void setSelectionPackage(ArrayList<PackageClass> selectionPackage) {
this.selectionPackage = selectionPackage;
}
public ArrayList<PackageClass> getSelectionPackages() {
return selectionPackage;
}
public ExtensionClass getSelectionExtension() {
if (selectionExtension == null || selectionExtension.isEmpty()) {
return null;
}
return selectionExtension.get(0);
}
public void setSelectionExtension(ArrayList<ExtensionClass> selectionExtension) {
this.selectionExtension = selectionExtension;
}
public ArrayList<ExtensionClass> getSelectionExtensions() {
return selectionExtension;
}
}
I started using the poll component of Primefaces. Goal: refresh a confirmDialog window which acts as a progress bar. The xhtml:
<h:form id="pbForm" prependId="false">
<p:confirmDialog id ="progressBar" message= ""
header="Retrieving information..."
widgetVar="pbar"
severity="info">
<h:outputText id="PBlaunch" value="#{pBLaunchSearch.getLaius()}"/>
<p:poll interval="1" update="PBlaunch" />
</p:confirmDialog>
</h:form>
My bean for the progress bar:
#ManagedBean
#RequestScoped
public class PBLaunchSearch {
private static StringBuilder sb = new StringBuilder();
public static void setLaius(String toAdd) {
sb.append(toAdd);
sb.append("<br>");
}
public static String getLaius() {
return sb.toString();
}
public static void resetLaius() {
sb = new StringBuilder();
}
}
The operation which takes time in the background is a few API calls. After each API call that finishes, I have this command:
PBLaunchSearch.setLaius("another API call returned");
Problem: the confirmDialog remains empty (outputText id="PBlaunch" remains empty) until all the API calls have been made, at which point all the messages appear at once (but too late...)
Any clue as to why?
I am using JSF 1.2 framework. Right now i am trying to implement a file upload process in which the number of files to be uploaded is controlled by the end user. Please find the below snapshot and code snippet for reference.
XHTML Implementation:-
<a4j:commandLink action="#{importWSDLBean.xsdLoopIncrementAction}" reRender="WSDLPanelGrid">
<h:graphicImage value="/images/plus_icon.gif" />
</a4j:commandLink>
<a4j:commandLink action="#{importWSDLBean.xsdLoopDecrementAction}" reRender="WSDLPanelGrid">
<h:graphicImage value="/images/minus_icon.gif" />
</a4j:commandLink>
<h:panelGrid id="WSDLPanelGrid">
<c:forEach items="#{importWSDLBean.acscDataList}" var="inputFUpload">
<t:inputFileUpload id="#{inputFUpload.id}" value="#{inputFUpload.value}" />
</c:forEach>
</h:panelGrid>
Java Bean Implementation:-
public String xsdLoopIncrementAction() {
if (acscDataList == null) {
acscDataList = new ACSCDataList(new ArrayList());
HtmlInputFileUpload htmlUpload = new HtmlInputFileUpload();
htmlUpload.setId("upload" + (acscDataList.size() + 1));
acscDataList.add(htmlUpload);
} else {
HtmlInputFileUpload htmlUpload = new HtmlInputFileUpload();
htmlUpload.setId("upload" + (acscDataList.size() + 1));
acscDataList.add(htmlUpload);
}
return "success";
}
public String xsdLoopDecrementAction() {
if (acscDataList != null) {
if (acscDataList.size() > 0) {
acscDataList.remove(acscDataList.size() - 1);
}
}
return "success";
}
This implementation resets the file upload values whenever i increment or decrement the no. of file upload fields. Also when i submit the form i cant able to get the UploadedFile object (File Upload prerequisite such as Form type and Web.xml configuration is also included).
Can anyone help me out?
If you create dinamically yours input uploads? with binding property
<h:panelGrid binding="#{importWSDLBean.myPanelGrid}"></h:panelGrid>
in your backing bean add property
private javax.faces.component.html.HtmlPanelGrid myPanelGrid;
/**
* #return the myPanelGrid
*/
public javax.faces.component.html.HtmlPanelGrid getMyPanelGrid() {
return myPanelGrid;
}
/**
* #param myPanelGrid the myPanelGrid to set
*/
public void setMyPanelGrid(javax.faces.component.html.HtmlPanelGrid myPanelGrid) {
this.myPanelGrid = myPanelGrid;
}
/*change for your value upload type*/
Map<String,Object> values = new LinkedHashMap<String, Object>();
public void addInputAction() {
String key = "key"+values.size();
values.put(key,"newValue");
HtmlInputText input = new HtmlInputText();
/*add input property (converter,css,etc?)*/
input.setId("id_"+key);
input.setValueExpression("value", createValueExpression(
"#{WSDLPanelGrid.values['"+key+"']}", new Class[0], String.class));
/*add to panel grid your input*/
myPanelGrid.getChildren().add(input);
}
public static ValueExpression createValueExpression(String value,
Class[] params, Class returnType) {
FacesContext fctx = FacesContext.getCurrentInstance();
ELContext elctx = fctx.getELContext();
Application jsfApp = fctx.getApplication();
ExpressionFactory exprFactory = jsfApp.getExpressionFactory();
ValueExpression valueExpr = exprFactory.createValueExpression(elctx,
value, returnType);
return valueExpr;
}
Does something prevent you from using JSF 2? Primefaces ( www.primefaces.org ) has a multiple fileupload component. It is available for JSF 1.2, but development will go on for JSF 2 only.
I am having a problem with custom components in facelets. The first time that the page is rendered, the attributes are set properly on the component class. When a form is submitted however, the attributes are not set.
Here is the class that I am using to test this.
public class TestEcho extends UIData
{
/** Logger. */
private static Log log = LogFactory.getLog(TestEcho.class);
private String msg;
public TestEcho()
{
log.debug("Constructor.");
}
public void encodeEnd(FacesContext context) throws IOException
{
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeText("The value of msg is '" + msg + "'.", null);
writer.endElement("div");
}
public void setMsg(String msg)
{
log.debug("Setting msg to '" + msg + "'.");
this.msg = msg;
}
}
The component is used in the .xhtml page like this.
<h:form>
<v:testEcho msg="hello" />
<h:commandButton action="#{PictureManager.trigger}" value="Click" />
</h:form>
When the page renders for the first time, the component renders the following html code.
<div>The value of msg is 'hello'.</div>
When the button is clicked, it renders this.
<div>The value of msg is 'null'.</div>
From the log, you can see that the component is constructed again, but the attribute is not set.
13:23:42,955 DEBUG [TestEcho] Constructor.
13:23:42,955 DEBUG [TestEcho] Setting msg to 'hello'.
----- Button was pressed here -----
13:25:48,988 DEBUG [TestEcho] Constructor.
13:25:49,144 DEBUG [PictureManager] Button pressed.
From what I understand, facelets does all the wiring of attributes to components so I don't need a tag class, but I don't understand why the attribute would be set correctly the first time, but not the second time.
You must save your state by overriding the saveState and restoreState methods.
So, saveState must return a Serializable object (e.g. a JavaBean or Object[] array) containing the value in msg and whatever is returned by super.saveState. This object will be provided to restoreState where the method must restore msg from the object and pass the parent state to super.restoreState.
McDowell's answer did it. Just for completeness, here's the two methods I added.
public Object saveState(FacesContext context)
{
Object[] rtrn = new Object[2];
rtrn[0] = super.saveState(context);
rtrn[1] = msg;
return rtrn;
}
public void restoreState(FacesContext context, Object state)
{
Object[] values = (Object[]) state;
super.restoreState(context, values[0]);
msg = (String) values[1];
}