Bonjour à tous,
J'ai un problème lorsque j'utilise a4j:jsFunction et une datatable.
Fonctionnellement :
J'ai une page avec un input field et un lien 'Rechercher'. Il faut appuyer sur Entrée pour envoyer le formulaire. Les résultats de recherche sont affichés juste en dessous de l'input text. Lorsque quelque chose est écrit dans ce champ, un message doit apparaître signalant que le champ à été modifié et que les résultats affichés ne correspondent plus aux critères de recherche.
Le problème :
Lorsque l'input text est modifié et qu'on soumet rapidement le formulaire en appuyant sur Entrée, parfois, j'ai une NullPointerException. J'imagine que c'est à cause du call Ajax qui n'est pas complètement terminé et qui modifie peut-être mon bean.
Tout se passe bien si j'attend quelques secondes, le temps que le message s'affiche.
Je pense que c'est la partie la plus importante du stacktrace :
Voici quelques détails :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 java.lang.IllegalArgumentException: row is unavailable at javax.faces.model.ListDataModel.getRowData(ListDataModel.java:66) at org.ajax4jsf.model.SequenceDataModel.getRowData(SequenceDataModel.java:147) at org.ajax4jsf.component.UIDataAdaptor.getRowData(UIDataAdaptor.java:242) at be.cm.apps.prest.beans.prestations.SearchPrestationBean.getCurrentInteger(SearchPrestationBean.java:111)
L'input field a un event onkeyup qui appelle une fonction javascript (addSynchronizationErrorMessage()) que j'ai écrit moi même. Cette fonction appelle à son tour une autre fonction javascript (addSynchronizationErrorMessageAjaxCall()). Cette dernière n'est pas quelque chose que j'ai écrit moi-même : c'est une fonction générée par Richfaces a4j:jsFunction.
Ci-dessous vous trouverez le code qui pose problème. J'ai essayé de le réduire au maximum pour que ce soit facile de reproduire le problème. J'ai lu que je pouvais utiliser certaines choses pour résoudre le problème (ignoreDupresponse, limitToList, a4j:form, ...) mais aucune solution n'a fonctionné jusqu'à présent.
Nous utilisons les librairies suivantes : MyFaces 1.1.5, Tomahawk 1.1.9, jQuery 1.5.2, RichFaces 3.1.6.
Le code jsp :
Et voici le code de mon bean :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%> <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%> <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%> <f:view> <f:loadBundle var="msg" basename="be.apps.bundle.messages"/> <html> <body onkeydown="return search(event)" onload="setFocusOnLoadInScreen();"> <h:form id="actionForm0"> <t:div id="messagesPanel"> <t:messages id="errorMessage" globalOnly="false" showDetail="false" forceIdIndex="true"/> </t:div> <a4j:jsFunction name="addSynchronizationErrorMessageAjaxCall" action="#{searchPrestationBean.addDivergenceBetweenSearchCriteriaAndResultsMessage}" reRender="actionForm0:messagesPanel" immediate="true" /> <h:inputText id="origin" value="#{searchPrestationBean.origin}" onkeyup="addSynchronizationErrorMessage();" /> <t:commandLink id="defaultButton" value="#{msg.global_search}" action="#{searchPrestationBean.search}" /> <rich:dataTable id="dataTableInfoPanels" value="#{searchPrestationBean.integers}" binding="#{searchPrestationBean.dataTable}"> <rich:column> <t:htmlTag value="nobr"> <h:outputText value="#{searchPrestationBean.displayInfo}" /> </t:htmlTag> </rich:column> </rich:dataTable> </h:form> </body> </html> </f:view>
Que feriez-vous ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 import java.util.Arrays; import java.util.List; import java.util.Random; import org.richfaces.component.html.HtmlDataTable; import be.cm.apps.prest.faces.beans.AbstractScreenBean; public class SearchPrestationBean extends AbstractScreenBean { private List<Integer> integers; private HtmlDataTable dataTable; private String origin; private Integer randomInteger; public SearchPrestationBean() { } /** * {@inheritDoc} */ @Override public String initPage() { randomInteger = null; return "searchPrestation"; } public void addDivergenceBetweenSearchCriteriaAndResultsMessage() { getCommonHelper().addMessage("validation.error.searchAndResultSynchronization"); } public String search() { Random random = new Random(); setIntegers(Arrays.asList(new Integer(random.nextInt()))); return null; } public String getOrigin() { return this.origin; } public void setOrigin(String origin) { this.origin = origin; } public String getDisplayInfo() { randomInteger = getCurrentInteger(); return randomInteger.toString(); } public HtmlDataTable getDataTable() { return this.dataTable; } public void setDataTable(HtmlDataTable dataTable) { this.dataTable = dataTable; } public Integer getCurrentInteger() { if (dataTable != null) { return (dataTable.getRowCount() != 0 ? (Integer) dataTable.getRowData() : null); } return null; } public List<Integer> getIntegers() { return this.integers; } public void setIntegers(List<Integer> integers) { this.integers = integers; }
Merci d'avance pour votre aide !
Nis.
Partager