This project is read-only.

Help for simple form

Developer
Aug 3, 2010 at 10:41 AM
Edited Aug 4, 2010 at 10:43 AM
Hello, this must be very easy to implement, but... how to build a simple form? I'm trying to build a form with some controls (dropdownlists,, textboxes) I wish to use to pass parameters to a stored procedure, but cannot get parameters passed when I submit the form: can you help? I have some controls, like this dropdown I populate via sql:
<xsl:variable name="ruolo" select="'Administrators'"/>
<xsl:variable name="sql">
            exec GetUsersByRolename 0,<xsl:text><![CDATA[']]></xsl:text><xsl:value-of select="$ruolo"/><xsl:text><![CDATA[']]></xsl:text>
</xsl:variable>

Choose User: 
<select name="iduser" id="iduser">
            <option value="0">Any</option>
            <xsl:for-each select="mdo:sql($sql, 'table')//table">
                    <option value="{Userid}">{{DisplayName}}</option>
            </xsl:for-each>
</select>

Then I want user to select a value in this (and others) dropdown, click a submit button and use the value as parameter for a query. I tried to use mdo:navigate, but cannot get the selected value:
a href="{mdo:navigate('$iduser', mdo:param('$iduser') )}">Cerca
User actually navigates to same page, but my "iduser" querystring param is always empty. Also tried mdo:submit and ajax, with same result. With mdo:param or mdo:request I can retrieve the value, but I miss setting it :( Is this possible? Or should I do something different, maybe mdo:asp? Thanks for any help, al.
/>
/> UPDATE: solved by using this kind of syntax:
select onchange="{mdo:ajax('$idDist', '@this.value')}">
Coordinator
Aug 4, 2010 at 10:49 AM
Edited Aug 4, 2010 at 10:53 AM

Hello,

1. First of all I’d like to say that building SQL queries using XSL is a very vulnerable technique. You must create a parameterized query and then pass parameter values:

     mdo:sql('select * from a_table where a_field = @a_value', 'table', '@a_value', xpath-for-value)

2. Values of controls are got by mdo:request() function. If we have

     <input type="text" name="a_control" />

We use mdo:request('a_control') to retrieve value on server side.

3. If you need to move user to another page based on values of controls you can use mdo:redirect(path)

Here is a sample of something very similar to what you need:

Here is Live Demo: http://xsltdb.com/trapias.aspx

<!-- create SQL statements -->
<xsl:variable name="sql-roles">
   exec {databaseOwner}[{objectQualifier}GetRoles]
</xsl:variable>
<xsl:variable name="sql-users">
   <!-- this one with parameter: @role -->
   exec {databaseOwner}[{objectQualifier}GetUsersByRolename] 0, @role
</xsl:variable>

Choose Role:
<select name="role" onchange="{mdo:ajax()}">
  <option value="">Any</option>
  <xsl:for-each select="mdo:sql($sql-roles, 'role')//role">
    <option value="{RoleName}">
      <!-- Here we emulate stateful control and set selected atribute -->
      <xsl:if test="mdo:request('role')=RoleName">
        <xsl:attribute name="selected">selected</xsl:attribute>
      </xsl:if>
      {{RoleName}}
    </option>
  </xsl:for-each>
</select>

<br/>Choose User: 
<select name="iduser" id="iduser">
  <option value="0">Any</option>
  <xsl:for-each select="mdo:sql($sql-users, 'table',
        '@role', mdo:request('role', 0))//table">
    <option value="{UserID}">
      <!-- Here we emulate stateful control and set selected atribute -->
      <xsl:if test="mdo:request('iduser')=UserID">
        <xsl:attribute name="selected">selected</xsl:attribute>
      </xsl:if>
      {{DisplayName}}
    </option>
  </xsl:for-each>
</select>

<br/><br/>
<input type="checkbox" name="redirect"/>
Redirect to this URL on submit
(will be appended with ?id=[userid]):
<input type="text" name="url"/>

