Issue with the second AJAX request!!

UI Components for JSF
Post Reply
schowla
Posts: 10
Joined: 20 Nov 2013, 01:20

21 Jul 2014, 20:30

Hello,

We have an issue with Ajax in jsf/primefaces application. We are using Primefaces 3.5 with JBoss EAP 6.1.

Below is our scenario.

Primefaces Panel -> Panel Grid (2 columns) -> Label & primefaces input element (Textbox/Checkbox/RadioButton etc). On change of any input element, we have an ajax call, we process the input and oncomplete of the respective ajax action with the help of an update attribute, we are updating the parent panel.
Based on the answer we show/hide sub questions inside the same panel. While Ajax request is in progress, if user performs any subsequent action on other input elements (select checkboxes or radio buttons) on same page the result of this request is not getting retained.
Once the panel gets updated for first ajax request, the data entered by user as part of second action is getting lost. We have tried to solve this issue by trying both async="true" and async="false".

Could anyone please suggest how to fix this issue? Please let me know if you need me to provide any information to understand this issue.

Source code:

PrimePost.xhtml:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
	<h:form prependId="false" id="inputForm">
		<h:outputText id="outputTextClearload">
			<f:event id="event1" type="javax.faces.event.PreRenderComponentEvent"
				listener="#{inputAction.initializeQuestions}" render="false" />
		</h:outputText>
		<p:panel id="inputPanel">
			<ui:repeat var="question" value="#{inputBean.questionList}"
				varStatus="status">
				<h:panelGrid columns="2" border="0" id="questiongrid"
					rendered="#{!question.hideQuestion}">
					<h:panelGroup id="questionLabelPanelGroup">
						<p:outputLabel value="#{question.questionLable} :"
							id="outputLabel" />
					</h:panelGroup>
					<h:panelGroup id="componentPanelGroup">
						<p:inputText value="#{question.textAnswer}" id="textQuestion1"
							rendered="#{question.questionType == 'TXT'}">
							<p:ajax event="change" update=":inputForm:inputPanel"
								listener="#{inputAction.processTextAnswer(question)}" />
							<f:param id="questionId" name="questionId" value="#{question.id}"></f:param>
						</p:inputText>
						<p:selectBooleanCheckbox value="#{question.textAnswer}"
							id="selectBooleanCheckBoxMain"
							rendered="#{question.questionType == 'CHK'}">
							<p:ajax event="change" update=":inputForm:inputPanel"
								listener="#{inputAction.processTextAnswer(question)}" />
							<f:param id="questionId1" name="questionId"
								value="#{question.id}"></f:param>
						</p:selectBooleanCheckbox>
					</h:panelGroup>
				</h:panelGrid>
			</ui:repeat>
		</p:panel>
		<p:ajaxStatus style="width:64px;height:64px;position:fixed;right:5px;bottom:5px" id="ajaxStatusPanel">
			<f:facet name="start">
				<h:graphicImage value="/image/default/loading.gif" />
			</f:facet>
			<f:facet name="complete">
				<h:outputText value="" />
			</f:facet>
		</p:ajaxStatus>		
	</h:form>
</h:body>
</html>
InputAction.java:

Code: Select all

package com.primefaces.test;


import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;

/*
 * Change log:
 * 
 * Jun 21, 2013 Initial version
 */
@RequestScoped
@ManagedBean
public class InputAction {

	public void processTextAnswer(Question question) {
		String questionType = question.getQuestionType();
		System.out.println("processTextAnswer:"+questionType);
		InputBean inputBean = (InputBean) this
				.getManagedBean(InputBean.name);
		Question question3 = new Question("3",false, "Question 3", "false", "CHK");
		List<Question> questionList = inputBean.getQuestionList();
		questionList.add(question3);
		try {
		    Thread.sleep(10000);
		} catch(InterruptedException ex) {
		    Thread.currentThread().interrupt();
		}
	}
	
	public void initializeQuestions(ComponentSystemEvent event) {
		InputBean inputBean = (InputBean) this
				.getManagedBean(InputBean.name);
		if (inputBean == null) {
			inputBean = new InputBean();
		}
		
		Question question1 = new Question("1",false, "Question 1", "", "TXT");
		Question question2 = new Question("2",false, "Question 2", "false", "CHK");
		
		List<Question> questionList = new ArrayList<Question>();
		questionList.add(question1);
		questionList.add(question2);
		inputBean.setQuestionList(questionList);
	}
	
