当对选择输入初始化 selected 时,它会将 [style=" display:none "] 添加到 select 标签并创建它需要的各种 div 标签,如下所示。
<select name="country" id="country" style="display: none; " class="chzn-done">
<option selected="selected" value=""></option>
...
</select>
这很好,但是如果我将 html5 'required' 属性添加到我的 select 标记中,我们会遇到问题,这会在选择初始化后生成以下标记:
<select name="country" id="country" required="required" style="display: none; " class="chzn-done">
<option selected="selected" value=""></option>
...
</select>
当用户提交表单而不选择值时会出现问题。 对于用户来说,浏览器似乎什么都不做。 事实上,它会向用户显示一条错误消息来选择一个值,但是因为 CSS 指示浏览器不要显示 select 元素,所以错误消息也不会出现。
这发生在 Chrome 中,我不确定其他浏览器的行为。
我还没有深入挖掘到提出解决方案的建议,但这是一个问题,因为我们开始在表单中包含 html5 属性。
我也是最近才注意到这个问题。
并非所有浏览器都支持必需,因此我创建了一个后备以在提交时循环遍历表单的元素,并验证存在“必需”时是否存在某些值。
问题仍然存在于 chrome 中,因为隐藏的选择没有价值,并且没有按照 webkit 文档提醒用户:
http://trac.webkit.org/wiki/Styling%20Form%20Controls
“验证消息由四个带有伪类的 div 元素和一些消息文本节点组成。您可以通过更改这些伪类的样式来自定义外观。”
我认为处理这个问题的最好方法是选择使用类似的类为它们呈现的选择生成附加标记,以便它们在浏览器中默认设置样式,或者可能将伪元素附加到验证失败的元素中在 CSS 中使用适当的失败条件,如 :invalid。
现在,看起来您唯一的选择是像我的 javascript 解决方案一样拥有 DOM 级别的后备。 如果有帮助,我可以在此处提供它,但这实际上是对所选框架的一种后备,而不是修复所选框架的方法。
这个问题的现状如何? 我与最新版本的 Firefox ( 14.0.1 ) 有完全相同的问题
由于 HTML5 属性在网站中越来越多地使用,因此应该以某种方式解决这个问题。
我也有同样的问题。 我很想知道您的后备解决方案。
谢谢
看起来只有一个主要问题,还有一个很好解决的次要问题。
第一项是问题较多的一项。 这可以通过使用不同的选择元素隐藏方法来解决吗? 用“位置:绝对;可见性:隐藏;”替换隐藏选择元素上的“显示:无” 变得非常接近 - 尽管这将更依赖于周围的 CSS ...
但它不适用于 Webkit。 错误标志似乎继承了 webkit (Chrome) 中选择框的样式,因此如果您设置 opacity: .5,该标志也将是 opacity .5(作为一个示例)。 无赖。
还有一个 - Opera 按原样正常工作,但如果我将其更改为上述基于位置的 CSS,则它无法正常工作。 多么痛苦。
对不起,垃圾邮件了。 我想我明白了! 如果将 select 元素包装在一个 span 中,并在包装器上使用此 CSS(并删除 select 元素上的 display:none):
width: 0px;
height: 0px;
overflow: hidden;
display: inline-block;
position: absolute;
您将收到错误消息,同时不会中断页面流程。 唯一的问题是您必须让该框可见才能看到错误消息,因为如果您不这样做,Firefox 和 WebKit 会隐藏该消息。 这会导致选择框通过表单接收选项卡。
解决方法可能是在提交(或“无效”事件)时将显示从无切换到内联块,然后在某些输入事件(如鼠标按下或按键)上将其切换回。
还有一个小的定位问题,可以通过强制位置直接位于所选框的下方来解决。
如果可能的话,很高兴看到对此有某种内置支持。
我在这里写了一个补丁: https :
它可能不够健壮,无法包含在内,但请随时对其进行测试。
谢谢@CaptainN! 我去看看!
@CaptainN ,我让它工作了 - 感谢你做出这些改变。 但是,您知道如何让错误弹出窗口的宽度超过选择框本身的宽度吗? 在我的一些较小的选择元素上,错误消息非常细,看起来不太好,甚至可能难以阅读。
如果没有,没关系,您已经为此提供了很多帮助。 再次感谢!
@caderade我不知道如何解决这个问题。 我尝试了overflow:visible和其他一些东西,但它仍然显示很短我会再尝试一些东西,但这看起来像是 Firefox 的问题,可能没有解决方法(这些标志通常很难处理以及那种光芒,我还没有找到一种完全风格化的方法)。
@CaptainN :非常好。
它在 Firefox 17 和 Chrome 23 中对我来说效果很好。
在 IE 8+9(根本不支持 HTML5 表单验证)中,当更改字段的值时,由于使用了未知的:valid
选择器,我收到一个 JavaScript 错误。 因此脚本被中止并且表单不会以任何方式变得丑陋,这是我在 IE 中所期望的。 :smirk: 不过,不提出错误会更好。 任何的想法?
哦打扰了。 我实际上认为 jQuery 会保护我更多! 我将不得不添加一个IE检查或其他东西......
凯文 N。
@CaptainN在 Chrome 中我也有这个问题。 不确定您是否认为这只是 Firefox 的问题。 但是伙计,再次感谢一个人。 很棒的工作! 如果您能够解决宽度问题,请告诉我们。
看起来 jQuery 有一些内置的伪选择器支持,还有一个钩子系统,所以插件可以添加自己的,如果没有找到,它会将它传递给底层实现 - 所以 :required 和 :valid 抛出错误在 IE(可能还有一些版本的 Safari)中,如果它们没有被 polyfill。 我会看看我是否可以在那里抛出另一种检查,而不是使用伪选择器。 看起来我可以只检查 attr("required") 来替换 :required - 我可能需要对 :valid 进行某种功能检测 - 也许检查 .oninvalid 属性?
好的,我得到了一个修复 IE 错误的新补丁(也应该在任何其他浏览器中修复它)。 此补丁更改了一些内容(您不应该注意到)。 以下是我的笔记:
@CaptainN对于 UglifyJS 的问题,请确保安装版本 1,因为版本 2 不是 BC。 #915 正在更新packages.json
如何使用 npm 切换版本?
@CaptainN npm install uglify-js@1
强制使用版本 1 IIRC(但我不是节点专家)。 另一个解决方案是签出我的分支并使用更新的 packages.json 文件运行npm install
。
我能够在我的工作 Mac 上构建丑化版本(也许它有一个旧版本的 uglify-js?)。 它们现在在我的回购中是最新的。
我目前只使用 jQuery 风格。 IE8/9 中不再有脚本错误。 :+1: 很快就会在上游看到这个功能。
我们也面临这个问题。 除了禁用 HTML5 验证之外,还有其他解决方法吗?
@CaptainN根据我阅读的
我以为我解决了这个问题。 那个叉子是很久以前的了,可能需要更新。 我会看看这周我是否能做到这一点,并调查 IE 错误。
我同步了这个上游,我在 IE 中没有看到任何未定义的错误通知。 再次尝试我的 repo,如果您仍然看到这个问题,请告诉我。 (抱歉拖了这么久)
谢谢!
:+1:
有人可以为我总结一下吗? 是否有准备用于生产的分叉或补丁?
有一个与此相关的拉取请求 - #900 将拉取我的 adcSTUDIO/Chosen fork。
而不是隐藏原始选择框 - 当需要选择时,并且出现错误时,补丁会将选择框放置在“选择”选择框下方,以便内置的 HTML5 错误消息出现在正确的位置。 编辑:我可能应该注意,如果该框未标记为“必需”且从未失效,则保留现有行为。
除了显示内置的 HTML5 错误通知之外,此拉取请求不会添加任何其他功能。
谢谢凯文!
2013/7/29 凯文纽曼通知@ github.com
有一个与此相关的拉取请求 - #900 https://github.com/harvesthq/chosen/issues/900将拉取我的 adcSTUDIO/Chosen fork。
而不是隐藏原来的选择框 - 当需要选择时,
当出现错误时,补丁会将选择框定位在下方
选择框,以便内置的 HTML5 错误消息出现在
正确的位置。此拉取请求不会添加任何其他功能
使内置的 HTML5 错误通知显示。—
直接回复本邮件或在Gi tHub上查看
.
乌尔斯·布雷姆
马赫特网站
许可证。 菲尔。 一世
剧院广场 2
3011伯尔尼
电话。 布罗:+41 31 311 73 61
电话。 Mobil & Combox: +41 76 327 01 51
http://www.ursbraem.ch
私人:
本登费尔德大街 50
3013伯尔尼
电话 +41 31 301 41 90
你好,
我刚刚获得了最新版本 (1.0),但仍然遇到此问题。 当 selected 被添加到具有 required 属性的选择框中时,在 Firefox 中,“请从列表中选择一个项目”工具提示出现在屏幕的左上角。 在 Chrome 中什么也没有发生。 拉取请求未与 1.0 版集成吗? 怎么下载那个补丁? 抱歉,我对 Github 不太熟悉,提前致谢!
我认为我的更改没有合并。 我的叉子可能也需要更新 - 已经有一段时间了。
啊,那太糟糕了。 知道它是否在主分支管道上吗? 有什么建议可以让它在此期间工作吗?
我不知道他们是否打算将其集成到 master 中,但是您可以做的是使用我的 fork,并将其同步到 master,这将使您从他们的 repo 中获取最新的更新,并应用我的更改(假设没有冲突) - 或者只是使用我有点过时的叉子。 不幸的是,我没有时间在短期内更新我的 fork。
这是我的叉 btw: https :
谢谢,凯文。
亚伦·盖兹
首席软件架构师
MedAdaptics - http://medadaptics.com
(781) 767-7434
2013 年 11 月 27 日星期三下午 12:35,Kevin Newman通知@github.com 写道:
这是我的叉 btw: https :
—
直接回复本邮件或在Gi tHub上查看
.
@CaptainN你有没有用你的更改打开 PR ? 我在此讨论中没有看到任何指向 PR 的链接。 而且如果没有 PR 审核,你的 fork 不太可能被审核(维护者审核提交的贡献,已经需要时间了,所以他们不会试图找到未提交的贡献)
有一个 PR #900 - 它有点乱 - 我可能会在某个时候重新调整它的基础,如果有帮助的话就清理它。
你好!
一切都非常非常简单,你不需要有 2 年的时间来讨论它:)
@CaptainN @yaronguez @stof @kenearley
要在用户不选择任何选项时添加正确显示浏览器错误消息并选择<select required>,
如果你不想花时间编辑插件代码,只需添加类似setAttribute('style', 'display:visible; position: absolute; clip: rect (0,0,0,0)'); 初始化所选插件后。
例子:
函数初始化选择(){ $('select.chzn').each(function(index) { $(this).选择({ disable_search_threshold: 5, no_results_text: "Ничего не найдено!" }); this.setAttribute('style','display:visible; position:absolute; clip:rect(0,0,0,0)'); }); }
就这样。 啊啊啊现在……迪斯科! :)
** 适用于支持“required”属性的浏览器。
@Aharito我们不会通过执行此操作来解决 Tab 键顺序问题吗?
谢谢@Aharito,它在选定的 v1.1.0 上运行良好,只需将$('select.chzn')
替换$('.chosen-select')
。
我以为我尝试了那个剪辑:矩形技巧,并发现了一些问题。 也许使用较旧的浏览器? 我想如果它现在工作很好。
我认为我的解决方案也可能存在制表符问题(我不记得了,已经有一段时间了) - 我通过仅将补丁应用于构成所需属性的字段来减少影响。
我们已经在对$().chosen()
所有调用中对此进行了标准化
$.fn.oldChosen = $.fn.chosen
$.fn.chosen = function(options) {
var select = $(this)
, is_creating_chosen = !options || _.isObject(options)
if (is_creating_chosen && select.css('position') === 'absolute') {
// if we are creating a chosen and the select already has the appropriate styles added
// we remove those (so that the select hasn't got a crazy width), then create the chosen
// then we re-add them later
select.removeAttr('style')
}
var ret = select.oldChosen(options)
if (is_creating_chosen) {
// https://github.com/harvesthq/chosen/issues/515#issuecomment-33214050
// only do this if we are initializing chosen (no params, or object params) not calling a method
select.attr('style','display:visible; position:absolute; clip:rect(0,0,0,0)');
}
return ret
}
@ghiculescu这并不能解决在选择中使用 tab 或 shift-tab 的问题,是吗?
@DASPRiD不。
这作为可能的掩盖解决方案怎么样。
它并不完美,但实际上,它通过将焦点传递到下一个选择的对话框来阻止原始选择的出现,但也许它又近了一步
“选择选择”只是我对特定类的选择的选择器,我不确定“单击焦点”是否涵盖了我应该挂钩的所有相应事件,但也许有人可以说还缺少什么?
也有可能我对所选的 html 结构有一些误解, find("a") 太自由了,有人有更多经验吗?
$(".chosen-select").on("click focus",function(event){
$(this).next(".chosen-container").find("a").trigger(event.type);
});
哦,当然“ display:visible ”应该是“ display:block ”之类的? 原因 v isibility:visible是有效的,但display:visible我确定不是
我发现,如果您在同一个容器中有多个彼此相邻的选择,这会将它们全部移到错误的位置,因此 position: absolute 使验证消息出现在错误的位置。
我通过分离并重新连接到选定的容器来解决这个问题,就像这样
$(".chosen-select").each(function(){
$(this).next(".chosen-container").prepend($(this).detach());
});
上面的解决方案,经过更多的调查,表明它完全禁用了对字段的跳转,我无法解决这个问题,但是它确实消除了当你跳转时弹出选择的问题,所以这是更多在我看来很重要的问题,如果可以的话,我可以不使用 Tab 键而生活,这样它就不会破坏显示,因为越来越多的人正在使用移动设备并且无论如何都不会使用 Tab 键,它只会影响桌面用户,这仍然很重要,但是相对来说,可控。
但是,如果有人通过某种方式解决了这个问题,我很想知道。
好的,除了我之前尝试的内容之外,我发现所选择的事件正在使用,并决定当我对现在隐藏的选择执行任何事件时,我可以劫持它并触发所选事件以将其打开。
我认为它很好用。
$(".chosen-select").each(function(){
// take each select and put it as a child of the chosen container
// this mean it'll position any validation messages correctly
$(this).next(".chosen-container").prepend($(this).detach());
// apply all the styles, personally, I've added this to my stylesheet
$(this).attr("style","display:block!important; position:absolute; clip:rect(0,0,0,0)");
// to all of these events, trigger the chosen to open and receive focus
$(this).on("click focus keyup",function(event){
$(this).closest(".chosen-container").trigger("mousedown.chosen");
});
});
我认为这是迄今为止我得到的最好的版本。 令人高兴的是,这解决了向前跳转问题,仍然存在反向跳转,您无法通过选择的选择向后跳转,因为第二次跳转到选择元素时,您会立即重新聚焦到选择的容器中,这意味着您重新陷入只能向前跳。
跟踪上一个元素可能是一个想法,如果之前具有选项卡焦点的元素位于当前焦点元素的前面,则您将向后退,然后适当地跳过重新聚焦到所选元素并选择上一个选项卡,但是我不确定该怎么做。
经过很长时间的阅读,我想我尝试了多年来提交的建议。
不幸的是,我无法让@christomas的代码起作用。 我在没有可见结果的提交函数中调用它(也没有错误)。
好消息是@ghiculescu的新功能就像一种享受,因为我仍然可以使用 CDN 选择的文件,只需在我的 js 文件中使用该功能。
@DASPRiD @charettes你是什么意思选项卡不适用于修改后的功能? 它似乎对我有用
很容易将 tabindex: -1 添加到@ghiculescu的片段的选择中,解决制表问题。
示例: http :
我现在可以看到问题了! 您的添加效果很好@andreialecu
顺便说一下,还需要另外添加一个。 在 iPhone 或其他不受支持的设备上,小提琴将无法正常工作。 Chosen 在 iPhone 上禁用自身并保持<select>
不变,上面小提琴中的代码将隐藏它,无法与选择交互。
这个小提琴修复了它(通过添加一个显示:无检查):
http://jsfiddle.net/hq7b426j/1/
啊,那就更好了!! 谢谢! 我也在测试,但如果有其他问题我会发布
@CaptainN请简要说明我有同样的问题。 我需要把那个代码。 我正在使用 wrapbootstrap 的 inspina 主题。
@vidhyaprakash85我不确定你的意思。 我很久以前就分叉了,并写了一个拉取请求(#900),但现在 repos 不同步,而且我的分叉已经过时了。 如果有帮助,您可以在这里找到它: https :
我已经在使用https://github.com/harvesthq/chosen如何做到这一点:(
@andreialecu你的代码工作正常! 谢谢!!!
谢谢@christhomas,你的代码效果很好:舞者:
@christomas或@ghiculescu都没有使用多组选择为我工作。 暂时将其留给服务器验证。
当我尝试使用@ghiculescu补丁时,它工作正常,只是在选择框下方始终显示滚动条。
当我尝试@christomas补丁时,弹出窗口没有打开搜索框。
我不得不修改@ghiculescu的脚本,这样我就可以像这样调用
target.find('select')
.chosen('destroy')
.chosen({disable_search_threshold: 10})
否则,第二次旅行删除了第一次添加的样式:
$.fn.oldChosen = $.fn.chosen
$.fn.chosen = function(options) {
var select = $(this)
, is_creating_chosen = !!options
var style = 'display:visible; position:absolute; clip:rect(0,0,0,0);'
if (is_creating_chosen && select.css('position') === 'absolute' && select.attr('style') != style) {
// if we are creating a chosen and the select already has the appropriate styles added
// we remove those (so that the select hasn't got a crazy width), then create the chosen
// then we re-add them later
select.removeAttr('style')
}
var ret = select.oldChosen(options)
// only act if the select has display: none, otherwise chosen is unsupported (iPhone, etc)
if (is_creating_chosen && select.css('display') === 'none') {
// https://github.com/harvesthq/chosen/issues/515#issuecomment-33214050
// only do this if we are initializing chosen (no params, or object params) not calling a method
select.attr('style', style);
select.attr('tabindex', -1);
}
return ret
}
我只是在第一个条件中添加了这个额外的条件: && select.attr('style') != style
@doganmeh在 Chrome 和移动设备(使用 Chrome)中运行良好,但在 Firefox 53.0 中无法运行时进行了测试
即使这个http://jsfiddle.net/hq7b426j/1/在 Firefox 53.0 中也不起作用
嗯,但这似乎更像是 Firefox 的问题,因为如果您多次单击该按钮,您将看到 Firefox 尝试显示消息(但从未完全呈现)
我用过这个解决方案。 它非常简单并且完美运行:
<style>
select.submitted:invalid + .chosen-container{
border-color: red !important;
}
</style>
$('#yourSelector').chosen({
no_results_text: "yourText",
disable_search_threshold: 9,
search_contains: true
//your parameters
}).on('invalid', function(){
$(this).addClass('submitted');
});
如果您选择了多项选择,这似乎不起作用:
http://jsfiddle.net/jeromax/o5a8aogh/
我修好了它。
`
$.fn.oldChosen = $.fn.chosen
$.fn.chosen = 功能(选项){
var select = $(this),
is_creating_chosen = !!options;
if (is_creating_chosen && select.css('position') === 'absolute') {
// 如果我们正在创建一个选择并且选择已经添加了适当的样式
// 我们删除那些(以便选择没有疯狂的宽度),然后创建选择的
// 然后我们稍后重新添加它们
select.removeAttr('style');
}
var ret = select.oldChosen(options)
// 仅当 select 具有 display:none 时才起作用,否则不支持 selected(iPhone 等)
if (is_creating_chosen && select.css('display') === 'none') {
// https://github.com/harvesthq/chosen/issues/515#issuecomment -33214050
// 仅当我们初始化 selected(无参数或对象参数)而不调用方法时才执行此操作
$(this).each(function(index){
if($(this)[0].multiple==true){
$(this).attr('style','display:visible; width:0px; height:0px; margin-top:25px; position:absolute; clip:rect(0,0,0,0)');
}else{
$(this).attr("style","display:visible; position:absolute; clip:rect(0,0,0,0)");
}
})
select.attr('tabindex', -2);
}
返回 ret
}
`
+1
有人可以为此提交修复程序吗? 这是一个很老的问题,现在非常重要的功能。 谢谢你。
不适用于最新版本。
当使用 angular-chosen 时,这似乎也破坏了 angular.js 表单验证。
现在是 2018 年,我们仍然遇到同样的问题。 HTML 标准无法正常工作并与外部插件集成真是太糟糕了。 疯狂的时代:)
这也破坏了 Drupal 选择的插件。 见https://www.drupal.org/project/chosen/issues/2705891
除了解决方法之外,找不到任何适当的解决方案:
<div class="form__select">
<select class="chosen">
<!-- options -->
</select>
</div>
.form__select {
position: relative;
}
.form__select .chosen {
display: block !important;
height: 0;
position: absolute;
left: 35px;
bottom: 0;
outline: none;
border-color: white;
pointer-events: none;
}
如果您对所有select
元素使用 Chosen,您可以使用此 CSS 更改使其可见(对 DOM),但没有不透明度、没有高度、绝对位置。
这些 CSS 选择器针对无效的 select 元素,其中一个针对multiple
添加一个15px
margin-top
以使其在多选元素上居中。
select:invalid {
height: 0px !important;
opacity: 0 !important;
position: absolute !important;
display: flex !important;
}
select:invalid[multiple] {
margin-top: 15px !important;
}
演示: http :
但真的……这应该已经由 Chosen.JS 库处理了
这是我的解决方法,如果它有任何用处:
// Initialise Chosen
$(function () {
$('select').chosen();
});
// Place the original input behind the Chosen input, matching the height and width so that the warning appears in the correct position
$('select').on('chosen:ready', function () {
const height = $(this).next('.chosen-container').height();
const width = $(this).next('.chosen-container').width();
$(this).css({
'position': 'absolute',
'height': height,
'width': width,
'opacity': 0
})
.show();
});
@jonathanbull你能在上下文中展示它吗? 我尝试了您的解决方案,但没有奏效。
@AndrewSouthpaw这是我的代码,
$("#select").val([]); // disable default selection by browser
$('#select').on('chosen:ready', function(evt, params, chosen) {
$(this).css({'position': 'absolute', 'height': 0, 'opacity': 0}).show();
});
$("#select").chosen();
我使用了稍微不同的代码(基于此处的代码):
$('.chosen-select').on("chosen:ready", function (evt, data) {
$(this)
.addClass('chosen_hidden')
.attr('tabindex', '-1')
.prependTo(data.chosen.container)
.show()
})
.chosen({width: '100%'})
.chosen_hidden {
position: absolute;
top: 0;
bottom: 0;
max-height: 100%; // required for IE 10
// **not required** opacity: 0;
}
它不处理“销毁”操作,但它确实很好地定位了错误消息,并且似乎适用于 Firefox 和 Chromiun。 由于原始选择器未隐藏,因此错误高亮边框可见。 更新:使用max-height
它也适用于 IE。 其他更新:添加 tabindex -1 以确保它不会获得焦点。 (同时仍可聚焦并接收错误消息)。
有一个公开的 PR 解决了这个问题,但我认为它丢失了,因为它针对的另一个线程已关闭。 见#2594
@jhedstrom很乐意看到合并。 不知道这个库还在维护吗?
我使用了类似于上面@eloyesp的解决方案的东西,并在这里分享:
https://github.com/harvesthq/chosen/pull/2594#issuecomment -714806139
感谢@jhedstrom为我指明了正确的方向!
最有用的评论
+1
有人可以为此提交修复程序吗? 这是一个很老的问题,现在非常重要的功能。 谢谢你。