Создание настраиваемых полей меток в формах - PullRequest
1 голос
/ 22 июня 2009

Я бы хотел создать следующую разметку:

<label for="field">Something <span class="hint">Field hint</span></label>

из следующего кода:

form_for ... do |f|
    f.label :field, :hint => "Field hint"
end

До сих пор я создал инициализатор для хранения пользовательских функций, который повторно открывает ActionView :: Helpers :: FormBuilder и изменяет метод метки, однако я не уверен, каков наилучший способ на самом деле получить диапазон в текст для метки. Если я попытаюсь вставить текст напрямую, то rails, по правде говоря, избегает содержимого.

Я бы очень хотел использовать существующую инфраструктуру меток, поскольку она поддерживает все ошибки проверки. Это исключает использование content_tag и генерацию всего этого самостоятельно (что будет работать, но не кажется ... правильным).

Ответы [ 2 ]

3 голосов
/ 22 июня 2009

Вместо изменения компоновщика по умолчанию вы должны создать собственный компоновщик и передать его в форму с параметром: builder.

class HintFormBuilder < ActionView::Helpers::FormBuilder
end

form_for @resource, :builder => HintFormBuilder do |f|
# ...
end

Конструктор Hint наследует все функции FormBuilder, включая проверку, сообщения об ошибках и т. Д. Теперь вы должны изменить то, что вам нужно изменить, чтобы настроить поведение. Это действительно сырой проект.

class HintFormBuilder < ActionView::Helpers::FormBuilder

  (%w(label)).each do |selector|
    src = <<-end_src
      def #{selector}(method, options = {})
        hint = options.delete(:hint)
        returning(super) do |element|
          # replace here the value of element with hint 
          # if hint != nil
          # remember to use gsub! and not gsub
        end
      end
    end_src
    class_eval src, __FILE__, __LINE__
  end

end

РЕДАКТИРОВАТЬ на основе первого комментария:

Это всегда хорошая идея не взламывать внутренности Rails, потому что вам, возможно, придется использовать, сейчас или в будущем, плагины или функции, основанные на исходном поведении. Если вы не хотите вручную добавлять конструктор в свои формы, вы можете создать помощника.

def search_form_for (record_or_name_or_array, * args, & proc) options = {: builder => HintFormBuilder}

form_for(record_or_name_or_array, 
         *(args << options),
         &proc)

конец

Если вы хотите снова открыть исходный класс, я бы предложил создать новый метод. Это решение также применимо к пользовательскому помощнику и имеет то преимущество, что вы можете настроить его без необходимости gsub! ответ. Да, ГСУБ! это обычный способ сделать это, потому что при расширении исходных методов у вас есть доступ только к методу / опциям и результату, а не к значению (которое вводится переменной @object).

class ActionView::Helpers::FormBuilder

  def label_with_hint(method, text = nil, options = {})
    hint = options.delete(:hint)
    # do your own customizations...
    @template.label(@object_name, method, text, objectify_options(options))
  end

end

РЕДАКТИРОВАТЬ: Я ошибся, вы можете передать пользовательский текст в качестве параметра, поэтому вам не нужно gsub! возвращенная строка. Я запутался в теге text_field. На этом этапе вы можете использовать либо первый (создание подклассов с / без пользовательского метода), второй (взлом внутренних устройств) или третий вариант (взлом внутренних объектов с помощью пользовательского метода) и перехватывать текстовое значение перед его отправкой в ​​@ template.label.

Также обратите внимание, что текст может быть нулевым. Если ноль, значение автоматически генерируется из метода. Вы должны знать об этом.

1 голос
/ 22 июня 2009

Вот что я бы сделал.

# config/initializers/[anything].rb
ActionView::Base.default_form_builder = CustomFormBuilder

# lib/custom_form_builder.rb
class CustomFormBuilder < ActionView::Helpers::FormBuilder
  def label(field, text, options = {})
    if options[:hint]
      hint = @template.content_tag(:span, options[:hint], :class => "hint")
      super(field, "#{field.to_s.humanize} #{hint}", options)
    else
      super
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...