7 Replies Latest reply on Feb 16, 2011 9:46 PM by derekmd

    Hide Validation Error Icon After Successful Subsequent AJAX Call

    derekmd

      I have a <rich:inplaceInput> AJAX persisting for the onviewactivated event. When there's a validation error an absolutely positioned exclamation point appears on the component's left side. Problem is after correcting the problem & successfully persisting, the icon isn't hidden since its HTML is appending to the root <body> instead of within the reRender parent (<a4j:output> or <s:div>). Is there a method to force the icon to hide on success keeping in mind the generated <img> element added to the DOM uses style="" instead of class="" for the CSS (so a simple JQuery call won't do)?

       

      e.g., /composition/inplaceInput.xhtml

       

      {code:xml}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

          <s:div id="#{reRender}">

              <span>

                  <h:outputText value="#{label}" />

                  <s:span styleClass="required" rendered="#{required}">*</s:span>

              </span>

              <span>

                  <rich:inplaceInput id="#{id}" value="#{value}" showControls="true" editEvent="ondblclick" layout="block" label="#{label}" required="#{required}">

                      <a4j:support event="onviewactivated" action="#{backingBean.save}" limitToList="true" reRender="#{reRender}" />

                  </rich:inplaceInput>

                  <s:message for="#{id}" />

              </span>

          </s:div>

      </ui:composition>{code}

        • 1. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
          ilya_shaikovsky

          at first

          <span>
            <rich:inplaceInput id="#{id}" value="#{value}" showControls="true" editEvent="ondblclick" layout="block" label="#{label}" required="#{required}">

          layout=block means that inplace will use div markup. And this is not valid to place block elements inside inline ones in html. So could cause different glitches after ajax updates.

          • 2. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
            derekmd

            I attempted removing layout="block" to revert back to inline but the AJAX behaviour didn't change. The RichFaces error icon still appears appended in the root of the generated DOM's <body> even after the resubmitted AJAX call successfully goes through.

            • 3. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
              ilya_shaikovsky

              if some elements getting encoded via ajax in the wrong places - it's probably caused by the fact that you have some other non -valid code in your page markup and it's tried to be corrected by filters. check generated html with w3c validator.

              • 4. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
                derekmd

                Here is a simplified example:

                 

                {code:xml}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                <f:view xmlns="http://www.w3.org/1999/xhtml"         xmlns:s="http://jboss.com/products/seam/taglib"         xmlns:ui="http://java.sun.com/jsf/facelets"         xmlns:f="http://java.sun.com/jsf/core"         xmlns:h="http://java.sun.com/jsf/html"         xmlns:rich="http://richfaces.org/rich"         xmlns:a4j="http://richfaces.org/a4j"         xmlns:tcp="http://www.phenogenomics.ca/jsf"         contentType="text/html"> <html>    <head>       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>       <title>inplaceInput validation icon test</title>       <link href="/stylesheet/theme.css" rel="stylesheet" type="text/css" />       <a4j:loadStyle src="resource:///stylesheet/theme.xcss"/>    </head>    <body>       <h:form name="mouselineForm" id="mouselineForm">          <s:div id="contactEmail_div">             <rich:inplaceInput id="contactEmail" value="#{mouselineHome.instance.contactEmail}" showControls="true" editEvent="ondblclick" layout="block" required="true">                <a4j:support event="onviewactivated" action="#{mouselinePage.save}" limitToList="true" reRender="contactEmail_div" />                <s:validate />             </rich:inplaceInput>             <s:message for="contactEmail" />          </s:div>       </h:form>    </body> </html>
                </f:view>{code}

                 

                 

                This generates this XHTML (the only W3C compliance warning is on the input's autocomplete="false" attribute):

                 

                 

                {code:xml}<!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">    <head>       <script src="/a4j/g/3_3_3.CR1/org/ajax4jsf/framework.pack.js" type="text/javascript"></script>       <script src="/a4j/g/3_3_3.CR1/org/richfaces/ui.pack.js" type="text/javascript"></script>       <link class="component" href="/a4j/s/3_3_3.CR1org/richfaces/renderkit/html/css/basic_both.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <link class="component" href="/a4j/s/3_3_3.CR1org/richfaces/renderkit/html/css/extended_both.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" media="rich-extended-skinning" rel="stylesheet" type="text/css" />       <link class="component" href="/a4j/s/3_3_3.CR1/org/richfaces/skin.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <script id="org.ajax4jsf.queue_script" type="text/javascript">if (typeof A4J != 'undefined') { if (A4J.AJAX) { with (A4J.AJAX) {if (!EventQueue.getQueue('org.richfaces.queue.global')) { EventQueue.addQueue(new EventQueue('org.richfaces.queue.global',null,null)) };}}};</script>       <link class="component" href="/a4j/s/3_3_3.CR1META-INF/skins/laguna.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <script type="text/javascript">window.RICH_FACES_EXTENDED_SKINNING_ON=true;</script>       <link class="user" href="/a4j/s/3_3_3.CR1stylesheet/theme.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <link type="text/css" href="/openFacesResources/org/openfaces/renderkit/default-2.0.css" rel="stylesheet"/>       <script src="/openFacesResources/org/openfaces/util/util-2.0.js" type="text/javascript"></script>       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />       <title>inplaceInput validation icon test</title>       <link href="/stylesheet/theme.css" rel="stylesheet" type="text/css" />    </head>    <body>       <form id="mouselineForm" name="mouselineForm" method="post" action="/mouseline/Mouseline.seam" enctype="application/x-www-form-urlencoded">          <input type="hidden" name="mouselineForm" value="mouselineForm" />          <div id="mouselineForm:contactEmail_div">             <div class="rich-inplace rich-inplace-input rich-inplace-view " id="mouselineForm:contactEmail" style="zoom: 1; ">                <input autocomplete="off" class="rich-inplace-field" id="mouselineForm:contactEmailtempValue" style="clip:rect(0px 0px 0px 0px)" type="text" value="example@email.com" />                <input autocomplete="off" id="mouselineForm:contactEmailvalue" name="mouselineForm:contactEmail" type="hidden" value="example@email.com" />                <div class="rich-inplace-input-controls-set" id="mouselineForm:contactEmailbar" style="display:none;">                   <div class="rich-inplace-shadow" id="mouselineForm:contactEmailbtns_shadow">                      <table border="0" cellpadding="0" cellspacing="0" class="rich-inplace-shadow-size">                         <tbody>                            <tr>                               <td class="rich-inplace-shadow-tl"><img alt="" height="1" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="10" /></td>                               <td class="rich-inplace-shadow-tr"><img alt="" height="10" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="1" /></td>                            </tr>                            <tr>                               <td class="rich-inplace-shadow-bl"><img alt="" height="10" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="1" /></td>                               <td class="rich-inplace-shadow-br"><img alt="" height="1" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="10" /></td>                            </tr>                         </tbody>                      </table>                   </div>                   <div id="mouselineForm:contactEmailbuttons" style="position:relative; width: 1px">                      <input class="rich-inplace-control " id="mouselineForm:contactEmailok" onmousedown="this.className='rich-inplace-control-press '" onmouseout="this.className='rich-inplace-control '" onmouseover="this.className='rich-inplace-control '" onmouseup="this.className='rich-inplace-control '" src="/a4j/g/3_3_3.CR1org.richfaces.renderkit.html.images.SaveControlIcon/DATB/eAHzOBTNlsLw!!9!ABMwBM0_" type="image" />                      <input class="rich-inplace-control " id="mouselineForm:contactEmailcancel" onmousedown="this.className='rich-inplace-control-press  '" onmouseout="this.className='rich-inplace-control '" onmouseover="this.className='rich-inplace-control '" onmouseup="this.className='rich-inplace-control '" src="/a4j/g/3_3_3.CR1org.richfaces.renderkit.html.images.CancelControlIcon/DATB/eAETFZ!-!!9!AAlNA8E_" type="image" />                   </div>                   <script type="text/javascript">var inplaceInput = new Richfaces.InplaceInput('mouselineForm:contactEmail',{'events':{'onviewactivated':function(event){A4J.AJAX.Submit('mouselineForm',event,{'similarityGroupingId':'mouselineForm:j_id4','parameters':{'mouselineForm:j_id4':'mouselineForm:j_id4'} } )}} ,'attributes':{'editEvent':'ondblclick','showControls':true} } );</script>                </div>                example@email.com             </div>             <span id="mouselineForm:j_id5" style="display: none;"></span>          </div>          <input type="hidden" name="javax.faces.ViewState" value="j_id8" />       </form>    </body> </html>{code}

                 

                An error condition on changing contactEmail such as a left blank for the required field or entering an invalid email address generates this XHTML:

                 

                 

                {code:xml}<!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">    <head>       <script src="/a4j/g/3_3_3.CR1/org/ajax4jsf/framework.pack.js" type="text/javascript"></script>       <script src="/a4j/g/3_3_3.CR1/org/richfaces/ui.pack.js" type="text/javascript"></script>       <link class="component" href="/a4j/s/3_3_3.CR1org/richfaces/renderkit/html/css/basic_both.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <link class="component" href="/a4j/s/3_3_3.CR1org/richfaces/renderkit/html/css/extended_both.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" media="rich-extended-skinning" rel="stylesheet" type="text/css" />       <link class="component" href="/a4j/s/3_3_3.CR1/org/richfaces/skin.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <script id="org.ajax4jsf.queue_script" type="text/javascript">if (typeof A4J != 'undefined') { if (A4J.AJAX) { with (A4J.AJAX) {if (!EventQueue.getQueue('org.richfaces.queue.global')) { EventQueue.addQueue(new EventQueue('org.richfaces.queue.global',null,null)) };}}};</script>       <link class="component" href="/a4j/s/3_3_3.CR1META-INF/skins/laguna.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <script type="text/javascript">window.RICH_FACES_EXTENDED_SKINNING_ON=true;</script>       <link class="user" href="/a4j/s/3_3_3.CR1stylesheet/theme.xcss/DATB/eAF72c2jGbp8hjQAEMYDWQ__" rel="stylesheet" type="text/css" />       <link type="text/css" href="/openFacesResources/org/openfaces/renderkit/default-2.0.css" rel="stylesheet"/>       <script src="/openFacesResources/org/openfaces/util/util-2.0.js" type="text/javascript"></script>       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />       <title>inplaceInput validation icon test</title>       <link href="/stylesheet/theme.css" rel="stylesheet" type="text/css" />    </head>    <body>       <form id="mouselineForm" name="mouselineForm" method="post" action="/mouseline/Mouseline.seam" enctype="application/x-www-form-urlencoded">          <input type="hidden" name="mouselineForm" value="mouselineForm" />          <div id="mouselineForm:contactEmail_div">             <div class="rich-inplace rich-inplace-input rich-inplace-view " id="mouselineForm:contactEmail" style="zoom: 1; " title="must be a well-formed email address">

                               <script type="text/javascript">//<![CDATA[                   O$.addLoadEvent(function(){O$.addMessageById('mouselineForm:contactEmail', 'must be a well-formed email address', 'must be a well-formed email address', 'error');new O$._FloatingIconMessageRenderer('mouselineForm:dfm1', 'mouselineForm:contactEmail', '/openFacesResources/org/openfaces/component/validation/error_icon-2.0.gif', -4, -4, 'o_floatingIconMessage', {}, false, false, true, true).update();

                                  })

                                  //]]>

                               </script>                <input autocomplete="off" class="rich-inplace-field" id="mouselineForm:contactEmailtempValue" style="clip:rect(0px 0px 0px 0px)" type="text" value="example@" />                <input autocomplete="off" id="mouselineForm:contactEmailvalue" name="mouselineForm:contactEmail" type="hidden" value="example@" />

                               <div class="rich-inplace-input-controls-set" id="mouselineForm:contactEmailbar" style="display:none;">                   <div class="rich-inplace-shadow" id="mouselineForm:contactEmailbtns_shadow">                      <table border="0" cellpadding="0" cellspacing="0" class="rich-inplace-shadow-size">                         <tbody>                            <tr>                               <td class="rich-inplace-shadow-tl"><img alt="" height="1" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="10" /></td>                               <td class="rich-inplace-shadow-tr"><img alt="" height="10" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="1" /></td>                            </tr>                            <tr>                               <td class="rich-inplace-shadow-bl"><img alt="" height="10" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="1" /></td>                               <td class="rich-inplace-shadow-br"><img alt="" height="1" src="/a4j/g/3_3_3.CR1images/spacer.gif" style="border:0" width="10" /></td>                            </tr>                         </tbody>                      </table>                   </div>                   <div id="mouselineForm:contactEmailbuttons" style="position:relative; width: 1px">                      <input class="rich-inplace-control " id="mouselineForm:contactEmailok" onmousedown="this.className='rich-inplace-control-press '" onmouseout="this.className='rich-inplace-control '" onmouseover="this.className='rich-inplace-control '" onmouseup="this.className='rich-inplace-control '" src="/a4j/g/3_3_3.CR1org.richfaces.renderkit.html.images.SaveControlIcon/DATB/eAHzOBTNlsLw!!9!ABMwBM0_" type="image" />                      <input class="rich-inplace-control " id="mouselineForm:contactEmailcancel" onmousedown="this.className='rich-inplace-control-press  '" onmouseout="this.className='rich-inplace-control '" onmouseover="this.className='rich-inplace-control '" onmouseup="this.className='rich-inplace-control '" src="/a4j/g/3_3_3.CR1org.richfaces.renderkit.html.images.CancelControlIcon/DATB/eAETFZ!-!!9!AAlNA8E_" type="image" />                   </div>                   <script type="text/javascript">var inplaceInput = new Richfaces.InplaceInput('mouselineForm:contactEmail',{'events':{'onviewactivated':function(event){A4J.AJAX.Submit('mouselineForm',event,{'similarityGroupingId':'mouselineForm:j_id4','parameters':{'mouselineForm:j_id4':'mouselineForm:j_id4'} } )}} ,'attributes':{'editEvent':'ondblclick','showControls':true} } );</script>                </div>                example@

                            </div>             <span id="mouselineForm:j_id5" style="display: none;"></span>          </div>          <input type="hidden" name="javax.faces.ViewState" value="j_id8" />       </form>

                      <script xmlns="http://www.w3.org/1999/xhtml">A4J.AJAX._scriptEvaluated=true;</script>

                      <img id="mouselineForm:dfm1" src="/openFacesResources/org/openfaces/component/validation/error_icon-2.0.gif" style="position: absolute; z-index: 700; left: -4px; top: -4px; " alt="must be a well-formed email address" title="must be a well-formed email address" />    </body> </html>{code}

                 

                The problem is after resubmitting the inplaceInput with the correct example@mail.com value, the AJAX does trigger and the bean successfully persists, but the final <img id="mouselineForm:dfm1"... /> tag still appears in the DOM!

                • 5. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
                  ilya_shaikovsky

                  seems you simplified code too much. using seam 2.2.0 RF 3.3.3 and this code:

                   

                  <h:form name="mouselineForm" id="mouselineForm">
                  <s:decorate>
                  <s:div id="contactEmail_div">
                  <rich:inplaceInput id="contactEmail" value="#{userBean.name}"
                  showControls="true" editEvent="ondblclick" layout="block"
                  required="true">
                  <a4j:support event="onviewactivated" 
                  limitToList="true" reRender="contactEmail_div" />
                  <s:validate />
                  </rich:inplaceInput>
                  <s:message for="contactEmail"/>
                  </s:div>
                  </s:decorate>
                  </h:form>
                  

                   

                  I'm still not getting the float image you mentioning and see just message which added and removed fine.

                  • 6. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
                    derekmd

                    ...4 months pass...

                     

                    It's definitely an OpenFaces problem where it's using filters to place additional functionality on top of JSF component validation. The issue is their error icon code assumes a POST of the full page will be made so A4J support offered by RichFaces causes confusing results (e.g., error icon still appearing after validation succeeded.) I've created an OpenFaces forum post in an attempt to clear up the issue but I doubt support for RichFaces' AJAX will be taken into consideration.

                    • 7. Re: Hide Validation Error Icon After Successful Subsequent AJAX Call
                      derekmd

                      FYI, the problem is due to OpenFaces' validation not properly supporting AJAX. A feature request has been created for this issue: http://requests.openfaces.org/browse/OF-80

                       

                      It can be temporarily fixed by disabling the validation error icon on client-side using the below tag inside your <a4j:form>:

                       

                      {code:xml}<o:clientValidationSupport clientValidation="off" useDefaultServerValidationPresentation="false"/>{code}

                       

                      POST requests will still show the icon and <h:message> errors will still display after AJAX reRender.