Hi Jeremy, Doesn't dojo already add support for this? I have a custom xslt transforming integer-widgets to NumberTextBox dates to DateTextBox and so on. One thing I was working on was to support server side validation errors. The only solution I could come up for here, was to add a client side regexp that is always false, but I thought "yuck!" every time I saw the code so I removed it again ... I'll send you my xslt (even if it depends on some Java-Script I wrote). It's really basic and only supports the usecases I used in my application. But maybe it helps. Now please don't complain about the really basic xslt ... I didnt want to get lost in XSLT issues and wanted to concentrate on the Dojo Support ... One thing I have to mention ... I user TinyMCE as HTMLArea Widget.
I think generating the validation-output needed for client side-validation shouldn't be a big problem, since its the same for almost all widgets the class having to be patched should be the simple Widget base-classes. I would volunteer implementing it, but only if it is really wanted. Chris <?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fi="http://apache.org/cocoon/forms/1.0#instance" exclude-result-prefixes="fi"> <xsl:template match="page"> <page> <!--xsl:if test="//fi:field[(fi:datatype/@type='string') and (fi:styling/@type='htmlarea')]"> <xsl:text disable-output-escaping="yes"> <![CDATA[<script language="javascript" type="text/javascript" src="/resources/forms/tiny_mce/tiny_mce_src.js"></script>]]> </xsl:text> </xsl:if--> <script type="text/javascript"> dojo.require("dijit.form.TextBox"); <xsl:if test="//fi:field/fi:[EMAIL PROTECTED]'date']">dojo.require("dijit.form.DateTex tBox"); </xsl:if> <xsl:if test="//fi:field[(fi:datatype/@type='integer') or (fi:datatype/@type='float')]" >dojo.require("dijit.form.NumberTextBox"); </xsl:if> <xsl:if test="//fi:field[(fi:datatype/@type='string') and fi:selection-list]" >dojo.require("dijit.form.FilteringSelect"); </xsl:if> <xsl:if test="//fi:booleanfield">dojo.require("dijit.form.CheckBox"); </xsl:if> dojo.parser.parse(dojo.byId('<xsl:value-of select="@name"/>')); </script> <xsl:apply-templates select="* | text()"/> </page> </xsl:template> <!-- Form Fields handling --> <xsl:template match="fi:[EMAIL PROTECTED] = 'cweb']" priority="5"> <form id="[EMAIL PROTECTED]" class="soria" onsubmit="return false;"> <xsl:copy-of select="@*"/> <input type="hidden" name="forms_submit_id"/> <xsl:apply-templates/> </form> <xsl:if test="//fi:validation-message"> <table> <xsl:for-each select="//fi:validation-message"> <tr> <td> <xsl:value-of select="../@id"/>: <xsl:value-of select="."/> </td> </tr> </xsl:for-each> </table> </xsl:if> </xsl:template> <xsl:template match="fi:form-template" priority="0"> <form class="soria"> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </form> <xsl:if test="//fi:validation-message"> <table> <xsl:for-each select="//fi:validation-message"> <tr> <td> <xsl:value-of select="../@id"/>: <xsl:value-of select="."/> </td> </tr> </xsl:for-each> </table> </xsl:if> </xsl:template> <xsl:template match="fi:continuation-id"> <input type="hidden" name="continuation-id" value="{.}"/> </xsl:template> <!-- //////////////////////////////////////////////////////////////////////////// //////// // // Widget definitions // //////////////////////////////////////////////////////////////////////////// ///////// --> <xsl:template match="fi:field[fi:styling/@type='hidden']" priority="6"> <input type="hidden" name="[EMAIL PROTECTED]"> <xsl:attribute name="value"> <xsl:value-of select="fi:value"/> </xsl:attribute> </input> </xsl:template> <!-- date widget --> <xsl:template match="fi:field[fi:datatype/@type='date']" priority="0"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:value-of select="fi:value"/> </xsl:when> <xsl:when test="@state = 'active'"> <input type="text" name="[EMAIL PROTECTED]" dojoType="dijit.form.DateTextBox"> <xsl:attribute name="value"> <xsl:value-of select="fi:value"/> </xsl:attribute> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="fi:styling/@style"/> </input> </xsl:when> </xsl:choose> </xsl:template> <!-- integer widget --> <xsl:template match="fi:field[fi:datatype/@type='integer']" priority="0"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:value-of select="fi:value"/> </xsl:when> <xsl:when test="@state = 'active'"> <input type="text" name="[EMAIL PROTECTED]" dojoType="dijit.form.NumberTextBox"> <xsl:attribute name="value"> <xsl:value-of select="fi:value"/> </xsl:attribute> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="fi:styling/@style"/> <!--xsl:if test=""> <xsl:attribute name="promptMessage">Enter a value between -20000 and +20000</xsl:attribute> </xsl:if--> <!--constraints="{min:-20000,max:20000,places:0}" invalidMessage= "Invalid elevation."--> </input> </xsl:when> </xsl:choose> </xsl:template> <!-- float widget --> <xsl:template match="fi:field[fi:datatype/@type='float']" priority="0"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:value-of select="fi:value"/> </xsl:when> <xsl:when test="@state = 'active'"> <input type="text" name="[EMAIL PROTECTED]" dojoType="dijit.form.NumberTextBox"> <xsl:attribute name="value"> <xsl:value-of select="fi:value"/> </xsl:attribute> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="fi:styling/@style"/> <!--xsl:if test=""> <xsl:attribute name="promptMessage">Enter a value between -20000 and +20000</xsl:attribute> </xsl:if--> <!--constraints="{min:-20000,max:20000,places:0}" invalidMessage= "Invalid elevation."--> </input> </xsl:when> </xsl:choose> </xsl:template> <!-- string with selection-list widget --> <xsl:template match="fi:field[(fi:datatype/@type='string') and fi:selection-list]" priority="5"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:for-each select="fi:selection-list/fi:item"> <xsl:if test="../../fi:value = @value"> <xsl:choose> <xsl:when test="fi:label"> <xsl:value-of select="fi:label"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="@value"/> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:for-each> </xsl:when> <xsl:when test="@state = 'active'"> <select name="[EMAIL PROTECTED]" dojoType="dijit.form.FilteringSelect" autocomplete="false"> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="fi:styling/@style"/> <xsl:for-each select="fi:selection-list/fi:item"> <option> <xsl:attribute name="value"> <xsl:value-of select="@value"/> </xsl:attribute> <xsl:if test="../../fi:value = @value"> <xsl:attribute name="selected">selected</xsl:attribute> </xsl:if> <xsl:choose> <xsl:when test="fi:label"> <xsl:value-of select="fi:label"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="@value"/> </xsl:otherwise> </xsl:choose> </option> </xsl:for-each> </select> </xsl:when> </xsl:choose> </xsl:template> <!-- string with html-area widget --> <xsl:template match="fi:field[(fi:datatype/@type='string') and (fi:styling/@type='htmlarea')]" priority="5"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:value-of select="fi:value"/> </xsl:when> <xsl:when test="@state = 'active'"> <div> <textarea title="{fi:hint}" name="[EMAIL PROTECTED]"> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="@style | fi:styling/@style"/> <xsl:value-of select="fi:value"/>&nbsp; </textarea> </div> <script language="javascript" type="text/javascript"> <![CDATA[ tinyMCE.init({ mode : "textareas", theme : "advanced", plugins : "safari,style,layer,table,save,advhr,advimage,advlink,inlinepopups,insertdat etime,preview,media,searchreplace,contextmenu,paste,directionality,fullscree n,noneditable,visualchars,nonbreaking,template,pagebreak", theme_advanced_buttons1_add_before : "save,newdocument,separator", theme_advanced_buttons1_add : "fontselect,fontsizeselect", theme_advanced_buttons2_add : "separator,forecolor,backcolor", theme_advanced_buttons2_add_before: "cut,copy,paste,pastetext,pasteword,separator,search,replace,separator", theme_advanced_buttons3_add_before : "tablecontrols,separator", theme_advanced_buttons3_add : "emotions,iespell,media,advhr,separator,print,separator,ltr,rtl,separator,fu llscreen", theme_advanced_buttons4 : "visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertim age", theme_advanced_toolbar_location : "top", theme_advanced_toolbar_align : "left", theme_advanced_statusbar_location : "bottom", external_link_list_url : "html-area/example_link_list.js", external_image_list_url : "html-area/example_image_list.js", flash_external_list_url : "html-area/example_flash_list.js", template_external_list_url : "html-area/example_template_list.js", theme_advanced_resize_horizontal : false, theme_advanced_resizing : true, apply_source_formatting : true, spellchecker_languages : "+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Po lish=pl,Portuguese=pt,Spanish=es,Swedish=sv" }); ]]> </script> </xsl:when> </xsl:choose> </xsl:template> <xsl:template match="@*|*" mode="htmlarea-copy"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="htmlarea-copy"/> </xsl:copy> </xsl:template> <xsl:template match="text()" mode="htmlarea-copy"> <xsl:copy-of select="translate(., ' ', '')"/> </xsl:template> <!-- password string widget --> <xsl:template match="fi:field[(fi:datatype/@type='string') and (fi:styling/@type='password')]" priority="5"> <xsl:choose> <xsl:when test="@state = 'output'"> XXXXXXXXXXXX </xsl:when> <xsl:when test="@state = 'active'"> <input type="password" name="[EMAIL PROTECTED]" dojoType="dijit.form.TextBox" trim="true"> <xsl:attribute name="value"> <xsl:value-of select="fi:value"/> </xsl:attribute> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="fi:styling/@style"/> <!--xsl:attribute name="regExp">[\w]+</xsl:attribute> <xsl:attribute name="invalidMessage">Invalid Non-Space Text.</xsl:attribute--> </input> </xsl:when> </xsl:choose> </xsl:template> <!-- normal string widget --> <xsl:template match="fi:field[fi:datatype/@type='string']"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:value-of select="fi:value"/> </xsl:when> <xsl:when test="@state = 'active'"> <input type="text" name="[EMAIL PROTECTED]" dojoType="dijit.form.TextBox" trim="true"> <xsl:attribute name="value"> <xsl:value-of select="fi:value"/> </xsl:attribute> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onchange">forms_submitForm(this)</xsl:attribute> </xsl:if> <xsl:copy-of select="fi:styling/@style"/> <!--xsl:attribute name="regExp">[\w]+</xsl:attribute> <xsl:attribute name="invalidMessage">Invalid Non-Space Text.</xsl:attribute--> </input> </xsl:when> </xsl:choose> </xsl:template> <!-- booleanfield widget --> <xsl:template match="fi:booleanfield"> <xsl:choose> <xsl:when test="@state = 'output'"> <xsl:value-of select="fi:value"/> </xsl:when> <xsl:when test="@state = 'active'"> <input type="checkbox" name="[EMAIL PROTECTED]" dojoType="dijit.form.CheckBox" value="true"> <xsl:if test="fi:value = 'true'"> <xsl:attribute name="checked">checked</xsl:attribute> </xsl:if> <xsl:if test="@required = 'true'"> <xsl:attribute name="required">true</xsl:attribute> </xsl:if> <xsl:if test="@listening = 'true'"> <xsl:attribute name="onclick">forms_submitForm(this)</xsl:attribute> </xsl:if> </input> </xsl:when> </xsl:choose> </xsl:template> <xsl:template match="fi:action"> <input id="[EMAIL PROTECTED]" type="submit" name="[EMAIL PROTECTED]" title="{fi:hint}"> <xsl:attribute name="value"> <xsl:value-of select="fi:label/node()"/> </xsl:attribute> <xsl:if test="ancestor::fi:[EMAIL PROTECTED]'cweb']"> <xsl:attribute name="onclick">forms_submitForm(this, '<xsl:value-of select="@id"/>'); return false;</xsl:attribute> </xsl:if> <!--xsl:apply-templates select="." mode="styling"/--> </input> </xsl:template> <xsl:template match="fi:action[fi:styling/@type = 'link']" priority="1"> <a id="[EMAIL PROTECTED]" title="{fi:hint}" href="#" onclick="forms_submitForm(this, '[EMAIL PROTECTED]'); return false;"> <!--xsl:apply-templates select="." mode="styling"/--> <xsl:copy-of select="fi:label/node()"/> </a> </xsl:template> <xsl:template match="fi:repeater-size"> <input type="hidden" name="[EMAIL PROTECTED]" value="[EMAIL PROTECTED]"/> </xsl:template> <!-- Defaults --> <xsl:template match="@*|node()" priority="-1" mode="forms-header"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="@*|node()" priority="-1"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="fi:label"/> </xsl:stylesheet> -----Ursprüngliche Nachricht----- Von: Jeremy Quinn [mailto:[EMAIL PROTECTED] Gesendet: Montag, 14. Juli 2008 12:41 An: dev@cocoon.apache.org Betreff: Re: AW: Client-side validation in CForms Hi Christofer On 13 Jul 2008, at 13:13, Christofer Dutz wrote: > When I was working on my first attempts to do exactly what you are > trying to > do (CForms using dojo 1.1 and client side validation), I ran into > exactly > the same problem as you did. I too think it would be easily possible > to > implement client and server-side validation using dojo. Even if it > would not > be possible to implement all. > > Unfortunately the fi-output is hard-coded into the widget class > implementation and no validation information is sent. Making client- > side > validation work, it would make it necessary to patch every single > Widget > class to output this validation-data, but should be easy to > accomplish. > > I stopped my work on this, since I had doubt's anyone would be > interested in > a feature like this and the thought of having to maintain patches > for so > many classes let me drop that idea. I had a look as well and did not fancy ploughing in to the code to add this right now, as I have so much else to do before I can release the client-side stuff (hence asking for volunteers .... ) What I am working on in the meantime is using the (existing) <fi:datatype base="string|integer|long|double|float|decimal"/> tags to perform basic datatype validation on the client. My hope is that adding support for this now, will make it easier to add fuller validation client-side in the future. BTW. Christofer, I attempted to contact you earlier about the private work you said you had been doing on Dojo 1.1, to see if I could roll it into my work. If you are interested in contributing, please contact me off-list. Many thanks regards Jeremy > > -----Ursprüngliche Nachricht----- > Von: Jeremy Quinn [mailto:[EMAIL PROTECTED] > Gesendet: Mittwoch, 9. Juli 2008 17:17 > An: dev@cocoon.apache.org > Betreff: Client-side validation in CForms > > Hi All > > As you may know, I am working heavily on the revamp of Dojo on the > client-side of CForms. > > In Dojo it is possible to perform quite a lot of validation on form > fields. There is a partial match between the validation capabilities > of CForms and those of Dojo. Several people have thought in the past > that it would be good to have the same validation occur on both the > server and the client. > > OTTOMH, the kind of validators we could probably make work in both > places would be : > email, length, mod10, range and regexp (plus maybe javascript, if we > > can sort out any context differences) > > ATM however, no validation information is output by the form > generation process. Datatypes are there (which I can initially use) > but no validation. > > So my question is, would someone volunteer to either add the > definition's validation tags to the output or help work out the > cleanest approach to adding it? > > Many thanks > > > regards Jeremy > >