diff --git a/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php b/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php index 3ca48ba25..ab46c269c 100644 --- a/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php +++ b/app/plugins/CoreEnroller/src/Model/Table/EnrollmentAttributesTable.php @@ -165,6 +165,10 @@ public function initialize(array $config): void { 'type' => 'auxiliary', 'model' => 'CoSettings' ], + 'types' => [ + 'type' => 'auxiliary', + 'model' => 'Types' + ], ]); $this->setLayout([ 'index' => 'iframe', diff --git a/app/plugins/CoreEnroller/templates/element/field.php b/app/plugins/CoreEnroller/templates/element/field.php index 68e4be12b..b5cd48d5a 100644 --- a/app/plugins/CoreEnroller/templates/element/field.php +++ b/app/plugins/CoreEnroller/templates/element/field.php @@ -112,7 +112,12 @@ // HIDDEN Field // We print directly, we do not delegate to the element for further processing // In case this is a hidden field, we need to get only the value - $attr->hidden && $hidden =>$this->Form->hidden($formArguments['fieldName'], ['value' => $options['default']]), - // Default use case - default => $this->element('form/listItem', ['arguments' => $formArguments]) + $attr->hidden && $hidden => $this->Form->hidden($formArguments['fieldName'], ['value' => $options['default']]), + // For the case of xxx_person_id fields, we will render the People a Picker element. + str_ends_with($attr->attribute, 'person_id') => $this->element('CoreEnroller.spa-field', [ + 'vueElementName' => 'peopleAutocomplete', + 'formArguments' => $formArguments + ]), +// Default use case + default => $this->element('form/listItem', ['arguments' => $formArguments]) }; diff --git a/app/plugins/CoreEnroller/templates/element/spa-field.php b/app/plugins/CoreEnroller/templates/element/spa-field.php new file mode 100644 index 000000000..06cb19901 --- /dev/null +++ b/app/plugins/CoreEnroller/templates/element/spa-field.php @@ -0,0 +1,61 @@ + + +
  • +
    +
    +
    + + + element('form/requiredSpan') ?> + +
    + +
    + +
    + +
    + Field->constructSPAField( + // The Default field will be used to harvest the attributes + element: $this->Field->formField(...$formArguments), + // Vue/JS element + vueElementName: $vueElementName + ) ?> +
    +
    +
  • diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php index 8fcf3ad67..f9a1a1693 100644 --- a/app/src/View/Helper/FieldHelper.php +++ b/app/src/View/Helper/FieldHelper.php @@ -73,6 +73,7 @@ class FieldHelper extends Helper { * @param array $config The configuration settings provided to this helper. * * @return void + * @since COmanage Registry v5.0.0 */ public function initialize(array $config): void { @@ -94,6 +95,7 @@ public function initialize(array $config): void * @param string $fieldName * * @return array + * @since COmanage Registry v5.0.0 */ public function calculateLabelAndDescription(string $fieldName): array { @@ -180,6 +182,7 @@ public function calculateLabelAndDescription(string $fieldName): array * Calculate the list of classes for the li element * * @return string + * @since COmanage Registry v5.0.0 */ public function calculateLiClasses(): string { @@ -219,6 +222,41 @@ public function calculateLiClasses(): string return $classes; } + /** + * Construct the SPA field element + * + * @param string $fieldName The field name + * @param array $formParams The field parameters + * @param string $vueElementName The name of the JavaScript module + * + * @return string + * @since COmanage Registry v5.0.0 + */ + public function constructSPAField(string $element, string $vueElementName): string { + // Parse the ID attribute + $regexId = '/id="(.*?)"/m'; + preg_match_all($regexId, $element, $matchesId, PREG_SET_ORDER, 0); + + // Parse the Name attribute + $regexName = '/name="(.*?)"/m'; + preg_match_all($regexName, $element, $matchesName, PREG_SET_ORDER, 0); + + // Parse the Class attribute + $regexClass = '/class="(.*?)"/m'; + preg_match_all($regexClass, $element, $matchesClass, PREG_SET_ORDER, 0); + if(!empty($matchesId[0][1]) && !empty($matchesName[0][1])) { + return $this->getView()->element($vueElementName, [ + 'htmlId' => $matchesId[0][1], + 'fieldName' => $matchesName[0][1], + 'containerClasses' => $matchesClass[0][1], + 'type' => 'field' + ]); + } + + // Fallback to an error element + return $this->getView()->element('elementFallback'); + } + /** * Emit a date/time form control. * This is a wrapper function for $this->control() diff --git a/app/templates/element/form/elementFallback.php b/app/templates/element/form/elementFallback.php new file mode 100644 index 000000000..33c16a4e3 --- /dev/null +++ b/app/templates/element/form/elementFallback.php @@ -0,0 +1,32 @@ + + +Element ID not provided \ No newline at end of file diff --git a/app/templates/element/peopleAutocomplete.php b/app/templates/element/peopleAutocomplete.php index 7787bbf36..93666844c 100644 --- a/app/templates/element/peopleAutocomplete.php +++ b/app/templates/element/peopleAutocomplete.php @@ -33,6 +33,7 @@ $htmlId = $htmlId ?? 'cmPersonPickerId'; $actionUrl = $actionUrl ?? []; // the url of the page to launch on select for a stand-alone picker $viewConfigParameters = $viewConfigParameters ?? []; + $containerClasses = $containerClasses ?? 'cm-autocomplete-container'; // Get the CSRF Token in JavaScript $token = $this->request->getAttribute('csrfToken'); @@ -132,7 +133,7 @@ } // Mount the component and provide a global reference for this app instance. - window. = app.mount("#-container"); + window. = app.mount("#-container"); -
    +
    diff --git a/app/webroot/js/comanage/components/autocomplete/cm-autocomplete-people.js b/app/webroot/js/comanage/components/autocomplete/cm-autocomplete-people.js index 990378c2e..aa6388569 100644 --- a/app/webroot/js/comanage/components/autocomplete/cm-autocomplete-people.js +++ b/app/webroot/js/comanage/components/autocomplete/cm-autocomplete-people.js @@ -194,8 +194,8 @@ export default { this.options.inputProps.dataPersonid = this.person.value } else if(this.options.type == 'field') { // The picker is part of a standard form field - const field = document.getElementById(this.options.fieldName); - field.value = this.person.value; + this.options.inputProps.dataPersonid = this.person.value + this.options.inputProps.value = `${this.person.label} (ID: ${this.person.value})` } else { // The picker is stand-alone, and should render the configured page in a modal on @item-select const urlForModal = this.options.actionUrl + '&person_id=' + this.person.value; @@ -249,7 +249,7 @@ export default { mounted() { if(this.options.inputValue != undefined && this.options.inputValue != '' - && this.options.htmlId == 'person_id') { + && this.options.htmlId.endsWith('person_id')) { this.options.inputProps.value = `${this.options.formParams?.fullName} (ID: ${this.options.inputValue})` } },