As per discussions on Slack, this is not an out of the box feature, and requires custom code.
I did not need to make it complicated, as I only need this in one place, on one form (for now), so I solved it with some javascript and manipulating the autocomplete path of the 2nd element.
This way I keep all the standard webform elements (so no custom elements needed) and use the drupal native autocomplete functionality.
First, I created a new javascript file with my custom code.
Not going to explain what the code does, it is pretty straight forward, but, ask if something needs clarification.
(function ($, Drupal, once) {
Drupal.behaviors.autocompleteHook = {
attach: function (context) {
if (!once('companyHook', 'html').length) {
return;
}
$('body').on('autocompleteclose', '#edit-client-company', function (e) {
setTargetPath(e.target.value);
});
// if loaded for an edit.
setTargetPath($('#edit-client_company').val());
},
};
function setTargetPath(elementValue) {
$('.js-form-item-client-project-manager').hide();
if(elementValue) {
var regex = /\((\d+)\)/;
var match = elementValue.match(regex);
if (match && match[1]) {
$('.js-form-item-client-project-manager').show();
let url = updateUrlParameter($('#edit-client-project-manager').attr('data-autocomplete-path'), 'target_id', match[1]);
$('#edit-client-project-manager').attr('data-autocomplete-path', url);
}
}
}
function updateUrlParameter(url, param, paramVal) {
var newAdditionalURL = '';
var tempArray = url.split('?');
var baseURL = tempArray[0];
var additionalURL = tempArray[1];
var temp = '';
if (additionalURL) {
var tmpAnchor = additionalURL.split('&');
var paramExists = false;
for (var i = 0; i < tmpAnchor.length; i++) {
if (tmpAnchor[i].split('=')[0] == param) {
tmpAnchor[i] = param + '=' + paramVal;
paramExists = true;
}
temp += i < (tmpAnchor.length - 1) ? tmpAnchor[i] + '&' : tmpAnchor[i];
}
if (!paramExists) {
temp += '&' + param + '=' + paramVal;
}
} else {
temp = param + '=' + paramVal;
}
newAdditionalURL = baseURL + '?' + temp;
return newAdditionalURL;
}
})(jQuery, Drupal, once);
I added a custom class 'hidden' to the 2nd element, forgoing with the built in element dependency display rules. I have that in my global theme css already as display: none
Then following bog standard drupal ways, I created the needed entry in [module].libraries.yml
autocompleteCompany:
js:
js/ihop-autocomplete-company.js: {}
dependencies:
- core/jquery
- core/once
and then in the form's WebformHandler::alter_form
function (Using webform handlers, as apposed to hooks in .module file), I attached that library
public function alterForm(
array &$form,
FormStateInterface $form_state,
WebformSubmissionInterface $webform_submission
) {
....
$form['#attached']['library'][] = 'ihop/autocompleteCompany';
....
}
so, upon doing a selection of the first field's autocomplete, my js hook fires (listening to autocompleteclose
) which then:
- Makes the 2nd element visible / invisible, depending on some factors.
- Injects or updates the attribute
data-autocomplete-path
of the 2nd element. Thsi then now passes an additional param, target_id
The last(ref note below) step here is then to get the value of that param in a view hook (located in the .module file), and use it to set a filter.
case 'list_client_pm_entity_ref':
$companyId = $view->getRequest()->query->get('target_id');
$filters['field_company_target_id']['value'] = [$companyId => $companyId];
break;
Note: At this point, it works only if you use a different lookup string in the 2nd field. This is due to autocomplete.js caching the results.
So, that is my next step, and there is some details here: How to prevent Autocomplete Caching?