RFC: Moodleforms prototype in 1.7

RFC: Moodleforms prototype in 1.7

by Martin Dougiamas -
Number of replies: 9
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
We've put a prototype of the Moodleforms implementation (that we most recently discussed at the OU Moot) in Moodle 1.7.

The API is based on HTML Quickform (Moodleforms just extends it with a Moodly layer), and produces clean table-less forms with server and client-side validation in a minimum of code and no markup required.

It's still very early and subject to change and no REAL forms will be implemented with in Moodle 1.7.   However, we'd like to try and get the API nailed in 1.7 so that developers can start using it when developing towards 1.8 (the prime feature of which is better accessibility).

To try it out, load the latest 1.7 dev, then visit the course settings page of any course, and change the edit.php in the URL to edit2.php.   The form is not styled properly yet, so it may look kinda ugly, but try it out, kick the tires and look at the code (the main library is cvs:/moodle/lib/formslib.php).

Suggestions for improvement are very welcome!
Average of ratings: -
In reply to Martin Dougiamas

Re: RFC: Moodleforms prototype in 1.7

by Jamie Pratt -
I've been working on the formslib code. Some nice features of the new library will be :

  • forms are entirely laid out with css, which will make them more accessible.
  • client and server side error checking of forms. On error the form fields where there is an error are highlighted and an error message printed.
  • form definition is used to validate submitted form data, so for a form where you have a select or group of checkboxes or radio fields the script will know not to accept submitted data not included as an option in the field.
I've committed the html quickforms library under lib/pear/ and under lib/form/ you can find some classes describing form elements specifically for Moodle which are child classes of quickform form elements.

I'm going to do a little more work on the processing of submitted data to provide functionality similar to optional_param and required_param tommorrow.

Jamie
In reply to Jamie Pratt

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Jamie Pratt -

After discussion with Urs Hunkler we have come up with a proposal for a standard html structure for all forms in Moodle. The html structure should be along the following lines :


<form class="mform" id="formid">
    <fieldset id="fieldsetid">
        <legend>General</legend>
        <div class="fitem">
            <label for="id_s_opentogoogle">Open to Google
                <span class="fshortname">theshortname</span>
                <span class="fhelplink">
                    <a .. >
                        <img src=".." alt="Required field.">
                    </a>
                </span>
                <span class="frequired">...</span>
            </label>
            <div class="felement fcheckbox">
                <input id="id_s_opentogoogle" name="s_opentogoogle" value="1" type="checkbox" />
            </div>
            <div class="fdescription">If you enable this setting....</div>
        </div>
        <div class="fitem">
            <label class="flabel" for="id_shortname">Short name
                <span class="fhelplink">..</span>
                <span class="frequired">
                    <a .. >
                        <img src=".." alt="Required field.">
                    </a>
                </span>
            </label>
            <div class="felement ftext">
                <input type="text"  name="shortname" id="id_shortname" value=""/>
            </div>
        </div>
        <div class="fitem">
            <label>Course enrollable
                <span class="fhelplink">..</span>
            </label>
            <!--a group of elements with just one label -->
            <!--ids are randomly generated and labels match-->
            <div class="felement fgroup">
                <input type="radio" id="f84d3be" value="0" name="enrollable">
                <label for="f_84d3be">No</label>
                <!--if required you could put a <br /> in here -->
                <input type="radio" id="f2864a1" value="1" name="enrollable">
                <label for="f2864a1">Yes</label>
                <!--if required you could put a <br /> in here -->
                <input type="radio" checked="checked" id="f6fd32b" value="2" name="enrollable">
                <label for="f6fd32b">Date range
                </label>
            </div>      
        </div>
        <div class="fitem">
            etc.

        </div>
    </fieldset>
    <!-- this fieldset doesn't have a visible border-->
    <fieldset class="hidden">
        <div class="fitem">
            <!-- although we don't have a label in here we can include 
                    a label tag just because then we can use a common style for 
                    layout -->
            <label for="id_submit"></label>
            <div class="felement fsubmit">
                <input type="submit" value="Save changes" name="submit" id="id_submit">
            </div>
        </div>
        <br />
        <span class="fhelplink">
            <a .. >
                <img src=".." alt="Required field.">
            </a>
        </span> denotes required field.

    </fieldset>
</form>
In reply to Jamie Pratt

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Jamie Pratt -
Following further discussion we've made a couple of changes (and my editing time has expired mixed Here is the revised version :

