Dialogs are used in Totara to let you pick one or more items from a hierarchy. For instance, you can pick courses inside a learning plan using a dialog.

Architecture of A Totara Dialog Box

Let’s take /totara/plan/components/objective/find-course.php as an example. This file contains code to instantiate a dialog class and output the markup for the dialog. You use your own extension of the totara_dialog_content class to determine the options in the dialog box. For instance, to disable the framework picker for the goals dialog box, you would set:

public $display_picker = false;

(In /totara/core/dialogs/dialog_content_goals.class.php, or your own copy).

You can call the /totara/plan/components/objective/find-course.php script directly, to see what it outputs:


But normally, it’s included by the javascript inside /totara/plan/components/objective/find-course.js, which itself is included through /totara/plan/components/objective/view.php:

$jsmodule = array(
    'name' => 'totara_plan_objective_find_course',
    'fullpath' => '/totara/plan/components/objective/find-course.js',
    'requires' => array('json'));
  array('args' => '{"plan_id":'.$id.',"objective_id":'.$caid.'}'), 

Please note that javascript files are normally loaded using the function local_js() (defined in local/js/lib/setup.php).

The javascript file find-course.js initializes the dialog popup (line 106):

totaraDialogs['evidence'] = new totaraDialog(
        buttons: buttonsObj,
        title: '<h2>' + M.util.get_string('addlinkedcourses', 
          'totara_plan') + '</h2>'

The javascript totaraDialog prototype is defined here: /totara/core/js/lib/totara_dialog.js

Displaying Linked Items in The Dialog

Items which have already been selected (or linked) are displayed in gray. To set the selected items, use the “selected_items” property of your dialog class (an extension of totara_dialog_content defined in /totara/core/dialogs/dialog_content_goals.class.php):

$dialog->selected_items = $selected;

The linked (or selected) items are identified based on their original id. So, if you retrieve the linked items from an association table, you should not use the association table’s id column, but the linked item’s id. E.g.:

$linked_goals = objective_goal::get_linked_goals($objectiveid);
$selected = array();
foreach($linked_goals as $linked_goal) {
    $linked_goal->id = $linked_goal->goalid;
    $selected[$linked_goal->goalid] = $linked_goal;
$dialog->selected_items = $selected;


/totara/core/js/lib/totara_dialog.js has a _save which uses the default url (line 589):

totaraDialog_handler.prototype._save = function(url) {

But /totara/plan/components/objective/find-course.js adds its own _save handler to a button which is passed along to totaraDialog during the initialization (line 103):

buttonsObj[M.util.get_string('save','totara_core')] = function() { handler._save(saveurl); }

In the end, the js file calls the php update script, e.g. /totara/plan/components/objective/update-course.php, line 98 (see also the next part of this tutorial):

var saveurl = url + 'update-course.php?planid='+ // etc

Updating The Page through Ajax

In the case of the Linked Courses section on the Objectives tab (so, /totara/plan/components/objective/view.php?id=1&itemid=1), the page is updated if you save a linked course. The javascript calls this php script to produce the updated output:


The javascript also contains an update handler, which is presumably a callback function (line 74 of /totara/plan/components/objective/find-course.js):

totaraDialog_handler_preRequisite.prototype._update = function(response) {

Removing Items

The items displayed in a dialog usually cannot be deleted (removed) there. Instead, on the main page you’ll see a submit button, e.g. “Remove linked courses”. This button submits to the main page itself, with a specific action, e.g. in /totara/plan/components/objective/view.php:

    if ($action === 'removelinkedcourses' && !$plan->is_complete()) {
	//... call removal code here

Personal Tools