Skip to content

Commit b7c345c

Browse files
authored
Merge pull request #60 from grezniczek/jsmo-ajax
Bugfix with filter logic and switching to JSMO.ajax()
2 parents 742734d + 4680fbf commit b7c345c

File tree

7 files changed

+135
-28
lines changed

7 files changed

+135
-28
lines changed

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.vscode export-ignore
2+
/.gitignore export-ignore
3+
/.gitattributes export-ignore
4+
EM.code-workspace export-ignore

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
package-lock.json

.vscode/launch.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Listen for XDebug",
9+
"type": "php",
10+
"request": "launch",
11+
"port": 9003
12+
},
13+
{
14+
"type": "chrome",
15+
"request": "attach",
16+
"name": "Attach to Chrome",
17+
"port": 9222,
18+
"webRoot": "${workspaceFolder}",
19+
"sourceMaps": false
20+
}
21+
],
22+
"compounds": [
23+
{
24+
"name": "Chrome + XDebug",
25+
"configurations": ["Attach to Chrome", "Listen for XDebug"]
26+
}
27+
]
28+
}

EM.code-workspace

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
},
6+
{
7+
"path": "..\\..\\external_modules",
8+
"name": "EM Framework"
9+
},
10+
{
11+
"path": "..\\..\\codebase",
12+
"name": "REDCap"
13+
}
14+
],
15+
"settings": {
16+
"php.suggest.basic": false
17+
}
18+
}