<form class="mform" id="formid">
<fieldset id="fieldsetid">
<legend>General</legend>
<div class="fitem">
<label for="id_s_opentogoogle">Open to Google
<span class="fshortname">theshortname</span>
<span class="helplink">....</span>
<span class="helplink">
<a .. >
<img src=".." alt="Required field.">
</a>
</span>
</label>
<div class="felement fcheckbox">
<input id="id_s_opentogoogle" name="s_opentogoogle" value="1" type="checkbox" />
</div>
<div class="fdescription">If you enable this setting....</div>
</div>
<div class="fitem">
<label class="flabel" for="id_shortname">Short name
<span class="helplink">..</span>
<span class="helplink">
<a .. >
<img src=".." alt="Required field.">
</a>
</span>
</label>
<div class="felement ftext">
<input type="text" name="shortname" id="id_shortname" value=""/>
</div>
</div>
<div class="fitem">
<label>Course enrollable
<span class="helplink">..</span>
</label>
<!--a group of elements with just one label -->
<!--ids are randomly generated and labels match-->
<div class="felement fgroup">
<input type="radio" id="f84d3be" value="0" name="enrollable">
<label for="f_84d3be">No</label>
<!--if required you could put a <br /> in here
elements align beside one another,
with <br /> they align below each other. -->
<input type="radio" id="f2864a1" value="1" name="enrollable">
<label for="f2864a1">Yes</label>
<!--if required you could put a <br /> in here -->
<input type="radio" checked="checked" id="f6fd32b" value="2" name="enrollable">
<label for="f6fd32b">Date range
</label>
</div>
</div>
<div class="fitem">
etc.

</div>
</fieldset>
<!-- this fieldset doesn't have a visible border-->
<fieldset class="hidden">
<div class="fitem">
<!-- although we don't have a label in here we can include
a label tag just because then we can use a common style for
layout -->
<label for="id_submit"></label>
<div class="felement fsubmit">
<input type="submit" value="Save changes" name="submit" id="id_submit">
</div>
</div>
<div class="fdescription">
<span class="helplink">
<a .. >
<img src=".." alt="Required field.">
</a>
</span> denotes required field.
</div>
</fieldset>
</form>
In reply to Jamie Pratt

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Nick Freear -
Dear Jamie and Urs

I'm snowed under here, but have a few thoughts regarding accessibility/usability for the forms work. First, I like the use of <label>, <fieldset> and <legend>.

Have you considered using lists in the form? Prettier accessible forms has some useful ideas. Also, if the final <div> "denotes required field" is an explanation, then this should probably go at the top of the form.

Must dash, but I've copied and modified your HTML below.

Nick

<form class="mform" id="formid">

        <div class="fdescription">
            <span class="helplink">
                <a .. >
                    <img src=".." alt="Required field.">
                </a>
            </span> denotes required field.
        </div>    

    <fieldset id="fieldsetid">
        <legend>General</legend>
        
        <ol>
        <li class="fitem">
            <label for="id_s_opentogoogle">Open to Google
                <span class="fshortname">theshortname</span>
                <span class="helplink">....</span>
                <span class="helplink">
                    <a .. >
                        <img src=".." alt="Required field.">
                    </a>
                </span>
            </label>
            <div class="felement fcheckbox">
                <input id="id_s_opentogoogle" name="s_opentogoogle" value="1" type="checkbox" />
            </div>
            <div class="fdescription">If you enable this setting....</div>
        </li>
        <li class="fitem">
            <label class="flabel" for="id_shortname">Short name
                <span class="helplink">..</span>
                <span class="helplink">
                    <a .. >
                        <img src=".." alt="Required field.">
                    </a>
                </span>
            </label>
            <div class="felement ftext">
                <input type="text"  name="shortname" id="id_shortname" value=""/>
            </div>
        </li>

        <li class="fitem">
            <label>Course enrollable
                <span class="helplink">..</span>
            </label>
            <!--a group of elements with just one label -->
            <!--ids are randomly generated and labels match-->
            <div class="felement fgroup">
                <input type="radio" id="f84d3be" value="0" name="enrollable">
                <label for="f_84d3be">No</label>
                <!--if required you could put a <br /> in here
                    elements align beside one another,
                    with <br /> they align below each other. -->
                <input type="radio" id="f2864a1" value="1" name="enrollable">
                <label for="f2864a1">Yes</label>
                <!--if required you could put a <br /> in here -->
                <input type="radio" checked="checked" id="f6fd32b" value="2" name="enrollable">
                <label for="f6fd32b">Date range
                </label>
            </div>     
        </li>
        <li class="fitem">
            etc.

        </li>
        </ol>
    </fieldset>

    <fieldset>
        <legend></legend>
        <ol>
            <li>...
            </li>
        </ol>
    </fieldset>

    <!-- this fieldset doesn't have a visible border-->
    <fieldset class="hidden">
        <div class="fitem">
            <!-- although we don't have a label in here we can include
                    a label tag just because then we can use a common style for
                    layout -->
            <label for="id_submit"></label>
            <div class="felement fsubmit">
                <input type="submit" value="Save changes" name="submit" id="id_submit">
            </div>
        </div>

    </fieldset>
