RichFaces JavaScript Fehler “this._form is null”

Entwickelt man an einer JSF Anwendung unter der Verwendung von JBoss RichFaces bekommt ziemlich jeder mal den Fehler “this._form is null” zu sehen. Hat man im Firefox noch das Add-on Firebug installiert so sieht die Meldung meist wie folgt aus:

Für diesen Fehler gibt es viele Ursachen aber generell nur eine Begründung: Es existiert kein Formular welches um den Link, Button oder Bereich, im diesem Beispiel eine Tabelle, gespannt sein muss (<h:form>…</h:form>).
Vor allem bei der Verwendung von Ajax (Ajax4Jsf Tags) bzw. den RichFaces Komponenten wie der <a4j:commandLink> oder der <a4j:commandButton> sowie alle Komponenten die selbst intern auch Ajax verwenden wie z.b. die Sortierfunktion bei der Rich DataTable kommt dieser Fehler in der Entwicklung häufig vor.

In diesem Beispiel (Screenshot oben) wurde eine RichFaces DataTable mit Sortieren der Spalten verwendet. Im ersten Schritt erstellt man meist nur die DataTable (<rich:dataTable>…</rich:dataTable>) ohne Sortierung und dazu wird natürlich auch kein Formular benötigt. Um die Sortierung hinzuzufügen wird bei den einzelnen <rich:column> Elementen das Attribut sortBy="" hinzugefügt. So sieht der Source Code für eine solche Tabelle wie folgt aus:

  <div>
    <rich:dataTable id="userList"
       value="#{userList.resultList}"
       var="user"
       rendered="#{not empty userList.resultList}"
       style="margin-top: 20px; width: 500px;"
       columnsWidth="50px">

       <f:facet name="header">
          <rich:columnGroup>
            <rich:column colspan="2" style="text-align:left;">
              <h:outputText value="Alle konfigurierten User" />
              &#160;(#{userList.resultCount})
           </rich:column>
         </rich:columnGroup>
        </f:facet>

        <rich:column sortBy="#{user.id}">
            <f:facet name="header">Id</f:facet>
            <h:outputText value="#{user.id}"/>
        </rich:column>

        <rich:column sortBy="#{user.name}">
            <f:facet name="header">Name</f:facet>
            #{user.name}
        </rich:column>

      </rich:dataTable>
  </div>

Das Sortieren selbst wird mit Hilfe von Ajax durchgeführt. Ajax allein benötigt natürlich kein Formular allerdings benötigen die RichFaces Komponenten die mit Ajax funktionieren oder Ajax Funktionalität einbringen ein gültiges Formular. Der Grund liegt darin, dass fast immer etwas mit Ajax “submittet” werden soll um eine Aktion auzuführen. So kommt dieser “this._form is null” auch häufig bei der Verwendung der <a4j:commandLink> Komponente vor. Obwohl es aussieht wie ein normaler Html Link wird dennoch ein Formular submittet und somit ein <h:form> Tag benötigt.

So ist die Lösung für unsere Tabelle mit der Sortierfunktion relativ einfach:

  <div>
    <h:form>
      <rich:dataTable id="userList" ...>
        ...
      </rich:dataTable>
    </h:form>
  </div>

Noch ein kleiner Tipp am Rande: Verwendet man die Möglichkeit nach dem Ajax Request einen Bereich oder eine Komponente neu zu renderen (Attribut reRender) dann sollte man versuchen das <h:form> Tag außerhalb des neu zu rendernden Bereiches zu lassen. Zum Beispiel so:

  <div>
    <h:form>

      <a4j:outputPanel id="editUserPanel">
        <!-- Eingabefelder welche mit Ajax gespeichert wird -->
        <h:inputText value="#{user.name}"/>
        ...
      </a4j:outputPanel>

      <a4j:commandLink action="#{myBB.saveUser}" reRender="editUserPanel"/>

    </h:form>
  </div>

Setzt man das <h:form> Tag innerhalb des <a4j:outputPanel> Tags kann es nach dem neu Rendern auch vorkommen, dass dieser ominöse “this._form is null” Fehler auftritt.
Am besten fährt man, wenn die Formular Tags außerhalb solcher dynamischen Bereiche definiert sind. Möchte man die zu submittenden Daten für den Ajax Reqeust eingrenzen steht extra dafür die AjaxRegion Komponente (<a4j:region>) zur Verfügung.

Tags: , ,

Wenn du Fragen oder Anregungen zum Post hast, dann hinterlasse doch einen Kommentar oder wenn du weiterhin Artikel von Javathreads lesen möchtest, dann abonniere den RSS Feed und sehe direkt in deinem Feed Reader die nächsten Artikel.

Ähnliche Artikel, die dich interessieren könnten:
Kommentare

Thanks for your blog entry, this kind of ‘bug’ had me hunting for days.
In my case I had a a4j:function surround by an a4j:form.
I called this function outside this form using:

The function executed nicely in firefox, but not in Internet Explorer, although in Firefox I got the ‘this._form is null’ error.
I finally found the solution when I changed the button declaration to:

This caused the Firebug debugger to start just before the function call. To my surprise it showed three lines instead of two:
onclick {
debugger;
functionname();
A4J.Submit(…);
}

It appeared that because I used richfaces added the A4J.Submit line. And as the commandbutton wasn’t surrounded by a form, this resulted in the ‘this._form is null’ error.
So sometimes you have to look a little bit further to find the error :-) I changed the declaration to:

Now it works perfectly.

Hmm, your blogging software ate my xhtml code.
To summarise: even when you have a ajax function that is nicely placed in a form, if you call that function from an ajax commandButton not placed in of a form you get into the same trouble.

Yes you’re right! You have to place a form always around a4j:commandButton and a4j:commandLink otherwise the ajax call can’t be created because the ajax call will also submit the form wich is surrounded.
Maybe in this case you can also use the A4J componente a4j:ajaxForm but the rule is always to put a form tag around any commandButton or commandLink.

Thanks for your hint!

Wirklich sehr hilfreich und auch anschaulich erklärt.
Vielen Dank
Hiro

Hinterlasse einen Kommentar