Skip to content

Commit

Permalink
People picker:copy vue element value to a visually hidden cakephp for…
Browse files Browse the repository at this point in the history
…m input element (#325)
  • Loading branch information
Ioannis authored Aug 8, 2025
1 parent 397ad14 commit c4ce79a
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 9 deletions.
2 changes: 1 addition & 1 deletion app/src/Lib/Traits/SearchFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ public function getSearchableAttributes(string $controller, \DateTimeZone $vv_tz
'type' => 'search',
'fieldName' => $field,
'personType' => $f['picker']['type'],
'htmlId' => $field, // This is the input ID
'htmlId' => Inflector::dasherize($field) . '-picker', // This is the input ID
'viewConfigParameters' => $f['picker']['configuration']
];
$this->viewVars['vv_autocomplete_arguments'] = $autocompleteArgs;
Expand Down
2 changes: 1 addition & 1 deletion app/src/View/Helper/FieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public function constructSPAField(string $element, string $vueElementName): stri

if(!empty($matchesId[0][1]) && !empty($matchesName[0][1])) {
$vueElementProperties = [
'htmlId' => $matchesId[0][1],
'htmlId' => $matchesId[0][1] . '-picker',
'fieldName' => $matchesName[0][1],
'containerClasses' => $matchesClass[0][1],
'type' => 'field',
Expand Down
4 changes: 3 additions & 1 deletion app/templates/element/filter/filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
const filterForm = document.getElementById("top-filters-form");
filterForm.addEventListener('formdata', (event) => {
if(event.formData.has('person_id')) {
const personId = $(filterForm).find('#person_id')[0].getAttribute('datapersonid')
const personId = $(filterForm).find('#person-id-picker')[0].getAttribute('datapersonid')
if(personId != undefined && personId != '') {
event.formData.set('person_id', personId)
} else {
event.formData.delete('person_id')
}
}
});
Expand Down
3 changes: 3 additions & 0 deletions app/templates/element/filter/topButtons.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
// to store the correct identifier in the case of dates. Dates have two search fields for each column
// which makes it more complicated to keep track of the id.
$data_identifier = is_array($params) ? implode(':', array_keys($params)) : $key;
if ($data_identifier === 'person_id') {
$data_identifier = 'person_id_picker';
}

// The populated variables are in plural while the column names are singular
// Convention: It is a prerequisite that the vvar should be the plural of the column name
Expand Down
2 changes: 2 additions & 0 deletions app/templates/element/javascript.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@
let ident_to_snake = ident.replace(/_/g, "-");
let filterId = '#' + ident_to_snake;
$(filterId).val("");
// This will only apply to the people picker field
$(filterId).attr('datapersonid', '');
});

$(this).closest('form').submit();
Expand Down
26 changes: 21 additions & 5 deletions app/templates/element/peopleAutocomplete.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
$fieldName = $fieldName ?? 'person_id';
// Used by the SearchFilter Configuration
$personType = $personType ?? 'person';
$htmlId = $htmlId ?? 'cmPersonPickerId';
$htmlId = $htmlId ?? 'person-id-picker';
// Does it have a value already. Default or stored
// CAKEPHP automatically generates a select element if the value is an integer. This is not helpful here.
$inputValue = $inputValue ?? $vv_field_arguments["fieldOptions"]["default"] ?? $vv_field_arguments["fieldOptions"]["value"] ?? '';
Expand All @@ -63,6 +63,20 @@
$personRecord = $this->Petition->getRecordForId('person_id', $inputValue, ['PrimaryName', 'EmailAddresses']);
$canvasUrl = $this->Url->build(['controller' => 'people', 'action' => 'edit', $inputValue]);
}
$searchPeople = $this->request->getAttribute('webroot') . 'api/ajax/v2/people/pick?co_id=' . $vv_cur_co->id;
if (isset($vv_petition->id)) {
$searchPeople = $this->request->getAttribute('webroot') . 'api/ajax/v2/people/pick?co_id=' . $vv_cur_co->id . '&petition_id=' . $vv_petition->id;
}

// This is the actual field that will be submitted.
print $this->Form->control($fieldName, [
'id' => $fieldName,
'value' => '',
'type' => 'text',
'class' => 'visually-hidden',
'label' => false,
]
);
?>

<script type="module">
Expand All @@ -84,7 +98,7 @@
viewConfigParameters: <?= json_encode($viewConfigParameters) ?>,
webroot: '<?= $this->request->getAttribute('webroot') ?>',
// co_id query parameter is required since it is the People's primary link
searchPeople: `<?= $this->request->getAttribute('webroot') ?>api/ajax/v2/people/pick?co_id=<?= $vv_cur_co->id ?>`
searchPeople: `<?= $searchPeople ?>`
}
}

Expand All @@ -93,15 +107,17 @@
return {
autocompleteOptions: {
label: '<?= $label ?>',
fieldName: '<?= $fieldName ?>',
fieldName: '<?= $fieldName ?>', // This property hold the form input id
type: '<?= $type ?>',
personType: '<?= $personType ?>',
minLength: 2, // XXX probably should be set by config and default to 3
htmlId: '<?= $htmlId ?>',
htmlId: '<?= $htmlId ?>', // This property holds the vuejs input id
actionUrl: '<?= $constructedActionUrl ?>',
inputValue: '<?= $inputValue ?>',
inputProps: {
name: '<?= $fieldName ?>',
// We need to skip the name since we do not want to submit the vue input field
//name: '<?php //= $htmlId ?>//',
dataName: '<?= $htmlId ?>',
// This is not translated to data-personid but to datapersonid.
dataPersonid: '<?= $inputValue ?>'
},
Expand Down
11 changes: 11 additions & 0 deletions app/webroot/css/co-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,17 @@ li[data-pc-section="emptymessage"] {
[v-cloak] {
display: none;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
border: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap; /* Prevent text wrapping */
}
/* ENTITY ID under each Edit/View Form/List */
#cm-entity-id {
position: absolute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ export default {
setPerson() {
if(['search', 'field'].includes(this.options.type)) {
this.options.inputProps.dataPersonid = this.person.value;
// Update the field that will be submitted
let inputElement = document.getElementById(this.options.fieldName)
inputElement.value = 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;
Expand Down Expand Up @@ -258,9 +262,11 @@ export default {
mounted() {
if(this.options.inputValue != undefined
&& this.options.inputValue != ''
&& this.options.inputProps.name.endsWith('person_id')) {
&& this.options.inputProps.dataName.endsWith('person-id-picker')) {
this.person = `${this.options.personRecord.primary_name.given} ${this.options.personRecord.primary_name.family} (ID: ${this.options.personRecord.id})`;
this.personUrl = `${this.options.canvasUrl}`;
let inputElement = document.getElementById(this.options.fieldName)
inputElement.value = this.options.personRecord.id;
}
},
computed: {
Expand Down

0 comments on commit c4ce79a

Please sign in to comment.