[英]jquery Select2 prevent selecting in ajax response
I want to prevent from adding a category to the Select2 element if it fails creating the row first in my db.如果在我的数据库中首先创建行失败,我想阻止向 Select2 元素添加类别。 The action is not prevented when i call ev.preventDefault();当我调用 ev.preventDefault(); 时不会阻止该操作; Nothing happens.. what is wrong?什么都没发生。。有什么问题吗?
$('#sel2').select2({
placeholder: 'Enter categories',
minimumInputLength: 3,
multiple: true,
ajax: {
url: 'async/get_categories.php',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
q: term,
};
},
results: function (data, page) {
return {
results: data.items
};
},
cache: true
},
formatResult: format,
formatSelection: format
}).on('select2-selecting', function(e) {
console.log(e);
if (e.val == 4) {
// if category id equals 4
// do not add this category to select 2
// e.preventDefault();
// the above works just fine and its just for testing
}
// Is something wrong here?
var ev = e;
$.ajax({
type: 'POST',
url: 'async/create_profile_category.php',
data: {
profile_id: '1',
category_id: ev.val
},
success: function(response) {
console.log(response);
if (response.error === false) {
// category assigned successfully
} else {
// failed to assign category
// so i want now to prevent from adding to select2
console.log('should not add this category');
ev.preventDefault();
// the above is not working
}
},
error: function() {
alert('Failed to assign category!');
}
});
});
The AJAX request is made asynchronusly, so by the time it has finished the element has already been added. AJAX 请求是异步发出的,因此在它完成时元素已经被添加。 Even though you are calling ev.preventDefault()
, it is too late for it to make a difference.即使您正在调用ev.preventDefault()
,也为时已晚,要有所作为。 So this leaves you with two options:所以这给你留下了两个选择:
preventDefault
to make the difference.同步发出请求,这将允许preventDefault
发挥作用。Both options have their pros and cons, and it's up to you to decide which option you go with.两种选择都有其优点和缺点,由您决定选择哪个选项。
Pros优点
Cons缺点
Pros优点
Cons缺点
What's important to consider here is the user experience of both options.这里需要重点考虑的是这两个选项的用户体验。 When making synchronus requests, it's not uncommon for the browser to stop relaying events - which gives the illusion that the UI has locked up and the page has gone unresponsive.在发出同步请求时,浏览器停止中继事件的情况并不少见 - 这会让人产生 UI 已锁定且页面无响应的错觉。 This has the benefit of ensuring that the value never shows up if it isn't allowed.这样做的好处是可以确保值在不允许的情况下永远不会出现。 But if users typically can add the elements, it also has the downside of complicating the most common use case.但是,如果用户通常可以添加元素,那么它也有使最常见用例复杂化的缺点。
If users can usually add elements, then it is a better experience to add the element while the request is being made, and then notifying the user later (while removing the element) if there was an issue.如果用户通常可以添加元素,那么最好在发出请求时添加元素,然后在出现问题时通知用户(同时删除元素)。 This is very common is web applications, and you can see it being used in many places, such as the Twitter and Facebook like buttons (where requests usually work), as well as places on Stack Overflow.这在 Web 应用程序中很常见,您可以在许多地方看到它的使用,例如 Twitter 和 Facebook 之类的按钮(请求通常在这些地方工作),以及 Stack Overflow 上的地方。
There is a way to get around this with version4 of the select2 library.有一种方法可以使用 select2 库的 version4 来解决这个问题。
on select2:selecting
we cancel the preTrigger event.在select2:selecting
我们取消了 preTrigger 事件。 Which will stop the select2:select
event.这将停止select2:select
事件。 We do our ajax call.我们进行 ajax 调用。 On success we then get out Select2
instance then call the trigger of the Observer that way it by passes overwritten trigger method on your select2 instance.成功后,我们将退出Select2
实例,然后通过在您的 select2 实例上传递覆盖的触发器方法来调用观察者的触发器。
The call
method needs your select2 instance as the context so that the existing listeners are available to call. call
方法需要您的 select2 实例作为上下文,以便可以调用现有的侦听器。
var sel = $('#sel');
sel.select2(config);
sel.on('select2:selecting', onSelecting);
function onSelecting(event)
{
$.ajax({
type: 'POST',
url: 'async/create_profile_category.php',
data: {
profile_id: '1',
category_id: event.params.args.data.id
},
success: function(event, response) {
console.log(response);
if (response.error === false) {
// category assigned successfully
// get select2 instance
var Select2 = $users.data('select2');
// remove prevented flag
delete event.params.args.prevented;
// Call trigger on the observer with select2 instance as context
Select2.constructor.__super__.trigger.call(Select2, 'select', event.params.args);
} else {
// failed to assign category
// so i want now to prevent from adding to select2
console.log('should not add this category');
}
}.bind(null, event),
error: function() {
alert('Failed to assign category!');
}
});
event.preventDefault();
return false;
}
here how I did it for yii2 Select2 integrated into Gridview:在这里,我是如何将 yii2 Select2 集成到 Gridview 中的:
'pluginEvents' => [
'select2:selecting' => "
function(event)
{
var select2 = $('#types-" . $model->id . "');
select2.select2('close');
$.post('update',{id: " . $model->id . ", type_id: event.params.args.data.id})
.done (function(response)
{
select2.val(event.params.args.data.id);
select2.trigger('change');
})
.fail(function(response)
{
krajeeDialog.alert('Error on update:'+response.responseText);
});
event.preventDefault();
return false;
}",
],
it allows to asynchoronous update data in the grid using select2 and ajax and return it to previous value if there was an error on updating.它允许使用 select2 和 ajax 异步更新网格中的数据,如果更新出错,则将其返回到先前的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.