1

I'm new in moodle and I always programmed at client-side. I think maybe I'm missing something because of that reason. I need to provide the user with diverse UI elements, according to what he selects in a combo. So I was thinking in writing the lements according to a strategy (design pattern). From an object in the mod_form.php, I was trying to execute something like this:

$this -> _form  -> addElement('select', 'displayStrategy', get_string('displayStrategy', 'xForum'), $displayStrategy, array('onchange' => 'javascript: function loadStrategy(selVal){

$.ajax({
 type: "POST",
 url: "../mod/xForum/action/displayStrategy.php",
 data: { class: selVal }
}).done(function( msg ) { 
 console.log("Strategy was executed");
});
}; loadStrategy(this.value);') ); 

That is being executed and the log is printed in the console, but the content in displayStrategy.php is never executed, a "loading" effect is added to the current view and a last problem is I also need to call a function in the same object that is writting the UI ( the one in mod_form.php that executes all the $this -> _form -> addElement(...))

Can you give me a hand? How can I execute those methods according to the strategy?

Thanks a lot!

gal007
  • 6,911
  • 8
  • 47
  • 70

2 Answers2

3

My answer is similar to Andres Ramos's answer

First, add a separate js file in your PHP file to write your JS function.

require_js("./class-section.js"); 

In this file write below, encodeURI for sending space too.

function fetchSectionsfromclassName() {
        var class= $('#id_user_create_grade').val();
        $('#id_user_create_section').load('getter.php?className=' + encodeURI(class));
}

Now above function requires a getter.php file So create a new gettter.php file where you will fetch section from className. I have a table lo_sections in database that has two column 'class' and 'section'. In getter.php write this

<?php
require_once("../config.php");
global $DB;

// Get the parameter
$className = $_GET['className'];
if($className) {
    $sections =  $DB->get_records('lo_sections', array('class' => $className));
    foreach ($sections as $key => $value) {
        echo "<option value=".$value->section.">" .$value->section . "</option>";
    }
}

In your PHP file where you want to add two dropdowns write this here the first dropdown is for class and second for a section like (A, B, C)

$attributes =  array('onchange' => 'javascript:fetchSectionsfromclassName()');
$defaultOption = array("NA" => "NA");
$mform->addElement('select', "user_create_class", 'class', $this->options, $attributes);
$mform->addElement('select', 'user_create_section', 'Section', $defaultOption);
Abhi
  • 1,127
  • 1
  • 12
  • 25
2

I did the following to achieve this:

  1. Put your script on a separate document and call it within your file_form.php:

    // Get data dynamically based on the selection from the dropdown
    $PAGE->requires->js(new moodle_url('/blocks/mymodulename/js/myscript.js'));
    
  2. The file myscript.js has the ".change" functions to identify when the "select" was changed and ".load" to get the data from the file getter.php passing the parameter from the select that changed. Also notice the prefix #id_ before departmentid and studentid, if you inspect the elements, that's how the are actually called.

    window.onload = init;
    
    function init() {
    
        // When a select is changed, look for the students based on the department id
        // and display on the dropdown students select
        $('#id_departmentid').change(function() {
            $('#id_studentid').load('getter.php?departmentid=' + $('#id_departmentid').val());                                
        });
    
    }
    
  3. On the getter.php file, capture the parameter sent through $_GET method, do your query and echo your results. So file getter.php would look like this:

    <?php 
    require_once("../../config.php");
    global $DB;
    
    // Get the parameter
    $departmentid = optional_param('departmentid',  0,  PARAM_INT);
    
    // If departmentid exists
    if($departmentid) {
    
        // Do your query 
        $query = 'SELECT * FROM {table_without_prefix} WHERE departmentid = ' . $departmentid;
        $student_arr = $DB->get_records_sql($query, null,  $limitfrom=0,  $limitnum=0);
    
        // echo your results, loop the array of objects and echo each one
        echo "<option value='0'>All Students</option>";
        foreach ($student_arr as $student) {
            echo "<option value=".$student->id.">" . $student->fullname . "</option>";  
        }
    
    }
    ?>
    
  4. Finally your file_form.php would have the 2 selects, one with the options, and the other with where you need to show the results.

    $mform->addElement('select', 'departmentid', "Select Department", $department_array);
    $student_array = array("All Students");
    $mform->addElement('select', 'studentid', "Select Student", $student_array);
    

Also, make sure to add the following function so you can properly read the data when using $form->get_data();

function get_data(){
    global $DB;

    $data = parent::get_data();

    if (!empty($data)) {
        $mform =& $this->_form;

        // Add the studentid properly to the $data object.
        if(!empty($mform->_submitValues['studentid'])) {
            $data->studentid = $mform->_submitValues['studentid'];
        }

    }

    return $data;
}
  1. Here is a quick video of the results: http://screencast.com/t/KDtiWzDN

I hope it helps!

Andres Ramos
  • 330
  • 4
  • 13