	/**
	 * Return the managed bean with the given name
	 * 
	 * @param mgdBeanName
	 *            the name of the managed bean to retrieve
	 * @return
	 */
	protected Object getManagedBean(String mgdBeanName) {
		String expression = "#{" + mgdBeanName + "}";
		return resolveExpression(expression);
	}
	
	/**
	 * Return the result of the resolved expression
	 * 
	 * @param expression
	 * @return
	 */
	protected Object resolveExpression(String expression) {
		Object value = null;
		if ((expression.indexOf("#{") != -1)
				&& (expression.indexOf("#{") < expression.indexOf('}'))) {
			value = getFacesContext()
					.getApplication()
					.getExpressionFactory()
					.createValueExpression(getFacesContext().getELContext(),
							expression, Object.class)
					.getValue(getFacesContext().getELContext());
		} else {
			value = expression;
		}
		return value;
	}
	
	/**
	 * This method will return the faces context object.
	 * 
	 * @return
	 */
	public FacesContext getFacesContext() {
		return FacesContext.getCurrentInstance();
	}
}
InputBean.java:

Code: Select all

package com.primefaces.test;

import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class InputBean {
	
	public static final String name = "inputBean";
	
	private List<Question> questionList;

	public List<Question> getQuestionList() {
		return questionList;
	}

	public void setQuestionList(List<Question> questionList) {
		this.questionList = questionList;
	}
}
Question.java:

Code: Select all

package com.primefaces.test;

import java.io.Serializable;

public class Question implements Serializable {

	private static final long serialVersionUID = -7965863451830961041L;
	
	private String id;
	
	private boolean hideQuestion;
	
	private String questionLable;
	
	private String textAnswer;
	
	private String questionType;

	public Question(String id, boolean hideQuestion, String questionLable,
			String textAnswer, String questionType) {
		super();
		this.id = id;
		this.hideQuestion = hideQuestion;
		this.questionLable = questionLable;
		this.textAnswer = textAnswer;
		this.questionType = questionType;
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}


	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}


	/**
	 * @return the hideQuestion
	 */
	public boolean isHideQuestion() {
		return hideQuestion;
	}

	/**
	 * @param hideQuestion the hideQuestion to set
	 */
	public void setHideQuestion(boolean hideQuestion) {
		this.hideQuestion = hideQuestion;
	}

	/**
	 * @return the questionLable
	 */
	public String getQuestionLable() {
		return questionLable;
	}

	/**
	 * @param questionLable the questionLable to set
	 */
	public void setQuestionLable(String questionLable) {
		this.questionLable = questionLable;
	}

	/**
	 * @return the textAnswer
	 */
	public String getTextAnswer() {
		return textAnswer;
	}

	/**
	 * @param textAnswer the textAnswer to set
	 */
	public void setTextAnswer(String textAnswer) {
		this.textAnswer = textAnswer;
	}

	/**
	 * @return the questionType
	 */
	public String getQuestionType() {
		return questionType;
	}

	/**
	 * @param questionType the questionType to set
	 */
	public void setQuestionType(String questionType) {
		this.questionType = questionType;
	}
}
Last edited by schowla on 28 Jul 2014, 17:33, edited 5 times in total.

kukeltje
Expert Member
Posts: 9605
Joined: 17 Jun 2010, 13:34
Location: Netherlands

21 Jul 2014, 20:54

Please edit your post and use code tags. But also use correct indentation. And make it as minimal as possible (e.g. is the tooltip required? Remove styling, replace EL with fixed values were possible etc) and make it fully working as well (no code 'snippets') and if possible provide a bean as well, fully (imports, annotations) but also as minimal as possible (no dependencies on databases, external frameworks, remove all unrelevant methods etc)

schowla
Posts: 10
Joined: 20 Nov 2013, 01:20

21 Jul 2014, 22:47

Ronald, Thanks for your reply. Edited my post as per your comments.

schowla
Posts: 10
Joined: 20 Nov 2013, 01:20

28 Jul 2014, 17:32

Narrowed down the issue. When there are multiple ajax events triggering from same parent container which updates the same component post request (using update attribute), in this scenario the second ajax request is not being submitted at all.

If I keep first ajax request's action method in sleeping mode (Using Thread.sleep()), then second ajax request is getting triggered successfully if I use "async=true".

Is this standard behavior of Ajax?

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 27 guests