Skip to content

Commit ee351f6

Browse files
committed
New features
- Action tag for alternative "Add" button label - Action tag for suppressing display of choice field values
1 parent f0ad131 commit ee351f6

File tree

4 files changed

+79
-94
lines changed

4 files changed

+79
-94
lines changed

InstanceTable.php

Lines changed: 59 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ class InstanceTable extends AbstractExternalModule
2828
protected $group_id;
2929
protected $repeat_instance;
3030
protected $defaultValueForNewPopup;
31-
protected $hideChoice;
32-
3331

3432
const ACTION_TAG = '@INSTANCETABLE';
3533
const ACTION_TAG_HIDE_FIELD = '@INSTANCETABLE_HIDE';
@@ -40,11 +38,11 @@ class InstanceTable extends AbstractExternalModule
4038
const ACTION_TAG_VARLIST = '@INSTANCETABLE_VARLIST'; // provide a comma-separated list of variables to include (not including any tagged HIDE)
4139
const ACTION_TAG_PAGESIZE = '@INSTANCETABLE_PAGESIZE'; // Override default choices for page sizing: specify integer default page size, use -1 for All
4240
const ACTION_TAG_REF = '@INSTANCETABLE_REF';
43-
const ACTION_TAG_SRC = '@INSTANCETABLE_SRC'; // deprecated
41+
const ACTION_TAG_SRC = '@INSTANCETABLE_SRC'; // deprecated
4442
const ACTION_TAG_DST = '@INSTANCETABLE_DST'; // deprecated
4543
const ACTION_TAG_FILTER = '@INSTANCETABLE_FILTER';
46-
const ACTION_TAG_ADDBTNLABEL = '@INSTANCETABLE_ADDBTNLABEL';
47-
const ACTION_TAG_HIDECHOICEVAL = '@INSTANCETABLE_HIDECHOICEVAL';
44+
const ACTION_TAG_ADDBTNLABEL = '@INSTANCETABLE_ADDBTNLABEL';
45+
const ACTION_TAG_HIDECHOICEVALUES = '@INSTANCETABLE_HIDECHOICEVALUES';
4846
const ADD_NEW_BTN_YSHIFT = '0px';
4947
const MODULE_VARNAME = 'MCRI_InstanceTable';
5048

