Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a dynamic (AJAX) filter form #190

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 88 additions & 21 deletions filter/filter_form.php → classes/filter_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
defined('MOODLE_INTERNAL') || die();

require_once("$CFG->libdir/formslib.php");
use core_form\dynamic_form;

/**
*
*/
abstract class mod_datalynx_filter_base_form extends moodleform {
abstract class mod_datalynx_filter_base_form extends dynamic_form {

protected $_filter = null;
protected $_customfilter = null;
Expand All @@ -39,16 +40,57 @@ abstract class mod_datalynx_filter_base_form extends moodleform {
*/
protected $_df = null;

/*
*
*/
public function __construct($df, $filter, $action = null, $customdata = null, $method = 'post', $target = '',
$attributes = null, $editable = true, $customfilter = false) {
$this->_filter = $filter;
$this->_customfilter = $customfilter;
$this->_df = $df;
public function get_context_for_dynamic_submission(): context {
return \context_system::instance();
}

parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
public function check_access_for_dynamic_submission(): void {
// TODO: Implement permissions check.
return;
}

public function set_data_for_dynamic_submission(): void {
$datalynx_id = $this->_ajaxformdata["d"];
$filter_id = $this->_ajaxformdata["fid"];

if ($datalynx_id == null || $filter_id == null) {
return;
}

$this->_df = \mod_datalynx\datalynx::get_datalynx_by_instance($datalynx_id);
$fm = $this->_df->get_filter_manager();
$this->_filter = $fm->get_filter_from_id($filter_id);

// Update filter parameters based on the current form data (in order to dynamically render new form fields for filter details):
if ($this->_ajaxformdata["update"] && confirm_sesskey()) {
$procesedfilters = $fm->process_filters_for_ajax_refresh('update', $filter_id, $this, true);
$this->_filter = $procesedfilters[0];
}
}

public function process_dynamic_submission() {

$datalynx_id = $this->_ajaxformdata["d"];
$filter_id = $this->_ajaxformdata["fid"];

if ($datalynx_id == null || $filter_id == null) {
return;
}

$this->_df = \mod_datalynx\datalynx::get_datalynx_by_instance($datalynx_id);
$fm = $this->_df->get_filter_manager();
$this->_filter = $fm->get_filter_from_id($filter_id);

if ($this->_ajaxformdata["update"] && confirm_sesskey()) { // Add/update a new filter.
$procesedfilters = $fm->process_filters_for_ajax_submission('update', $filter_id, $this, true);
$this->_filter = $procesedfilters[0];
}

return $this->_df->notifications;
}

public function get_page_url_for_dynamic_submission(): moodle_url {
return new moodle_url('/mod/datalynx/view.php', array('id' => $this->_df->id));
}

/*
Expand Down Expand Up @@ -214,9 +256,6 @@ public function custom_search_definition($customsearch, $fields, $fieldoptions,
$mform->disabledIf("searchoption$count", 'searchandor' . ($count - 1), 'eq', 0);
}
}

$mform->registerNoSubmitButton('addsearchsettings');
$mform->addElement('submit', 'addsearchsettings', get_string('reload'));
}

/*
Expand Down Expand Up @@ -259,15 +298,18 @@ public function html() {

class mod_datalynx_filter_form extends mod_datalynx_filter_base_form {

public function definition() {}

/*
*
*/
public function definition() {
public function definition_after_data() {
$df = $this->_df;
$filter = $this->_filter;
$name = empty($filter->name) ? get_string('filternew', 'datalynx') : $filter->name;
$description = empty($filter->description) ? '' : $filter->description;
$visible = !isset($filter->visible) ? 1 : $filter->visible;

$fields = $df->get_fields();
$fieldoptions = array(0 => get_string('choose')) + $df->get_fields(array('entry'), true);

Expand Down Expand Up @@ -334,10 +376,25 @@ public function definition() {

$this->custom_search_definition($filter->customsearch, $fields, $fieldoptions, true);

// Hidden fields to track the Datalynx instance and the filter id.
if ($df !== null) {
$mform->addElement('hidden', 'd', $df->id());
}
if ($filter !== null) {
$mform->addElement('hidden', 'fid', $filter->id);
}
$mform->addElement('hidden', 'refreshonly', '0');
$mform->addElement('hidden', 'update', '1');

// Buttons.
$this->add_action_buttons(true);
}

public function get_ajax_form_data() {
// Convert to stdClass:
return json_decode(json_encode($this->_ajaxformdata));
}

/**
* @param array $data
* @param array $files
Expand All @@ -346,16 +403,26 @@ public function definition() {
*/
public function validation($data, $files) {
$errors = parent::validation($data, $files);
if (array_key_exists('refreshonly', $data)) {
if ($data['refreshonly'] == '0') {

$df = $this->_df;
$filter = $this->_filter;
$df = $this->_df;
$filter = $this->_filter;

// Validate unique name.
if (empty($data['name']) || $df->name_exists('filters', $data['name'], $filter->id)) {
$errors['name'] = get_string('invalidname', 'datalynx',
get_string('filter', 'datalynx'));
// Validate unique name.
if (empty($data['name']) || $df->name_exists('filters', $data['name'], $filter->id)) {
$errors['name'] = get_string('invalidname', 'datalynx',
get_string('filter', 'datalynx'));
}
} else {
// If we do not return any error after a submission, the form will
// be regarded as submitted and will render empty.
// We need to return a dummy error to prevent this.
// This also prevents process_dynamic_submission from being executed in this case,
// as the form gets no validated flag:
$errors['dummy_error_for_refreshing'] = 'dummy_error_for_refreshing';
}
}

return $errors;
}
}
Expand Down
50 changes: 50 additions & 0 deletions datalynx.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,3 +474,53 @@ function bulk_action(elem, url, action, defaultval) {
M.mod_datalynx.field_gradeitem_form_init = function () {
Y.one('#mform1').one('select[name="param1"]').set('value', Y.one('#mform1').one('input[type="hidden"][name="param1"]').get('value'));
};

M.mod_datalynx.filter_form_init = function () {
require(['core_form/dynamicform', 'core/toast'], function (DynamicForm, Toast) {
const container = document.querySelector('#formcontainer');
const dynamicForm = new DynamicForm(container, 'mod_datalynx_filter_form');

dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED, e => {
e.detail.good.forEach(successMessage => {
Toast.add(successMessage, {
type: 'success',
});
});
e.detail.bad.forEach(errorMessage => {
Toast.add(errorMessage, {
type: 'danger',
});
});
let searchParams = new URLSearchParams(window.location.search)
dynamicForm.load({
d: searchParams.get("d"),
fid: searchParams.get("fid")
});
})

container.addEventListener('change', e => {
if (e.target.matches('.custom-select') && (e.target.name.startsWith('searchfield') || e.target.name.startsWith('sortfield'))) {
e.preventDefault();
document.getElementsByName("refreshonly")[0].value = "1";
dynamicForm.submitFormAjax();
}
});

container.addEventListener('click', e => {
if (e.target.matches('input[type="submit"]')) {
e.preventDefault();
document.getElementsByName("refreshonly")[0].value = "0";
dynamicForm.submitFormAjax();
}
});

$(function() {
let searchParams = new URLSearchParams(window.location.search)
dynamicForm.load({
d: searchParams.get("d"),
fid: searchParams.get("fid")
});
});

});
};
18 changes: 1 addition & 17 deletions field/field_class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,7 @@ public function format_search_value($searchparams) {
*/
public function parse_search($formdata, $i) {
$fieldname = "f_{$i}_{$this->field->id}";
return optional_param_array($fieldname, false, PARAM_NOTAGS);
return is_array($formdata->$fieldname) ? $formdata->$fieldname : false;
}

/**
Expand All @@ -1027,14 +1027,6 @@ public function parse_search($formdata, $i) {
public static function is_customfilterfield() {
return true;
}

public function get_argument_count(string $operator) {
if ($operator === "") { // "Empty" operator
return 0;
} else {
return 1;
}
}
}

/**
Expand Down Expand Up @@ -1267,14 +1259,6 @@ public function get_supported_search_operators() {
'ALL_OF' => get_string('allof', 'datalynx'),
'EXACTLY' => get_string('exactly', 'datalynx'), '' => get_string('empty', 'datalynx'));
}

public function get_argument_count(string $operator) {
if ($operator === "") { // "Empty" operator
return 0;
} else {
return 1;
}
}
}

/**
Expand Down
8 changes: 0 additions & 8 deletions field/select/field_class.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,4 @@ public function get_search_value($value) {
return '';
}
}

public function get_argument_count(string $operator) {
if ($operator === "") { // "Empty" operator
return 0;
} else {
return 1;
}
}
}
Loading
Loading