DEV Community

Cover image for Extending Moodle forms
hribeir0
hribeir0

Posted on

2

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

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay