2

私は selected.js ( http://harvesthq.github.com/chosen/ ) を使用しています。誰かが選択した選択ボックスと client_side_validations を一緒に使用できるかどうか疑問に思っていました。

問題は、choose を使用すると、元の 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-chosenselectedで選択ボックスを初期化するためにデータ属性 ( ) を使用していることに注意してください。また、動作するように選択されたラベル クリックで開くには、ラベル クリックでリスト ボックスを明示的に開きます。

// 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
  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 に答える