<!-- submit form and mark submission with @action = save.
this would allow us to distinguish different submissions -->
<br/><br/><a href="{mdo:jsubmit('@action', 'save')}">Submit</a>

<!-- here we check if we are processing appropriate submission -->
<xsl:if test="mdo:param('@action')='save'">
  <xsl:if test="mdo:request('redirect')='on'">
    <xsl:execute select="mdo:redirect(concat(mdo:request('url'), '?id=', mdo:request('iduser')))"/>
  </xsl:if>
  <br/><br/>Selected role name: <b>{{mdo:request('role')}}</b>
  <br/><br/>Selected user ID: <b>{{mdo:request('iduser')}}</b>
</xsl:if>

Here is Live Demo: http://xsltdb.com/trapias.aspx

Developer
Aug 4, 2010 at 3:29 PM
Anton, thank you so so much for your help: the more I use this module, the more I love it! The only problem I find is that it does so many things that I cannot always get the point immediately: I managed to get my form working (but will improve it following your suggestions!), but after that I got a new question mark with server side scripts.

Following the example at http://xsltdb.codeplex.com/wikipage?title=server-side%20scripting I could setup a first version, saved from VStudio (via rich client) of my form using a custom function; I then opened the script on the page, and from that moment I always get an error:

System.Xml.Xsl.XslTransformException: Cannot find the script or external object that implements prefix 'urn:script'. at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args) at <xsl:template match="/">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results) at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XsltArgumentList arguments, XmlWriter results, XmlResolver documentResolver) at Findy.XsltDb.Transformer.DoTransform(XslCompiledTransform t, XmlReader xr, XsltArgumentList xslArg, StringWriter sw) at Findy.XsltDb.Transformer.TransformRelease(String xml, String xsl, Helper h, String html, Boolean IsSuper) at Findy.XsltDb.Transformer.JustTransform(String xsl, String xml, Boolean debug, Boolean IsSuper) at Findy.XsltDb.Transformer.Transform(String xml, String xsl, Boolean IsSuper) at Findy.XsltDb.ViewXsltDb.Page_Init(Object sender, EventArgs e)

I tried saving again from VStudio, adding the script declaration and the script itself at the beginning, before the xsl:template, and also writing it down in "compressed" format on the web page, but still get this error: what's the right way to declare server side scripts? PS: I'm currently running v. 1.1.45.
Developer
Aug 4, 2010 at 5:13 PM
I solved with server side scripts: I just stripped off all comments (like <!-- @@@============= DO NOT EDIT THIS HEADER ============== -->), and saved my xslt directly from the online editor (but also works with Visual Studio and rich client). Now it correctly recognizes my custom script.
Coordinator
Aug 4, 2010 at 8:13 PM

As you can see XsltDb supports 3 forms of XSL: short / medium / full.

  • - full - all tags are manually added to configuration
  • - medium - no stylesheet tag and optionally xsl:output tag
  • - short no xsl:stylesheet, xsl:output and xsl:template tags

XsltDb can determine absense of xsl:stylesheet, xsl:output and xsl:template tag and add them on the fly. This helps keeping simple configurations very small.

XsltDb is also capable of adding namespaces (prefixes) as mdo, msxsl, script, telerik, asp, dnn when required.

But rich client is not so smart as module itself. Rich client tinks that you never switch between forms, it cant automatically add/remove namespaces and tags. So If you use rich client I would recommend to use full XSLT form and controll all tags and prefixes manually. In this case XsltDb won't "correct" your XSL and will work as expected.

Developer
Aug 5, 2010 at 2:02 PM
Anton, I understood this by looking at rich.aspx source: simple and effective, you can really control everything by a full xsl or write down only the necessary code with a short xsl. I like this :-) As for the rich client I have a couple of ideas on how to evolve it, I will send you code as soon as I get something useful. Best Regards, al.