[ 'name' => tra('Dynamic Items List'), 'description' => tra('Dynamically updates a selection list based on linked data from another tracker.'), 'help' => 'Dynamic items list', 'prefs' => ['trackerfield_dynamiclist'], 'tags' => ['advanced'], 'default' => 'n', 'params' => [ 'trackerId' => [ 'name' => tr('Tracker ID'), 'description' => tr('Tracker to link with'), 'filter' => 'int', 'legacy_index' => 0, 'profile_reference' => 'tracker', ], 'filterFieldIdThere' => [ 'name' => tr('Field ID (Other tracker)'), 'description' => tr('Field ID to link with in the other tracker'), 'filter' => 'int', 'legacy_index' => 1, 'profile_reference' => 'tracker_field', 'parent' => 'trackerId', 'parentkey' => 'tracker_id', ], 'filterFieldIdHere' => [ 'name' => tr('Field ID (This tracker)'), 'description' => tr('Field ID to link with in the current tracker'), 'filter' => 'int', 'legacy_index' => 2, 'profile_reference' => 'tracker_field', 'parent' => 'input[name=trackerId]', 'parentkey' => 'tracker_id', ], 'listFieldIdThere' => [ 'name' => tr('Listed Field'), 'description' => tr('Field ID to be displayed in the dropdown list.'), 'filter' => 'int', 'legacy_index' => 3, 'profile_reference' => 'tracker_field', 'parent' => 'trackerId', 'parentkey' => 'tracker_id', ], 'statusThere' => [ 'name' => tr('Status Filter'), 'description' => tr('Restrict listed items to specific statuses.'), 'filter' => 'alpha', 'options' => [ 'opc' => tr('all'), 'o' => tr('open'), 'p' => tr('pending'), 'c' => tr('closed'), 'op' => tr('open, pending'), 'pc' => tr('pending, closed'), ], 'legacy_index' => 4, ], 'hideBlank' => [ 'name' => tr('Hide blank'), 'description' => tr('Hide first blank option, thus preselecting the first available option.'), 'filter' => 'int', 'options' => [ 0 => tr('No'), 1 => tr('Yes'), ], 'legacy_index' => 5, ], 'selectMultipleValues' => [ 'name' => tr('Select multiple values'), 'description' => tr('Allow the user to select multiple values'), 'filter' => 'int', 'options' => [ 0 => tr('No'), 1 => tr('Yes'), ], 'legacy_index' => 6, ], ], ], ]; } function getFieldData(array $requestData = []) { $ins_id = $this->getInsertId(); $data = [ 'value' => (isset($requestData[$ins_id])) ? $requestData[$ins_id] : $this->getValue(), ]; if ($this->getOption('selectMultipleValues') && ! is_array($data['value'])) { $data['value'] = explode(',', $data['value']); } return $data; } function renderInput($context = []) { // REFACTOR: can't use list-tracker_field_values_ajax.php yet as it doesn't seem to filter // Modified to support multiple dynamic item list fields bound to the same $filterFieldIdHere // When changing $filterFieldValueHere (i.e combobox) the $originalValue will be send as part of the request to the backend. // The backend returns an json array('request' => $requestData, 'response' => $responseData). // This way we can keep the default $originalValue, even when changing the selection forth and back. // It fixes also the issue that, if more than one dynamic item list fields are set and use the same // $filterFieldIdHere, then the initial value was wrong due to multiple fires of the handler. $filterFieldIdHere = trim($this->getOption('filterFieldIdHere')); $trackerIdThere = $this->getOption('trackerId'); $listFieldIdThere = $this->getOption('listFieldIdThere'); $filterFieldIdThere = $this->getOption('filterFieldIdThere'); $statusThere = $this->getOption('statusThere'); $isMandatory = $this->getConfiguration('isMandatory'); $insertId = $this->getInsertId(); $originalValue = $this->getConfiguration('value'); $hideBlank = $this->getOption('hideBlank'); $selectMultipleValues = $this->getOption('selectMultipleValues'); $filterFieldValueHere = $originalValue; if (! empty($context['itemId'])) { $itemInfo = TikiLib::lib('trk')->get_tracker_item($context['itemId']); if (! empty($itemInfo) && ! empty($itemInfo[$filterFieldIdHere])) { $filterFieldValueHere = $itemInfo[$filterFieldIdHere]; } } if ($filterFieldIdHere == $this->getConfiguration('fieldId')) { return tr('*** ERROR: Field ID (This tracker) cannot be the same: %0 ***', $filterFieldIdHere); } if (! TikiLib::lib('trk')->get_tracker_field($listFieldIdThere)) { return tr('*** ERROR: Field %0 not found ***', $listFieldIdThere); } if ($this->getOption('selectMultipleValues')) { if (is_array($originalValue)) { $originalValue = implode(',', $originalValue); } $filterFieldValueHere = explode(',', $originalValue); $multiple = ' multiple="multiple"'; } else { $multiple = ''; } TikiLib::lib('header')->add_jq_onready( ' $("body").on("change", "input[name=ins_' . $filterFieldIdHere . '], select[name=ins_' . $filterFieldIdHere . ']", function(e) { $.getJSON( "tiki-tracker_http_request.php", { filterFieldIdHere: ' . $filterFieldIdHere . ', trackerIdThere: ' . $trackerIdThere . ', listFieldIdThere: ' . $listFieldIdThere . ', filterFieldIdThere: ' . $filterFieldIdThere . ', statusThere: "' . $statusThere . '", mandatory: "' . $isMandatory . '", insertId: "' . $insertId . '", // need to pass $insertId in case we have more than one field bound to the same eventsource originalValue: "' . $originalValue . '", hideBlank: ' . intval($hideBlank) . ', selectMultipleValues: ' . $selectMultipleValues . ', filterFieldValueHere: $(this).val() // We need the field value for the fieldId filterfield for the item $(this).val }, // callback function(data, status) { if (data && data.request && data.response) { targetDDL = "select[name=" + data.request.insertId + "]"; $ddl = $(targetDDL); $ddl.empty(); var v, l; response = data.response; $.each( response, function (i,data) { if (data && data.length > 1) { v = data[0]; l = data[1]; } else { v = "" l = ""; } $ddl.append( $("