views:

78

answers:

1

I am having two radio buttons of label 'Text Mode' and 'Html Mode'. If Text Mode is selected only <h:inputTextarea/> should be displayed and the contents of HTML editor must be empty. If Html Mode is selected <rich:editor/> should be displayed and the Text textarea must be empty. The default selection is Text mode. (i.e. if the user adds text in Text mode and navigates to the HTML mode, we would like to clear the textarea before showing the rich:editor and vice versa)

 <input id="textMode" type="radio" name="text" value="textMode">Text mode</input>
 <input id="htmlMode" type="radio" name="text" value="htmlMode">Html mode</input>

 <table id="questionText">
  <tr>
   <td id="textQuestionField">
    <h:inputTextarea value="#{forum.message}" cols="80" rows="3"/>
   </td>

   <td id="htmlQuestionField">
    <rich:editor theme="advanced" useSeamText="true" viewMode="visual" autoResize="true" value="#{forum.message}">
     <f:param name="theme_advanced_buttons1" value="newdocument,separator,cut,copy,paste,separator,bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,hr,removeformat,visualaid,separator,sub,sup"/>
     <f:param name="theme_advanced_buttons2" value="bullist,numlist,separator,outdent,indent,blockquote,separator,undo,redo,separator,link,unlink,anchor,separator,image,cleanup,help,code,separator,forecolor,backcolor"/>
     <f:param name="theme_advanced_buttons3" value="fontselect,fontsizeselect,formatselect,styleselect,separator,charmap"/>
     <f:param name="theme_advanced_resizing" value="true"/>
     <f:param name="theme_advanced_toolbar_location" value="top" />
     <f:param name="theme_advanced_toolbar_align" value="left" />
        </rich:editor>
    </td>
 </tr>
</table>


function textHtmlQuestionHandler(tableId, radioButtonTextId, radioButtonHtmlId, textQuestionId, htmlQuestionId) {
    // Text Mode is enabled by default
    jQuery(radioButtonTextId).attr('checked', true);
    jQuery(tableId).find(htmlQuestionId).hide();

    jQuery("input[type='radio']").change(function() {
        // Hide HTML question field, if text mode is enabled
        if (jQuery(radioButtonTextId).is(':checked')) {
            jQuery(tableId).find(textQuestionId).show();
            jQuery(tableId).find(htmlQuestionId).hide();
        } else if (jQuery(radioButtonHtmlId).is(':checked')) {
            // Hide text question field, if HTML mode is enabled
            jQuery(tableId).find(htmlQuestionId).show();
            jQuery(tableId).find(textQuestionId).hide();
        }
    });
}

How to achieve this?

+3  A: 

You shouldn't do this solely at the client side. You have to notify the JSF component tree in the server side as well about the change in the state. Otherwise it won't be able to display the model value, let alone to process it the way as you'd expect from the client side's state. You have to display the radiobuttons using a real JSF <h:selectOneRadio> component and fire partial submits using RichFaces' builtin <a4j:support>.

<h:selectOneRadio value="#{forum.editmode}" valueChangeListener="#{forum.editmodeChanged}">
    <f:selectItem itemValue="text" itemLabel="Text mode" />
    <f:selectItem itemValue="html" itemLabel="HTML mode" />
    <a4j:support event="change" reRender="questionText" />
</h:selectOneMenu>

<h:panelGroup id="questionText">
    <h:inputTextarea value="#{forum.message}" rendered="#{forum.editmode == 'text'}" />
    <rich:editor value="#{forum.message}" rendered="#{forum.editmode == 'html'}" />
</h:panelGroup>

In this example, the <a4j:support> will re-render the <h:panelGroup id="questionText"> on every change of the radiobutton group. The panelgroup contains the textarea and the rich editor whose rendered attribute in turn depends on the selected radiobutton value.

You could use the valuechangelistener to clear the #{forum.message} whenever the #{forum.editmode} has changed.

public void editmodeChanged(ValueChangeEvent event) {
    this.message = null;
}

Don't forget to preset the value of property behind #{forum.editmode} to some default value in bean's constructor, for the case that you'd like to preserve a default mode. I.e.

public Forum() {
    this.editmode = "text";
}
BalusC