Bonjour à vous,
en fait, j'ai trouvé un script javascript intéressant pour taper des tags qui existent et qui n'existent pas.
Cependant, dans le code actuel, la source des codes existants est alimenté via un tableau json :
J'aimerais bien retourner les éléments existants via une requête sur une table.
J'ai donc remplacer le tableau json par :
Le problème, c'est que je reçois l'erreur suivante :
Uncaught TypeError: Cannot use 'in' operator to search for 'length' in []
at w (jquery.min.js:2)
at Function.map (jquery.min.js:2)
at t.<computed>.<computed>._normalize (jquery-ui.min.js:8)
at t.<computed>.<computed>._normalize (jquery-ui.min.js:6)
at t.<computed>.<computed>.__response (jquery-ui.min.js:8)
at t.<computed>.<computed>.__response (jquery-ui.min.js:6)
at t.<computed>.<computed>.n (jquery-ui.min.js:6)
at t.<computed>.<computed>.__response (jquery-ui.min.js:8)
at t.<computed>.<computed>.__response (jquery-ui.min.js:6)
at t.<computed>.<computed>.<anonymous> (jquery-ui.min.js:8)
Au niveau de l'url de ma page PHP, voici comment l'appel est fait :
item.php?query%5Bterm%5D=pizza
Le %5B représente la caractère [ et le %5D le caractère ].
En plus, il vient mettre le chaîne de caractères "term" dans l'argument de l'url.
Voici le code javascript du script que j'ai trouvé pour insérer des tags existants et nouveaux :
Avez-vous une idée de la raison du problème ?
Y a-t-il un moyen pour débugger facilement le code javascript / Ajax ?
Merci d'avance
Bonne journée
Thierry
en fait, j'ai trouvé un script javascript intéressant pour taper des tags qui existent et qui n'existent pas.
Cependant, dans le code actuel, la source des codes existants est alimenté via un tableau json :
$('#form-tags-4').tagsInput({
'autocomplete': {
source: [
'apple',
'banana',
'orange',
'pizza'
]
}
});
J'aimerais bien retourner les éléments existants via une requête sur une table.
J'ai donc remplacer le tableau json par :
$('#form-tags-4').tagsInput({
'autocomplete': {
source: function (query, process) {
return $.get('item.php', {query: query}, function (data) {
return process(data);
});
}
}
});
Le problème, c'est que je reçois l'erreur suivante :
Uncaught TypeError: Cannot use 'in' operator to search for 'length' in []
at w (jquery.min.js:2)
at Function.map (jquery.min.js:2)
at t.<computed>.<computed>._normalize (jquery-ui.min.js:8)
at t.<computed>.<computed>._normalize (jquery-ui.min.js:6)
at t.<computed>.<computed>.__response (jquery-ui.min.js:8)
at t.<computed>.<computed>.__response (jquery-ui.min.js:6)
at t.<computed>.<computed>.n (jquery-ui.min.js:6)
at t.<computed>.<computed>.__response (jquery-ui.min.js:8)
at t.<computed>.<computed>.__response (jquery-ui.min.js:6)
at t.<computed>.<computed>.<anonymous> (jquery-ui.min.js:8)
Au niveau de l'url de ma page PHP, voici comment l'appel est fait :
item.php?query%5Bterm%5D=pizza
Le %5B représente la caractère [ et le %5D le caractère ].
En plus, il vient mettre le chaîne de caractères "term" dans l'argument de l'url.
Voici le code javascript du script que j'ai trouvé pour insérer des tags existants et nouveaux :
$(function() {
$('#form-tags').tagsInput({
'autocomplete': {
source: function (query, process) {
return $.get('itemp.php', {query: query}, function (data) {
//data = $.parseJSON(data);
return process(data);
});
}
}
});
});
/* jQuery Tags Input Revisited Plugin */
(function($) {
var delimiter = [];
var inputSettings = [];
var callbacks = [];
$.fn.addTag = function(value, options) {
options = jQuery.extend({
focus: false,
callback: true
}, options);
this.each(function() {
var id = $(this).attr('id');
var tagslist = $(this).val().split(_getDelimiter(delimiter[id]));
if (tagslist[0] === '') tagslist = [];
value = jQuery.trim(value);
if ((inputSettings[id].unique && $(this).tagExist(value)) || !_validateTag(value, inputSettings[id], tagslist, delimiter[id])) {
$('#' + id + '_tag').addClass('error');
return false;
}
$('<span>', {class: 'tag'}).append(
$('<span>', {class: 'tag-text'}).text(value),
$('<button>', {class: 'tag-remove'}).click(function() {
return $('#' + id).removeTag(encodeURI(value));
})
).insertBefore('#' + id + '_addTag');
tagslist.push(value);
$('#' + id + '_tag').val('');
if (options.focus) {
$('#' + id + '_tag').focus();
} else {
$('#' + id + '_tag').blur();
}
$.fn.tagsInput.updateTagsField(this, tagslist);
if (options.callback && callbacks[id] && callbacks[id]['onAddTag']) {
var f = callbacks[id]['onAddTag'];
f.call(this, this, value);
}
if (callbacks[id] && callbacks[id]['onChange']) {
var i = tagslist.length;
var f = callbacks[id]['onChange'];
f.call(this, this, value);
}
});
return false;
};
$.fn.removeTag = function(value) {
value = decodeURI(value);
this.each(function() {
var id = $(this).attr('id');
var old = $(this).val().split(_getDelimiter(delimiter[id]));
$('#' + id + '_tagsinput .tag').remove();
var str = '';
for (i = 0; i < old.length; ++i) {
if (old[i] != value) {
str = str + _getDelimiter(delimiter[id]) + old[i];
}
}
$.fn.tagsInput.importTags(this, str);
if (callbacks[id] && callbacks[id]['onRemoveTag']) {
var f = callbacks[id]['onRemoveTag'];
f.call(this, this, value);
}
});
return false;
};
$.fn.tagExist = function(val) {
var id = $(this).attr('id');
var tagslist = $(this).val().split(_getDelimiter(delimiter[id]));
return (jQuery.inArray(val, tagslist) >= 0);
};
$.fn.importTags = function(str) {
var id = $(this).attr('id');
$('#' + id + '_tagsinput .tag').remove();
$.fn.tagsInput.importTags(this, str);
};
$.fn.tagsInput = function(options) {
var settings = jQuery.extend({
interactive: true,
placeholder: 'Add a tag',
minChars: 0,
maxChars: null,
limit: null,
validationPattern: null,
width: 'auto',
height: 'auto',
autocomplete: null,
hide: true,
delimiter: ',',
unique: true,
removeWithBackspace: true
}, options);
var uniqueIdCounter = 0;
this.each(function() {
if (typeof $(this).data('tagsinput-init') !== 'undefined') return;
$(this).data('tagsinput-init', true);
if (settings.hide) $(this).hide();
var id = $(this).attr('id');
if (!id || _getDelimiter(delimiter[$(this).attr('id')])) {
id = $(this).attr('id', 'tags' + new Date().getTime() + (++uniqueIdCounter)).attr('id');
}
var data = jQuery.extend({
pid: id,
real_input: '#' + id,
holder: '#' + id + '_tagsinput',
input_wrapper: '#' + id + '_addTag',
fake_input: '#' + id + '_tag'
}, settings);
delimiter[id] = data.delimiter;
inputSettings[id] = {
minChars: settings.minChars,
maxChars: settings.maxChars,
limit: settings.limit,
validationPattern: settings.validationPattern,
unique: settings.unique
};
if (settings.onAddTag || settings.onRemoveTag || settings.onChange) {
callbacks[id] = [];
callbacks[id]['onAddTag'] = settings.onAddTag;
callbacks[id]['onRemoveTag'] = settings.onRemoveTag;
callbacks[id]['onChange'] = settings.onChange;
}
var markup = $('<div>', {id: id + '_tagsinput', class: 'tagsinput'}).append(
$('<div>', {id: id + '_addTag'}).append(
settings.interactive ? $('<input>', {id: id + '_tag', class: 'tag-input', value: '', placeholder: settings.placeholder}) : null
)
);
$(markup).insertAfter(this);
$(data.holder).css('width', settings.width);
$(data.holder).css('min-height', settings.height);
$(data.holder).css('height', settings.height);
if ($(data.real_input).val() !== '') {
$.fn.tagsInput.importTags($(data.real_input), $(data.real_input).val());
}
// Stop here if interactive option is not chosen
if (!settings.interactive) return;
$(data.fake_input).val('');
$(data.fake_input).data('pasted', false);
$(data.fake_input).on('focus', data, function(event) {
$(data.holder).addClass('focus');
if ($(this).val() === '') {
$(this).removeClass('error');
}
});
$(data.fake_input).on('blur', data, function(event) {
$(data.holder).removeClass('focus');
});
if (settings.autocomplete !== null && jQuery.ui.autocomplete !== undefined) {
$(data.fake_input).autocomplete(settings.autocomplete);
$(data.fake_input).on('autocompleteselect', data, function(event, ui) {
$(event.data.real_input).addTag(ui.item.value, {
focus: true,
unique: settings.unique
});
return false;
});
$(data.fake_input).on('keypress', data, function(event) {
if (_checkDelimiter(event)) {
$(this).autocomplete("close");
}
});
} else {
$(data.fake_input).on('blur', data, function(event) {
$(event.data.real_input).addTag($(event.data.fake_input).val(), {
focus: true,
unique: settings.unique
});
return false;
});
}
// If a user types a delimiter create a new tag
$(data.fake_input).on('keypress', data, function(event) {
if (_checkDelimiter(event)) {
event.preventDefault();
$(event.data.real_input).addTag($(event.data.fake_input).val(), {
focus: true,
unique: settings.unique
});
return false;
}
});
$(data.fake_input).on('paste', function () {
$(this).data('pasted', true);
});
// If a user pastes the text check if it shouldn't be splitted into tags
$(data.fake_input).on('input', data, function(event) {
if (!$(this).data('pasted')) return;
$(this).data('pasted', false);
var value = $(event.data.fake_input).val();
value = value.replace(/\n/g, '');
value = value.replace(/\s/g, '');
var tags = _splitIntoTags(event.data.delimiter, value);
if (tags.length > 1) {
for (var i = 0; i < tags.length; ++i) {
$(event.data.real_input).addTag(tags[i], {
focus: true,
unique: settings.unique
});
}
return false;
}
});
// Deletes last tag on backspace
data.removeWithBackspace && $(data.fake_input).on('keydown', function(event) {
if (event.keyCode == 8 && $(this).val() === '') {
event.preventDefault();
var lastTag = $(this).closest('.tagsinput').find('.tag:last > span').text();
var id = $(this).attr('id').replace(/_tag$/, '');
$('#' + id).removeTag(encodeURI(lastTag));
$(this).trigger('focus');
}
});
// Removes the error class when user changes the value of the fake input
$(data.fake_input).keydown(function(event) {
// enter, alt, shift, esc, ctrl and arrows keys are ignored
if (jQuery.inArray(event.keyCode, [13, 37, 38, 39, 40, 27, 16, 17, 18, 225]) === -1) {
$(this).removeClass('error');
}
});
});
return this;
};
$.fn.tagsInput.updateTagsField = function(obj, tagslist) {
var id = $(obj).attr('id');
$(obj).val(tagslist.join(_getDelimiter(delimiter[id])));
};
$.fn.tagsInput.importTags = function(obj, val) {
$(obj).val('');
var id = $(obj).attr('id');
var tags = _splitIntoTags(delimiter[id], val);
for (i = 0; i < tags.length; ++i) {
$(obj).addTag(tags[i], {
focus: false,
callback: false
});
}
if (callbacks[id] && callbacks[id]['onChange']) {
var f = callbacks[id]['onChange'];
f.call(obj, obj, tags);
}
};
var _getDelimiter = function(delimiter) {
if (typeof delimiter === 'undefined') {
return delimiter;
} else if (typeof delimiter === 'string') {
return delimiter;
} else {
return delimiter[0];
}
};
var _validateTag = function(value, inputSettings, tagslist, delimiter) {
var result = true;
if (value === '') result = false;
if (value.length < inputSettings.minChars) result = false;
if (inputSettings.maxChars !== null && value.length > inputSettings.maxChars) result = false;
if (inputSettings.limit !== null && tagslist.length >= inputSettings.limit) result = false;
if (inputSettings.validationPattern !== null && !inputSettings.validationPattern.test(value)) result = false;
if (typeof delimiter === 'string') {
if (value.indexOf(delimiter) > -1) result = false;
} else {
$.each(delimiter, function(index, _delimiter) {
if (value.indexOf(_delimiter) > -1) result = false;
return false;
});
}
return result;
};
var _checkDelimiter = function(event) {
var found = false;
if (event.which === 13) {
return true;
}
if (typeof event.data.delimiter === 'string') {
if (event.which === event.data.delimiter.charCodeAt(0)) {
found = true;
}
} else {
$.each(event.data.delimiter, function(index, delimiter) {
if (event.which === delimiter.charCodeAt(0)) {
found = true;
}
});
}
return found;
};
var _splitIntoTags = function(delimiter, value) {
if (value === '') return [];
if (typeof delimiter === 'string') {
return value.split(delimiter);
} else {
var tmpDelimiter = '?';
var text = value;
$.each(delimiter, function(index, _delimiter) {
text = text.split(_delimiter).join(tmpDelimiter);
});
return text.split(tmpDelimiter);
}
return [];
};
})(jQuery);
Avez-vous une idée de la raison du problème ?
Y a-t-il un moyen pour débugger facilement le code javascript / Ajax ?
Merci d'avance
Bonne journée
Thierry