
Чтобы покупателю нужно было заполнять меньше полей и нажимать меньше кнопок, на страницах сайта располагают формы быстрого заказа, которые позволяют оформить заказ прямо на месте. Обычно это имеет вид всплывающего окна с формой.
Начало
Разместим на странице товара кнопку, вызывающую всплывающее окно:
<a href="#" class="button fast_check" >В 1 клик</a>
Выглядит она примерно так:
Далее нужно разместить html код формы. Создадим сниппет fast_checkout и разместим его перед закрывающим тегом body.
Напишем код формы и стили:
<div class="form_shadow"> </div> <div class="checkoutmsg"> <a class="closemsg" href="#">×</a> <form id="fast_checkout" class="contact" action="/cart_items" method="post" role="form"> <div class="h3">Быстрый заказ</div> <input type="text" id="check_name" value="" class="required" placeholder="Имя" /> <input type="text" id="check_phone" value="" class="required" placeholder="Телефон" /> <input type="text" id="check_mail" class="required" placeholder="E-mail" /> <input type="hidden" id="check_var" value="" /> <input type="hidden" id="check_del" value="" /> <input type="hidden" id="check_pay" value="" /> <textarea id="check_comment" placeholder="Комментарий"></textarea> <a href="#" class="bttn">Отправить</a> <div class="notifications"> </div> </form> </div> <script type="text/javascript" src="{{'jquery.maskedinput.js'| asset_url}}"></script> <script type="text/javascript" src="https://cdn.rawgit.com/jashkenas/coffeescript/master/extras/coffee-script.js"></script> <script type="text/coffeescript"> </script> <style> .form_shadow { position: fixed; width: 100%; height: 100%; background: rgba(0,0,0,0.4); display: none; z-index: 9998; top: 0px; left: 0px; } .closemsg { float: right; margin-top: -5px; font-size: 18px; } .checkoutmsg { position: fixed; top: 40%; left: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); z-index: 9999; display: none; background-color: #fff; padding: 25px; } .checkoutmsg .contact .h3 { font-size: 18px; line-height: 30px; color: #4D3535; text-transform: uppercase; margin-bottom: 10px; } .checkoutmsg .contact input, .contact button, .contact select, .contact textarea { padding: 6px; border: 1px solid #e9e9e9; color: #2e3a47; outline: none; } .checkoutmsg .contact input[type="text"], .contact input[type="email"], .contact input[type="number"], .contact textarea { padding: 7px; margin-left: 0px; margin-right: 0px; -webkit-border-radius: 0px; -moz-border-radius: 0px; -ms-border-radius: 0px; -o-border-radius: 0px; border-radius: 0px; appearance: none; -moz-appearance: none; -ms-appearance: none; -o-appearance: none; -webkit-appearance: none; -webkit-transition: all 0.15s linear 0s; transition: all 0.15s linear 0s; height: 40px; float: left; width: 100%; font-size: 15px; line-height: 40px; margin-bottom: 10px; } .checkoutmsg .contact .bttn { display: inline-block; margin-bottom: 0; text-align: center; vertical-align: middle; cursor: pointer; background-image: none; border: 1px solid transparent; white-space: nowrap; line-height: 1.428571429; border-radius: 4px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; text-align: center; background-color: #4D3535; color: #FFFFFF; padding: 5px 20px; font-size: 12px; font-weight: 300; -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; width: auto; text-transform: uppercase; -webkit-transition: background-color 400ms linear; transition: background-color 400ms linear; height: auto; text-decoration: none !important; } .checkoutmsg .contact .bttn:hover { background: #de5648; } .checkoutmsg .contact .notifications { text-align: left; width: 400px; font-style: italic; color: red; margin-top: 10px; } .checkoutmsg .contact textarea { height: 100px; }<span id="selection-marker-1" class="redactor-selection-marker"></span> </style>
Видимые поля формы это имя, телефон, почта и комментарий. Также в скрытых полях в форме содержатся необходимые для оформления заказа id варианта товара, способ доставки и оплаты.
Механика формы
Напишем механизмы показа и срытия формы, а также вспомогательные функции для валидации телефона и почты
$ -> $("input[name='feedback[phone]']").mask '+7 (999) 999-9999' validateEmail = (email) -> re = /\S+@\S+\.\S+/ re.test email hideForm = (e) -> e.preventDefault(); $('.form_shadow').fadeOut() $('.recallmsg').hide() $('.recall_link').on 'click', (e) -> e.preventDefault(); $('.form_shadow').fadeIn() $('.recallmsg').show() $('.form_shadow').on 'click', (e) -> console.log 1 hideForm e $('.recallmsg .closemsg').on 'click', (e) -> hideForm e
Формирование заказа
По клику на кнопку “Отправить”, происходит проверка полей форм с классом .required на наличие в них какой-либо информации, а также проверка почты на наличие характерной структуры.
$('.checkoutmsg').find('.bttn').on 'click', (e) -> e.preventDefault() is_error = false r = $(@).parent('form.contact') note = r.find('.notifications') r.find("input.required, textarea.required").each -> if @value == @defaultValue is_error = true $(@).css 'background', 'rgba(255, 0, 0, 0.2)' console.log $(@) else $(@).css 'background', '#fff' email = r.find("#check_mail") if validateEmail email.val() email.css 'background', '#fff' else email.css 'background','rgba(255, 0, 0, 0.2)' is_error = true if is_error note.html 'Не все поля заполнены правильно!' note.css 'color','red' return
Далее, двумя последовательными запросами, сначала товар добавляется в корзину, а затем автоматически оформляется заказ. В случае успеха происходит редирект на страницу заказа.
name = $('#check_name').val() phone = $('#check_phone').val() mail = $('#check_mail').val() variant = $('#check_var').val() delivery = $('#check_del').val() payment = $('#check_pay').val() comment = $('#check_comment').val() $.ajax url: '/cart_items.json' type: 'post' data: "_method=put&cart[quantity][#{variant}]=1" success: -> $.ajax url: '/fast_checkout.json' type: 'post' data: "pid_value=1&client[name]=#{ name }&order[comment]=#{ comment }&client[email]=#{ mail }&client[phone]=#{ phone }&order[delivery_variant_id]=#{ delivery }&order[payment_gateway_id]=#{ payment }" dataType: 'json' success: (response) -> location.href = response.location if response.status is 'ok'
Результат
Теперь все работает и форма внешне выглядит так:
Полный итоговый код сниппета:
<div class="form_shadow"> </div> <div class="checkoutmsg"> <a class="closemsg" href="#">×</a> <form id="fast_checkout" class="contact" action="/cart_items" method="post" role="form"> <div class="h3">Быстрый заказ</div> <input type="text" id="check_name" value="" class="required" placeholder="Имя" /> <input type="text" id="check_phone" value="" class="required" placeholder="Телефон" /> <input type="text" id="check_mail" class="required" placeholder="E-mail" /> <input type="hidden" id="check_var" value="" /> <input type="hidden" id="check_del" value="" /> <input type="hidden" id="check_pay" value="" /> <textarea id="check_comment" placeholder="Комментарий"></textarea> <a href="#" class="bttn">Отправить</a> <div class="notifications"> </div> </form> </div> <script type="text/javascript" src="{{'jquery.maskedinput.js'| asset_url}}"></script> <script type="text/javascript" src="https://cdn.rawgit.com/jashkenas/coffeescript/master/extras/coffee-script.js"></script> <script type="text/coffeescript"> $ -> $("#check_phone").mask '+7 (999) 999-9999' validateEmail = (email) -> re = /\S+@\S+\.\S+/ re.test email hideForm = (e) -> e.preventDefault(); $('.form_shadow').fadeOut() $('.checkoutmsg').hide() $('.fast_check').on 'click', (e) -> e.preventDefault(); $('.form_shadow').fadeIn() $('.checkoutmsg').show() $('.form_shadow').on 'click', (e) -> hideForm e $('.checkoutmsg .closemsg').on 'click', (e) -> hideForm e $('.checkoutmsg').find('.bttn').on 'click', (e) -> e.preventDefault() is_error = false r = $(@).parent('form.contact') note = r.find('.notifications') r.find("input.required, textarea.required").each -> if @value == @defaultValue is_error = true $(@).css 'background', 'rgba(255, 0, 0, 0.2)' console.log $(@) else $(@).css 'background', '#fff' email = r.find("#check_mail") if validateEmail email.val() email.css 'background', '#fff' else email.css 'background','rgba(255, 0, 0, 0.2)' is_error = true if is_error note.html 'Не все поля заполнены правильно!' note.css 'color','red' return name = $('#check_name').val() phone = $('#check_phone').val() mail = $('#check_mail').val() variant = $('#check_var').val() delivery = $('#check_del').val() payment = $('#check_pay').val() comment = $('#check_comment').val() $.ajax url: '/cart_items.json' type: 'post' data: "_method=put&cart[quantity][#{variant}]=1" success: -> $.ajax url: '/fast_checkout.json' type: 'post' data: "pid_value=1&client[name]=#{ name }&order[comment]=#{ comment }&client[email]=#{ mail }&client[phone]=#{ phone }&order[delivery_variant_id]=#{ delivery }&order[payment_gateway_id]=#{ payment }" dataType: 'json' success: (response) -> location.href = response.location if response.status is 'ok' </script> <style> .form_shadow { position: fixed; width: 100%; height: 100%; background: rgba(0,0,0,0.4); display: none; z-index: 9998; top: 0px; left: 0px; } .closemsg { float: right; margin-top: -5px; font-size: 18px; } .checkoutmsg { position: fixed; top: 40%; left: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); z-index: 9999; display: none; background-color: #fff; padding: 25px; } .checkoutmsg .contact .h3 { font-size: 18px; line-height: 30px; color: #4D3535; text-transform: uppercase; margin-bottom: 10px; } .checkoutmsg .contact input, .contact button, .contact select, .contact textarea { padding: 6px; border: 1px solid #e9e9e9; color: #2e3a47; outline: none; } .checkoutmsg .contact input[type="text"], .contact input[type="email"], .contact input[type="number"], .contact textarea { padding: 7px; margin-left: 0px; margin-right: 0px; -webkit-border-radius: 0px; -moz-border-radius: 0px; -ms-border-radius: 0px; -o-border-radius: 0px; border-radius: 0px; appearance: none; -moz-appearance: none; -ms-appearance: none; -o-appearance: none; -webkit-appearance: none; -webkit-transition: all 0.15s linear 0s; transition: all 0.15s linear 0s; height: 40px; float: left; width: 100%; font-size: 15px; line-height: 40px; margin-bottom: 10px; } .checkoutmsg .contact .bttn { display: inline-block; margin-bottom: 0; text-align: center; vertical-align: middle; cursor: pointer; background-image: none; border: 1px solid transparent; white-space: nowrap; line-height: 1.428571429; border-radius: 4px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; text-align: center; background-color: #4D3535; color: #FFFFFF; padding: 5px 20px; font-size: 12px; font-weight: 300; -webkit-border-radius: 3px; -moz-border-radius: 3px; -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; width: auto; text-transform: uppercase; -webkit-transition: background-color 400ms linear; transition: background-color 400ms linear; height: auto; text-decoration: none !important; } .checkoutmsg .contact .bttn:hover { background: #de5648; } .checkoutmsg .contact .notifications { text-align: left; width: 400px; font-style: italic; color: red; margin-top: 10px; } .checkoutmsg .contact textarea { height: 100px; } </style>
Итог
Для окончательного результата возможно скомпилировать CoffeeScript в Javascript. Будет быстрее работать и грузиться, однако загрузка формы происходит в самом конце, а сам скрипт начинает работать только по клику. К тому же, при компиляции будет сложнее впоследствии редактировать код, что для такого скрипта может понадобиться. Тем не менее вот полный код сниппета на JS:
