2

我正在使用 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:

我现在有以下对我有用的解决方案。

  • 将类“chzn-dropdown”应用于我选择的所有选择
  • 使用了 client_side_validations Gem 提供的以下回调
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();
  }
  }
}
4

3 回答 3

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); });
于 2012-12-17T11:55:42.333 回答
0

尝试这个:

告诉 gem 你想要验证选择标签:

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

当 Chosen 的 Dropbox 更改时强制验证:

$('#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 %>
于 2013-07-12T10:47:48.527 回答
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"));
      }
    }
  }
于 2012-07-16T18:45:58.997 回答