About Listening to Changes of Autocomplete Fields which don't Fire Any Special Events
Django-Grappelli's autocomplete fields don’t trigger any JavaScript events when a selection is made, making it difficult to detect changes. If you need dynamic functionality based on the selected value, you can override the getter for the read-only field’s value and inject your callback function there. Here's how:
$(document).ready(function () {
function watchForAutocompleteChanges(fieldSelector, callback) {
const hiddenFields = document.querySelectorAll(
`${fieldSelector}:not([data-watcher-installed])`
);
hiddenFields.forEach(function (hiddenField) {
hiddenField.setAttribute('data-watcher-installed', 'true');
const originalDescriptor = Object.getOwnPropertyDescriptor(
HTMLInputElement.prototype, 'value'
);
let currentValue = hiddenField.value;
Object.defineProperty(hiddenField, 'value', {
get: function () {
return currentValue;
},
set: function (newValue) {
const oldValue = currentValue;
currentValue = newValue;
originalDescriptor.set.call(this, newValue);
if (oldValue !== newValue && newValue) {
// The autocomplete text input is the previous sibling
const $autocompleteField = $(this).prev();
callback($autocompleteField, {
hiddenField: this,
oldValue: oldValue,
newValue: newValue
});
}
},
enumerable: true,
configurable: true
});
});
}
watchForAutocompleteChanges(
'id_country',
function($autocompleteField, data) {
console.log(`New country value: ${data.newValue}`);
}
);
});
Tips and Tricks Programming Django 5.2 Django 4.2 Django 3.2 JavaScript Django Grappelli
Also by me
Django Paddle Subscriptions app
For Django-based SaaS projects.
Django GDPR Cookie Consent app
For Django websites that use cookies.