InstanceTable.php

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,20 @@ public function redcap_survey_page_top($project_id, $record, $instrument, $event
9191
$this->initHook($record, $instrument, $event_id, true, $group_id, $repeat_instance);
9292
$this->pageTop();
9393
}
94-
94+
95+
public function redcap_module_ajax($action, $payload, $project_id, $record, $instrument, $event_id, $repeat_instance, $survey_hash, $response_id, $survey_queue_hash, $page, $page_full, $user_id, $group_id) {
96+
$this->initHook($record, $instrument, $event_id, false, $group_id, $repeat_instance);
97+
if ($action == "get-data") {
98+
$event = intval($payload["event_id"]);
99+
$form = $this->framework->escape($payload["form_name"]);
100+
$fields = $this->framework->escape($payload["fields"]);
101+
$filter = $payload["filter"];
102+
$hideChoiceValues = ($payload["hide_vals"]=='1');
103+
$data = $this->getInstanceData($record, $event, $form, $fields, $filter, true, $hideChoiceValues);
104+
return $data;
105+
}
106+
}
107+
95108
protected function initHook($record, $instrument, $event_id, $isSurvey, $group_id, $repeat_instance) {
96109
global $Proj, $lang, $user_rights;
97110
$this->Proj = $Proj;
@@ -246,9 +259,6 @@ protected function setTaggedFields() {
246259
reset($includeVars);
247260
$repeatingFormDetails['var_list'] = $includeVars;
248261

249-
$ajaxUrl = $this->getUrl('instance_table_ajax.php');
250-
$filter = htmlspecialchars(str_replace("'",self::REPLQUOTE_SINGLE,str_replace('"',self::REPLQUOTE_DOUBLE,$filter)), ENT_QUOTES);
251-
252262
if (preg_match("/".self::ACTION_TAG_SCROLLX."/", $fieldDetails['field_annotation'])) {
253263
$repeatingFormDetails['scroll_x'] = true;
254264
} else {
@@ -276,7 +286,12 @@ protected function setTaggedFields() {
276286
$repeatingFormDetails['hide_choice_values'] = false;
277287
}
278288

279-
$repeatingFormDetails['ajax_url'] = $ajaxUrl."$hideVals&record={$this->record}&event_id=$eventId&form_name=$formName&filter=$filter&fields=".implode('|',$includeVars);
289+
$repeatingFormDetails["ajax"] = [
290+
"event_id" => $eventId,
291+
"form_name" => $formName,
292+
"filter" => $filter,
293+
"fields" => $includeVars
294+
];
280295
$repeatingFormDetails['markup'] = '';
281296

282297
$this->taggedFields[] = $repeatingFormDetails;
@@ -420,7 +435,6 @@ public function getInstanceData($record, $event, $form, $fields, $filter, $inclu
420435
$this->user_rights = &$user_rights;
421436
$this->isSurvey = (PAGE==='surveys/index.php');
422437
$instanceData = array();
423-
$filter = str_replace(self::REPLQUOTE_SINGLE,"'",str_replace(self::REPLQUOTE_DOUBLE,'"',$filter));
424438

425439
// find any descriptive text fields tagged with @FORMINSTANCETABLE=form_name
426440

@@ -615,6 +629,8 @@ protected function makeOntologyDisplay($val, $service, $category) {
615629

616630
protected function insertJS() {
617631
global $lang;
632+
$this->framework->initializeJavascriptModuleObject();
633+
$jsmo_name = $this->framework->getJavascriptModuleObjectName();
618634
?>
619635
<style type="text/css">
620636
.<?php echo self::MODULE_VARNAME;?> tbody tr { font-weight:normal; }
@@ -633,8 +649,10 @@ protected function insertJS() {
633649
var lengthVal;
634650
var lengthLbl;
635651
var lengthChange;
652+
var JSMO = <?=$jsmo_name?>;
636653

637654
function init() {
655+
// console.log('Instance Table', config);
638656
config.forEach(function(taggedField) {
639657
taggedFieldNames.push(taggedField.field_name);
640658
$('#'+taggedField.field_name+'-tr td:last')
@@ -654,7 +672,9 @@ function init() {
654672
lengthVal = lengthLbl = [taggedField.page_size];
655673
lengthChange = false;
656674
}
657-
var thisTbl = $('#'+taggedField.html_table_id)
675+
var thisTbl;
676+
if (isSurvey) {
677+
thisTbl = $('#'+taggedField.html_table_id)
658678
.DataTable( {
659679
"stateSave": true,
660680
"stateDuration": 0,
@@ -673,11 +693,36 @@ function init() {
673693
"targets": "_all"
674694
}]
675695
} );
676-
if (!taggedField.show_instance_col) {
677-
thisTbl.column( 0 ).visible( false );
696+
if (!taggedField.show_instance_col) {
697+
thisTbl.column( 0 ).visible( false );
698+
}
678699
}
679-
if (!isSurvey) {
680-
thisTbl.ajax.url(taggedField.ajax_url).load();
700+
else {
701+
JSMO.ajax('get-data', taggedField.ajax).then(function(data) {
702+
thisTbl = $('#'+taggedField.html_table_id)
703+
.DataTable( {
704+
"stateSave": true,
705+
"stateDuration": 0,
706+
"lengthMenu": [lengthVal, lengthLbl],
707+
"lengthChange": lengthChange,
708+
"columnDefs": [{
709+
"render": function (data, type, row) {
710+
let val = data;
711+
if ($.isPlainObject(data)) {
712+
if (data.hasOwnProperty(type)) { // e.g. sort, filter for dates
713+
val = data[type];
714+
}
715+
}
716+
return val;
717+
},
718+
"targets": "_all"
719+
}],
720+
"data": data
721+
} );
722+
if (!taggedField.show_instance_col) {
723+
thisTbl.column( 0 ).visible( false );
724+
}
725+
});
681726
}
682727
});
683728

@@ -714,12 +759,14 @@ function refreshTableDialog() {
714759
,function() {
715760
// refresh all instance tables (e.g. to pick up changes to multiple forms across repeating event
716761
$('.'+tableClass).each(function() {
717-
$(this).DataTable().ajax.reload( null, false ); // don't reset user paging on reload
762+
performTableRefresh(this);
718763
});
719764
},langYes
720765
);
721766
}
722767

768+
769+
723770
return {
724771
addNewInstance: function(record, event, form, linkFld, linkIns) {
725772
var ref = (linkFld=='')?'':'&link_field='+linkFld+'&link_instance='+linkIns;
@@ -729,6 +776,12 @@ function refreshTableDialog() {
729776
editInstance: function(record, event, form, instance) {
730777
instancePopup('View instance', record, event, form, instance);
731778
return false;
779+
},
780+
getConfig: function() {
781+
return config;
782+
},
783+
getJSMO: function() {
784+
return JSMO;
732785
}
733786
}
734787
})(window, document, jQuery, app_path_webroot, pid, simpleDialog);
@@ -743,7 +796,20 @@ function refreshTables() {
743796
function actuallyRefreshTables() {
744797
var tableClass = '<?php echo self::MODULE_VARNAME;?>';
745798
$('.'+tableClass).each(function() {
746-
$(this).DataTable().ajax.reload( null, false ); // don't reset user paging on reload
799+
performTableRefresh(this);
800+
});
801+
}
802+
803+
function performTableRefresh(tbl) {
804+
var id = tbl.id;
805+
var config = <?=self::MODULE_VARNAME?>.getConfig();
806+
var jsmo = <?=self::MODULE_VARNAME?>.getJSMO();
807+
var it = config.filter(function(x) { return x.html_table_id == id; })[0];
808+
jsmo.ajax('get-data', it.ajax).then(function(data) {
809+
var dt = $(tbl).DataTable();
810+
dt.clear();
811+
dt.rows.add(data);
812+
dt.draw();
747813
});
748814
}
749815

@@ -912,4 +978,4 @@ public function redcap_every_page_before_render($project_id) {
912978
}
913979
}
914980
}
915-
}
981+
}

config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
],
1111
"description": "Use the action tag <code>@INSTANCETABLE=form_name</code> in a descriptive text field to include a table showing data from repeat instances of that form.<br>If project is longitudinal, use <code>@INSTANCETABLE=event_name:form_name</code> to specify the event and form (can be a repeating form or a form in a repeating event).<br>Other action tags are available for controlling cetain properties of te tables and their contents.",
1212
"framework-version": 14,
13+
"auth-ajax-actions": [
14+
"get-data"
15+
],
1316
"action-tags": [
1417
{
1518
"tag": "@INSTANCETABLE",

instance_table_ajax.php

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)