mfe
8. Oktober 2013 um 12:32
1
Hallo,
ich habe in meinem Bean eine List und diese möchte ich nun darstellen. Ich habe das momentan so:
<ul ><!--
<for:forEach id="steps" items="#{RecipeBean.recipe.steps}" var="step">
<li> <com:Step description="#{step.stepDescription}" removeText="#{msg['step.delete']}" removeAction="#{RecipeBean.removeStep(step)}"
Quantities="#{step.quantity}" addText="#{msg['quantity.add']}" addAction=""/></li>
</for:forEach>-->
<p:commandButton id="addstep"/>
</ul>
Das klappt eigentlich auch gut. Wenn man auf den Button AddStep klick soll eine Step zur liste hinzugefügt werden. Das soll per ajax geschehen. Nur das Problem ist mit dem forEach kann ich die angezeigte Step “html Liste” nicht updaten. Bei den Primfaces habe ich das Control p: DataList gesehen, allerdings bekomme ich mit diesem Control mein com:Step Composite Component nicht hinein. Auch würden die
fehlen. Hat jemand eine Idee wie ich das Problem lösen kann?
for:foreach? Meinst Du c:foreach?
Es gibt auch ein ui:repeat .
mfe
9. Oktober 2013 um 00:01
3
Ich habe das forEach durch das ui:repeat ersetzt, aber wenn ich auf den Button klicke und ein Element zur liste hinzufüge wird das ui:repeat nicht upgedated.
Das uiRepeat hat als id steps.
<p:commandButton id="addstep" action="#{RecipeBean.addStep}" update="steps"/>
Ich kann nur für Primefaces sprechen, aber hier gilt explizit: ui:repeat macht mit Ajax Updates Probleme und sollte deshalb nicht eingesetzt werden, hier ist die DataList Standard. Die
würde man hier auch hinein bekommen.
Aus welcher Bibliothek kommt denn dein com:Step/ ?
mfe
9. Oktober 2013 um 00:26
5
Wenn ich von Primefaces die DataList verwende verhält sich meine com:Step/ Component falsch.
Also aussehen tut das ganze so:
<p:dataList id="steps" value="#{RecipeBean.recipe.steps}" var="step" itemType="disc">
<com:Step description="#{step.stepDescription}" removeText="#{msg['step.delete']}" removeAction="#{RecipeBean.removeStep(step)}"
Quantities="#{step.quantity}" addText="#{msg['quantity.add']}" addAction="#{RecipeBean.addQuantity(step)}"/>
</p:dataList>
<p:commandButton id="addstep" value="#{msg['step.add']}" action="#{RecipeBean.addStep}" update="steps"/>
Step:
<?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:cc="http://xmlns.jcp.org/jsf/composite"
xmlns:com="http://xmlns.jcp.org/jsf/composite/Get.comp"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:for="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
>
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="stepId" type="int" shortDescription="id of the step" />
<cc:attribute name="description" type="String" required="true" />
<cc:attribute name="removeText" type="String" />
<cc:attribute name="removeAction" method-signature="java.lang.String action()" />
<cc:attribute name="Quantities" type="java.util.List" shortDescription="contains information about ingredients and their quantitie (List Quantity)" />
<cc:attribute name="addText" type="String" />
<cc:attribute name="addAction" />
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<h:form>
<h:inputHidden id="id" value="#{cc.attrs.stepId}" />
<p:inplace widgetVar="basic_#{cc.id}">
<p:inputText value="#{cc.attrs.description}" id="description">
<p:ajax event="blur" oncomplete="basic_#{cc.id}.hide();" />
</p:inputText>
</p:inplace>
<h:commandButton id="removeStep" action="#{cc.attrs.removeAction}" value="#{cc.attrs.removeText}" />
<!-- show Quantities -->
<ul>
<p:dataList id="quantities" value="#{cc.attrs.Quantities}" var="quantity" itemType="disc">
<com:Quantity Amount="#{quantity.amount}" Measurement="#{quantity.getMeasurement()}" Ingredient="#{quantity.getIngredient()}" />
</p:dataList>
<li> <h:commandButton id="addQuantity" action="#{cc.attrs.addAction}" value="#{cc.attrs.addText}" /> </li>
</ul>
</h:form>
</cc:implementation>
</html>
Das Problem mit der DataList Lösung: Das p:inplace und das auto hide mit dem “<p:ajax event=“blur” oncomplete=“basic_#{cc.id}.hide();” />” funktioniert nur mit dem letzten Element in der DataList. Klicke ich in der DataList ein anderes step Element an um den Text description zu ändern, wird auto. das letzte Element in der Liste aktiv.
Außerdem zeigt er nicht alle Control vom <com:Quantity /> an. Mit dem forEach hat das alles noch funktioniert.
[EDIT]:
Wenn ich die foreach im Steps ebenfalls durch ein DataList ersetze werden die Controls angezeigt. Habe den Quellcode ebenfalls ausgebessert. Das Verhalten von <p:inplace/> funktioniert noch nicht mit der <p: DataList/>
Zeig mal bitte den generierten Quellcode. Bist du sicher, dass die widgetvar Attribute sauber durchnumeriert werden?
mfe
9. Oktober 2013 um 00:49
7
Ich habe nach doppelten ID’s gesucht aber keine gefunden, aber vlt. habe ich die auch übersehen:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><link type="text/css" rel="stylesheet" href="/wie-koche-ich/javax.faces.resource/theme.css.xhtml?ln=primefaces-aristo" /><link type="text/css" rel="stylesheet" href="/wie-koche-ich/javax.faces.resource/primefaces.css.xhtml?ln=primefaces" /><script type="text/javascript" src="/wie-koche-ich/javax.faces.resource/jquery/jquery.js.xhtml?ln=primefaces"></script><script type="text/javascript" src="/wie-koche-ich/javax.faces.resource/primefaces.js.xhtml?ln=primefaces"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="resources/css/default.css" rel="stylesheet" type="text/css" />
<link href="resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
<title>Facelets Template</title></head><body>
<div id="top" class="top">Top
</div>
<div id="content" class="center_content">
<form id="j_idt8" name="j_idt8" method="post" action="/wie-koche-ich/editRecipe.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt8" value="j_idt8" />
<input id="j_idt8:recipename" type="text" name="j_idt8:recipename" value="SPÄTZLE OHNE EI" />
<div id="j_idt8:steps" class="ui-datalist ui-widget"><div id="j_idt8:steps_content" class="ui-datalist-content ui-widget-content"><ul id="j_idt8:steps_list" class="ui-datalist-data" type="disc"><li class="ui-datalist-item"><html xmlns="http://www.w3.org/1999/xhtml">
<!-- INTERFACE -->
<!-- IMPLEMENTATION -->
<form id="j_idt8:steps:0:j_idt13:j_idt14" name="j_idt8:steps:0:j_idt13:j_idt14" method="post" action="/wie-koche-ich/editRecipe.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt8:steps:0:j_idt13:j_idt14" value="j_idt8:steps:0:j_idt13:j_idt14" />
<input id="j_idt8:steps:0:j_idt13:j_idt14:id" type="hidden" name="j_idt8:steps:0:j_idt13:j_idt14:id" />
<!-- http://stackoverflow.com/questions/19198273/hide-inputtext-on-lost-focus-with-pinplace --><span id="j_idt8:steps:0:j_idt13:j_idt14:j_idt16" class="ui-inplace ui-hidden-container"><span id="j_idt8:steps:0:j_idt13:j_idt14:j_idt16_display" class="ui-inplace-display" style="display:inline">Alle Zutaten beginnend mit dem Mehl vermischen. </span><span id="j_idt8:steps:0:j_idt13:j_idt14:j_idt16_content" class="ui-inplace-content" style="display:none"><input id="j_idt8:steps:0:j_idt13:j_idt14:description" name="j_idt8:steps:0:j_idt13:j_idt14:description" type="text" value="Alle Zutaten beginnend mit dem Mehl vermischen. " class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" /><script id="j_idt8:steps:0:j_idt13:j_idt14:description_s" type="text/javascript">PrimeFaces.cw('InputText','widget_j_idt8_steps_0_j_idt13_j_idt14_description',{id:'j_idt8:steps:0:j_idt13:j_idt14:description',behaviors:{blur:function(event) {PrimeFaces.ab({source:'j_idt8:steps:0:j_idt13:j_idt14:description',event:'blur',process:'j_idt8:steps:0:j_idt13:j_idt14:description',oncomplete:function(xhr,status,args){basic_j_idt13.hide();;}}, arguments[1]);}}});</script></span></span><script id="j_idt8:steps:0:j_idt13:j_idt14:j_idt16_s" type="text/javascript">PrimeFaces.cw('Inplace','basic_j_idt13',{id:'j_idt8:steps:0:j_idt13:j_idt14:j_idt16',effect:'fade',effectSpeed:'normal',event:'click',toggleable:true});</script><input id="j_idt8:steps:0:j_idt13:j_idt14:removeStep" type="submit" name="j_idt8:steps:0:j_idt13:j_idt14:removeStep" value="Schritt löschen" />
<!-- show Quantities --><div id="j_idt8:steps:0:j_idt13:j_idt14:quantities" class="ui-datalist ui-widget"><div id="j_idt8:steps:0:j_idt13:j_idt14:quantities_content" class="ui-datalist-content ui-widget-content"><ul id="j_idt8:steps:0:j_idt13:j_idt14:quantities_list" class="ui-datalist-data" type="disc"><li class="ui-datalist-item"><html xmlns="http://www.w3.org/1999/xhtml">
<!-- INTERFACE -->
<!-- IMPLEMENTATION -->
<form id="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27" name="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27" method="post" action="/wie-koche-ich/editRecipe.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27" value="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27" />
<input id="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:id" type="hidden" name="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:id" /><input id="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:amount" type="text" name="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:amount" value="10" /><input id="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:measurement" type="text" name="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:measurement" value="g" /><input id="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:ingredient" type="text" name="j_idt8:steps:0:j_idt13:j_idt14:quantities:0:j_idt26:j_idt27:ingredient" value="mehl" /><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="7550668209404370601:-467515547181952132" autocomplete="off" />
</form>
</html></li></ul></div></div><script id="j_idt8:steps:0:j_idt13:j_idt14:quantities_s" type="text/javascript">PrimeFaces.cw('DataList','widget_j_idt8_steps_0_j_idt13_j_idt14_quantities',{id:'j_idt8:steps:0:j_idt13:j_idt14:quantities'});</script><input id="j_idt8:steps:0:j_idt13:j_idt14:addQuantity" type="submit" name="j_idt8:steps:0:j_idt13:j_idt14:addQuantity" value="Mengenangabe hinzufügen" /><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="7550668209404370601:-467515547181952132" autocomplete="off" />
</form>
</html></li><li class="ui-datalist-item"><html xmlns="http://www.w3.org/1999/xhtml">
<!-- INTERFACE -->
<!-- IMPLEMENTATION -->
<form id="j_idt8:steps:1:j_idt13:j_idt14" name="j_idt8:steps:1:j_idt13:j_idt14" method="post" action="/wie-koche-ich/editRecipe.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt8:steps:1:j_idt13:j_idt14" value="j_idt8:steps:1:j_idt13:j_idt14" />
<input id="j_idt8:steps:1:j_idt13:j_idt14:id" type="hidden" name="j_idt8:steps:1:j_idt13:j_idt14:id" />
<!-- http://stackoverflow.com/questions/19198273/hide-inputtext-on-lost-focus-with-pinplace --><span id="j_idt8:steps:1:j_idt13:j_idt14:j_idt16" class="ui-inplace ui-hidden-container"><span id="j_idt8:steps:1:j_idt13:j_idt14:j_idt16_display" class="ui-inplace-display" style="display:inline">In einem Kochtopf heißes Wasser mit Salz zum Kochen bringen. Wir verwenden für unser vorhaben ein Spätzlesieb.</span><span id="j_idt8:steps:1:j_idt13:j_idt14:j_idt16_content" class="ui-inplace-content" style="display:none"><input id="j_idt8:steps:1:j_idt13:j_idt14:description" name="j_idt8:steps:1:j_idt13:j_idt14:description" type="text" value="In einem Kochtopf heißes Wasser mit Salz zum Kochen bringen. Wir verwenden für unser vorhaben ein Spätzlesieb." class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" /><script id="j_idt8:steps:1:j_idt13:j_idt14:description_s" type="text/javascript">PrimeFaces.cw('InputText','widget_j_idt8_steps_1_j_idt13_j_idt14_description',{id:'j_idt8:steps:1:j_idt13:j_idt14:description',behaviors:{blur:function(event) {PrimeFaces.ab({source:'j_idt8:steps:1:j_idt13:j_idt14:description',event:'blur',process:'j_idt8:steps:1:j_idt13:j_idt14:description',oncomplete:function(xhr,status,args){basic_j_idt13.hide();;}}, arguments[1]);}}});</script></span></span><script id="j_idt8:steps:1:j_idt13:j_idt14:j_idt16_s" type="text/javascript">PrimeFaces.cw('Inplace','basic_j_idt13',{id:'j_idt8:steps:1:j_idt13:j_idt14:j_idt16',effect:'fade',effectSpeed:'normal',event:'click',toggleable:true});</script><input id="j_idt8:steps:1:j_idt13:j_idt14:removeStep" type="submit" name="j_idt8:steps:1:j_idt13:j_idt14:removeStep" value="Schritt löschen" />
<!-- show Quantities --><div id="j_idt8:steps:1:j_idt13:j_idt14:quantities" class="ui-datalist ui-widget"><div id="j_idt8:steps:1:j_idt13:j_idt14:quantities_content" class="ui-datalist-content ui-widget-content"><ul id="j_idt8:steps:1:j_idt13:j_idt14:quantities_list" class="ui-datalist-data" type="disc"></ul></div></div><script id="j_idt8:steps:1:j_idt13:j_idt14:quantities_s" type="text/javascript">PrimeFaces.cw('DataList','widget_j_idt8_steps_1_j_idt13_j_idt14_quantities',{id:'j_idt8:steps:1:j_idt13:j_idt14:quantities'});</script><input id="j_idt8:steps:1:j_idt13:j_idt14:addQuantity" type="submit" name="j_idt8:steps:1:j_idt13:j_idt14:addQuantity" value="Mengenangabe hinzufügen" /><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="7550668209404370601:-467515547181952132" autocomplete="off" />
</form>
</html></li></ul></div></div><script id="j_idt8:steps_s" type="text/javascript">PrimeFaces.cw('DataList','widget_j_idt8_steps',{id:'j_idt8:steps'});</script><button id="j_idt8:addstep" name="j_idt8:addstep" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" onclick="PrimeFaces.ab({source:'j_idt8:addstep',update:'j_idt8:steps'});return false;" type="submit"><span class="ui-button-text ui-c">Schritt hinzufügen</span></button><script id="j_idt8:addstep_s" type="text/javascript">PrimeFaces.cw('CommandButton','widget_j_idt8_addstep',{id:'j_idt8:addstep'});</script><input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="7550668209404370601:-467515547181952132" autocomplete="off" />
</form>
</div></body>
</html>
Versuch mal in der Entwicklerkonsole des Browsers die Elemente direkt über die WidgetVar in Javascript anzusprechen, also so: basic_123.show()
Findet er da alle Inplaces über den WidgetVar Namen?
Edit: Gerade gesehen: Du hast verschachtelte Forms in deinem Code, das dürfte das Problem sein
mfe
9. Oktober 2013 um 01:17
9
[QUOTE=inv_zim;68764]
Edit: Gerade gesehen: Du hast verschachtelte Forms in deinem Code, das dürfte das Problem sein[/QUOTE]
Es liegt an der ID. Er erzeugt nur eine basic_j_idt13 id/variable. Was kann ich da machen?
PS: Die Forms in den Components habe ich gelöscht.
inv_zim
9. Oktober 2013 um 01:23
10
Du hast ja in der p:dataList var="step"
gesetzt. Haben deine Steps eindeutige ID? Dann könntest du sagen widgetVar="basic_#{step.id}"
oder so ähnlich.