0

I am creating a composite component that consists of a selectOneListbox and several selectManyCheckboxes. The user will be presented with these inputs and once they have made their selections, the values of these components will be combined to produce a formatted String output which is the "value" of this composite component. Currently I have the composite component looking something like below, how do I bind the formatted output string to the value of the composite component when the user submits the form?

I am using Primefaces along with JSF but I think the solution (whatever it is) should be able to apply to either.

Composite Component:

The formatted string is displayed to the user as the user makes the selections on the screen. This is done via ajax updates to the outputText formattedOutput. I added a hidden input at the bottom of the CC. The idea is that I'll use javascript to set the new value of formattedOutput whenever it gets updated, but I'm not sure how.

<composite:interface>
     <composite:attribute name="value" required="true"/>
</composite:interface>

<composite:implementation>

  <div id="#{cc.clientId}">

    <h:outputLabel value="Current Formatted Output" for="formattedOutput"/>
    <h:outputText value="#{backingBean.formattedOutput}" id="formattedOutput"/>

    <p:outputLabel value="First Input" for="input1"/>
    <p:selectOneListbox id="input1" required="true" value="#{backingBean.input1}">
         <f:selectItems value="#{staticControlsData.options1}"/>
         <p:ajax event="change" update="formattedOutput" listener="#{backingBean.buildFormattedOutputString}"/>
    </p:selectOneListbox>

    <p:outputLabel value="Second Input" for="input2"/>
    <p:selectManyCheckbox id="input2" value="#{backingBean.input2}">
        <f:selectItems value="#{staticControlsData.options2}"/>
        <p:ajax event="change" update="formattedOutput" listener="#{backingBean.buildFormattedOutputString}"/>
    </p:selectManyCheckbox>

    <h:inputHidden id="hiddenValue" value="#{cc.attrs.value}"/>
  </div>
</composite:implementation>

This is how I want the composite component to be used:

<h:form>
    <my:component value="#{anotherBean.aField}" />
    <p:commandButton value="Save" />
        <p:commandButton value="Cancel" immediate="true"/>
</h:form>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
citress
  • 889
  • 3
  • 13
  • 35

1 Answers1

0

Add this script to composite component:

function ajaxUpdateComplete(){
    var formattedOutputElement = document.getElementById("#{cc.clientId}" + ":formattedOutput");
    var updatedValue = formattedOutputElement.innerHTML;//we are taking innerHTML because outputText renders as span and has no "value"
    var hiddenElement = document.getElementById('#{cc.clientId}' + ":hiddenValue");
    hiddenElement.value = updatedValue;
}

And to your two <p:ajax> add oncomplete="ajaxUpdateComplete"

So, after each ajax call value of hidden field will be updated and ready to be post with form, which your composite component lays in

n1k1ch
  • 2,594
  • 3
  • 31
  • 35
  • Whilst this may work, this is not the "legal" way to set the value of a composite component. You're basically completely missing the point of a composite component this way. – BalusC Aug 02 '13 at 11:12