</form>
In reply to Nick Freear

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Urs Hunkler -
Picture of Core developers

Dear Nick,

@ "Have you considered using lists in the form? Prettier accessible forms has some useful ideas."

No I haven't. I read the ALA article with interest. But after reading the ALA article I see major differences between the simple form example they show and the much more complex Moodle forms like course edit or the admin forms.

Where do you see the advantage in using <ol> and <li> as containers against <div>? With CSS you can handle many container types nearly the same, you can even tell some to behave like another type as you often do with the <ul> and <li> tags.

In the complex Moodle forms we must handle <ol> and <li> like <div> and loose any advantage they have in simple forms. These easily can be thought as lists of items. Complex forms I would never perceive mainly as a list.

From the semantic point of view fieldsets with legends and the label/item pairs give an optimal impression about the type of information you deal with. What is the advantage to add another semantical level with the information that you work with a list especially when there is no "real" list?

I see <ol> and <li> only as another option to get the same result as the one Jamie showed. Nick, I am very interested to hear about the advantages you see.

The argument that some screen readers inform about the number of items in <ol> is interesting indeed. But does it really help when I know that there are 3 or 7 or 2 items following? I don't know.

One point to keep in mind is that the descriptions could have lists too and then we may face a similar situation as in the Moodle course pages. There you must be very careful with lists in your content and the CSS for them.

Looking forward to your answer
Urs

In reply to Nick Freear

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Jamie Pratt -
Hi Nick,

We see in the ALA example that in some places they include the item into the <label> and place the text behind the item (instead of using the for attribute). We notice they nest the input element when the label is written behind the item. We wonder if there is an accessibility advantage to this. Maybe the screen readers read the text before the item when the item is nested in the label???

I was all for lists but Urs pointed out that lists inherit from the lists they are nested in so styling may become a little more complex and might possibly cause problems with nested content. Better to keep it simple if possible. But I've experimented and it is fairly simple to make moodleforms produce lists. I've commented out the code I added to do this. We can put it back in if the consensus weighs in for this.

Jamie




In reply to Jamie Pratt

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Jamie Pratt -
It will also becokme fairly easy to customize the structure of the html used to lay out the form items since there will be one or two places to edit.

If there is enough demand we could pull php templates out of theme directories I guess, to allow customisation with theme plug ins.

Jamie
In reply to Nick Freear

Re: RFC: Moodleforms prototype in 1.7 -- html structure

by Urs Hunkler -
Picture of Core developers

One addition:

on the FormElements page of CSS-Discuss the following sentence is important.

"Firefox 1.0 ... Hmm... basically fieldsets are incredibly buggy in Firefox and will drive you insane."

Firefox 1.5 does not behave much better as I know from my experience from the actual work on Moodle forms. Firefox renders fieldsets really quite strange.

Will lists make live easier or even more difficult?

Urs

In reply to Jamie Pratt

Re: RFC: Moodleforms prototype in 1.7

by Jamie Pratt -
Me and Urs agreed that :
  • the css for laying out the form should go in the form section of the styles_layout.css in the standard theme.
  • it might be a good idea to have a universal function call to wrap the html a form item in appropriate html. This could be used to quickly replace code using tables as an alternative to moodle forms for transforming old code only. We thought it might be a good idea to move the function in the admin libs which is being used to layout forms in to weblib.php
  • Urs will be working on making one unified set of css styles for moodleforms, the admin settings forms and possible other forms to be converted throughout the site with function calls to layout form items.