From f7a2ae63db935606ca7fe5d6a9e7ad8580b565ab Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Sun, 15 Sep 2024 15:25:17 +0200 Subject: [PATCH 01/11] Implement a dynamic (AJAX) filter form --- {filter => classes}/filter_form.php | 143 ++++++++++++++++++++++++---- datalynx.js | 41 ++++++++ field/field_class.php | 17 ++-- filter/filter_class.php | 115 +++++++++++++++++++++- filter/index.php | 7 ++ 5 files changed, 290 insertions(+), 33 deletions(-) rename {filter => classes}/filter_form.php (81%) diff --git a/filter/filter_form.php b/classes/filter_form.php similarity index 81% rename from filter/filter_form.php rename to classes/filter_form.php index f67f698d..b6bbc533 100644 --- a/filter/filter_form.php +++ b/classes/filter_form.php @@ -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; @@ -39,16 +40,66 @@ 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_module::instance($this->_df->cm->id); + return \context_system::instance(); + } + + public function check_access_for_dynamic_submission(): void { + return; + //return has_capability('mod/datalynx:edit', $this->get_context_for_dynamic_submission()); + require_capability('moodle/site:config', \context_system::instance()); + } + + public function set_data_for_dynamic_submission(): void { + global $DB; + + // echo "set_data_for_dynamic_submission"; + // print_r($this->_filter); + // print_r($this->_df); + // print_r($this->_form); + // print_r($this->_customdata); + // print_r($this->_ajaxformdata["d"]); + // print_r($this->_ajaxformdata["fid"]); + + $datalynx_id = $this->_ajaxformdata["d"]; + + // $this->_filter = + $this->_df = \mod_datalynx\datalynx::get_datalynx_by_instance($datalynx_id); - parent::__construct($action, $customdata, $method, $target, $attributes, $editable); + // if (!$this->_df = $DB->get_record('datalynx', array('id' => $datalynx_id))) { + // throw new moodle_exception('invaliddatalynx', 'datalynx', null, null, + // "Datalynx id: $datalynx_id"); + //} else { + // print_r($this->_df); + //} + } + + public function process_dynamic_submission() { + /* $data = $this->get_ajax_form_data(); + //print("PROCESS_DYNAMIC_SUBMISSION"); + //print_r($data); + + // Save the filter. + $filter = $this->_filter; + $filter->name = $data['name']; + $filter->description = $data['description']; + $filter->visible = $data['visible']; + $filter->perpage = $data['perpage']; + $filter->selection = $data['selection']; + $filter->groupby = $data['groupby']; + $filter->search = $data['search']; + // $filter->customsort = serialize($this->process_custom_sort($data)); TODO VP: Where should these methods be lcocated? + // $filter->customsearch = serialize($this->process_custom_search($data)); + $filter->timemodified = time(); + + // $filter->save(); TODO VP: Method not found + + return $filter; */ + } + + public function get_page_url_for_dynamic_submission(): moodle_url { + return new moodle_url('/mod/datalynx/view.php', array('id' => $this->_df->id)); } /* @@ -214,9 +265,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')); } /* @@ -263,13 +311,48 @@ class mod_datalynx_filter_form extends mod_datalynx_filter_base_form { * */ public function definition() { + + // print_r($this->_ajaxformdata); + + $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); + + // VP: Taken over from filter/index.php. START + + // TODO: Delete, duplicate, etc... should these be available in AJAX? + + //print("FILTER1"); + //print_r($this->_filter); + + // DATA PROCESSING. + if ($this->_ajaxformdata["update"] && confirm_sesskey()) { // Add/update a new filter. + $procesedfilters = $fm->process_filters_ajax('update', $filter_id, $this, true); + $this->_filter = $procesedfilters[0]; + } + // END + $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); + + // VP: We won't need this null check, as the filter will only be instantiated from AJAX in the future (the old instantiation is superfluous). + if ($df !== null) { + $fields = $df->get_fields(); + $fieldoptions = array(0 => get_string('choose')) + $df->get_fields(array('entry'), true); + } else { + $fields = []; + $fieldoptions = []; + } $mform = &$this->_form; @@ -334,10 +417,24 @@ 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() { + return json_decode(json_encode($this->_ajaxformdata)); + } + /** * @param array $data * @param array $files @@ -346,16 +443,20 @@ public function definition() { */ public function validation($data, $files) { $errors = parent::validation($data, $files); + 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')); + } } + // FIXME: It looks like if we don't return any errors, the form will not be refreshed. Need to debug this. + $errors['fake'] = 'fake'; return $errors; } } diff --git a/datalynx.js b/datalynx.js index 7048717c..870353dd 100644 --- a/datalynx.js +++ b/datalynx.js @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // Along with Moodle. If not, see . + /** * @package mod_datalynx * @copyright 2013 onwards David Bogner, Michael Pollak, Ivan Sakic and others. @@ -474,3 +475,43 @@ 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'], function (DynamicForm) { + const container = document.querySelector('#formcontainer'); + const dynamicForm = new DynamicForm(container, 'mod_datalynx_filter_form'); + + dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED, e => { + e.preventDefault(); + e.details.d = e.details.dataid; + e.details.fid = e.details.id; + dynamicForm.load(e.details); + }); + + // TODO: Not all custom selects should trigger a refresh. + container.addEventListener('change', e => { + if (e.target.matches('.custom-select')) { + 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(); + } + }); + + $( document ).ready(function() { + let searchParams = new URLSearchParams(window.location.search) + dynamicForm.load({ + d: searchParams.get("d"), + fid: searchParams.get("fid") + }); + }); + + }); +}; diff --git a/field/field_class.php b/field/field_class.php index f3af1cc3..7f8c88dd 100644 --- a/field/field_class.php +++ b/field/field_class.php @@ -847,6 +847,15 @@ public function is_datalynx_content() { protected function filearea($suffix = null) { return false; } + + // TODO: Git PR to move this to the base class. + public function get_argument_count(string $operator) { + if ($operator === "") { // "Empty" operator + return 0; + } else { + return 1; + } + } } /** @@ -1267,14 +1276,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; - } - } } /** diff --git a/filter/filter_class.php b/filter/filter_class.php index d996867d..967656c4 100644 --- a/filter/filter_class.php +++ b/filter/filter_class.php @@ -706,6 +706,115 @@ public function get_filters($exclude = null, $menu = false, $forceget = false) { } } + public function process_filters_ajax($action, $fids, $mform) { + global $DB, $OUTPUT; + + $df = $this->_df; + + $filters = array(); + // TODO may need new roles. + if (has_capability('mod/datalynx:managetemplates', $df->context)) { + // Don't need record from database for filter form submission. + if ($fids) { // Some filters are specified for action. + $filters = $DB->get_records_select('datalynx_filters', "id IN ($fids)"); + } else { + if ($action == 'update') { + $filters[] = $this->get_filter_from_id(self::BLANK_FILTER); + } + } + } + $processedfids = array(); + $processedfilters = array(); + $strnotify = ''; + + // TODO update should be roled. + if (empty($filters)) { + $df->notifications['bad'][] = get_string("filternoneforaction", 'datalynx'); + return false; + } else { + // Go ahead and perform the requested action. + switch ($action) { + case 'update': // Add new or update existing. + $filter = reset($filters); + + if ($mform->is_cancelled()) { + break; + } + + // Regenerate form and filter to obtain custom search data. + $formdata = $mform->get_ajax_form_data(); + // $formdata["dataid"] = $formdata["d"]; + // $formdata["id"] = $formdata["fid"]; + + $filter = $this->get_filter_from_form($filter, $formdata); + $filterform = $this->get_filter_form($filter); + + // Return to form (on reload button press). + //print_r($formdata); + if ($formdata->refreshonly == '1') { // VP: no submit button pressed (reload only) + // $this->display_filter_form($filterform, $filter); + + $processedfids[] = $filter->id; // VP Added this line. + $processedfilters[] = $filter; // VP Added this line. + //print("FILTER2"); + //print_r($filter); + + // Process validated. + } else { + + //if ($formdata = $filterform->get_data()) { // TODO VP: This should fail if there are validation errors + if ($formdata = $mform->get_ajax_form_data()) { + + // Get clean filter from formdata. + $filter = $this->get_filter_from_form($filter, $formdata, true); + + if ($filter->id) { + $DB->update_record('datalynx_filters', $filter); + $processedfids[] = $filter->id; + $processedfilters[] = $filter; // VP Added this line. + $strnotify = 'filtersupdated'; + + $other = array('dataid' => $this->_df->id()); + $event = \mod_datalynx\event\field_updated::create( + array('context' => $this->_df->context, + 'objectid' => $filter->id, 'other' => $other)); + $event->trigger(); + } else { + $filter->id = $DB->insert_record('datalynx_filters', $filter, true); + $processedfids[] = $filter->id; + $processedfilters[] = $filter; // VP Added this line. + $strnotify = 'filtersadded'; + + $other = array('dataid' => $this->_df->id()); + $event = \mod_datalynx\event\field_created::create( + array('context' => $this->_df->context, + 'objectid' => $filter->id, 'other' => $other + )); + $event->trigger(); + } + // Update cached filters. + $this->_filters[$filter->id] = $filter; + } else { + // Form validation failed so return to form. + //$this->display_filter_form($filterform, $filter); + } + } + + break; + default: + break; + } + + if (!empty($strnotify)) { + $filtersprocessed = $processedfids ? count($processedfids) : 'No'; + $df->notifications['good'][] = get_string($strnotify, 'datalynx', + $filtersprocessed); + } + return $processedfilters; + } + } + + // TODO VP: Remove Update and Refresh from here (handled via AJAX) /** */ public function process_filters($action, $fids, $confirmed = false) { @@ -890,11 +999,9 @@ public function process_filters($action, $fids, $confirmed = false) { */ public function get_filter_form($filter) { global $CFG; - - require_once("$CFG->dirroot/mod/datalynx/filter/filter_form.php"); $formurl = new moodle_url('/mod/datalynx/filter/index.php', array('d' => $this->_df->id(), 'fid' => $filter->id, 'update' => 1)); - $mform = new mod_datalynx_filter_form($this->_df, $filter, $formurl); + $mform = new mod_datalynx_filter_form($formurl); return $mform; } @@ -908,7 +1015,7 @@ public function display_filter_form($mform, $filter, $urlparams = null) { $this->_df->print_header(array('tab' => 'filters', 'urlparams' => $urlparams)); echo $heading; - $mform->display(); + echo html_writer::div('', '', ['id' => 'formcontainer', 'data-region' => 'form']); $this->_df->print_footer(); exit(); diff --git a/filter/index.php b/filter/index.php index 1ec8bb69..b93eb5ba 100644 --- a/filter/index.php +++ b/filter/index.php @@ -51,6 +51,13 @@ $df = new mod_datalynx\datalynx($urlparams->d, $urlparams->id); require_capability('mod/datalynx:managetemplates', $df->context); +$module = array( + 'name' => 'mod_datalynx', + 'fullpath' => '/mod/datalynx/datalynx.js', + 'requires' => array('moodle-core-notification-dialogue') +); +$PAGE->requires->js_init_call('M.mod_datalynx.filter_form_init', $options, true, $module); + $df->set_page('filter/index', array('modjs' => true, 'urlparams' => $urlparams)); require_login($df->data->course, false, $df->cm); From c15365e35b7aae3995b3ffaae98d7195e78bd0c1 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Sun, 15 Sep 2024 15:47:02 +0200 Subject: [PATCH 02/11] Fix errors --- classes/filter_form.php | 3 +-- filter/filter_class.php | 2 +- filter/index.php | 34 ++++++++++++++-------------------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index b6bbc533..44bf7665 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -312,11 +312,10 @@ class mod_datalynx_filter_form extends mod_datalynx_filter_base_form { */ public function definition() { - // print_r($this->_ajaxformdata); - $datalynx_id = $this->_ajaxformdata["d"]; $filter_id = $this->_ajaxformdata["fid"]; + if ($datalynx_id == null || $filter_id == null) { return; } diff --git a/filter/filter_class.php b/filter/filter_class.php index 967656c4..e8b0461e 100644 --- a/filter/filter_class.php +++ b/filter/filter_class.php @@ -1007,7 +1007,7 @@ public function get_filter_form($filter) { /** */ - public function display_filter_form($mform, $filter, $urlparams = null) { + public function display_filter_form($filter, $urlparams = null) { $streditinga = $filter->id ? get_string('filteredit', 'datalynx', $filter->name) : get_string( 'filternew', 'datalynx'); $heading = html_writer::tag('h2', format_string($streditinga), diff --git a/filter/index.php b/filter/index.php index b93eb5ba..35247b19 100644 --- a/filter/index.php +++ b/filter/index.php @@ -56,7 +56,7 @@ 'fullpath' => '/mod/datalynx/datalynx.js', 'requires' => array('moodle-core-notification-dialogue') ); -$PAGE->requires->js_init_call('M.mod_datalynx.filter_form_init', $options, true, $module); +$PAGE->requires->js_init_call('M.mod_datalynx.filter_form_init', array(), true, $module); $df->set_page('filter/index', array('modjs' => true, 'urlparams' => $urlparams)); @@ -69,24 +69,20 @@ $fm = $df->get_filter_manager(); // DATA PROCESSING. -if ($urlparams->update && confirm_sesskey()) { // Add/update a new filter. - $fm->process_filters('update', $urlparams->fid, true); +if ($urlparams->duplicate && confirm_sesskey()) { // Duplicate any requested filters. + $fm->process_filters('duplicate', $urlparams->duplicate, $urlparams->confirmed); } else { - if ($urlparams->duplicate && confirm_sesskey()) { // Duplicate any requested filters. - $fm->process_filters('duplicate', $urlparams->duplicate, $urlparams->confirmed); + if ($urlparams->delete && confirm_sesskey()) { // Delete any requested filters. + $fm->process_filters('delete', $urlparams->delete, $urlparams->confirmed); } else { - if ($urlparams->delete && confirm_sesskey()) { // Delete any requested filters. - $fm->process_filters('delete', $urlparams->delete, $urlparams->confirmed); + if ($urlparams->visible && confirm_sesskey()) { // Set filter's visibility. + $fm->process_filters('visible', $urlparams->visible, true); // Confirmed by default. } else { - if ($urlparams->visible && confirm_sesskey()) { // Set filter's visibility. - $fm->process_filters('visible', $urlparams->visible, true); // Confirmed by default. - } else { - if ($urlparams->default && confirm_sesskey()) { // Set filter to default. - if ($urlparams->default == -1) { - $df->set_default_filter(); // Reset. - } else { - $df->set_default_filter($urlparams->default); - } + if ($urlparams->default && confirm_sesskey()) { // Set filter to default. + if ($urlparams->default == -1) { + $df->set_default_filter(); // Reset. + } else { + $df->set_default_filter($urlparams->default); } } } @@ -96,15 +92,13 @@ // Edit a new filter. if ($urlparams->new && confirm_sesskey()) { $filter = $fm->get_filter_from_id($fm::BLANK_FILTER); - $filterform = $fm->get_filter_form($filter); - $fm->display_filter_form($filterform, $filter, $urlparams); + $fm->display_filter_form($filter, $urlparams); // Or edit existing filter. } else { if ($urlparams->fedit && confirm_sesskey()) { $filter = $fm->get_filter_from_id($urlparams->fedit); - $filterform = $fm->get_filter_form($filter); - $fm->display_filter_form($filterform, $filter, $urlparams); + $fm->display_filter_form($filter, $urlparams); // Or display the filters list. } else { From 00cd92e10d799f5a3aa479d9c49b208b312858d0 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Mon, 16 Sep 2024 01:03:08 +0200 Subject: [PATCH 03/11] Adjust click handler to react to the "searchfield" dropdowns only --- classes/filter_form.php | 1 - datalynx.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index 44bf7665..55e36812 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -315,7 +315,6 @@ public function definition() { $datalynx_id = $this->_ajaxformdata["d"]; $filter_id = $this->_ajaxformdata["fid"]; - if ($datalynx_id == null || $filter_id == null) { return; } diff --git a/datalynx.js b/datalynx.js index 870353dd..297b203c 100644 --- a/datalynx.js +++ b/datalynx.js @@ -490,7 +490,7 @@ M.mod_datalynx.filter_form_init = function () { // TODO: Not all custom selects should trigger a refresh. container.addEventListener('change', e => { - if (e.target.matches('.custom-select')) { + if (e.target.matches('.custom-select') && e.target.name.startsWith('searchfield')) { e.preventDefault(); document.getElementsByName("refreshonly")[0].value = "1"; dynamicForm.submitFormAjax(); From fd811bdfaae2fd590b3c273fa09852533e8d9f9c Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Mon, 16 Sep 2024 01:34:53 +0200 Subject: [PATCH 04/11] Remove resolved TODO --- datalynx.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/datalynx.js b/datalynx.js index 297b203c..291294cc 100644 --- a/datalynx.js +++ b/datalynx.js @@ -488,7 +488,6 @@ M.mod_datalynx.filter_form_init = function () { dynamicForm.load(e.details); }); - // TODO: Not all custom selects should trigger a refresh. container.addEventListener('change', e => { if (e.target.matches('.custom-select') && e.target.name.startsWith('searchfield')) { e.preventDefault(); @@ -505,7 +504,7 @@ M.mod_datalynx.filter_form_init = function () { } }); - $( document ).ready(function() { + $(document).ready(function() { let searchParams = new URLSearchParams(window.location.search) dynamicForm.load({ d: searchParams.get("d"), From 7d81f7497b687d1a3aa1236d5c4ef303ffae3f19 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Wed, 18 Sep 2024 21:04:24 +0200 Subject: [PATCH 05/11] Signal a successful submission with a toast message --- classes/filter_form.php | 48 +++++++++++++++++++++++++++++++++++------ datalynx.js | 16 ++++++++------ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index 55e36812..572a9daf 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -52,8 +52,20 @@ public function check_access_for_dynamic_submission(): void { } public function set_data_for_dynamic_submission(): void { + // Since this runs after definition(), we are not using it, as the form's composition already depends on the data loaded. global $DB; + $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); + // echo "set_data_for_dynamic_submission"; // print_r($this->_filter); // print_r($this->_df); @@ -62,10 +74,10 @@ public function set_data_for_dynamic_submission(): void { // print_r($this->_ajaxformdata["d"]); // print_r($this->_ajaxformdata["fid"]); - $datalynx_id = $this->_ajaxformdata["d"]; + //$datalynx_id = $this->_ajaxformdata["d"]; // $this->_filter = - $this->_df = \mod_datalynx\datalynx::get_datalynx_by_instance($datalynx_id); + //$this->_df = \mod_datalynx\datalynx::get_datalynx_by_instance($datalynx_id); // if (!$this->_df = $DB->get_record('datalynx', array('id' => $datalynx_id))) { // throw new moodle_exception('invaliddatalynx', 'datalynx', null, null, @@ -76,6 +88,24 @@ public function set_data_for_dynamic_submission(): void { } public function process_dynamic_submission() { + //echo "PRODISU"; + + $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_ajax('update', $filter_id, $this, true); + $this->_filter = $procesedfilters[0]; + } + /* $data = $this->get_ajax_form_data(); //print("PROCESS_DYNAMIC_SUBMISSION"); //print_r($data); @@ -312,6 +342,8 @@ class mod_datalynx_filter_form extends mod_datalynx_filter_base_form { */ public function definition() { + //print("FILTER FORM DEFINITION"); + $datalynx_id = $this->_ajaxformdata["d"]; $filter_id = $this->_ajaxformdata["fid"]; @@ -319,14 +351,13 @@ public function definition() { return; } + // TODO VP: Conditionally set these (if not yet set by PRODISU) // Move these to LOAD_DATA: $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); // VP: Taken over from filter/index.php. START - // TODO: Delete, duplicate, etc... should these be available in AJAX? - //print("FILTER1"); //print_r($this->_filter); @@ -430,6 +461,7 @@ public function definition() { } public function get_ajax_form_data() { + // Convert to stdClass: return json_decode(json_encode($this->_ajaxformdata)); } @@ -451,10 +483,12 @@ public function validation($data, $files) { $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: + $errors['dummy_error_for_refreshing'] = 'dummy_error_for_refreshing'; } - - // FIXME: It looks like if we don't return any errors, the form will not be refreshed. Need to debug this. - $errors['fake'] = 'fake'; return $errors; } } diff --git a/datalynx.js b/datalynx.js index 291294cc..989785c9 100644 --- a/datalynx.js +++ b/datalynx.js @@ -477,16 +477,18 @@ M.mod_datalynx.field_gradeitem_form_init = function () { }; M.mod_datalynx.filter_form_init = function () { - require(['core_form/dynamicform'], function (DynamicForm) { + 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.preventDefault(); - e.details.d = e.details.dataid; - e.details.fid = e.details.id; - dynamicForm.load(e.details); - }); + Toast.add('Form saved successfully.'); + 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')) { @@ -504,7 +506,7 @@ M.mod_datalynx.filter_form_init = function () { } }); - $(document).ready(function() { + $(function() { let searchParams = new URLSearchParams(window.location.search) dynamicForm.load({ d: searchParams.get("d"), From 5cc2123b2e2e5907710d8f138c3db2ee4b8060c2 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Sun, 22 Sep 2024 21:34:08 +0200 Subject: [PATCH 06/11] Exploratory analysis --- classes/filter_form.php | 40 +++++++++++++++++++++++++--------------- datalynx.js | 1 + filter/filter_class.php | 21 ++++++++++++++++++++- index.php | 2 +- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index 572a9daf..42d326b7 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -337,12 +337,20 @@ public function html() { class mod_datalynx_filter_form extends mod_datalynx_filter_base_form { + //public function is_submitted() { + // TODO: Should return true if reloadonly is set to 0. + //return true; + //} + + public function definition() { + + } + /* * */ - public function definition() { - - //print("FILTER FORM DEFINITION"); + //public function definition_after_data() { + public function definition_after_data() { $datalynx_id = $this->_ajaxformdata["d"]; $filter_id = $this->_ajaxformdata["fid"]; @@ -473,21 +481,23 @@ public function get_ajax_form_data() { */ public function validation($data, $files) { $errors = parent::validation($data, $files); - if ($data['refreshonly'] == '0') { + 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: + $errors['dummy_error_for_refreshing'] = 'dummy_error_for_refreshing'; } - } 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: - $errors['dummy_error_for_refreshing'] = 'dummy_error_for_refreshing'; } return $errors; } diff --git a/datalynx.js b/datalynx.js index 989785c9..fe4db615 100644 --- a/datalynx.js +++ b/datalynx.js @@ -501,6 +501,7 @@ M.mod_datalynx.filter_form_init = function () { container.addEventListener('click', e => { if (e.target.matches('input[type="submit"]')) { e.preventDefault(); + alert("Submit"); document.getElementsByName("refreshonly")[0].value = "0"; dynamicForm.submitFormAjax(); } diff --git a/filter/filter_class.php b/filter/filter_class.php index e8b0461e..aa7074f7 100644 --- a/filter/filter_class.php +++ b/filter/filter_class.php @@ -762,8 +762,27 @@ public function process_filters_ajax($action, $fids, $mform) { // Process validated. } else { + //$valid = $filterform->is_validated(); + //$formdata = $mform->get_data(); // This returns null because is_submitted() is false. + //var_dump($formdata); + //$valid = $filterform->is_validated(); + //var_dump($valid); + //if ($formdata = $filterform->get_data()) { // TODO VP: This should fail if there are validation errors - if ($formdata = $mform->get_ajax_form_data()) { + //if ($formdata = $mform->get_data()) { + + $formdata1 = $mform->get_ajax_form_data(); + $formdata2 = $mform->get_data(); // Something is missing from get_data that is contained in ajax_form_data. Some filters do not save correctly with this. New data entered is not there. + + // VP TODO: Problem: $mform is validated, but it does not contain the correct form definition! It is mising the dynamic parts. Can we somehow retrieve the correct form definition ($filterform) before validation runs? + // Need to check where QuickForm=>validate() is called and need to change the contents of the form by then (if we can). Or just perhaps see if definition_after_data is generating the correct fields... + // Hofix (if it needs to be fixed fast): just use ajax_form_data here, but only if the submitted data is valid (i.e. get_data is not null.) However: we are probably not validating the dynamically placed fields... + + if ($formdata2 != null) { + $formdata2->_qf__mod_datalynx_filter_form = "1"; + } + + if ($formdata = $formdata2) { // Get clean filter from formdata. $filter = $this->get_filter_from_form($filter, $formdata, true); diff --git a/index.php b/index.php index 832d723f..35cbe43b 100644 --- a/index.php +++ b/index.php @@ -168,4 +168,4 @@ echo html_writer::empty_tag('br'); echo html_writer::tag('div', html_writer::table($table), array('class' => 'no-overflow')); -echo $OUTPUT->footer(); +echo $OUTPUT->footer(); \ No newline at end of file From 68355f188034a5fdb451292998b253ac0048d60c Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Wed, 25 Sep 2024 16:17:27 +0200 Subject: [PATCH 07/11] get_data contains all the correct data! --- filter/filter_class.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/filter/filter_class.php b/filter/filter_class.php index aa7074f7..19730193 100644 --- a/filter/filter_class.php +++ b/filter/filter_class.php @@ -747,7 +747,6 @@ public function process_filters_ajax($action, $fids, $mform) { // $formdata["id"] = $formdata["fid"]; $filter = $this->get_filter_from_form($filter, $formdata); - $filterform = $this->get_filter_form($filter); // Return to form (on reload button press). //print_r($formdata); @@ -762,6 +761,10 @@ public function process_filters_ajax($action, $fids, $mform) { // Process validated. } else { + // Temp: VP: This is a hack to get the form data from the form. We should not need this. + $processedfids[] = $filter->id; // VP Added this line. + $processedfilters[] = $filter; // VP Added this line. + //$valid = $filterform->is_validated(); //$formdata = $mform->get_data(); // This returns null because is_submitted() is false. //var_dump($formdata); @@ -771,18 +774,14 @@ public function process_filters_ajax($action, $fids, $mform) { //if ($formdata = $filterform->get_data()) { // TODO VP: This should fail if there are validation errors //if ($formdata = $mform->get_data()) { - $formdata1 = $mform->get_ajax_form_data(); - $formdata2 = $mform->get_data(); // Something is missing from get_data that is contained in ajax_form_data. Some filters do not save correctly with this. New data entered is not there. + //$formdata1 = $mform->get_ajax_form_data(); + //$formdata2 = $mform->get_data(); // Something is missing from get_data that is contained in ajax_form_data. Some filters do not save correctly with this. New data entered is not there. // VP TODO: Problem: $mform is validated, but it does not contain the correct form definition! It is mising the dynamic parts. Can we somehow retrieve the correct form definition ($filterform) before validation runs? // Need to check where QuickForm=>validate() is called and need to change the contents of the form by then (if we can). Or just perhaps see if definition_after_data is generating the correct fields... // Hofix (if it needs to be fixed fast): just use ajax_form_data here, but only if the submitted data is valid (i.e. get_data is not null.) However: we are probably not validating the dynamically placed fields... - if ($formdata2 != null) { - $formdata2->_qf__mod_datalynx_filter_form = "1"; - } - - if ($formdata = $formdata2) { + if ($formdata = $mform->get_data()) { // Get clean filter from formdata. $filter = $this->get_filter_from_form($filter, $formdata, true); From cb8c1c16a6f3547ccfc8b96fd2b028c5b921a1ad Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Wed, 25 Sep 2024 17:36:01 +0200 Subject: [PATCH 08/11] Refactor process_filters_ajax(), made sort fields trigger an AJAX refresh --- classes/filter_form.php | 29 +++----- datalynx.js | 3 +- filter/filter_class.php | 142 +++++++++++++++++++--------------------- 3 files changed, 79 insertions(+), 95 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index 42d326b7..d9c8c1f9 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -102,7 +102,7 @@ public function process_dynamic_submission() { $this->_filter = $fm->get_filter_from_id($filter_id); if ($this->_ajaxformdata["update"] && confirm_sesskey()) { // Add/update a new filter. - $procesedfilters = $fm->process_filters_ajax('update', $filter_id, $this, true); + $procesedfilters = $fm->process_filters_for_ajax_submission('update', $filter_id, $this, true); $this->_filter = $procesedfilters[0]; } @@ -349,7 +349,6 @@ public function definition() { /* * */ - //public function definition_after_data() { public function definition_after_data() { $datalynx_id = $this->_ajaxformdata["d"]; @@ -364,17 +363,11 @@ public function definition_after_data() { $fm = $this->_df->get_filter_manager(); $this->_filter = $fm->get_filter_from_id($filter_id); - // VP: Taken over from filter/index.php. START - - //print("FILTER1"); - //print_r($this->_filter); - - // DATA PROCESSING. - if ($this->_ajaxformdata["update"] && confirm_sesskey()) { // Add/update a new filter. - $procesedfilters = $fm->process_filters_ajax('update', $filter_id, $this, true); + // 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]; } - // END $df = $this->_df; $filter = $this->_filter; @@ -382,14 +375,8 @@ public function definition_after_data() { $description = empty($filter->description) ? '' : $filter->description; $visible = !isset($filter->visible) ? 1 : $filter->visible; - // VP: We won't need this null check, as the filter will only be instantiated from AJAX in the future (the old instantiation is superfluous). - if ($df !== null) { - $fields = $df->get_fields(); - $fieldoptions = array(0 => get_string('choose')) + $df->get_fields(array('entry'), true); - } else { - $fields = []; - $fieldoptions = []; - } + $fields = $df->get_fields(); + $fieldoptions = array(0 => get_string('choose')) + $df->get_fields(array('entry'), true); $mform = &$this->_form; @@ -495,7 +482,9 @@ public function validation($data, $files) { } 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: + // 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'; } } diff --git a/datalynx.js b/datalynx.js index fe4db615..f38f1f90 100644 --- a/datalynx.js +++ b/datalynx.js @@ -491,7 +491,7 @@ M.mod_datalynx.filter_form_init = function () { }) container.addEventListener('change', e => { - if (e.target.matches('.custom-select') && e.target.name.startsWith('searchfield')) { + 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(); @@ -501,7 +501,6 @@ M.mod_datalynx.filter_form_init = function () { container.addEventListener('click', e => { if (e.target.matches('input[type="submit"]')) { e.preventDefault(); - alert("Submit"); document.getElementsByName("refreshonly")[0].value = "0"; dynamicForm.submitFormAjax(); } diff --git a/filter/filter_class.php b/filter/filter_class.php index 19730193..703f5be7 100644 --- a/filter/filter_class.php +++ b/filter/filter_class.php @@ -706,7 +706,7 @@ public function get_filters($exclude = null, $menu = false, $forceget = false) { } } - public function process_filters_ajax($action, $fids, $mform) { + public function process_filters_for_ajax_refresh($action, $fids, $mform) { global $DB, $OUTPUT; $df = $this->_df; @@ -733,96 +733,92 @@ public function process_filters_ajax($action, $fids, $mform) { return false; } else { // Go ahead and perform the requested action. - switch ($action) { - case 'update': // Add new or update existing. - $filter = reset($filters); - - if ($mform->is_cancelled()) { - break; - } + if ($action == 'update') { + $filter = reset($filters); + if (!$mform->is_cancelled()) { // Regenerate form and filter to obtain custom search data. $formdata = $mform->get_ajax_form_data(); - // $formdata["dataid"] = $formdata["d"]; - // $formdata["id"] = $formdata["fid"]; - $filter = $this->get_filter_from_form($filter, $formdata); + $processedfids[] = $filter->id; + $processedfilters[] = $filter; + } + } + return $processedfilters; + } + } - // Return to form (on reload button press). - //print_r($formdata); - if ($formdata->refreshonly == '1') { // VP: no submit button pressed (reload only) - // $this->display_filter_form($filterform, $filter); - - $processedfids[] = $filter->id; // VP Added this line. - $processedfilters[] = $filter; // VP Added this line. - //print("FILTER2"); - //print_r($filter); - - // Process validated. - } else { - - // Temp: VP: This is a hack to get the form data from the form. We should not need this. - $processedfids[] = $filter->id; // VP Added this line. - $processedfilters[] = $filter; // VP Added this line. - - //$valid = $filterform->is_validated(); - //$formdata = $mform->get_data(); // This returns null because is_submitted() is false. - //var_dump($formdata); - //$valid = $filterform->is_validated(); - //var_dump($valid); + public function process_filters_for_ajax_submission($action, $fids, $mform) { + global $DB, $OUTPUT; - //if ($formdata = $filterform->get_data()) { // TODO VP: This should fail if there are validation errors - //if ($formdata = $mform->get_data()) { + $df = $this->_df; - //$formdata1 = $mform->get_ajax_form_data(); - //$formdata2 = $mform->get_data(); // Something is missing from get_data that is contained in ajax_form_data. Some filters do not save correctly with this. New data entered is not there. + $filters = array(); + // TODO may need new roles. + if (has_capability('mod/datalynx:managetemplates', $df->context)) { + // Don't need record from database for filter form submission. + if ($fids) { // Some filters are specified for action. + $filters = $DB->get_records_select('datalynx_filters', "id IN ($fids)"); + } else { + if ($action == 'update') { + $filters[] = $this->get_filter_from_id(self::BLANK_FILTER); + } + } + } + $processedfids = array(); + $processedfilters = array(); + $strnotify = ''; - // VP TODO: Problem: $mform is validated, but it does not contain the correct form definition! It is mising the dynamic parts. Can we somehow retrieve the correct form definition ($filterform) before validation runs? - // Need to check where QuickForm=>validate() is called and need to change the contents of the form by then (if we can). Or just perhaps see if definition_after_data is generating the correct fields... - // Hofix (if it needs to be fixed fast): just use ajax_form_data here, but only if the submitted data is valid (i.e. get_data is not null.) However: we are probably not validating the dynamically placed fields... + // TODO update should be roled. + if (empty($filters)) { + $df->notifications['bad'][] = get_string("filternoneforaction", 'datalynx'); + return false; + } else { + // Go ahead and perform the requested action. + if ($action == 'update') { + $filter = reset($filters); - if ($formdata = $mform->get_data()) { + if (!$mform->is_cancelled()) { + // Regenerate form and filter to obtain custom search data. + $formdata = $mform->get_ajax_form_data(); + $filter = $this->get_filter_from_form($filter, $formdata); - // Get clean filter from formdata. - $filter = $this->get_filter_from_form($filter, $formdata, true); + if ($formdata = $mform->get_data()) { - if ($filter->id) { - $DB->update_record('datalynx_filters', $filter); - $processedfids[] = $filter->id; - $processedfilters[] = $filter; // VP Added this line. - $strnotify = 'filtersupdated'; + // Get clean filter from formdata. + $filter = $this->get_filter_from_form($filter, $formdata, true); - $other = array('dataid' => $this->_df->id()); - $event = \mod_datalynx\event\field_updated::create( - array('context' => $this->_df->context, - 'objectid' => $filter->id, 'other' => $other)); - $event->trigger(); - } else { - $filter->id = $DB->insert_record('datalynx_filters', $filter, true); - $processedfids[] = $filter->id; - $processedfilters[] = $filter; // VP Added this line. - $strnotify = 'filtersadded'; + if ($filter->id) { + $DB->update_record('datalynx_filters', $filter); + $processedfids[] = $filter->id; + $processedfilters[] = $filter; // VP Added this line. + $strnotify = 'filtersupdated'; - $other = array('dataid' => $this->_df->id()); - $event = \mod_datalynx\event\field_created::create( - array('context' => $this->_df->context, - 'objectid' => $filter->id, 'other' => $other - )); - $event->trigger(); - } - // Update cached filters. - $this->_filters[$filter->id] = $filter; + $other = array('dataid' => $this->_df->id()); + $event = \mod_datalynx\event\field_updated::create( + array('context' => $this->_df->context, + 'objectid' => $filter->id, 'other' => $other)); + $event->trigger(); } else { - // Form validation failed so return to form. - //$this->display_filter_form($filterform, $filter); + $filter->id = $DB->insert_record('datalynx_filters', $filter, true); + $processedfids[] = $filter->id; + $processedfilters[] = $filter; // VP Added this line. + $strnotify = 'filtersadded'; + + $other = array('dataid' => $this->_df->id()); + $event = \mod_datalynx\event\field_created::create( + array('context' => $this->_df->context, + 'objectid' => $filter->id, 'other' => $other + )); + $event->trigger(); } + // Update cached filters. + $this->_filters[$filter->id] = $filter; } - - break; - default: - break; + } } + // TODO VP: Display $strnotify as the JS toast notification after AJAX submission. if (!empty($strnotify)) { $filtersprocessed = $processedfids ? count($processedfids) : 'No'; $df->notifications['good'][] = get_string($strnotify, 'datalynx', From c850639d9c556d0c3f1747e05a57109e6df1ac18 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Wed, 25 Sep 2024 18:11:07 +0200 Subject: [PATCH 09/11] Display filter form notifications as toast messages --- classes/filter_form.php | 22 +--------------- datalynx.js | 11 +++++++- filter/filter_class.php | 57 ----------------------------------------- 3 files changed, 11 insertions(+), 79 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index d9c8c1f9..c10fb24d 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -88,7 +88,6 @@ public function set_data_for_dynamic_submission(): void { } public function process_dynamic_submission() { - //echo "PRODISU"; $datalynx_id = $this->_ajaxformdata["d"]; $filter_id = $this->_ajaxformdata["fid"]; @@ -106,26 +105,7 @@ public function process_dynamic_submission() { $this->_filter = $procesedfilters[0]; } - /* $data = $this->get_ajax_form_data(); - //print("PROCESS_DYNAMIC_SUBMISSION"); - //print_r($data); - - // Save the filter. - $filter = $this->_filter; - $filter->name = $data['name']; - $filter->description = $data['description']; - $filter->visible = $data['visible']; - $filter->perpage = $data['perpage']; - $filter->selection = $data['selection']; - $filter->groupby = $data['groupby']; - $filter->search = $data['search']; - // $filter->customsort = serialize($this->process_custom_sort($data)); TODO VP: Where should these methods be lcocated? - // $filter->customsearch = serialize($this->process_custom_search($data)); - $filter->timemodified = time(); - - // $filter->save(); TODO VP: Method not found - - return $filter; */ + return $this->_df->notifications; } public function get_page_url_for_dynamic_submission(): moodle_url { diff --git a/datalynx.js b/datalynx.js index f38f1f90..b9497e56 100644 --- a/datalynx.js +++ b/datalynx.js @@ -482,7 +482,16 @@ M.mod_datalynx.filter_form_init = function () { const dynamicForm = new DynamicForm(container, 'mod_datalynx_filter_form'); dynamicForm.addEventListener(dynamicForm.events.FORM_SUBMITTED, e => { - Toast.add('Form saved successfully.'); + 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"), diff --git a/filter/filter_class.php b/filter/filter_class.php index 703f5be7..c3b17cb8 100644 --- a/filter/filter_class.php +++ b/filter/filter_class.php @@ -818,7 +818,6 @@ public function process_filters_for_ajax_submission($action, $fids, $mform) { } } - // TODO VP: Display $strnotify as the JS toast notification after AJAX submission. if (!empty($strnotify)) { $filtersprocessed = $processedfids ? count($processedfids) : 'No'; $df->notifications['good'][] = get_string($strnotify, 'datalynx', @@ -828,7 +827,6 @@ public function process_filters_for_ajax_submission($action, $fids, $mform) { } } - // TODO VP: Remove Update and Refresh from here (handled via AJAX) /** */ public function process_filters($action, $fids, $confirmed = false) { @@ -874,61 +872,6 @@ public function process_filters($action, $fids, $confirmed = false) { } else { // Go ahead and perform the requested action. switch ($action) { - case 'update': // Add new or update existing. - $filter = reset($filters); - $mform = $this->get_filter_form($filter); - - if ($mform->is_cancelled()) { - break; - } - - // Regenerate form and filter to obtain custom search data. - $formdata = $mform->get_submitted_data(); - $filter = $this->get_filter_from_form($filter, $formdata); - $filterform = $this->get_filter_form($filter); - - // Return to form (on reload button press). - if ($filterform->no_submit_button_pressed()) { - $this->display_filter_form($filterform, $filter); - - // Process validated. - } else { - if ($formdata = $filterform->get_data()) { - // Get clean filter from formdata. - $filter = $this->get_filter_from_form($filter, $formdata, true); - - if ($filter->id) { - $DB->update_record('datalynx_filters', $filter); - $processedfids[] = $filter->id; - $strnotify = 'filtersupdated'; - - $other = array('dataid' => $this->_df->id()); - $event = \mod_datalynx\event\field_updated::create( - array('context' => $this->_df->context, - 'objectid' => $filter->id, 'other' => $other)); - $event->trigger(); - } else { - $filter->id = $DB->insert_record('datalynx_filters', $filter, true); - $processedfids[] = $filter->id; - $strnotify = 'filtersadded'; - - $other = array('dataid' => $this->_df->id()); - $event = \mod_datalynx\event\field_created::create( - array('context' => $this->_df->context, - 'objectid' => $filter->id, 'other' => $other - )); - $event->trigger(); - } - // Update cached filters. - $this->_filters[$filter->id] = $filter; - } else { - // Form validation failed so return to form. - $this->display_filter_form($filterform, $filter); - } - } - - break; - case 'duplicate': if (!empty($filters)) { foreach ($filters as $filter) { From 15131ea479fc12ae8e949cd5d59f72c022330d15 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Wed, 25 Sep 2024 18:21:54 +0200 Subject: [PATCH 10/11] Refactor --- classes/filter_form.php | 52 +++++------------------------------------ 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index c10fb24d..26881b8f 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -66,25 +66,11 @@ public function set_data_for_dynamic_submission(): void { $fm = $this->_df->get_filter_manager(); $this->_filter = $fm->get_filter_from_id($filter_id); - // echo "set_data_for_dynamic_submission"; - // print_r($this->_filter); - // print_r($this->_df); - // print_r($this->_form); - // print_r($this->_customdata); - // print_r($this->_ajaxformdata["d"]); - // print_r($this->_ajaxformdata["fid"]); - - //$datalynx_id = $this->_ajaxformdata["d"]; - - // $this->_filter = - //$this->_df = \mod_datalynx\datalynx::get_datalynx_by_instance($datalynx_id); - - // if (!$this->_df = $DB->get_record('datalynx', array('id' => $datalynx_id))) { - // throw new moodle_exception('invaliddatalynx', 'datalynx', null, null, - // "Datalynx id: $datalynx_id"); - //} else { - // print_r($this->_df); - //} + // 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() { @@ -317,38 +303,12 @@ public function html() { class mod_datalynx_filter_form extends mod_datalynx_filter_base_form { - //public function is_submitted() { - // TODO: Should return true if reloadonly is set to 0. - //return true; - //} - - public function definition() { - - } + public function definition() {} /* * */ public function definition_after_data() { - - $datalynx_id = $this->_ajaxformdata["d"]; - $filter_id = $this->_ajaxformdata["fid"]; - - if ($datalynx_id == null || $filter_id == null) { - return; - } - - // TODO VP: Conditionally set these (if not yet set by PRODISU) // Move these to LOAD_DATA: - $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]; - } - $df = $this->_df; $filter = $this->_filter; $name = empty($filter->name) ? get_string('filternew', 'datalynx') : $filter->name; From d925029be93cc287c3a3fd7c0207ebb2df54b416 Mon Sep 17 00:00:00 2001 From: Peter Velosy Date: Wed, 25 Sep 2024 18:42:38 +0200 Subject: [PATCH 11/11] Refactor --- classes/filter_form.php | 3 --- datalynx.js | 1 - field/field_class.php | 17 ----------------- field/select/field_class.php | 8 -------- index.php | 2 +- 5 files changed, 1 insertion(+), 30 deletions(-) diff --git a/classes/filter_form.php b/classes/filter_form.php index 26881b8f..ff7b5984 100644 --- a/classes/filter_form.php +++ b/classes/filter_form.php @@ -52,9 +52,6 @@ public function check_access_for_dynamic_submission(): void { } public function set_data_for_dynamic_submission(): void { - // Since this runs after definition(), we are not using it, as the form's composition already depends on the data loaded. - global $DB; - $datalynx_id = $this->_ajaxformdata["d"]; $filter_id = $this->_ajaxformdata["fid"]; diff --git a/datalynx.js b/datalynx.js index b9497e56..1bb82245 100644 --- a/datalynx.js +++ b/datalynx.js @@ -13,7 +13,6 @@ // You should have received a copy of the GNU General Public License // Along with Moodle. If not, see . - /** * @package mod_datalynx * @copyright 2013 onwards David Bogner, Michael Pollak, Ivan Sakic and others. diff --git a/field/field_class.php b/field/field_class.php index 7f8c88dd..02a14215 100644 --- a/field/field_class.php +++ b/field/field_class.php @@ -847,15 +847,6 @@ public function is_datalynx_content() { protected function filearea($suffix = null) { return false; } - - // TODO: Git PR to move this to the base class. - public function get_argument_count(string $operator) { - if ($operator === "") { // "Empty" operator - return 0; - } else { - return 1; - } - } } /** @@ -1036,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; - } - } } /** diff --git a/field/select/field_class.php b/field/select/field_class.php index 2c617917..5c7a3b3a 100644 --- a/field/select/field_class.php +++ b/field/select/field_class.php @@ -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; - } - } } diff --git a/index.php b/index.php index 35cbe43b..832d723f 100644 --- a/index.php +++ b/index.php @@ -168,4 +168,4 @@ echo html_writer::empty_tag('br'); echo html_writer::tag('div', html_writer::table($table), array('class' => 'no-overflow')); -echo $OUTPUT->footer(); \ No newline at end of file +echo $OUTPUT->footer();