jquery Select2 防止在 ajax 响应中选择
Posted
技术标签:
【中文标题】jquery Select2 防止在 ajax 响应中选择【英文标题】:jquery Select2 prevent selecting in ajax response 【发布时间】:2014-12-29 13:40:08 【问题描述】:如果在我的数据库中首先创建行失败,我想阻止向 Select2 元素添加类别。当我调用 ev.preventDefault(); 时,该操作不会被阻止;什么都没有发生……怎么了?
$('#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!');
);
);
【问题讨论】:
【参考方案1】:AJAX 请求是异步发出的,所以当它完成时,元素已经被添加。即使你打电话给ev.preventDefault()
,它也为时已晚。所以这给你留下了两个选择:
-
同步发出请求,这将使
preventDefault
有所作为。
异步发出请求,如果失败则手动删除元素。
这两种选择各有利弊,您可以自行决定选择哪一种。
-
同步发出请求
优点
如果请求失败,则永远不会添加该值。 在不能经常添加元素的情况下效果很好。缺点
阻止 UI - 因此用户在发出请求时可能会看到无响应的页面。-
异步发出请求
优点
不阻塞用户界面。 在通常可以添加元素的情况下效果很好。缺点
该值将始终显示给用户,即使稍后失败。 您必须手动取消设置新选项。这里需要考虑的重要一点是这两个选项的用户体验。在发出同步请求时,浏览器停止中继事件的情况并不少见——这会产生 UI 已锁定且页面已无响应的错觉。这样做的好处是确保在不允许的情况下该值永远不会出现。但是,如果用户通常可以添加元素,那么它也有使最常见的用例复杂化的缺点。
如果用户通常可以添加元素,那么在发出请求时添加元素会更好的体验,然后如果出现问题,稍后(在删除元素时)通知用户。这在 Web 应用程序中很常见,您可以在许多地方看到它被使用,例如 Twitter 和 Facebook 之类的按钮(请求通常工作的地方),以及 Stack Overflow 上的地方。
【讨论】:
【参考方案2】:有一种方法可以使用 select2 库的 version4 来解决这个问题。
在select2:selecting
上,我们取消了 preTrigger 事件。这将停止select2:select
事件。我们进行 ajax 调用。成功后,我们将退出 Select2
实例,然后调用 Observer 的触发器,通过在您的 select2 实例上传递覆盖的触发器方法。
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;
【讨论】:
【参考方案3】:这里我是如何将 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;
",
],
它允许使用 select2 和 ajax 异步更新网格中的数据,如果更新出现错误,则将其返回到以前的值。
【讨论】:
以上是关于jquery Select2 防止在 ajax 响应中选择的主要内容,如果未能解决你的问题,请参考以下文章
ajax调用HTML内容更改后select2 jquery插件不起作用
jQuery.map() 解析 select2 ajax 调用的结果
将参数传递给 jQuery 的 select2 ajax 调用
使用带有标签的select2 jquery插件:true,您如何防止选择出现在已选择的下拉列表中?