2012-06-08 42 views
2

我正在使用chosen.js(http://harvesthq.github.com/chosen/)。我想知道是否有人能够一起使用选择的选择框和client_side_validations。有没有人使用chosen.js下拉列表中的client_side_validations gem?

问题是,当我们使用选择它隐藏原来的选择元素,并呈现自己的下拉,而当我们专注了验证不被调用,并且当验证消息显示时,它显示与原始选择元素,所以错误的定位也是正确的。

什么能来处理这一个很好的方式,我是我们可以改变一些代码里面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:

我有以下的解决方案,现在是为我工作。

  • 应用类“chzn-下拉”我所有的选择,正在通过选择
  • 使用client_side_validations提供了以下回调宝石
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

你在哪里添加回调到你的应用程序? –

回答

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")); 
     } 
    } 
    } 
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); }); 
0

试试这个:

告诉您要验证选择标签的创业板:

ClientSideValidations.selectors.inputs += ', select'; 

强制验证时所选择的Dropbox的变化:

$('#form_field').chosen().change(function(e) { 
    var settings = window.ClientSideValidations.forms[this.form.id]; 
    $(this).isValid(settings.validators); 
}); 

既然选上的隐藏字段,将需要在该视图中明确验证该字段:

<%= form_for ..., :validate => true do |f| %> 
... 
    <%= f.validate :form_field %> 
... 
<% end %>