Подтвердить что ты не робот

Форма AJAX (с использованием simple_form) с сохраненной проверкой ошибок

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

Я работаю над фиктивным приложением, которое следует за этим руководством примерно... ajax/jquery tutorial...

Создав собственные настройки, руководство помогло мне создать "бренд" (включает в себя вложенные модели "модель", "подмодель" и "стиль" ) форму представления (используя simple_form) и список брендов на той же странице. Это работает отлично, и валидация (для моих моделей) применяется. Однако, когда я помещаю форму и список брендов на той же странице, я теряю аккуратные встроенные ошибки проверки, которые появляются при сбое отправки (см. Изображение ниже). Невозможность получить встроенные ошибки для работы заставила меня понять, что мне нужно больше узнать об рендеринге.. и вот почему я зациклен на поиске ответа на этот вопрос

enter image description here

... и вот список:

enter image description here

Ниже приведен контроллер для действия индекса:

  def index

    #This is for the product listing

    @brands = Brand.all.reverse 

    #This is for the form   

    @brand = Brand.new
    @model = Model.new
    @submodel = Submodel.new
    @style = Style.new

    respond_to do |format|
      format.html
    end
  end

В приведенной выше форме создается марка, модель, подмодель и стиль для использования в вложенной форме отправки... Ниже приведен код формы:

<%= simple_form_for @brand, :html => { :class => 'form-horizontal' }, :remote => true do |m| %>

  <fieldset style = "margin-top:34px;">
    <legend></legend>
    <%= m.input :name, :label => 'Brand' %>         
    <%= m.simple_fields_for :models, @model do |p| %>    
      <%= p.input :name, :label => 'Model' %>
      <%= p.simple_fields_for :submodels, @submodel do |s| %>
        <%= s.input :name, :label => 'Submodel' %>
        <%= s.simple_fields_for :styles, @style do |ss| %>
          <%= ss.input :name, :label => 'Style' %>
        <% end %>
      <% end %>
    <% end %>

    <div class="form-actions">
      <%= m.submit nil, :class => 'btn btn-primary' %>
      <%= link_to 'Cancel', brands_path, :class => 'btn' %>
    </div>
  </fieldset>
<% end %>

Теперь, когда вы видите, что я использую :remote => true... Я бы хотел, чтобы форма создавала новый "бренд" или для того, чтобы форма перезагружалась встроенными ошибками проверки. На данный момент мое действие создается так:

def create
    @brand = Brand.new(params[:brand])

    respond_to do |format|
      if @brand.save
        format.html { redirect_to brands_url, notice: 'Brand was successfully created.' }
        format.json { render json: @brand, status: :created, location: @brand }
        format.js
      else
        format.html { render action: "index" }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
        format.js { render 'reload' }
      end
    end
  end

Код, который появляется под if @brand.save, кажется, работает. но код ниже "else" не работает так, как хотелось бы. Итак, что происходит, когда @brand НЕ сохраняет? Я считаю, что код внутри действия индекса запускается, а затем @brand.errors преобразуется в json (который я предполагаю для ошибок проверки Simple_form), а затем выполняется перезагрузка .js.erb..

В попытке перезагрузить форму (с ошибками проверки) я поместил строку $("#entryform").load(location.href+" #entryform>*",""); в reload.js.erb... Когда я помещаю неверные данные в свою форму, вызывается reload.js.erb, но все, что происходит, состоит в том, что поля формы перезагружаются пустым, вместо того, чтобы вводить данные и встроенные ошибки проверки.

Надеюсь, что я предоставил достаточно информации здесь, чтобы получить помощь. На самом деле это борьба. Спасибо!

4b9b3361

Ответ 1

Я думаю, вы можете упростить это, поставив свою форму в частичном (назовем ее simple_form) и поместив этот код в reload.js.erb:

$("#entryform").html("<%= escape_javascript(render :partial => 'simple_form') %>");

Я не знаком с методом jQuery load, но я предполагаю, что он выполняет второй запрос. Ключ с ошибками рендеринга - это переменная экземпляра (@brand), которую вы используете, в то время как рендеринг формы должен быть тем же, который вы пытались сохранить в создании, поэтому вы можете проверить на нем ошибки. Вот почему вы всегда используете render вместо redirect_to, когда хотите визуализировать ошибки. Если вы выполните перенаправление, вы начнете новый запрос, то есть @brand будет повторно инициализирован. Я предполагаю, что ваш $(...).load(...) имеет ту же проблему.

Ответ 2

Спасибо за все Q & A на этом. Это спасло меня.

Упрощение структуры файлов @tsherif на одну метку (если у вас уже есть файл js), я решил эту проблему, вызвав визуализацию непосредственно в форме и показывая ее через javascript/coffeescript.

#immediate_controller
def action_with_modal
  @brand = params[:failed_brand] || Brand.new
end

#brands_controller
def create
  @brand = Brand.new(params[:brand]) 

  respond_to do |format|
    if @brand.save
      ...
    else
      params[:failed_brand] = @brand
      ...
      format.js { render 'simple_form' }
    end
  end
end

#coffeescript
$('form-selectors-here').on 'ajax:error', @reRegister

reRegister: (e, data) =>
  $("div-that-contains-form").html(data.responseText)

Ответ 3

Проверьте это: вызов .html(...) будет дублировать оболочку формы div. Используйте .replateWith(...) вместо =]