DEV Community

Cover image for Extending Moodle forms
hribeir0
hribeir0

Posted on

Extending Moodle forms

While not possible on every forms, most of the existing moodle forms are extendable whether by extending classes or by using callbacks - which in Wordpress are known by hooks. Also, Moodle forms are based on PEAR's QuickForm API so that can be useful information. I learned that recently (well all my dev work on Moodle is recent) when needed to add 2 new form fields on different contexts: in the new user auto-registration form and also when editing or adding an assignment activity.

I started by checking if any of the existing callbacks could help me with this and I was able to find _type_myplugin_extend_signup_form() and type_myplugin_coursemodule_standard_elements().

Extending Sign-up form

The first one would allow me to add an extra field in the registration form. Simply:

function theme_stream_extend_signup_form($mform) {
    // Inject a static element of the word 'injected'
    $html = '<div class="alert alert-primary" role="alert">
        This is a primary alert—check it out!
         </div>';
    $mform->addElement('static', 'injectedstatic', $html);
 }
Enter fullscreen mode Exit fullscreen mode

This is great! It works and adds a new static element identified by an id generated based on 'injectedstatic' as a last item on my sign up form. But it makes sense to have the warning before the relevant field, so how can I move my static element before, let's say the email field? JS could be used to move that item, but what horrendous hack would that be... Moodle should have a way right?

I'll give you insertElementBefore() Like you can imagine, this adds a form element before an existing one (if you want to move it around you would need to remove it before).

However, you also need to create it before inserting it so your code should be:

function theme_stream_extend_signup_form($mform) {
    // Inject a static element of the word 'injected'
    $html = '<div class="alert alert-primary" role="alert">
        This is a primary alert—check it out!
         </div>';
    $warning = $mform->createElement('static', 'warning', $html);
    $mform->insertElementBefore($warning, 'email', $html);
 }
Enter fullscreen mode Exit fullscreen mode

At this point, it is important to note that if you want to add a new field to your sign-up form, the best approach would be to create a custom profile field and make it available in the sign-up process/page. No code and 100% functional - custom profiles will be placed last on the form, but using the callback you can removeElement() and insertElementBefore().

$mform->insertElementBefore($mform->removeElement('country'), 'email');
Enter fullscreen mode Exit fullscreen mode

Extending Mod Assign form

Imagine that I want to add a warning when people add or edit an assignment. The form fiddling is pretty much done the same way, so the only difference is that we need to check if this form belongs to mod_assign or not because type_myplugin_coursemodule_standard_elements() is called on every mod.

For that, we do $cm = $formwrapper->get_current(); to get current form information and with a simple if we check if ($cm->modulename == 'assign') {}

The final code could be something like this:

function type_myplugin_coursemodule_standard_elements(moodleform_mod $formwrapper, MoodleQuickForm $mform) {
    $cm = $formwrapper->get_current();
    // Skip right away.
    if (!isset($cm) || $cm->modulename != 'assign') {
        return;
    }

    if ($cm->modulename == 'assign') {

        $html = '<p>my extra info</p>';
        $element= $mform->createElement('static', 'extraelement', '', $html);
        $mform->insertElementBefore($element, 'teamsubmission');

    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)