我使用的是selected.js(http://harvesthq.github.com/chosen/)。我想知道是否有人能够一起使用所选择的选择框和client_side_validations。
问题在于,当我们使用selected时,它会隐藏原始的select元素并改为呈现自己的下拉列表,当我们关注时,不会调用验证,并且当显示验证消息时,它会显示原始的select元素因此错误的定位也是正确的。
处理这个问题的好方法是什么,我可以更改ActionView::Base.field_error_proc
内部的一些代码,这些代码目前看起来像
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
unless html_tag =~ /^<label/
%{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
else
%{<div class="field_with_errors">#{html_tag}</div>}.html_safe
end
end
有什么想法吗?
编辑1:
我现在有以下解决方案。
clientSideValidations.callbacks.element.fail = function(element, message, callback) {
if (element.data('valid') !== false) {
if(element.hasClass('dropdown')){
chzn_element = $('#'+element.attr('id')+'_chzn');
console.log(chzn_element);
chzn_element.append("<label class='message-chzn'>"+message+"</label>");
}
else{
callback();
}
}
}
答案 0 :(得分:1)
关于在所选选项更改时验证未运行的问题,您可以尝试:
selectbox.change(function() { setTimeout(function() { selectbox.focusout() }) });
我仍然在寻找有关验证消息定位的解决方案,因为我真的很想避免篡改客户端验证javascript。
修改强>:
毕竟,这似乎是一个很好的解决方案,为了更接近客户端验证api,我想出了以下内容(可能涉及的人):
var settings = {
type: 'ActionView::Helpers::FormBuilder',
input_tag: '<div class="field_with_errors"><span id="input_tag" /><label class="message validationError" /></div>'
};
clientSideValidations.callbacks.element.fail = function (element, message, addError) {
if ($(element).data('chosen') != null) {
var chosen = $('#' + element.attr('id') + '_chzn');
clientSideValidations.formBuilders[settings.type].add(chosen, settings, message);
// Point the label back to the select box
$('label[for="' + chosen.attr('id') + '"]').attr('for', element.attr('id'));
// Mark it as invalid
chosen.data('valid', false);
} else {
addError(element, message);
}
};
clientSideValidations.callbacks.element.pass = function (element, removeError) {
if (element.data('chosen') != null) {
var chosen = $('#' + element.attr('id') + '_chzn');
clientSideValidations.formBuilders[settings.type].remove(chosen, settings);
// Un-mark it from invalid
chosen.data('valid', null);
} else {
removeError(element);
}
};
请注意,我使用数据属性(data-chosen
)来初始化所选的选择框。另外,对于标签点击打开选择工作,我明确打开标签上的列表框点击:
// element is the select box
// Delegate click event from related labels to element (this is already done on "good" browsers)
$('label[for="' + element.attr('id') + '"]').click(function() { element.click() });
// Delegate click event on original element and any related labels to open the list
$(element).click(function() { setTimeout(function() { element.trigger('liszt:open'); }, 0); });
答案 1 :(得分:0)
clientSideValidations.callbacks.element.fail = function(element, message, callback){
if(element.data("valid") !== false) {
callback();
if(element.is("select") && $("#" + element.attr("id") + "_chzn").length > 0){
element.parent().prepend($("#" + element.attr("id") + "_chzn"));
}
}
}
答案 2 :(得分:0)
试试这个:
告诉gem您要验证选择标记:
ClientSideValidations.selectors.inputs += ', select';
当Chosen的保管箱更改时强制验证:
$('#form_field').chosen().change(function(e) {
var settings = window.ClientSideValidations.forms[this.form.id];
$(this).isValid(settings.validators);
});
由于Chosen隐藏了该字段,您需要在视图中明确启用该字段的验证:
<%= form_for ..., :validate => true do |f| %>
...
<%= f.validate :form_field %>
...
<% end %>