@@ -250,33 +248,37 @@ protected function setTaggedFields() {
250248

251249
$ajaxUrl = $this->getUrl('instance_table_ajax.php');
252250
$filter = htmlspecialchars(str_replace("'",self::REPLQUOTE_SINGLE,str_replace('"',self::REPLQUOTE_DOUBLE,$filter)), ENT_QUOTES);
253-
$repeatingFormDetails['ajax_url'] = $ajaxUrl."&record={$this->record}&event_id=$eventId&form_name=$formName&filter=$filter&fields=".implode('|',$includeVars);
254-
$repeatingFormDetails['markup'] = '';
255251

256-
if (preg_match("/".self::ACTION_TAG_SCROLLX."/", $fieldDetails['field_annotation'], $matches)) {
252+
if (preg_match("/".self::ACTION_TAG_SCROLLX."/", $fieldDetails['field_annotation'])) {
257253
$repeatingFormDetails['scroll_x'] = true;
258254
} else {
259255
$repeatingFormDetails['scroll_x'] = false;
260256
}
261257

262-
if (preg_match("/".self::ACTION_TAG_HIDEADDBTN."/", $fieldDetails['field_annotation'], $matches)) {
258+
if (preg_match("/".self::ACTION_TAG_HIDEADDBTN."/", $fieldDetails['field_annotation'])) {
263259
$repeatingFormDetails['hide_add_btn'] = true;
264260
} else {
265261
$repeatingFormDetails['hide_add_btn'] = false;
266262
}
267263

268-
264+
$matches = array();
269265
if (preg_match("/".self::ACTION_TAG_ADDBTNLABEL."\s*=\'([^\']+)\'/", $fieldDetails['field_annotation'], $matches)) {
270-
$value = $matches[1];
271-
$repeatingFormDetails['button_label'] = $value;
272-
} else{
273-
$repeatingFormDetails['button_label'] = '';
266+
$repeatingFormDetails['button_label'] = REDCap::filterHtml($matches[1]);
267+
} else {
268+
$repeatingFormDetails['button_label'] = '';
274269
}
275270

276-
if (preg_match("/" . self::ACTION_TAG_HIDECHOICEVAL . "/", $fieldDetails['field_annotation'], $matches)) {
277-
$this->hideChoice = true;
271+
if (preg_match("/".self::ACTION_TAG_HIDECHOICEVALUES."/", $fieldDetails['field_annotation'])) {
272+
$hideVals = '&hide_vals=1';
273+
$repeatingFormDetails['hide_choice_values'] = true;
274+
} else {
275+
$hideVals = '';
276+
$repeatingFormDetails['hide_choice_values'] = false;
278277
}
279-
278+
279+
$repeatingFormDetails['ajax_url'] = $ajaxUrl."$hideVals&record={$this->record}&event_id=$eventId&form_name=$formName&filter=$filter&fields=".implode('|',$includeVars);
280+
$repeatingFormDetails['markup'] = '';
281+
280282
$this->taggedFields[] = $repeatingFormDetails;
281283
}
282284
}
@@ -345,11 +347,12 @@ protected function makeHtmlTable($repeatingFormDetails, $canEdit) {
345347
$eventId = $repeatingFormDetails['event_id'];
346348
$formName = $repeatingFormDetails['form_name'];
347349
$scrollX = $repeatingFormDetails['scroll_x'];
348-
$btnlabel = $repeatingFormDetails['button_label'];
349350
$linkField = $repeatingFormDetails['link_field'];
350351
$linkValue = $repeatingFormDetails['link_instance'];
351352
$filter = $repeatingFormDetails['filter']; // The filter actually contains linkfield=linkvalue
352353
$varList = $repeatingFormDetails['var_list'];
354+
$btnLabel = ($repeatingFormDetails['button_label']=='') ? $this->lang['data_entry_247'] : $repeatingFormDetails['button_label'];
355+
$hideChoiceValues = $repeatingFormDetails['hide_choice_values'];
353356

354357
$scrollStyle = ($scrollX) ? "display:block; max-width:790px;" : "";
355358
$nColumns = 1; // start at 1 for # (Instance) column
@@ -374,7 +377,7 @@ protected function makeHtmlTable($repeatingFormDetails, $canEdit) {
374377

375378
// if survey form get data on page load (as no add/edit and have no auth for an ajax call)
376379
if ($this->isSurvey) {
377-
$instanceData = $this->getInstanceData($this->record, $eventId, $formName, $varList, $filter, false);
380+
$instanceData = $this->getInstanceData($this->record, $eventId, $formName, $varList, $filter, false, $hideChoiceValues);
378381
if (count($instanceData) > 0) {
379382
$html.='<tbody>';
380383
foreach ($instanceData as $rowValues) {
@@ -388,20 +391,19 @@ protected function makeHtmlTable($repeatingFormDetails, $canEdit) {
388391
$html.='</tbody>';
389392
} else {
390393
// $html.='<tr><td colspan="'.$nColumns.'">No data available in table</td></tr>';
391-
// unnecessary and DT does not supprt colspan in body tr // https://datatables.net/forums/discussion/32575/uncaught-typeerror-cannot-set-property-dt-cellindex-of-undefined
394+
// unnecessary and DT does not support colspan in body tr // https://datatables.net/forums/discussion/32575/uncaught-typeerror-cannot-set-property-dt-cellindex-of-undefined
392395
}
393396
}
394397

395398
$html.='</table>';
396-
397-
$btnlabelval = $btnlabel == '' ? $this->lang['data_entry_247'] : $btnlabel;
399+
398400
if ($canEdit) {
399-
$html.='<div style="position:relative;top:'.self::ADD_NEW_BTN_YSHIFT.';margin-bottom:5px;"><button type="button" class="btn btn-sm btn-success " onclick="'.self::MODULE_VARNAME.'.addNewInstance(\''.$this->record.'\','.$eventId.',\''.$formName.'\',\''.$linkField.'\',\''.$linkValue.'\');"><span class="fas fa-plus-circle" aria-hidden="true"></span>&nbsp;'.$btnlabelval.'</button></div>'; // Add new
401+
$html.='<div style="position:relative;top:'.self::ADD_NEW_BTN_YSHIFT.';margin-bottom:5px;"><button type="button" class="btn btn-sm btn-success " onclick="'.self::MODULE_VARNAME.'.addNewInstance(\''.$this->record.'\','.$eventId.',\''.$formName.'\',\''.$linkField.'\',\''.$linkValue.'\');"><span class="fas fa-plus-circle mr-1" aria-hidden="true"></span>'.$btnLabel.'</button></div>'; // Add new
400402
}
401403
return $html;
402404
}
403405

404-
public function getInstanceData($record, $event, $form, $fields, $filter, $includeFormStatus=true) {
406+
public function getInstanceData($record, $event, $form, $fields, $filter, $includeFormStatus=true, $hideChoiceValues=false) {
405407
global $Proj, $lang, $user_rights;
406408
$this->Proj = $Proj;
407409
$this->lang = &$lang;
@@ -467,7 +469,7 @@ public function getInstanceData($record, $event, $form, $fields, $filter, $inclu
467469
$outValue = $this->makeFormStatusDisplay($value, $record, $event, $form, $instance);
468470

469471
} else if (in_array($fieldType, array("advcheckbox", "radio", "select", "checkbox", "dropdown", "sql", "yesno", "truefalse"))) {
470-
$outValue = $this->makeChoiceDisplay($value, $repeatingFormFields, $fieldName);
472+
$outValue = $this->makeChoiceDisplay($value, $repeatingFormFields, $fieldName, $hideChoiceValues);
471473

472474
} else if ($fieldType==='text') {
473475
$ontologyOption = $this->Proj->metadata[$fieldName]['element_enum'];
@@ -484,7 +486,7 @@ public function getInstanceData($record, $event, $form, $fields, $filter, $inclu
484486
$outValue = $this->makeTextDisplay($value, $repeatingFormFields, $fieldName);
485487

486488
} else if ($fieldType==='file') {
487-
$outValue = $this->makeFileDisplay($value, $record, $event, $instance, $fieldName, $survey_hash);
489+
$outValue = $this->makeFileDisplay($value, $record, $event, $instance, $fieldName);
488490

489491
} else {
490492
$outValue = htmlentities($value, ENT_QUOTES);
@@ -510,7 +512,7 @@ protected function makeInstanceNumDisplay($val, $record, $event, $form, $instanc
510512
return $this->makeOpenPopupAnchor($val, $record, $event, $form, $instance);
511513
}
512514

513-
protected function makeFormStatusDisplay($val, $record, $event, $form, $instance, ) {
515+
protected function makeFormStatusDisplay($val, $record, $event, $form, $instance) {
514516
switch ($val) {
515517
case '2':
516518
$circle = '<img src="'.APP_PATH_IMAGES.'circle_green.png" style="height:16px;width:16px;">';
@@ -525,7 +527,7 @@ protected function makeFormStatusDisplay($val, $record, $event, $form, $instance
525527
return $this->makeOpenPopupAnchor($circle, $record, $event, $form, $instance);
526528
}
527529

528-
protected function makeChoiceDisplay($val, $repeatingFormFields, $fieldName) {
530+
protected function makeChoiceDisplay($val, $repeatingFormFields, $fieldName, $hideChoiceValues=false) {
529531
if ($this->Proj->metadata[$fieldName]['element_type']==='sql') {
530532
$choices = parseEnum(getSqlFieldEnum($this->Proj->metadata[$fieldName]['element_enum']));
531533
} else {
@@ -535,25 +537,22 @@ protected function makeChoiceDisplay($val, $repeatingFormFields, $fieldName) {
535537
if (is_array($val)) {
536538
foreach ($val as $valkey => $cbval) {
537539
if ($cbval==='1') {
538-
$val[$valkey] = $this->makeChoiceDisplayHtml($valkey, $choices);
540+
$val[$valkey] = $this->makeChoiceDisplayHtml($valkey, $choices, $hideChoiceValues);
539541
} else {
540542
unset($val[$valkey]);
541543
}
542544
}
543545
$outValue = implode('<br>', $val); // multiple checkbox selections one per line
544546
} else {
545-
$outValue = $this->makeChoiceDisplayHtml($val, $choices);
547+
$outValue = $this->makeChoiceDisplayHtml($val, $choices, $hideChoiceValues);
546548
}
547549
return REDCap::filterHtml($outValue);
548550
}
549551

550-
protected function makeChoiceDisplayHtml($val, $choices)
551-
{
552+
protected function makeChoiceDisplayHtml($val, $choices, $hideChoiceValues=false) {
552553
if (array_key_exists($val, $choices)) {
553-
if ($this->hideChoice) {
554-
return $choices[$val];
555-
}
556-
return $choices[$val] . ' <span class="text-muted">(' . $val . ')</span>';
554+
$valDisplay = ($hideChoiceValues) ? '' : ' <span class="text-muted">('.$val.')</span>';
555+
return $choices[$val].$valDisplay;
557556
}
558557
return $val;
559558
}
@@ -562,54 +561,33 @@ protected function makeTextDisplay($val, $repeatingFormFields, $fieldName) {
562561
if (trim($val)=='') { return ''; }
563562
$valType = $repeatingFormFields[$fieldName]['text_validation_type_or_show_slider_number'];
564563
switch ($valType) {
565-
case 'date_mdy':
566-
$outVal = date("m-d-Y", strtotime($val));
567-
break;
568-
case 'date_dmy':
569-
$outVal = date("d-m-Y", strtotime($val));
570-
break;
571-
case 'datetime_mdy':
572-
$dateWithTime = date("Y-m-d H:i", strtotime($val));
573-
if ($dateWithTime == $val) {
574-
$outVal = date("d-m-Y H:i", strtotime($val));
575-
} else {
576-
$outVal = date("d-m-Y", strtotime($val));
577-
}
578-
break;
579-
case 'datetime_dmy':
580-
case 'datetime_seconds_mdy':
581-
$dateWithTimewiths = date("Y-m-d H:i:s", strtotime($val));
582-
$dateWithTime = date("Y-m-d H:i", strtotime($val));
583-
if ($dateWithTimewiths == $val) {
584-
$outVal = date("d-m-Y H:i:s", strtotime($val));
585-
} else if($dateWithTime == $val) {
586-
$outVal = date("d-m-Y H:i", strtotime($val));
587-
}else{
588-
$outVal = date("d-m-Y", strtotime($val));
589-
}
590-
break;
591-
case 'datetime_seconds_dmy':
592-
$outVal = DateTimeRC::datetimeConvert($val, 'ymd', substr($valType, -3)); // reformat raw ymd date/datetime value to mdy or dmy, if appropriate
593-
$outVal = $valType; // stick with standard ymd format for better sorting
594-
break;
595-
case 'email':
596-
$outVal = "<a href='mailto:$val'>$val</a>";
597-
break;
598-
default:
599-
$outVal = $val;
600-
break;
564+
case 'date_mdy':
565+
case 'date_dmy':
566+
case 'datetime_mdy':
567+
case 'datetime_dmy':
568+
case 'datetime_seconds_mdy':
569+
case 'datetime_seconds_dmy':
570+
$outVal = DateTimeRC::datetimeConvert($val, 'ymd', substr($valType, -3)); // reformat raw ymd date/datetime value to mdy or dmy, if appropriate
571+
$outVal = $val; // stick with standard ymd format for better sorting
572+
break;
573+
case 'email':
574+
$outVal = "<a href='mailto:$val'>$val</a>";
575+
break;
576+
default:
577+
$outVal = $val;
578+
break;
601579
}
602580
return REDCap::filterHtml($outVal);
603581
}
604582

605-
protected function makeFileDisplay($val, $record, $event_id, $instance, $fieldName, $survey_hash) {
606-
$survery_hash = $_GET['s'];
607-
if ($this->isSurvey){
608-
$downloadDocUrl = APP_PATH_SURVEY . "index.php?pid=".PROJECT_ID."&__passthru=".urlencode("DataEntry/file_download.php")."&doc_id_hash=".Files::docIdHash($val)."&id=$val&s=$survery_hash&record=$record&event_id=$event_id&field_name=$fieldName&instance=$instance";
609-
}else{
610-
$downloadDocUrl = APP_PATH_WEBROOT.'DataEntry/file_download.php?pid='.PROJECT_ID."&s=&record=$record&event_id=$event_id&instance=$instance&field_name=$fieldName&id=$val&doc_id_hash=".Files::docIdHash($val);
611-
}
612-
$fileDlBtn = "<button class='btn btn-defaultrc btn-xs' style='font-size:8pt;' onclick=\"window.open('$downloadDocUrl','_blank');return false;\">{$this->lang['design_121']}</button>";
583+
protected function makeFileDisplay($val, $record, $event_id, $instance, $fieldName) {
584+
if ($this->isSurvey) {
585+
$surveyHash = REDCap::filterHtml($_GET['s']);
586+
$downloadDocUrl = APP_PATH_SURVEY . "index.php?pid=".PROJECT_ID."&__passthru=".urlencode("DataEntry/file_download.php")."&doc_id_hash=".Files::docIdHash($val)."&id=$val&s=$surveyHash&record=$record&event_id=$event_id&field_name=$fieldName&instance=$instance";
587+
} else {
588+
$downloadDocUrl = APP_PATH_WEBROOT.'DataEntry/file_download.php?pid='.PROJECT_ID."&s=&record=$record&event_id=$event_id&instance=$instance&field_name=$fieldName&id=$val&doc_id_hash=".Files::docIdHash($val);
589+
}
590+
$fileDlBtn = "<button class='btn btn-defaultrc btn-xs' style='font-size:8pt;' onclick=\"window.open('$downloadDocUrl','_blank');return false;\">{$this->lang['design_121']}</button>";
613591
return str_replace('removed=','onclick=',REDCap::filterHtml($fileDlBtn));
614592
}
615593

@@ -882,7 +860,7 @@ function(){
882860
* - Augment the action_tag_explain content on project Design pages by adding some additional tr following the last built-in action tag.
883861
* @param type $project_id
884862
*/
885-
public function redcap_every_page_before_render($project_id) {
863+
public function redcap_every_page_before_render($project_id) {
886864
if (isset($_POST['extmod_closerec_home'])) {
887865
$_SESSION['extmod_closerec_home'] = $_POST['extmod_closerec_home'];
888866

0 commit comments

Comments
 (0)