← Back to team overview

schooltool-developers team mailing list archive

Re: jQuery UI modal dialogs findings

 

On 05/20/2011 05:18 AM, Douglas Cerna wrote:
[warning: tl;dr threat below, so have your coffee next to you...]

Hey everybody.

I've created a branch for my experiments with jQuery UI. It's at:

lp:~replaceafill/schooltool/schooltool_jquery-ui

Also, I've set up a testing instance at: http://69.164.203.135:7080 You will want to add a course.

  Nice work! (and a personal thankyou for the test instance ;) )

Here's what I've done so far:

0. I download the default js and theme files and added them as resources to the default skin.
  Ok...  unless menesis finds them packaged somewhere of course ;)

1. I ported the add form for courses to z3c.form. The current form is implemented using an<addform ...>  zcml directive. Please, let's kill those :)

  +1 :)

2. Having the new form ported to z3c.form makes easy to extract specific parts of it using the macros provided for each part of the form (header, errors, form body, buttons, etc).

Let's assume that at some point our (form) views will be able to render themselves in "inline format".

3. So, I subclassed this new form into a new view that renders only the<form>...</form>  part and I attached javascript behaviour to the two form buttons (Add and Cancel). This behaviour allows the form to send the POST data and receive the response using jQuery, so we avoid the full reload of the page. Any validation error is inserted into the form body using jQuery. This "inline" form works correctly by its own.

Cool. Though I'm a bit concerned with the amount of customization done in the "inline" course view class.

4. For the last step, I customized the course container view to create the actual jQuery UI dialog and insert the inline form. The set up of the dialog uses only four self-explaining options:

* autoOpen: false,
* modal: true,
* resizable: false,
*draggable: false

The width of the dialog is calculated based on the width of the inserted form:

width: $(addform_id).find('form').width() + 30

and the height of the dialog adjusts itself to height of the inserted form (when the form displays validation errors, the dialog resizes automatically).

  Great!

Finally, the container view attaches all the javascript behaviour to the "New Course" action button and shows all this functionality only if the user can edit the container (remember that the course container view is public).

Oh, a very good point there. What happens if the session expires and user gets magically redirected to login screen while clicking in such dialog?

Some comments and questions:

* We're not using jQuery modal forms per se. Just a modal dialog. This means that the dialog doesn't have any buttons. However, inserting the whole form in the dialog saves us trouble regarding, client vs server validation and translations. You can see the translations working in the inserted form in the testing instance. I enabled two languages, English and Spanish. You can change between them using the links next to the "Log Out" link.

  I think this worked out pretty well.

* Our default z3c-schooltool-form.pt template renders the ul.errors element conditionally. For the inserted form I needed something that was always rendered, so I used div.required-info for displaying the errors. No biggie, it can be fixed easily.

  I would prefer a full form reload here.

* The dialog is reused, this means that if the user closes the dialog or clicks the Cancel button, the data and validation errors are kept and displayed again if the user clicks the "New Course" button again. You can test this: click "New Course", click Add (you'll get a validation error), click Cancel (or click the X in the dialog title bar or press ESC), click "New Course" again and you will see that the validation error is still there. We could retrieve a new form on each click on "New Course" if you think that's appropriate.

A full form reload here would be arguably nicer. Also, maybe we could avoid loading *all* forms on page load.

* Justas and I already talked about having a better way to attach JavaScript behaviour to our action buttons, and I think he has an idea on how to do it.

Form id seems to be generated by the view. If somebody writes "add student" and "add teacher" views but forgets to make their ids different, could this be a problem? Two forms with same id in the page? Say "gradebook" and "gradebook"?..

If action button JS is added by action button viewlets themselves, they could append, say, their adapter names or such to the loaded form div.

* Finally and less importantly, we should roll out a jQuery UI theme with SchoolTool colors. That orange title bar for the dialogs looks weird.

  Yes, they do look odd.  But that's for the (near) future.

My next goal with this task is the datepicker. Specifically, how to display the appropriate translation based on the browser's locale.

Feedback and comments are welcome.

  A very nice prototype!

  A mental exercise...

  Can we write a pure JS function, that, given an action button:

    1. takes it's target link
    2. creates a jQuery dialog
3. loads the inline version of the target page (action button link); it should put some variable in the request header asking the page to render the inline version or something, then ST machinery could parse the (get/post) headers and either render the inline version of the target page if available or return an empty redirect to the target page. 4. whenever our function recieves a result header with redirect, window.location is set to the redirect target, if not - dialog div's contents are replaced with result contents 5. the function binds all form buttons to post the form and do step 4 with the results

TT wizard could work; calendar event adding + resource booking could work; container delete confirmations could work. Step 5 is very risky, of course. We probably don't want to bind with ALL buttons in the page. Maybe only those without onclick set. And we may want to bind cancel button to submit the form and close the dialog.

Cheers,
Justas



Follow ups

References