Merge branch '2-napraviti-dodavanje-termina' into 'master'
Added customer composite key Closes #2 See merge request kbr4/zsterminator!2
This commit is contained in:
151
app/javascript/controllers/customer_search_controller.js
Normal file
151
app/javascript/controllers/customer_search_controller.js
Normal file
@@ -0,0 +1,151 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["select", "phoneField", "birthYearField", "firstNameField", "surnameField", "newCustomerFields"]
|
||||
static values = {
|
||||
existingId: String,
|
||||
existingLabel: String
|
||||
}
|
||||
|
||||
connect() {
|
||||
let initialOptions = [];
|
||||
let initialValue = null;
|
||||
|
||||
if (this.hasExistingIdValue && this.hasExistingLabelValue && this.existingIdValue.length > 0) {
|
||||
initialOptions = [{ id: this.existingIdValue, label: this.existingLabelValue }];
|
||||
initialValue = this.existingIdValue;
|
||||
}
|
||||
|
||||
this.selectInstance = new TomSelect(this.selectTarget, {
|
||||
valueField: 'id',
|
||||
labelField: 'label',
|
||||
searchField: ['label'],
|
||||
maxItems: 1,
|
||||
create: true,
|
||||
createOnBlur: true,
|
||||
placeholder: 'Type to search customers...',
|
||||
|
||||
create: function(input) {
|
||||
return {
|
||||
id: `${input}__new`,
|
||||
label: `${input} (New Customer)`
|
||||
};
|
||||
},
|
||||
|
||||
options: initialOptions,
|
||||
items: initialValue ? [initialValue] : [],
|
||||
|
||||
load: async (query, callback) => {
|
||||
if (!query.length && !initialValue) return callback();
|
||||
|
||||
try {
|
||||
const response = await fetch(`/customers/search?q=${encodeURIComponent(query)}`, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
const existingOptionId = this.hasExistingIdValue ? this.existingIdValue : null;
|
||||
const filteredData = data.filter(item => item.id !== existingOptionId);
|
||||
|
||||
callback(filteredData);
|
||||
} catch (error) {
|
||||
console.error('Error loading customers:', error);
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
shouldLoad: function(query) {
|
||||
return query.length >= 2;
|
||||
},
|
||||
|
||||
render: {
|
||||
no_results: (data, escape) => {
|
||||
return '<div class="no-results">No customers found. Fill in the details below.</div>';
|
||||
},
|
||||
option: function(item) {
|
||||
return `<div>${item.label}</div>`;
|
||||
}
|
||||
},
|
||||
|
||||
onLoad: (data) => {
|
||||
if (!this.selectInstance.getValue() && (!data || data.length === 0)) {
|
||||
this.showNewCustomerFields();
|
||||
}
|
||||
},
|
||||
|
||||
onChange: (value) => {
|
||||
if (value === null || value === '') {
|
||||
this.showNewCustomerFields();
|
||||
} else if (!value.endsWith('__new')) {
|
||||
this.newCustomerFieldsTarget.classList.add('hidden');
|
||||
}
|
||||
},
|
||||
|
||||
onItemAdd: (value) => {
|
||||
this.customerSelected(value);
|
||||
},
|
||||
|
||||
onDropdownClose: (dropdown) => {
|
||||
if (!this.selectInstance.getValue()) {
|
||||
this.showNewCustomerFields();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (initialValue) {
|
||||
this.newCustomerFieldsTarget.classList.add('hidden');
|
||||
this.customerSelected(initialValue);
|
||||
}
|
||||
}
|
||||
|
||||
customerSelected(value) {
|
||||
if (value.endsWith('__new')) {
|
||||
const firstName = value.replace('__new', '');
|
||||
this.firstNameFieldTarget.value = firstName;
|
||||
this.showNewCustomerFields();
|
||||
return;
|
||||
}
|
||||
|
||||
const [firstName, surname, phone] = value.split('_');
|
||||
|
||||
if (firstName && surname && phone) {
|
||||
const customerData = this.selectInstance.options[value];
|
||||
|
||||
this.phoneFieldTarget.value = phone;
|
||||
this.firstNameFieldTarget.value = firstName;
|
||||
this.surnameFieldTarget.value = surname;
|
||||
|
||||
if (customerData && customerData.birthyear) {
|
||||
this.birthYearFieldTarget.value = customerData.birthyear;
|
||||
} else {
|
||||
this.birthYearFieldTarget.value = '';
|
||||
}
|
||||
|
||||
this.newCustomerFieldsTarget.classList.add('hidden');
|
||||
} else {
|
||||
console.warn("Selected customer value format unexpected:", value);
|
||||
this.clearFields();
|
||||
this.showNewCustomerFields();
|
||||
}
|
||||
}
|
||||
|
||||
showNewCustomerFields() {
|
||||
this.newCustomerFieldsTarget.classList.remove('hidden');
|
||||
}
|
||||
|
||||
clearFields() {
|
||||
this.phoneFieldTarget.value = '';
|
||||
this.firstNameFieldTarget.value = '';
|
||||
this.surnameFieldTarget.value = '';
|
||||
this.birthYearFieldTarget.value = '';
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.selectInstance) {
|
||||
this.selectInstance.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user