948 lines
30 KiB
JavaScript
948 lines
30 KiB
JavaScript
$.widget('wpj.admin_autocomplete', {
|
|
options: {
|
|
$menu: null,
|
|
|
|
minLength: 2,
|
|
xhr: null,
|
|
|
|
limit: 50,
|
|
type: 'product_id',
|
|
visible: 0,
|
|
parameters: null,
|
|
|
|
variations: false,
|
|
|
|
source: null,
|
|
|
|
searchTerm: null,
|
|
data: null,
|
|
templateContext: null,
|
|
|
|
resetInputOnClose: false,
|
|
showFlags: true,
|
|
|
|
searchEvent: null,
|
|
|
|
showResetButton: true,
|
|
flags: [],
|
|
|
|
template: '{{? it.items.length>2}} {{#def.header}} {{?}} {{~it.items :item :index}} {{#def.menuItem}} {{~}}',
|
|
subtemplates: {
|
|
header: '{{? it.me.options.showFlags && it.me.flags}}<div>{{~it.me.flags :flag}}{{#def.flag_button}}{{~}}</div>{{?}}',
|
|
flag_button: '<button type="button" class="btn btn-sm btn-default" style="width: auto; padding: 0 10px;" data-autocomplete-flag="{{=flag[0]}}">{{=flag[1]}}</button> ',
|
|
menuItem: '<div tabindex="-1" data-autocomplete-item="{{=index}}" {{? item.visible == "N"}}class="no-visible"{{?}} {{? item.visible == "O"}}class="old"{{?}}>' +
|
|
'{{? item.image && item.image.id}}<img src="{{=item.image.src}}" alt="{{=item.image.descr}}">{{?}}{{? !item.image}}<img src="/admin/static/images/no-image.png">{{?}}' +
|
|
'<p>{{=item.text}}<br><small>Kód: {{? item.code}}{{=item.code}} {{?}}| Skladem: {{=item.in_store}} ks{{? item.visible == "N"}} | Skrytý!{{?}}{{? item.visible == "O"}} | Prodej ukončen!{{?}}</small></p>' +
|
|
'{{#def.buttons}}' +
|
|
'</div>' +
|
|
'{{#def.bottom}}',
|
|
buttons: '',
|
|
bottom: ''
|
|
}
|
|
},
|
|
searchIconsWrapper: null,
|
|
selectPosition: NaN,
|
|
_create: function() {
|
|
this._super();
|
|
|
|
if (this.options.type === 'product_id' || this.options.type === 'productId') {
|
|
this.flags = [['s', 'pouze skladem'], ['v', 'pouze viditelné']];
|
|
}
|
|
|
|
this.options.source = wpj.template.compile(this.options.source);
|
|
|
|
var me = this;
|
|
|
|
if (!this.searchIconsWrapper && this.options.showResetButton) {
|
|
me.element.wrap('<div style="position: relative;"></div>');
|
|
this.searchIconsWrapper = me.element.parent();
|
|
|
|
const iconLoading = $('<i class="search-loading-icon hidden autocomplete-icon"></i>');
|
|
this.searchIconsWrapper.append(iconLoading);
|
|
|
|
const iconClear = $('<i class="bi bi-x-lg search-clear-icon hidden autocomplete-icon"></i>');
|
|
iconClear.on('click',function() {
|
|
me.element.val('');
|
|
me.searchIconsWrapper.find('.search-clear-icon').addClass('hidden');
|
|
});
|
|
this.searchIconsWrapper.append(iconClear);
|
|
}
|
|
|
|
|
|
// set placeholder
|
|
if (!this.element.attr('placeholder')) {
|
|
this.element.attr('placeholder', 'Vyhledejte psaním...');
|
|
}
|
|
|
|
var on = 'input';
|
|
if (this.options.minLength == 0) {
|
|
on = on + ' focus';
|
|
}
|
|
|
|
this.options.searchEvent = function(e) {
|
|
me._doSearch(me.element.val());
|
|
};
|
|
|
|
this.element.on(on, this.options.searchEvent);
|
|
},
|
|
_destroy: function() {
|
|
this.close();
|
|
if (this.options.$menu) {
|
|
this.options.$menu.remove();
|
|
this.options.$menu = null;
|
|
}
|
|
|
|
var on = 'input';
|
|
if (this.options.minLength == 0) {
|
|
on = on + ' focus';
|
|
}
|
|
|
|
this.element.off(on, this.options.searchEvent);
|
|
|
|
this._super();
|
|
},
|
|
_doSearch: function(term) {
|
|
var me = this;
|
|
me.searchTerm = term;
|
|
|
|
if (this.searchIconsWrapper) {
|
|
if (term.length > 0) {
|
|
this.searchIconsWrapper.find('.search-clear-icon').removeClass('hidden');
|
|
} else {
|
|
this.searchIconsWrapper.find('.search-clear-icon').addClass('hidden');
|
|
this.searchIconsWrapper.find('.search-loading-icon').addClass('hidden');
|
|
}
|
|
}
|
|
|
|
if (term.length >= this.options.minLength) {
|
|
wpj.domUtils.resetTimer('autocomplete', 300, function() {
|
|
if (me.searchIconsWrapper){
|
|
me.searchIconsWrapper.find('.search-loading-icon').removeClass('hidden');
|
|
}
|
|
me.search(term);
|
|
});
|
|
} else {
|
|
this.cancelSearch();
|
|
this.close();
|
|
}
|
|
},
|
|
onKeyPress: function(e) {
|
|
switch (e.key) {
|
|
case 'ArrowDown':
|
|
if (isNaN(this.selectPosition)) {
|
|
this.selectPosition = -1;
|
|
}
|
|
|
|
this.selectPosition++;
|
|
|
|
this.focusItem(this.selectPosition);
|
|
|
|
break;
|
|
case 'ArrowUp':
|
|
if (!isNaN(this.selectPosition) && this.selectPosition > 0) {
|
|
this.selectPosition--;
|
|
}
|
|
|
|
this.focusItem(this.selectPosition);
|
|
|
|
break;
|
|
case 'Enter':
|
|
if (!isNaN(this.selectPosition)) {
|
|
var $item = $('.autocomplete [data-autocomplete-item="' + this.selectPosition + '"]');
|
|
this.close();
|
|
this.select(e, $item);
|
|
} else {
|
|
e.preventDefault();
|
|
}
|
|
|
|
break;
|
|
default:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
focusItem: function(itemId) {
|
|
$('[data-autocomplete-item="' + itemId + '"]').focus();
|
|
|
|
return true;
|
|
},
|
|
search: function(term) {
|
|
if (this.options.xhr) {
|
|
this.options.xhr.abort();
|
|
}
|
|
|
|
term = encodeURIComponent(term);
|
|
|
|
var me = this,
|
|
url = this.options.source({
|
|
value: term,
|
|
limit: this.options.limit,
|
|
visible: this.options.visible,
|
|
type: this.options.type,
|
|
parameters: this.options.parameters,
|
|
me: this
|
|
});
|
|
|
|
this.options.xhr = $.getJSON(url, function(data) {
|
|
me.data = me.prepareData(data);
|
|
me.open();
|
|
me.render(me.data);
|
|
if (me.searchIconsWrapper){
|
|
me.searchIconsWrapper.find('.search-loading-icon').addClass('hidden');
|
|
}
|
|
});
|
|
},
|
|
cancelSearch: function() {
|
|
if (!this.options.xhr) {
|
|
return false;
|
|
}
|
|
|
|
this.options.xhr.abort();
|
|
this.options.xhr = null;
|
|
},
|
|
prepareData: function(data) {
|
|
return jQuery.extend(
|
|
{ items: data },
|
|
this.options.templateContext);
|
|
},
|
|
select: function(e, $item) {
|
|
var value = $item.data('autocomplete-item');
|
|
var elementName = this.element.attr('name');
|
|
var clone;
|
|
var text = $item.text();
|
|
|
|
this.element.val(text);
|
|
|
|
if (elementName != '') {
|
|
clone = this.element.clone();
|
|
clone.val(value);
|
|
clone.insertAfter(this.element);
|
|
clone.hide();
|
|
this.element.attr('name', '');
|
|
} else {
|
|
clone = this.element.next('input');
|
|
clone.val(value);
|
|
}
|
|
|
|
return false;
|
|
},
|
|
menu: function() {
|
|
var me = this;
|
|
|
|
this.options.$menu = $('<div class="autocomplete"></div>').insertBefore(this.element);
|
|
|
|
if (!me.element.closest('body').hasClass('window')) {
|
|
|
|
// Is the autocomplete in a window? If not, show it bellow input.
|
|
this.options.$menu.addClass('autocomplete-bottom');
|
|
|
|
} else if ((me.element.offset().top - $(window).scrollTop()) < ($(window).height() / 2)) {
|
|
|
|
// Is the input in the bottom half of window? Show autocomplete bellow input.
|
|
this.options.$menu.addClass('autocomplete-bottom');
|
|
this.options.$menu.css('max-height', ($(window).height() - (me.element.offset().top - $(window).scrollTop()) - 120));
|
|
|
|
} else {
|
|
|
|
// Is the input in the top half of window? Show autocomplete above.
|
|
this.options.$menu.addClass('autocomplete-top');
|
|
this.options.$menu.css('max-height', me.element.offset().top - $(window).scrollTop() - 20);
|
|
}
|
|
|
|
this.options.$menu.on('click', '[data-autocomplete-item]', function(e) {
|
|
if (!$(e.target).is('[data-autocomplete-add]')) {
|
|
me.close();
|
|
return me.select(e, $(e.currentTarget));
|
|
}
|
|
});
|
|
},
|
|
open: function() {
|
|
if (this.element.is('.opened')) {
|
|
return false;
|
|
}
|
|
|
|
this.selectPosition = NaN;
|
|
var me = this;
|
|
|
|
if (!this.options.$menu) {
|
|
this.menu();
|
|
}
|
|
|
|
this.element.addClass('opened');
|
|
this.options.$menu.addClass('opened');
|
|
|
|
$('body')
|
|
.on('click.admin_autocomplete', function(e) {
|
|
if (me.element.has(e.target).length) {
|
|
return;
|
|
}
|
|
|
|
if ($(e.target).is('[data-autocomplete-flag]')) {
|
|
var flag = $(e.target).data('autocomplete-flag');
|
|
var flagExp = new RegExp(flag + ': ', 'g');
|
|
var term = me.element.val();
|
|
if (flagExp.test(term)) {
|
|
term = term.replace(flagExp, '');
|
|
} else {
|
|
term = flag + ': ' + term;
|
|
}
|
|
me.element.val(term);
|
|
me._doSearch(term);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($(e.target).is('[data-autocomplete-add]')) {
|
|
return;
|
|
}
|
|
|
|
me.close();
|
|
})
|
|
.on('keydown.admin_autocomplete', function(e) { /* todo chrome neumi keypres */
|
|
if (e.key != 'Escape') {
|
|
return me.onKeyPress(e);
|
|
}
|
|
|
|
|
|
me.close();
|
|
return false;
|
|
});
|
|
},
|
|
close: function() {
|
|
if (!this.element.is('.opened')) {
|
|
return false;
|
|
}
|
|
|
|
$('body').off('click.admin_autocomplete')
|
|
.off('keydown.admin_autocomplete');
|
|
|
|
if (this.options.resetInputOnClose) {
|
|
this.element.val('');
|
|
}
|
|
this.element.removeClass('opened');
|
|
this.options.$menu.removeClass('opened');
|
|
},
|
|
render: function(data) {
|
|
data.me = this;
|
|
var template = this.getTemplate(),
|
|
html = template(data);
|
|
|
|
this.options.$menu.html(html);
|
|
},
|
|
getTemplate: function() {
|
|
return wpj.template.compile(this.options.template, this.options.subtemplates);
|
|
}
|
|
});
|
|
|
|
|
|
$.widget('wpj.adminAutoComplete', $.wpj.admin_autocomplete, {
|
|
options: {
|
|
source: './launch.php?s=autocomplete.php&type={{=it.type}}&term={{=it.value}}&limit={{=it.limit}}&visible={{=it.visible}}{{? it.parameters}}&{{=it.parameters}}{{?}}'
|
|
},
|
|
render: function(data) {
|
|
if (this._trigger('render', {}, data)) {
|
|
if (this._super(data)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
},
|
|
select: function(e, $item) {
|
|
if (this._trigger('select', e, { item: $item, data: this.data })) {
|
|
if ($item.data('autocomplete-item') != 'show-all') {
|
|
if (this._super(e, $item)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
});
|
|
|
|
$.widget('wpj.adminProductMultiselect', $.wpj.adminAutoComplete, {
|
|
options: {
|
|
source: './launch.php?s=autocomplete.php&type={{=it.type}}&term={{=it.value}}&limit={{=it.limit}}&visible={{=it.visible}}{{? it.parameters}}&{{=it.parameters}}{{?}}{{? it.me.options.variations}}&variations=1{{?}}',
|
|
showResetButton: false,
|
|
itemIdentifierKey: 'id',
|
|
targetSelect: null, // CSS selector pro <select>, kam se budou ukládat vybrané položky
|
|
showImages: true,
|
|
allowCustomValue: false,
|
|
template: '{{? it.items.length>2}} {{#def.header}} {{?}} {{? it.me.options.allowCustomValue}}{{#def.customOption}}{{?}} {{~it.items :item :index}} {{#def.menuItem}} {{~}}',
|
|
subtemplates: {
|
|
customOption: '{{? it.exists.findIndex((item) => item.toString().startsWith("_custom:")) === -1}}' +
|
|
'<div tabindex="-1" data-autocomplete-item="_custom">' +
|
|
'<p>Hledat výraz: {{=it.me.searchTerm}}</p>' +
|
|
'</div>{{?}}',
|
|
menuItem: `
|
|
<div tabindex="-1" data-autocomplete-item="{{=index}}" {{? item.visible == "N"}}class="no-visible"{{?}} {{? item.visible == "O"}}class="old"{{?}} {{? item.variations && item.variations.length > 1}}class='has-variations'{{?}}>
|
|
{{? it.me.options.showImages && item.image && item.image.id}}<img src="{{=item.image.src}}" alt="{{=item.image.descr}}">{{?}}{{? !item.image}}<img src="/admin/static/images/no-image.png">{{?}}
|
|
<p>{{=item.text}}<br><small>Kód: {{? item.code}}{{=item.code}} {{?}}| Skladem: {{=item.in_store}} ks{{? item.visible == "N"}} | Skrytý!{{?}}{{? item.visible == "O"}} | Prodej ukončen!{{?}}</small></p>
|
|
{{#def.buttons}}
|
|
</div>
|
|
{{#def.bottom}}`,
|
|
variation: `
|
|
{{var variation_array = v;}}
|
|
<div class="variation" tabindex="-1" data-autocomplete-item="{{=index}}-{{=i}}">
|
|
{{=variation_array.title}}
|
|
<small> Kód: {{=variation_array.code}} | Skladem: {{=variation_array.in_store}} ks</small>
|
|
</div>`,
|
|
bottom: '{{? item.variations}}' +
|
|
'{{~ item.variations :v:i }} {{? v.id}} {{#def.variation}} {{?}} {{~}}' +
|
|
'{{?}}',
|
|
buttons: '<button type="button" class="btn btn-default add{{? it.exists.indexOf(item[it.me.options.itemIdentifierKey].toString()) !== -1}} added{{?}}" data-autocomplete-add>' +
|
|
'{{? it.exists.indexOf(item[it.me.options.itemIdentifierKey].toString()) !== -1}}<span class="glyphicon glyphicon-ok"></span>{{??}}Přidat{{?}}' +
|
|
'</button>'
|
|
},
|
|
},
|
|
$select: null,
|
|
_create: function() {
|
|
this._super();
|
|
this.$select = $(this.element.next());
|
|
this.$select.parent().addClass('autocomplete-product-wrapper');
|
|
this.element.hide();
|
|
|
|
this.flags = [... (this.flags || []) , ...[['f', 'přidat vše']]];
|
|
|
|
let me = this;
|
|
$(document).ready(function() {
|
|
me.$select.parent().find('.chosen-choices .chosen-search-input').on('input', function(e) {
|
|
let search = $(this).val();
|
|
me.element.val(search);
|
|
me._doSearch(search);
|
|
});
|
|
});
|
|
},
|
|
open: function() {
|
|
var me = this;
|
|
|
|
$('body')
|
|
.on('click.admin_autocomplete [data-autocomplete-flag]', function(e) {
|
|
var flag = $(e.target).data('autocomplete-flag');
|
|
|
|
if (flag == "f") {
|
|
me.addItems( me.data.items );
|
|
|
|
e.stopImmediatePropagation();
|
|
me.close();
|
|
}
|
|
|
|
});
|
|
|
|
this._super();
|
|
},
|
|
addItem: function ($item) {
|
|
const selectedValue = $item.data('autocomplete-item').toString();
|
|
|
|
if (selectedValue === '_custom') {
|
|
this.selectCustomItem();
|
|
return;
|
|
}
|
|
|
|
const [productIndex, variationIndex] = selectedValue.split('-');
|
|
const product = this.data.items[+productIndex];
|
|
|
|
let variation;
|
|
|
|
if(variationIndex !== undefined) {
|
|
variation = product.variations[variationIndex];
|
|
}
|
|
|
|
this.selectItem(product, variation);
|
|
},
|
|
addItems: function (items) {
|
|
items.forEach((item) => {
|
|
this.selectItem(item);
|
|
});
|
|
},
|
|
selectItem: function(product, variation) {
|
|
let id = product[this.options.itemIdentifierKey];
|
|
let title = product.title;
|
|
|
|
if(variation) {
|
|
id += '-'+ variation[this.options.itemIdentifierKey];
|
|
title += ' | '+ variation.title;
|
|
}
|
|
|
|
let exists = this.getExistItems();
|
|
// if item is added already
|
|
if (exists.indexOf(id) !== -1) {
|
|
return false;
|
|
}
|
|
|
|
this.data.exists.push(id);
|
|
|
|
this.$select.append(`<option value="${id}" selected>${title}</option>`);
|
|
this.$select.trigger('chosen:updated');
|
|
this.$select.change();
|
|
},
|
|
selectCustomItem: function() {
|
|
this.$select.append(`<option value="_custom:${this.searchTerm}" selected>Hledat: ${this.searchTerm}</option>`);
|
|
this.$select.trigger('chosen:updated');
|
|
this.$select.change();
|
|
},
|
|
prepareData: function(data) {
|
|
var items = this._super(data);
|
|
items.exists = this.getExistItems();
|
|
|
|
return items;
|
|
},
|
|
getExistItems: function() {
|
|
var exists = [];
|
|
|
|
this.$select.find('option:selected').each(function() {
|
|
exists.push($(this).attr('value'));
|
|
});
|
|
|
|
return exists;
|
|
},
|
|
select: function(e, $item, close = true) {
|
|
if (this._trigger('select', e, { item: $item })) {
|
|
this.addItem($item);
|
|
if (close) {
|
|
this.close();
|
|
} else {
|
|
this.render(this.data);
|
|
}
|
|
this._trigger('afterSelect', e, { item: $item });
|
|
}
|
|
},
|
|
menu: function() {
|
|
this._super();
|
|
|
|
var me = this;
|
|
|
|
this.options.$menu.on('click', '[data-autocomplete-add]', function(e) {
|
|
me.select(e, $(e.currentTarget).parent('[data-autocomplete-item]'), false);
|
|
return false;
|
|
});
|
|
},
|
|
search: function(term) {
|
|
if(this.data) {
|
|
this.render(this.prepareData(this.data));
|
|
}
|
|
this._super(term);
|
|
}
|
|
});
|
|
|
|
$.widget('wpj.adminOrderAutoComplete', $.wpj.adminAutoComplete, {
|
|
options: {
|
|
type: 'orders',
|
|
subtemplates: {
|
|
menuItem: '<div tabindex="-1" data-autocomplete-item="{{=index}}">' +
|
|
'<p>Objednávka č. <strong>{{!item.order_no}}</strong><br><small>{{? item.invoice_firm}}{{!item.invoice_firm}}, {{?}}{{!item.customer_name}} | {{!item.print_price}}</small></p>' +
|
|
'{{#def.buttons}}' +
|
|
'</div>' +
|
|
'{{#def.bottom}}'
|
|
}
|
|
}
|
|
});
|
|
$.widget('wpj.adminVariationAutoComplete', $.wpj.admin_autocomplete, {
|
|
selectVariation: -1,
|
|
options: {
|
|
source: './launch.php?s=autocomplete.php&type={{=it.type}}&term={{=it.value}}&limit={{=it.limit}}&visible={{=it.visible}}&variations=1{{? it.parameters}}&{{=it.parameters}}{{?}}',
|
|
subtemplates: {
|
|
menuItem: `
|
|
<div tabindex="-1" data-autocomplete-item="{{=index}}" {{? item.visible == "N"}}class="no-visible"{{?}} {{? item.visible == "O"}}class="old"{{?}} {{? item.variations.length > 1}}class='has-variations'{{?}}>
|
|
{{? item.image && item.image.id}}<img src="{{=item.image.src}}" alt="{{=item.image.descr}}">{{?}}{{? !item.image}}<img src="/admin/static/images/no-image.png">{{?}}
|
|
<p>{{=item.text}}<br><small>Kód: {{? item.code}}{{=item.code}} {{?}}| Skladem: {{=item.in_store}} ks{{? item.visible == "N"}} | Skrytý!{{?}}{{? item.visible == "O"}} | Prodej ukončen!{{?}}</small></p>
|
|
{{#def.buttons}}
|
|
</div>
|
|
{{#def.bottom}}`,
|
|
|
|
bottom: '{{? item.variations}}' +
|
|
'{{~ item.variations :v:i }} {{? v.id}} {{#def.variation}} {{?}} {{~}}' +
|
|
'{{?}}',
|
|
variation: `
|
|
{{var variation_array = v;}}
|
|
<div class="variation" tabindex="-1" data-autocomplete-item="{{=index}}-{{=i}}">
|
|
{{=variation_array.title}}
|
|
<small> Kód: {{=variation_array.code}} | Skladem: {{=variation_array.in_store}} ks</small>
|
|
</div>`
|
|
},
|
|
// if true -> products with variations can be selected without variation
|
|
allowSelectProduct: true,
|
|
|
|
// the form in which to select items; if there are more autocomplete forms on one page
|
|
$form: null,
|
|
},
|
|
|
|
/**
|
|
* @param index {number}
|
|
* @return {object}
|
|
*/
|
|
getItemOnIndex: function(index) {
|
|
return this.data.items[index];
|
|
},
|
|
|
|
/**
|
|
* @param e {KeyboardEvent}
|
|
* @param $item {jQuery}
|
|
* @return {boolean}
|
|
*/
|
|
select: function(e, $item) {
|
|
const [productIndex, variationIndex] = $item.data('autocomplete-item').toString().split('-');
|
|
const product = this.getItemOnIndex(+productIndex);
|
|
let { variations, text } = product;
|
|
|
|
variations = variations.filter(v => !!v.id);
|
|
if(!this.options.allowSelectProduct && (variations.length > 0 && variationIndex === undefined)) {
|
|
e.preventDefault()
|
|
this.open();
|
|
return false;
|
|
}
|
|
|
|
const selectedVariation = variationIndex ? variations[+variationIndex] : null;
|
|
this.element.val(`${text}${selectedVariation ? ' | ' + selectedVariation.title : ''}`);
|
|
|
|
this.selectVariation = -1
|
|
this.selectPosition = 0
|
|
|
|
if (this._trigger('select', e, { item: $item, data: this.data, product, variations, variation: selectedVariation })) {
|
|
if (this._super(e, $item)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
},
|
|
/**
|
|
* @param index {number}
|
|
* @return {undefined|string[]|object[]}
|
|
*/
|
|
getVariationsOfItem: function(index) {
|
|
const item = this.getItemOnIndex(index);
|
|
if (!item) {
|
|
return undefined;
|
|
}
|
|
let { variations } = item;
|
|
|
|
if (!variations) {
|
|
return undefined;
|
|
}
|
|
|
|
if (typeof variations === 'string') {
|
|
variations = variations.split('|');
|
|
}
|
|
|
|
variations = variations.filter(variation => !!variation.id);
|
|
|
|
if (variations.length < 1) {
|
|
return undefined;
|
|
}
|
|
|
|
return variations;
|
|
},
|
|
|
|
/**
|
|
* @return {string}
|
|
*/
|
|
getFocusAttrOfSelectedItem: function() {
|
|
if (this.selectVariation === -1) {
|
|
return this.selectPosition.toString();
|
|
}
|
|
|
|
return `${this.selectPosition}-${this.selectVariation}`;
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param itemIndex {string|number}
|
|
* @return {true}
|
|
*/
|
|
focusItem: function(itemIndex) {
|
|
const selector = `[data-autocomplete-item="${itemIndex}"]`;
|
|
|
|
if (this.options.$form) {
|
|
this.options.$form.find(selector).trigger('focus');
|
|
} else {
|
|
$(selector).trigger('focus');
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* @param e {KeyboardEvent}
|
|
* @return {boolean}
|
|
*/
|
|
onKeyPress: function(e) {
|
|
switch (e.key) {
|
|
case 'ArrowDown': {
|
|
if (isNaN(this.selectPosition)) { this.selectPosition = -1; }
|
|
|
|
const variations = this.getVariationsOfItem(this.selectPosition);
|
|
const isLastProduct = this.selectPosition >= this.data.items.length - 1;
|
|
|
|
if (!isLastProduct && !variations) {
|
|
this.selectPosition++;
|
|
|
|
if (this.getVariationsOfItem(this.selectPosition)) {
|
|
this.selectVariation++;
|
|
} else {
|
|
this.selectVariation = -1;
|
|
}
|
|
}
|
|
|
|
if (variations) {
|
|
const isLastVariationOfProduct = this.selectVariation >= variations.length - 1;
|
|
|
|
if (!isLastProduct && isLastVariationOfProduct) {
|
|
this.selectPosition++;
|
|
this.selectVariation = this.getVariationsOfItem(this.selectPosition) ? 0 : -1;
|
|
} else if (!isLastVariationOfProduct) {
|
|
this.selectVariation++;
|
|
}
|
|
}
|
|
this.focusItem(this.getFocusAttrOfSelectedItem());
|
|
} break;
|
|
|
|
case 'ArrowUp': {
|
|
if (isNaN(this.selectPosition)) { break; }
|
|
|
|
if (this.selectVariation > 0) {
|
|
this.selectVariation--;
|
|
} else if (this.selectPosition > 0) {
|
|
this.selectPosition--;
|
|
|
|
const variations = this.getVariationsOfItem(this.selectPosition);
|
|
this.selectVariation = variations ? variations.length - 1 : -1;
|
|
}
|
|
|
|
this.focusItem(this.getFocusAttrOfSelectedItem());
|
|
} break;
|
|
|
|
case 'Enter': {
|
|
if (!isNaN(this.selectPosition)) {
|
|
const varPos = this.getFocusAttrOfSelectedItem();
|
|
const selector = `[data-autocomplete-item="${varPos}"]`;
|
|
|
|
let $item;
|
|
if (this.options.$form) {
|
|
$item = this.options.$form.find(selector);
|
|
} else {
|
|
$item = $(selector);
|
|
}
|
|
|
|
this.close();
|
|
this.select(e, $item);
|
|
} else {
|
|
e.preventDefault();
|
|
}
|
|
} break;
|
|
|
|
default: {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
});
|
|
|
|
$.widget('wpj.multiSelectAutoComplete', $.wpj.admin_autocomplete, {
|
|
options: {
|
|
append: true,
|
|
formWrapper: '',
|
|
formTemplate: '#multiselectAutocomplete',
|
|
itemIdentifierKey: 'id_rel_product',
|
|
source: './launch.php?s=autocomplete.php&type={{=it.type}}&term={{=it.value}}&limit={{=it.limit}}&visible={{=it.visible}}{{? it.parameters}}&{{=it.parameters}}{{?}}',
|
|
subtemplates: {
|
|
buttons: '<button type="button" class="btn btn-default add{{? it.exists.indexOf(item[it.me.options.itemIdentifierKey].toString()) !== -1}} added{{?}}" data-autocomplete-add>' +
|
|
'{{? it.exists.indexOf(item[it.me.options.itemIdentifierKey].toString()) !== -1}}<span class="glyphicon glyphicon-ok"></span>{{??}}Přidat{{?}}' +
|
|
'</button>'
|
|
},
|
|
templateData: {},
|
|
index: 0
|
|
},
|
|
_create: function() {
|
|
this._super();
|
|
|
|
this.flags = [... (this.flags || []) , ...[['f', 'přidat vše']]];
|
|
},
|
|
open: function() {
|
|
var me = this;
|
|
|
|
$('body')
|
|
.on('click.admin_autocomplete', function(e) {
|
|
if (me.element.has(e.target).length) {
|
|
return;
|
|
}
|
|
|
|
if ($(e.target).is('[data-autocomplete-flag]')) {
|
|
var flag = $(e.target).data('autocomplete-flag');
|
|
|
|
if (flag == "f") {
|
|
$.each(me.data.items, function(key, value) {
|
|
me.data.items[key]['index'] = ++ me.options.index;
|
|
})
|
|
|
|
me.addItems({ ...{items: me.data.items}, ...me.options.templateContext});
|
|
|
|
e.stopImmediatePropagation();
|
|
me.close();
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this._super();
|
|
},
|
|
template: function(template) {
|
|
return wpj.template.compile(template);
|
|
},
|
|
renderItem: function($item, itemIndex) {
|
|
var items = jQuery.extend({ items: [this.data.items[itemIndex]] }, this.options.templateContext);
|
|
|
|
console.log(items);
|
|
|
|
$item.find('.btn').text('').html('<span class="glyphicon glyphicon-ok"></span>').addClass('added');
|
|
|
|
this.addItems(items);
|
|
},
|
|
addItem: function($item) {
|
|
var itemIndex = $item.data('autocomplete-item'),
|
|
exists = this.getExistItems();
|
|
this.data.items[itemIndex]['index'] = ++this.options.index;
|
|
|
|
// if item is added already
|
|
if (exists.indexOf(this.data.items[itemIndex][this.options.itemIdentifierKey]) !== -1) {
|
|
return false;
|
|
}
|
|
|
|
this.data.items[itemIndex]['variations'] = this.getVariations($item, itemIndex);
|
|
|
|
this.renderItem($item, itemIndex);
|
|
},
|
|
addItems: function(items) {
|
|
if (typeof items == 'undefined' || items === null) {
|
|
console.log('no autocomplete items');
|
|
return;
|
|
}
|
|
|
|
// when it is send from template
|
|
if (typeof items.items === 'undefined') {
|
|
items = { items: items };
|
|
}
|
|
|
|
items = {...this.options.templateData, ...items};
|
|
|
|
var dotTemplate = $(this.options.formTemplate),
|
|
template = this.template(dotTemplate.text()),
|
|
html = template(items),
|
|
selector = '[data-autocomplete-items="' + this.options.formWrapper + '"]';
|
|
// prepend or append?
|
|
if (this.options.append) {
|
|
$(selector).append(html);
|
|
} else {
|
|
$(selector).prepend(html);
|
|
}
|
|
$(selector + ' [data-form-item]').each(function() {
|
|
var $deleteInput = $(this).find('[data-form-delete] input');
|
|
if (!$deleteInput.is(':checked')) {
|
|
$(this).css('display', 'block');
|
|
}
|
|
});
|
|
|
|
styleFormInputs(selector);
|
|
},
|
|
getExistItems: function() {
|
|
var exists = [];
|
|
|
|
$('[data-autocomplete-items="' + this.options.formWrapper + '"] [data-form-item]').each(function() {
|
|
var $deleteInput = $(this).find('[data-form-delete] input');
|
|
if (!$deleteInput.is(':checked')) {
|
|
var id = $(this).data('form-item');
|
|
exists.push(id.toString());
|
|
}
|
|
});
|
|
|
|
return exists;
|
|
},
|
|
prepareData: function(data) {
|
|
var items = this._super(data);
|
|
items.exists = this.getExistItems();
|
|
|
|
return items;
|
|
},
|
|
select: function(e, $item) {
|
|
if (this._trigger('select', e, { item: $item })) {
|
|
var $target = $(e.target);
|
|
if ($target.is('[data-autocomplete-add]')) {
|
|
this.addItem($item);
|
|
} else {
|
|
this.addItem($item);
|
|
this.close();
|
|
}
|
|
this._trigger('afterSelect', e, { item: $item });
|
|
}
|
|
},
|
|
menu: function() {
|
|
this._super();
|
|
|
|
var me = this;
|
|
|
|
this.options.$menu.on('click', '[data-autocomplete-add]', function(e) {
|
|
return me.select(e, $(e.currentTarget).parent('[data-autocomplete-item]'));
|
|
});
|
|
},
|
|
getVariations: function($item, itemIndex) {
|
|
if (this.options.variations == false) {
|
|
return false;
|
|
}
|
|
|
|
var url = 'launch.php?s=autocomplete.php&type=variation_id&term=&id_product=' + this.data.items[itemIndex][this.options.variations.product_field],
|
|
me = this,
|
|
selector = '[data-autocomplete-items="' + this.options.formWrapper + '"] [data-form-item="' + this.data.items[itemIndex]['id'] + '"]';
|
|
$.getJSON(url, function(data) {
|
|
if (data.length) {
|
|
// destroy item
|
|
$(selector).remove();
|
|
// load variations
|
|
me.data.items[itemIndex]['variations'] = data;
|
|
// render item
|
|
me.renderItem($item, itemIndex);
|
|
styleFormInputs(selector);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$.widget('wpj.multiAddAutoComplete', $.wpj.multiSelectAutoComplete, {
|
|
addItem: function($item) {
|
|
this._trigger('addItem', null, [$item, this]);
|
|
},
|
|
addItems: function(items) {
|
|
if (this._trigger('addItems', null, [items, this])) {
|
|
if (this._super(items)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
});
|
|
|
|
$.widget('wpj.userAutocomplete', $.wpj.adminAutoComplete, {
|
|
options: {
|
|
type: 'users',
|
|
subtemplates: {
|
|
menuItem: `
|
|
<div tabindex="-1" data-autocomplete-item="{{=index}}">
|
|
{{? item.invoice_firm && item.invoice_firm !== ''}}{{!item.invoice_firm}}<br />{{?}}
|
|
{{!item.invoice_name}} {{!item.invoice_surname}}<br />
|
|
{{?item.invoice_email}}{{!item.invoice_email}}{{?}}{{?item.invoice_phone}}, {{!item.invoice_phone}}{{?}}<br />
|
|
{{?item.invoice_street && item.invoice_street !== ''}}{{!item.invoice_street.trim()}}, {{?}}{{!item.invoice_zip}} {{!item.invoice_city}}
|
|
</div>
|
|
{{#def.bottom}}
|
|
`
|
|
}
|
|
},
|
|
select: function(e, $item) {
|
|
this.options.onSelect(e, $item, this.data.items)
|
|
this._super(e, $item)
|
|
}
|
|
})
|