Handling form submit event

Re: Handling form submit event

by Kevin Burton -
Number of replies: 7

Would you be able to direct me to where documentation is better?

In reply to Kevin Burton

Re: Handling form submit event

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

See the link Andrew gave above.

In reply to Tim Hunt

Re: Handling form submit event

by Kevin Burton -

I tried that. 

I have PHP code on my page that looks like:

$PAGE->requires->yui_module('moodle-mod_mediasite-search', 'M.mod_mediasite.search.init');

Thie JavaScript then looks like:

 

YUI.add('moodle-mod_mediasite-search', function(Y) {
M.mod_mediasite = M.mod_mediasite || {};
M.mod_mediasite.search = {
baseurl: null,
site: null,
resourceId: null,
tooltip: new Y.Overlay({width: 200, visible: false}),
searchprogress: new Y.Overlay({width: 200, visible: false}),
init: function() {

But when the page executes I get:

Uncaught TypeError: Cannot read property 'search' of undefined

Also there doesn't seem to be any mention on this page on using the function to handle a form submission that is part of the Moodle YUI library. Ideas?

 

In reply to Kevin Burton

Re: Handling form submit event

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Hi Kevin,

That generally happens because you've got some kind of issue in your code somewhere.

I've just knocked up a super quick example for you (attached).

If you unzip this folder into your mod_mediasite plugin, and add a call somewhere in your PHP to the following, then this should give you a working example to play with:

$PAGE->requires->yui_module('moodle-mod_mediasite-search', 'M.mod_mediasite.search.init', array(array('formid' => 'someFormId')));

For reference, your directory structure will look something like the following:

3554 /private/srv/www/loganberry.local/public_html/sm/mod:master> tree mediasite/
mediasite/
├── lang
│   └── en
│       └── mediasite.php
├── lib.php
├── mod_form.php
├── version.php
├── view.php
└── yui
    └── search
        └── search.js

4 directories, 6 files

Hope that this helps,

Andrew

Average of ratings: Useful (1)
In reply to Andrew Lyons

Re: Handling form submit event

by Kevin Burton -

Thank you very much. It seems much simpler when you lay it out like that. Very much appreciated.

Not to be ungrateful but would you mind showing me how I would use Y.io to post back? I want all of the global variables properly filled in so it appears as a "normal" postback.

Thanks again.

In reply to Andrew Lyons

Re: Handling form submit event

by Kevin Burton -

Progress I now am getting to the 'init' function. But for some reason my handler for the submit event doesn't seem to be called. I have:

M.mod_mediasite.search = {
. . . . .
form: null,
eventHandlers: [],

. . . . . .


init: function(formid) {
this.form = Y.one('#' + formid);
if(!this.form) {
console.log('The form identified by ' + formid + ' could not be found.');
}
this.eventHandlers.push(
this.form.on('submit', this.handleSubmission, this)
);

And the actual handler right now simply notes that the submit has happened:

handleSubmission: function(e) {
console.log('submitted');
},

 

I looked on the console.log (using Chrome) I didn't see this message. Ideas?

In reply to Kevin Burton

Re: Handling form submit event

by Andrew Lyons -
Picture of Core developers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers Picture of Testers

Apologies for the delays in my replies - I've had a busy couple of days.

Looking at this code, I'm not sure why your submission event isn't being called at present. It looks correct to me at a glance.

I assume you've tried stepping through with the JS debugger to make sure that the event is actually added. If you add a breakpoint on the eventHandlers.push and walk over, you can be sure. You can also run the following in your JS console to see those handlers (you'll need to be paused in the correct context in order to do so):

this.eventHandlers

My first guess though would be that you're not providing the correct formid to the init function. If you add a breakpoint at the this.form line, and then check what formid you're getting I think you'll find that formid is an object containing a formid. Normally we call this params, or args, or something. Personally, I quite like using the Y.Base class which includes a feature called Y.Attribute, but we'll leave that for another time for the moment as it complicates things somewhat.

So perhaps, try changing your code to:

init: function(args) {
    console.log(args);
    this.form = Y.one('#' + args.formid);
    if (!this.form) {
        Y.log('The form identified by ' + args.formid + ' could not be found. Bailing', 'warn', 'moodle-mod_mediasite-search');
        return;
    }

    // Add the submission events:
    this.eventHandlers.push(
        this.form.on('submit', this.handleSubmission, this);
    );
    
},

handleSubmission: function(e) {
    Y.log('Handling a submission event', 'debug', 'moodle-mod_mediasite-search');

// We must prevent the default browser action, otherwise the browser will redirect.
e.preventDefault(); }

You'll notice that I've used Y.log in a few places here. Y.log is filtered by YUI such that messages are not displayed when you do not have DEBUG_DEVELOPER set as your Moodle DEBUG setting. You may also know this setting as:

$CFG->debug = (E_ALL | E_STRICT);

The second argument to Y.log is the log category/level - choices are debug, info, warn, and error. The third argument is the source - this should be the module name. I'm writing some changes to make debugging easier at the moment which will utilise these more. It will mean that when your'e debugging your own module, you only get the messages you care about which should make life much easier.

You'll also notice that I've called preventDefault() on the event in handleSubmission. Without this, the page will submit anyway. See https://developer.mozilla.org/en-US/docs/Web/Reference/Events/submit for more information on the submit event.

Regarding your other question on how to use Y.io to submit the form, I've not tried this myself, but there is documentation on the YUI docs page. See http://yuilibrary.com/yui/docs/io/#serializing-html-form-as-data for more information. You're particularly interested in the form object being passed in the configuration. This is documented at http://yuilibrary.com/yui/docs/api/classes/IO.html#method_send.

You'll also want to take a peek at how we handle errors returned by IO requests. Here's an example of how we do so in Moodle in other places: https://github.com/moodle/moodle/blob/master/lib/yui/src/tooltip/js/tooltip.js#L372.

In order for the JS to realistically parse the content, you need to return a JSON object structure. This is easily achieved with a combination of adding the following to your AJAX script (the PHP side) before you require the Moodle configuration:

define('AJAX_SCRIPT', true);

And when you output content, add your return data to an Array or stdClass and return it with

echo json_encode($return);

Again, you can see an example of a basic Moodle AJAX script at https://github.com/moodle/moodle/blob/master/lib/help_ajax.php.

By doing this, you'll see that any Exceptions thrown by Moodle are correctly encoded and displayed in a dialogue to the user. Additionally, if the return value is not JSON, a message is displayed to the user.

Hope that this helps,

Andrew

In reply to Andrew Lyons

Re: Handling form submit event

by Kevin Burton -

Thank you for your continued help. I have been using console.log instead of Y.log because I wasn't sure what the best way of showing the log output. I know about 'render()' but it seemed more straightforward to just CTRL-SHIFT-J to see the log output. Maybe you have a better solution.

Anyway the results are the same I see the log entry for when I register the submit event but I do not see the log entry when I enter the handler. There was one important (now it seems important) I don't see the log entry when I don't have the call to preventDefault(). When I put that call in I see the log entry. I guess there isn't a way for me to just be a "fly on the wall" and everything proceeds as normally with me just listening?