Простая форма с полем выбора jquery не работает должным образом, если ошибки формы

У меня есть поле ввода с множественным выбором для формы в рельсах. Он работает отлично, за исключением случаев, когда пользователь отправляет значение, которое валидатор в модели не примет. Когда страница повторно отображается и отображается сообщение об ошибке, поле формы изменяется с поля множественного выбора на текстовое поле. Я думаю, проблема в том, что рельсы по какой-то причине меняют класс css. Вот контроллер, который загружает переменные экземпляра для формы:

def edit
    @skills = Skill.all.collect {|skill| skill.label}
    @profile = current_user.profile
end

Вот форма:

<%= simple_form_for(@profile, :html => { :method => :put }) do |f| %>
  <%= f.error_notification %>
        <%= f.input :tag_list, collection: @skills, 
          input_html: {class: 'chosen-select', multiple: true, 
          style: 'width: 390px; height: 40px; border-radius: 5px;'},  
          placeholder: 'Tags (seperated by commas)', label: "-" %> <br />
        <%= f.submit "Save" %>
<% end %>

Вот контроллер обновления:

def update

    @profile = current_user.profile

    begin
      if @profile.update_attributes!(profile_params)
        flash[:notice] = "Successfully updated profile."
        redirect_to profile_path(current_user.profile_name)
      else
        render :action => 'edit'
      end
    rescue
      render :action => 'edit'
    end
end

Форма отлично работает при первом перекрашивании. HTML-код, сгенерированный для поля, выглядит следующим образом:

<div class="input select optional profile_tag_list">
  <label class="select optional" for="profile_tag_list">-</label>
  <input name="profile[tag_list][]" type="hidden" value="" />
    <select class="select optional chosen-select" id="profile_tag_list" 
      multiple="multiple" name="profile[tag_list][]" 
      placeholder="Tags (seperated by commas)" 
      style="width: 390px; height: 40px; border-radius: 5px;">
         <option value="Finance">Finance</option>
         <option value="PHP">PHP</option>
         <option value="python">python</option>
    </select>
</div>

Но когда он отображается после сбоя действия обновления, HTML-код выглядит следующим образом:

<div class="input string optional profile_tag_list field_with_errors">
   <label class="string optional" for="profile_tag_list">-</label>
   <input class="string optional chosen-select" id="profile_tag_list" 
     multiple="multiple"  name="profile[tag_list][]" 
     placeholder="Tags (seperated by commas)" 
     style="width: 390px; height: 40px; border-radius: 5px;" type="text"
     value="PHP" />
       <span class="error">Please only submit skills from the list.</span>
</div>

Как заставить форму по-прежнему отображать поле выбора при повторном отображении? Спасибо.


person Philip7899    schedule 11.11.2013    source источник


Ответы (1)


Поскольку каждый запрос не имеет состояния, вам необходимо перестроить переменную экземпляра @skills, прежде чем вернуться к форме редактирования. Кроме того, вы обычно не хотите использовать "!" в вызове update_attributes, потому что это скажет выдать ошибку RecordInvalid, если произойдет какая-либо ошибка проверки. Вы можете просто использовать:

if @profile.update_attributes(profile_params)
  flash[:notice] = "Successfully updated profile."
  redirect_to profile_path(current_user.profile_name)
else
  @skills = Skill.all.collect {|skill| skill.label}
  render :action => 'edit'
end

Если установка переменной экземпляра становится сложной, вы можете переместить ее в общий метод, который используется как методами edit, так и update. И если вы сталкиваетесь с какой-либо другой ошибкой, отличной от RecordInvalid, вы можете рассмотреть возможность использования структуры begin/rescue.

person cschroed    schedule 11.11.2013