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 @@
+
+
+
+
+
+
+ = $label ?>
+
+ = $this->element('form/requiredSpan') ?>
+
+
+
+
+ = $description ?>
+
+
+
+ = $this->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.= $htmlId ?> = app.mount("#= $htmlId ?>-container");
+ window.= str_replace('-', '', $htmlId) ?> = app.mount("#= $htmlId ?>-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})`
}
},