Sign in

Зарегистрируйтесь, чтобы стать полноправным участником сообщества Masterpro.ws.

Getting started with Ajax forms on Rails

Getting started with Ajax forms on Rails
Getting started with Ajax forms on Rails

 

Кратенькое руководство на тему как сделать в Ruby on Rails форму отправки сообщений на аяксе (ajax) - штуку крайне полезную, пользующуюся сегодня у всех слоев народонаселения самым неподдельным интересом. Одним словом, без долгих раздумий - вперед.

Flash-message формы реализуем, что называется, своими руками, без использования заслуженных unobtrusive_flash и Growlyflash, о которых (в частности) речь в этом топике форума, также можно глянуть для кругозора и эту темку. Чтобы не повторяться, приведу ссылки на статьи блога, озаглавленные jQuery и Bootstrap для Ruby on Rails 6 и Форма обратной связи на Ruby on Rails, и далее сразу переходим собственно к ajax.

 

 

Итак, будем считать, форма отправки сообщений, перезагружающая страничку (или перенаправляющая на другую) у нас уже есть, и задача сформулирована следующим образом: научить ее работать посредством ajax. В Ruby on Rails, изначально заточенной под аякс, это крайне несложно; попросту добавьте remote: true к хелперу simple_form (все то же самое, если обходитесь form_with):

<%= simple_form_for @contact, remote: true do |f| %>

 

Метод способен выглядеть вот так:

  def create
    @contact = Contact.new(contact_params)
    if verify_recaptcha
      respond_to do |format|
        if @contact.save
          FormMailer.with(form: @contact).new_form_email.deliver_later
          format.js   { flash.now[:success] = 'Thank you for your message.' }
        else
          format.js { flash.now[:error] = see_errors(@contact) }
        end
      end
    end
  end

  private

  def contact_params
    params.require(:contact).permit(:name, :email, :subject, :message)
  end

 

Два замечания. В случае неудачи отправки очень хотелось бы вывести flash-сообщение, описывающее ошибку (или перечень ошибок), приведших к афронту; для этого я написал метод see_errors. Т.е. - проверяем заполнение полей формы не только на стороне клиента ( required: true ), но и на сервере:

  def see_errors(x)
    if x.errors.any?
      view_context.pluralize(x.errors.count, 'error').to_s +
        ' prohibited this call from being send: ' +
        x.errors.full_messages.map { |i| %('#{i}') }.join(',')
    end
  end

 

Теперь добавим валидации Active Record в модель. Например:

class Contact < ApplicationRecord
  validates :name, presence: true
  validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create, message: 'Invalid email' }
  validates :subject, length: { minimum: 5 }
  validates :message, length: { minimum: 15 }
end

 

Результат не заставляет себя ждать:

Active Record Validations. Getting started with Ajax forms on Rails
Active Record Validations. Getting started with Ajax forms on Rails

 

И второе. Если отправка письма ( т.е. if @contact.save ) увенчается успехом - с целью очистки формы зачастую звучит рекомендация реинициализировать объект:

@contact = Contact.new

 

- не уверен. Я бы лучше добавил reset в файл create.js.erb, который вам предстоит создать в директории, содержащей вьюхи контроллера: 

create.js.erb

console.log("This is the create.js.erb file");
$('#template').html("<%= j render 'template' %>");
$("#new_contact")[0].reset();
$('#flash-message').html("<%= j render 'shared/flash' %>").delay(4000).fadeOut(4000).css({display:"block"});

 

Примечание. Весь код полностью (а не фрагментарно) возможно увидеть в моем гитхабе, репозиторий называется CRUD-Blog:

Увидеть на гитхабе.

Демо:

Взглянуть Blog on Rails на Heroku.

 

Теперь, что касается render 'shared/flash':

_flash.html.erb

<div class="container">
  <% flash.each do |type, msg| %>
    <div class="alert <%= bootstrap_class_for_flash(type) %> alert-dismissable fade show">
      <%= msg %>
    </div>
  <% end %> 
</div>

 

, соответственно:

application_helper.rb

module ApplicationHelper
  def bootstrap_class_for_flash(flash_type)
    case flash_type
    when 'success'
      'alert-success'
    when 'error'
      'alert-danger'
    when 'warning'
      'alert-warning'
    when 'notice'
      'alert-info'
    else
      flash_type.to_s
    end
  end
end

 

Пожалуй, это все. В том случае, если вы не вознамеритесь добавить последний (на сегодня) штрих: выключить кнопку отправки сообщений до успешного прохождения recaptcha. Что крайне несложно:

1. Меняем в HTML тэг recaptcha следующим образом:

<%= recaptcha_tags :callback => "enableBtn" %>

2. Submit, кнопка отправки:

<%= f.submit :Send, id: 'sbm', disabled: 'disabled' %>

3 и последнее:

<script>
function enableBtn(){
   document.getElementById("sbm").disabled = false;
 } 
</script>

Оставить комментарий

Добавьте ваш комментарий

В блоге

Комментарии в блоге

  • Рамат Они до сих пор такую шляпу предлагают с оформлением в известную американскую компанию через ИП или самозанятого, на прошлой неделе…

    Пятница, 15 января 2021

    Опубликовано в: Про IT Selection, gray salary и Барака Обаму
  • serge Да вроде на месте ссылки, Вася. Чем не устраивает сайт разработчика и его github?

    Четверг, 17 декабря 2020

    Опубликовано в: Fakeloader.js
  • Вася А где ссылки на скрипты? или их нет? скачивать нечего?

    Четверг, 17 декабря 2020

    Опубликовано в: Fakeloader.js
  • Aleksej This is a very old project, Lukas. Support has ended.

    Воскресенье, 06 декабря 2020

    Опубликовано в: Category Product Combinations. Prestashop module
  • Lukas Hi. Not working properly for 1.7.7

    Воскресенье, 06 декабря 2020

    Опубликовано в: Category Product Combinations. Prestashop module