Записи с меткой "Формы"
CSS3-трансформации
Модель визуального форматирования CSS описывает систему координат внутри каждого позиционированного элемента. Система координат является точкой отсчета для свойств смещения. Положение и размеры в этом координатном пространстве можно рассматривать как заданные в пикселях, относительно точки отсчета, с положительными значениями, идущими вправо и вниз. Это координатное пространство можно изменить с помощью свойства transform.
CSS3-трансформации позволяют сдвигать, поворачивать и масштабировать элементы. Трансформации преобразовывают элемент, не затрагивая остальные элементы веб-страницы, т.е. другие элементы не сдвигаются относительно него.
В HTML трансформируемый элемент это: элемент с display: block; и display: inline-block;, а также элементы, значение свойства displayкоторых вычисляется как table-row, table-row-group, table-header-group, table-footer-group, table-cell или table-caption.
Трансформированным считается элемент с любым установленным значением свойства transform, отличным от none.
В SVG трансформируемый элемент — это элемент, который имеет атрибуты transform, patternTransform или gradientTransform.
Существуют два вида CSS3-трансформаций – 2Dи 3D. 2D-трансформации преобразовывают элементы в двумерном пространстве c помощью 2D-матрицы преобразований. Эта матрица применяется для вычисления новых координат объекта, на основе значений свойств transformи transform-origin. Преобразования влияют только на визуальный рендеринг. В отношении макета страницы они могут отразиться на переполнении содержимого блока. По умолчанию точка трансформации находится в центре элемента.
2D-трансформации элементов
1. Функции 2D-трансформации: свойство transform
Свойство transform задаёт вид преобразования элемента. Свойство описывается с помощью функций трансформации, которые смещают элемент относительно его текущего положения на странице или изменяют его первоначальные размеры и форму.
Свойство не наследуется.
|
Функция |
Описание |
|---|---|
|
none |
Значение по умолчанию, означает отсутствие трансформации. Также отменяет трансформацию для элемента из группы трансформируемых элементов. |
|
matrix(a, c, b, d, x, y) |
Смещает элементы и задает способ их трансформации, позволяя объединить несколько функций 2D-трансформаций в одной. В качестве трансформации допустимы поворот, масштабирование, наклон и изменение положения. Значение aизменяет масштаб по горизонтали. Значение от 0 до 1 уменьшает элемент, больше 1 — увеличивает. Значение cдеформирует (сдвигает) стороны элемента по оси Y, положительное значение — вверх, отрицательное — вниз. Значение bдеформирует (сдвигает) стороны элемента по оси X, положительное значение — влево, отрицательное — вправо. Значение dизменяет масштаб по вертикали. Значение меньше 1 уменьшает элемент, больше 1 — увеличивает. Значение xсмещает элемент по оси X, положительное — вправо, отрицательное — влево. Значение yсмещает элемент по оси Y, положительное значение — вниз, отрицательное — вверх. |
|
translate(x,y) |
Сдвигает элемент на новое место, перемещая относительно обычного положения вправо и вниз, используя координаты X и Y, не затрагивая при этом соседние элементы. Если нужно сдвинуть элемент влево или вверх, то нужно использовать отрицательные значения. |
|
translateX(n) |
Сдвигает элемент относительно его обычного положения по оси X. |
|
translateY(n) |
Сдвигает элемент относительно его обычного положения по оси Y. |
|
scale(x,y) |
Масштабирует элементы, делая их больше или меньше. Значения от 0 до 1 уменьшают элемент. Первое значение масштабирует элемент по ширине, второе — по высоте. Отрицательные значения отображают элемент зеркально. |
|
scaleX(n) |
Функция масштабирует элемент по ширине, делая его шире или уже. Если значение больше единицы, элемент становится шире, если значение находится между единицей и нулем, элемент становится уже. Отрицательные значения отображают элемент зеркально по горизонтали. |
|
scaleY(n) |
Функция масштабирует элемент по высоте, делая его выше или ниже. Если значение больше единицы, элемент становится выше, если значение находится между единицей и нулем — ниже. Отрицательные значения отображают элемент зеркально по вертикали. |
|
rotate(угол) |
Поворачивает элементы на заданное количество градусов, отрицательные значения от -1degдо -360degповорачивают элемент против часовой стрелки, положительные — по часовой стрелке. Значение rotate(720deg)поворачивает элемент на два полных оборота. |
|
skew(x-угол,y-угол) |
Используется для деформирования (искажения) сторон элемента относительно координатных осей. Если указано одно значение, второе будет определено браузером автоматически. |
|
skewX(угол) |
Деформирует стороны элемента относительно оси X. |
|
skewY(угол) |
Деформирует стороны элемента относительно оси Y. |
|
initial |
Устанавливает значение свойства в значение по умолчанию. |
|
inherit |
Наследует значение свойства от родительского элемента. |
Допустимые значения:
matrix()— любое число
translate(), translateX(), translateY()— единицы длины (положительные и отрицательные), %
scale(), scaleX(), scaleY()— любое число
rotate()— угол (deg, grad, radили turn)
skew(), skewX(), skewY()— угол (deg, grad, rad)
Можно объединить несколько трансформаций одного элемента, перечислив их через пробел в порядке проявления.
Синтаксис
transform: none;
transform: matrix(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
transform: rotate(45deg);
transform: translate(12px, 50%);
transform: translateX(2em);
transform: translateY(3in);
transform: scale(2, 0.5);
transform: scaleX(2);
transform: scaleY(0.5);
transform: skew(30deg, 20deg);
transform: skewX(30deg);
transform: skewY(1.07rad);
transform: translateX(10px) rotate(10deg) translateY(5px);
transform: inherit;
transform: initial;
2. Точка трансформации: свойство transform-origin
Свойство transform-origin позволяет сместить центр трансформации, относительно которого происходит изменение положения/размера/формы элемента. Значение по умолчанию — center, или 50% 50%. Задаётся только для трансформированных элементов.
Свойство не наследуется.
transform-origin
Значения:
ось Х(left, center, right, длина, %)
ось Y(top, center, bottom, длина, %)
Пара значений, заданная с помощью ключевых слов, единиц длины или процентов определяет, относительно какой части элемента будет происходить трансформация. Значения больше 100% увеличивают область трансформации элемента.
initial
Устанавливает значение свойства в значение по умолчанию.
inherit
Наследует значение свойства от родительского элемента.
Синтаксис
transform-origin: 2px;
transform-origin: bottom;
transform-origin: 3cm 2px;
transform-origin: left 2px;
transform-origin: right top;
transform-origin: inherit;
transform-origin: initial;
3. Область преобразования: свойство transform-box
Все преобразования, определяемые свойством transform и transform-origin, относятся к положению и размерам опорного блока элемента. Опорный блок элемента это виртуальный прямоугольник вокруг элемента, который формирует систему координат для отрисовки.
В некоторых браузерах опорный блок принимает центр SVG-холста в качестве точки преобразования. Чтобы решить эту проблему, можно задать для элемента transform-box.
Опорный блок добавляет дополнительное смещение к исходной точке, заданной свойством transform-origin.
Свойство не наследуется.
transform-box
Значения:
content-box
В качестве опорного блока выступает область содержимого элемента. Для элемента <table>эта область включает также заголовок таблицы и рамку.
border-box
В качестве опорного блока выступает область рамки элемента. Для элемента <table>эта область включает также заголовок таблицы и рамку.
fill-box
В качестве опорного блока выступает ограничивающая рамка, содержащая только геометрическую форму элемента.
stroke-box
В качестве опорного блока выступает ограничивающая рамка, содержащая геометрическую форму и обводку элемента.
view-box
В качестве опорного блока используется область просмотра на SVG-холсте, которая определяет прямоугольную область, в которую отображается содержимое SVG.
initial
Устанавливает значение свойства в значение по умолчанию.
inherit
Наследует значение свойства от родительского элемента.
Синтаксис
transform-box: content-box;
transform-box: border-box;
transform-box: fill-box;
transform-box: stroke-box;
transform-box: view-box;
transform-box: inherit;
transform-box: initial;jQuery Masked Input Plugin. Маска ввода для HTML элемента input
Для HostCMS
Подключаем в шапке сайта ->js('/bootstrap/js/jquery.maskedinput.min.js')
Назначение плагина masked input
-
<!-- Подключение библиотеки jQuery --> <script src="jquery.js"></script> <!-- Подключение jQuery плагина Masked Input --> <script src="jquery.maskedinput.min.js"></script>
Создание HTML маски ввода
-
Цифра 9 – соответствует цифре от 0 до 9.
-
Символ a – представляет собой любой английский символ (A-Z, a-z).
-
Знак * - представляет собой любой алфавитно-цифровой символ (A-Z, a-z, 0-9).
id="phone":<input id="phone" type="text">
<script>
//Код jQuery, установливающий маску для ввода телефона элементу input
//1. После загрузки страницы, когда все элементы будут доступны выполнить...
$(function(){
//2. Получить элемент, к которому необходимо добавить маску
$("#phone").mask("8(999) 999-9999");
});
</script>
Пример 1: 8(945) 64_-_____
<!--HTML элемент, который будет иметь заполнитель дд.мм.гггг -->
<input id="date" type="text">
<!--HTML элемент, который будет иметь в качестве заполнителя пробел -->
<input id="index" type="text">
<script>
$(function() {
//задание заполнителя с помощью параметра placeholder
$("#date").mask("99.99.9999", {placeholder: "дд.мм.гггг" });
//задание заполнителя с помощью параметра placeholder
$("#index").mask("999999", {placeholder: " " });
});
</script>
Пример 2: 15.мм.гггг
<!-- Ввод номера телефона осуществляется с помощью маски -->
<input id="phone" type="text">
<script>
$(function(){
//Использование параметра completed
$("#phone").mask("8(999) 999-9999", {
completed: function(){ alert("Вы ввели номер: " + this.val()); }
});
});
</script>
Пример 3: 6(945) 343-7667Подтвердите действие на sites.ruВы ввели номер: 6(945) 343-7667
<!-- Ввод номера телефона осуществляется с помощью маски -->
<input id="number" type="text">
<script>
jQuery(function($){
//создания своего специального символа для маски
$("#number").mask("0.9?9");
});
</script>
Пример 4: 0.2
Настройка маски ввода Masked Input
<!-- HTML элемент, имеющий маску телефона -->
<input id="number" type="text">
<script>
jQuery(function($){
//создания специального символа для маски
$.mask.definitions['~']='[+-]';
$("#number).mask("~9.99");
});
</script>
Пример 5: -5.3
<!-- HTML элемент, имеющий маску для ввода цвета в шестнадцатиричном формате -->
<input id="color" type="text">
<script>
jQuery(function($){
//создания специального символа h для маски
$.mask.definitions['h']='[A-Fa-f0-9]';
$("#color).mask("#hhhhhh");
});
</script>
Пример 6: #675a_
Пример создания маски ввода телефона
<div class="form-group">
<label for="phone">Телефон: </label>
<select id="country" class="form-control">
<option value="ru"><img src="">Россия +7</option>
<option value="ua">Украина +380</option>
<option value="by">Белоруссия +375</option>
</select>
<input id="phone" type="text" class="form-control">
</div>
<script>
jQuery (function ($) {
$(function() {
function maskPhone() {
var country = $('#country option:selected').val();
switch (country) {
case "ru":
$("#phone").mask("+7(999) 999-99-99");
break;
case "ua":
$("#phone").mask("+380(999) 999-99-99");
break;
case "by":
$("#phone").mask("+375(999) 999-99-99");
break;
}
}
maskPhone();
$('#country').change(function() {
maskPhone();
});
});
});
</script>
Пример 7Телефон:Белоруссия +375 +375(777) 6__--
JavaScript / jQuery . jquery.maskedinput.min.js
/*
jQuery Masked Input Plugin
Copyright (c) 2007 - 2015 Josh Bush (digitalbush.com)
Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
Version: 1.4.1
*/
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b,c=navigator.userAgent,d=/iphone/i.test(c),e=/chrome/i.test(c),f=/android/i.test(c);a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},autoclear:!0,dataName:"rawMaskFn",placeholder:"_"},a.fn.extend({caret:function(a,b){var c;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof a?(b="number"==typeof b?b:a,this.each(function(){this.setSelectionRange?this.setSelectionRange(a,b):this.createTextRange&&(c=this.createTextRange(),c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select())})):(this[0].setSelectionRange?(a=this[0].selectionStart,b=this[0].selectionEnd):document.selection&&document.selection.createRange&&(c=document.selection.createRange(),a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length),{begin:a,end:b})},unmask:function(){return this.trigger("unmask")},mask:function(c,g){var h,i,j,k,l,m,n,o;if(!c&&this.length>0){h=a(this[0]);var p=h.data(a.mask.dataName);return p?p():void 0}return g=a.extend({autoclear:a.mask.autoclear,placeholder:a.mask.placeholder,completed:null},g),i=a.mask.definitions,j=[],k=n=c.length,l=null,a.each(c.split(""),function(a,b){"?"==b?(n--,k=a):i[b]?(j.push(new RegExp(i[b])),null===l&&(l=j.length-1),k>a&&(m=j.length-1)):j.push(null)}),this.trigger("unmask").each(function(){function h(){if(g.completed){for(var a=l;m>=a;a++)if(j[a]&&C[a]===p(a))return;g.completed.call(B)}}function p(a){return g.placeholder.charAt(a<g.placeholder.length?a:0)}function q(a){for(;++a<n&&!j[a];);return a}function r(a){for(;--a>=0&&!j[a];);return a}function s(a,b){var c,d;if(!(0>a)){for(c=a,d=q(b);n>c;c++)if(j[c]){if(!(n>d&&j[c].test(C[d])))break;C[c]=C[d],C[d]=p(d),d=q(d)}z(),B.caret(Math.max(l,a))}}function t(a){var b,c,d,e;for(b=a,c=p(a);n>b;b++)if(j[b]){if(d=q(b),e=C[b],C[b]=c,!(n>d&&j[d].test(e)))break;c=e}}function u(){var a=B.val(),b=B.caret();if(o&&o.length&&o.length>a.length){for(A(!0);b.begin>0&&!j[b.begin-1];)b.begin--;if(0===b.begin)for(;b.begin<l&&!j[b.begin];)b.begin++;B.caret(b.begin,b.begin)}else{for(A(!0);b.begin<n&&!j[b.begin];)b.begin++;B.caret(b.begin,b.begin)}h()}function v(){A(),B.val()!=E&&B.change()}function w(a){if(!B.prop("readonly")){var b,c,e,f=a.which||a.keyCode;o=B.val(),8===f||46===f||d&&127===f?(b=B.caret(),c=b.begin,e=b.end,e-c===0&&(c=46!==f?r(c):e=q(c-1),e=46===f?q(e):e),y(c,e),s(c,e-1),a.preventDefault()):13===f?v.call(this,a):27===f&&(B.val(E),B.caret(0,A()),a.preventDefault())}}function x(b){if(!B.prop("readonly")){var c,d,e,g=b.which||b.keyCode,i=B.caret();if(!(b.ctrlKey||b.altKey||b.metaKey||32>g)&&g&&13!==g){if(i.end-i.begin!==0&&(y(i.begin,i.end),s(i.begin,i.end-1)),c=q(i.begin-1),n>c&&(d=String.fromCharCode(g),j[c].test(d))){if(t(c),C[c]=d,z(),e=q(c),f){var k=function(){a.proxy(a.fn.caret,B,e)()};setTimeout(k,0)}else B.caret(e);i.begin<=m&&h()}b.preventDefault()}}}function y(a,b){var c;for(c=a;b>c&&n>c;c++)j[c]&&(C[c]=p(c))}function z(){B.val(C.join(""))}function A(a){var b,c,d,e=B.val(),f=-1;for(b=0,d=0;n>b;b++)if(j[b]){for(C[b]=p(b);d++<e.length;)if(c=e.charAt(d-1),j[b].test(c)){C[b]=c,f=b;break}if(d>e.length){y(b+1,n);break}}else C[b]===e.charAt(d)&&d++,k>b&&(f=b);return a?z():k>f+1?g.autoclear||C.join("")===D?(B.val()&&B.val(""),y(0,n)):z():(z(),B.val(B.val().substring(0,f+1))),k?b:l}var B=a(this),C=a.map(c.split(""),function(a,b){return"?"!=a?i[a]?p(b):a:void 0}),D=C.join(""),E=B.val();B.data(a.mask.dataName,function(){return a.map(C,function(a,b){return j[b]&&a!=p(b)?a:null}).join("")}),B.one("unmask",function(){B.off(".mask").removeData(a.mask.dataName)}).on("focus.mask",function(){if(!B.prop("readonly")){clearTimeout(b);var a;E=B.val(),a=A(),b=setTimeout(function(){B.get(0)===document.activeElement&&(z(),a==c.replace("?","").length?B.caret(0,a):B.caret(a))},10)}}).on("blur.mask",v).on("keydown.mask",w).on("keypress.mask",x).on("input.mask paste.mask",function(){B.prop("readonly")||setTimeout(function(){var a=A(!0);B.caret(a),h()},0)}),e&&f&&B.off("input.mask").on("input.mask",u),A()})}})});
Загрузка изображений через форму
Показываем превью загружаемых изображений
<label for="fileUpload" class="download-file">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="25px" height="21px" version="1.1" viewBox="0 0 6.01 5.01"><path style="fill:#764E2B" d="M6.01 5.01l-6.01 0 0 -5.01 6.01 0 0 5.01 0 0zm-0.25 -4.76l-5.51 0 0 4.5 5.51 0 0 -4.5 0 0zm-0.25 4l-4.76 0 1 -1.87 0.75 0.76 1.26 -1.89 1.75 3zm-2.97 -0.71l-0.73 -0.74 -0.64 1.2 3.9 0 -1.33 -2.28 -1.2 1.82zm-1.16 -2.79c0.34,0 0.62,0.28 0.62,0.63 0,0.34 -0.28,0.62 -0.62,0.62 -0.35,0 -0.63,-0.28 -0.63,-0.62 0,-0.35 0.28,-0.63 0.63,-0.63zm0 0.25c0.2,0 0.37,0.17 0.37,0.38 0,0.2 -0.17,0.37 -0.37,0.37 -0.21,0 -0.38,-0.17 -0.38,-0.37 0,-0.21 0.17,-0.38 0.38,-0.38z"></path></svg>
<span class="download-file-text ps-2">Выберите несколько фото</span>
</label>
<input class="photo" type="file" name="files[]" value="" size="30" placeholder="Загрузить фото" multiple="true" accept="image" id="fileUpload" accepts=".jpg, .jpeg, .png, .webp">
<div id="image-holder" class="d-flex flex-wrap"></div>
JS для размещения в XSL-шаблон HOSTCMS
<SCRIPT>
<xsl:comment>
<xsl:text disable-output-escaping="yes">
<![CDATA[
$(function() {
$("#fileUpload").on('change', function () {
//Get count of selected files
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var image_holder = $("#image-holder");
image_holder.empty();
if (extn == "png" || extn == "jpg" || extn == "jpeg" || extn == "webp") {
if (typeof (FileReader) != "undefined") {
//loop for each file selected for uploaded.
for (var i = 0; i < countFiles; i++) {
var reader = new FileReader();
reader.onload = function (e) {
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(image_holder);
}
image_holder.show();
reader.readAsDataURL($(this)[0].files[i]);
}
} else {
alert("Ваш брузер не поддерживает FileReader!");
}
} else {
alert("Выберите файл в формате JPG, JPEG, PNG или WEBP!");
}
});
});
]]>
</xsl:text>
</xsl:comment>
</SCRIPT>
Добавляем поле загрузки файла (новое поле создается после загрузки изображения)
<SCRIPT>
function addOneMoreInput() {
$('input[type=file]').last().change(function() {
$(this).after('<input type="file" name="files[]" />');
$(this).off('change');
addOneMoreInput();
});
}
addOneMoreInput();
</SCRIPT>
Стили CSS
Загрузка формы на страницу с помощью AJAX
<button
class="btn btn-secondary btn-xl"
type="button"
onclick="
return
$.openForm('/zayavka/', 18 // здесь меняем ID формы
)"
>Заполнить заявку</button>
PHP . Код настроек ТДС "Отображение формы"
XSL . Шаблон "ОтобразитьФормуЗаявкаВМодальномОкне" с отправкой изображений
<!ENTITY labelModalTitle1 "Благодарим вас за заявку!">
<!ENTITY labelModalTitle2 "Заявка получена.">
<!ENTITY labelSuccessText "Мы свяжемся с вами в ближайшее время">
<!ENTITY labelSuccessText2 "Наш менеджер ответит на все ваши вопросы">
<!ENTITY labelERROR "ОШИБКА!">
<!ENTITY labelTextErrorId0 "Вы неправильно ввели код подтверждения отправки формы!">
<!ENTITY labelTextErrorId1 "Заполните все обязательные поля!">
<!ENTITY labelTextErrorId2 "С момента отправки последней формы прошло слишком мало времени!">
<!ENTITY labelTextError1 "Это поле пустое">
<!ENTITY labelTextError2 "E-mail должен иметь вид name@domain.com">
<!ENTITY labelText1 "Обязательное поле">
<!ENTITY labelCheckNumber1 "Проверочный код">
<!ENTITY labelCheckNumber2 "показать другой код">
JavaScript / jQuery . Размещаем в макете сайта. Из XSL шаблонов валидацию форм убрать
Загрузка формы на страницу с помощью AJAX для редакции HostCMS Старт
<button
type="button"
class="btn btn-transparent btn-lg"
onclick="return $.openForm('/zayavka/', 'Вопрос на тему - Ремонт и выкуп элитных швейцарских часов в Москве')"
tabindex="0">Задать вопрос
</button>
/mform, обработчик отправки формы (в также него добавлена возможность отправки вложенных файлов) send-zakaz.php<?php
$to = "info@test.com";
$email = "zayavka@test.com";
if ( isset( $_POST['phone'] ) ) {
$username= substr( $_POST['username'], 0, 40 );
$phone = substr( $_POST['phone'], 0, 15 );
$thema = substr( $_POST['thema'], 0, 250);
$mess = substr( $_POST['mess'], 0, 250);
$body = "Имя: ".$username."\r\n";
$body .= "Телефон: ".$phone."\r\n";
$body .= "Тема: ".$thema."\r\n\r\n";
$body .= "Сообщение: ".$mess."\r\n\r\n";
send_mail($to, $body, $email);
}
// Вспомогательная функция для отправки почтового сообщения с вложением
function send_mail($to, $body, $email)
{
$subject = 'Пользователь сайта test.com заполнил форму Заявки';
$boundary = "--".md5(uniqid(time())); // генерируем разделитель
$headers .= "From: ".$email."\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .="Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
$multipart = "--".$boundary."\r\n";
$multipart .= "Content-type: text/plain; charset=\"utf-8\"\r\n";
$multipart .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
$body = $body."\r\n\r\n";
$multipart .= $body;
mail($to, $subject, $multipart, $headers);
}
?>
В Основном макете, в самом низу, добавляем код модального окна, в которое будет загружаться наша форма
<div class="modal fade" id="applicationModal" tabindex="-1" aria-labelledby="applicationModalLabel" aria-modal="true" role="dialog">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header justify-content-center">
<div class="h4 m-0 modal-title" id="applicationModalLabel">Заявка</div>
<button class="btn-close" type="button" data-bs-dismiss="modal"></button>
</div>
<div id="modalContent" class="modal-body"></div>
</div>
</div>
</div>PHP . В поле "Динамическая страница" вставляем следующий код формы
<div id="formUpload">
<form method="get" id="form2" action="./">
<input type="hidden" name="thema" id="thema_2">
<div class="mb-3">
<input type="text" name="username" class="form-control" maxlength="40" placeholder="Ваше Имя *">
</div>
<div class="mb-3">
<input name="phone" class="form-control" maxlength="15" placeholder="Телефон *" type="text">
</div>
<div class="mb-3">
<textarea name="mess" class="form-control" rows="2" maxlength="300" placeholder="Ваш запрос *" type="text"></textarea>
</div>
<p>Можете приложить несколько фото высокого разрешения в разных ракурсах</p>
<div id="image-holder_2" class="d-flex flex-wrap"></div>
<div class="row">
<div class="col-12 col-sm-6">
<input class="file-upload d-none" type="file" name="files[]" value="" placeholder="Загрузить фото" multiple="true" accept="image" id="fileUpload_2" data-id="2" accepts=".jpg, .jpeg, .png, .webp">
<label for="fileUpload_2" class="download-file btn btn-transparent primary">Добавить фото</label>
</div>
<div class="col-12 col-sm-6 text-end">
<button type="submit" id="submit_2" autocomplete="off" class="btn btn-transparent btn-lg primary" disabled>Отправить заявку</button>
</div>
</div>
<div class="mt-4">
<div class="form-check">
<input id="checkbox_2" class="form-check-input" type="checkbox" name="checkbox" onchange="document.getElementById('submit_2').disabled = !this.checked;">
<label for="checkbox_2" class="form-check-label small">Я соглашаюсь на обработку своих персональных данных в соответствии с <a href="/private/" class="link-border"> Политикой конфиденциальности</a></label>
</div>
</div>
</form>
</div>
JavaScript / jQuery . Размещаем в макете сайта во вкладке Javascript обработчик AJAX загрузки формы
// Функции без создания коллекции
$.extend({
// Загрузка форм заявок на ajax с валидацией
openForm: function(path, form_title) {
$("#modalContent").load(path + " #formUpload", function(response){
// Если ответ не пустой, открываем модальное окно
if (response) {
$('#applicationModal').modal('show').appendTo('body');
$('#thema_2').text(form_title);
$('#form2').validate({
rules: {
phone: "required",
mess: "required"
},
messages: {
mess: "Заполните это поле",
phone: "Заполните это поле"
},
focusInvalid: true,
errorClass: "input_error",
submitHandler: function(form){
var form = document.forms.form2,
formData = new FormData(form),
xhr = new XMLHttpRequest();
xhr.open("POST", "/mform/send-zakaz.php");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if(xhr.status == 200) {
$("#form2").html('<p style="text-align:center">Ваша Заявка отправлена!<p>');
setTimeout(function(){
location.reload();
}, 1000);
}
}
};
xhr.send(formData);
}
});
$("#fileUpload_2").on('change', function () {
//Get count of selected files
var dataID = $(this).data('id');
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var image_holder = $("#image-holder_" + dataID);
console.log(dataID);
image_holder.empty();
if (extn == "png" || extn == "jpg" || extn == "jpeg" || extn == "webp") {
if (typeof (FileReader) != "undefined") {
//loop for each file selected for uploaded.
for (var i = 0; i < countFiles; i++) {
var reader = new FileReader();
reader.onload = function (e) {
$("<img />", {
"src": e.target.result,
"class": "thumb-image"
}).appendTo(image_holder);
}
image_holder.show();
reader.readAsDataURL($(this)[0].files[i]);
}
} else {
alert("Ваш брузер не поддерживает FileReader!");
}
} else {
alert("Выберите файл в формате JPG, JPEG, PNG или WEBP!");
}
});
}
});
},
............. остальной код
}
Информационный блок в карточке товара
Добавляем в карточку товара блок с призывом задать вопрос

1. В XSL шаблон вывода карточки товара в нужном месте размещаем данный код:
<div class="ask-question">
<div class="d-flex justify-content-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="40px" height="40px">
<path style="fill:#ccc" d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 7.1 5.8 12 12 12 2.4 0 4.9-.7 7.1-2.4L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zm32 352c0 17.6-14.4 32-32 32H293.3l-8.5 6.4L192 460v-76H64c-17.6 0-32-14.4-32-32V64c0-17.6 14.4-32 32-32h384c17.6 0 32 14.4 32 32v288zm-224-88c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm-8.5-24h17c4.2 0 7.7-3.3 8-7.5l7-112c.3-4.6-3.4-8.5-8-8.5h-31c-4.6 0-8.3 3.9-8 8.5l7 112c.3 4.2 3.8 7.5 8 7.5z"></path>
</svg>
<span class="ps-3 fs-4 fw-bold title">Есть вопросы?</span>
</div>
<div class="text">
Если у вас есть вопросы по товару, то задавайте их и мы вам с радостью ответим.
</div>
<div class="last">
<button type="button" id="questionModalOpen" data-bs-toggle="modal" data-bs-target="#questionModal" class="btn btn-transparent">Задать вопрос о товаре</button>
</div>
</div>
2. В макет добавляем код загрузки формы (в примере код формы с отправкой уведомления Пользователю). Форма будет в модальном окне. Нажатие на кнопку "Задать вопрос" вызовет открытие формы.
<?php
// ФОРМА ЗАЯВКИ
$oForm = Core_Entity::factory('Form', 1);
$Form_Controller_Show = new Form_Controller_Show($oForm);
if (!is_null(Core_Array::getPost($oForm->button_name)))
{
$Form_Controller_Show
->values($_POST + $_FILES)
// 0 - html, 1- plain text
->mailType(0)
->mailXsl(
Core_Entity::factory('Xsl')->getByName('ПисьмоКураторуФормыВФорматеHTML')
)
->mailFromFieldName('euronasos19@gmail.com')
->process();
// Отправляем письмо-подтверждение пользователю
$Form_Controller_Show1 = clone $Form_Controller_Show;
$sEmail = Core_Array::get($Form_Controller_Show1->values, 'email'); // здесь указать название поля input для email в форме
if (Core_Valid::email($sEmail)){
ob_start();
$Form_Controller_Show1
->xsl(
Core_Entity::factory('Xsl')->getByName('ПисьмоПодтверждениеПользователюФормыВФорматеHTML')
)
->show();
$sMailText = ob_get_clean();
if (mb_strpos($sMailText, 'ERROR TRUE') === FALSE){
$subject = 'На сайте site.ru Вами была заполнена форма Заявки';// Тему письма отредактировать
$oCore_Mail = Core_Mail::instance()
->to($sEmail)
->from('info@site.ru')
->subject($subject)
->message(trim($sMailText))
->contentType('text/html')
->header('X-HostCMS-Reason', 'Form');
$oCore_Mail->send();
}
}
}
$Form_Controller_Show
->xsl(
Core_Entity::factory('Xsl')->getByName('ОтобразитьФормуЗаявкиВМодальномОкне')
)
->show();
?>
XSL . ФормаЗаявкиВМодальномОкне
<!ENTITY labelModalTitle1 "Благодарим вас за заявку!">
<!ENTITY labelModalTitle2 "Заявка получена.">
<!ENTITY labelSuccessText "Мы свяжемся с вами в ближайшее время">
<!ENTITY labelSuccessText2 "Наш менеджер ответит на все ваши вопросы">
<!ENTITY labelERROR "ОШИБКА!">
<!ENTITY labelTextErrorId0 "Вы неправильно ввели код подтверждения отправки формы!">
<!ENTITY labelTextErrorId1 "Заполните все обязательные поля!">
<!ENTITY labelTextErrorId2 "С момента отправки последней формы прошло слишком мало времени!">
<!ENTITY labelTextError1 "Это поле пустое">
<!ENTITY labelTextError2 "E-mail должен иметь вид name@domain.com">
<!ENTITY labelText1 "Обязательное поле">
<!ENTITY labelCheckNumber1 "Проверочный код">
<!ENTITY labelCheckNumber2 "показать другой код">
Стили CSS
/******************************/
.ask-question {
padding:20px;
background-color: #f0f0f0;
max-width:450px;
text-align: center;
}
.ask-question > div:not(.last) {
margin-bottom:15px;
}
background:
border:
color: #212529;
/******************************/
Использование jQuery Validate для проверки форм
<script>
$(function() {
$(".validate").validate({
focusInvalid: true,
errorClass: "input_error",
onkeyup: false,
onfocusout: false,
rules: {
captcha: {
required: true,
remote: '/forms/'
},
author: "required",
text: "required",
email: {
required: true,
email: true
}
},
messages: {
author: "Пожалуйста, укажите своё Имя!",
text: "Пожалуйста, напишите свой комментарий!",
captcha: "Вы не вписали контрольное число!",
email: {
required: "Введите свой email",
email: "E-mail должен быть в формате name@domain.com"
}
}});
});
</script>
Core_Page::instance()
// jQuery
->js('/hostcmsfiles/jquery/jquery.min.js')
...
// Validate
->js('/hostcmsfiles/jquery/jquery.validate.min.js')
...
->showJs();
Указание валидации формы
<script>
$(".validate").validate();
</script>
Валидация всех форм:
<script>
$("form").validate();
</script>
Способы валидации форм
Использование имена классов как правила
<form action="." method="post" class="validate">
<input type="text" name="name" value="" class="required" />
<input type="submit" value="Submit" />
</form>
<form action="." method="post" class="validate">
<input type="text" name="name" value="" class="name" />
<input type="text" name="zip" value="" class="zip" />
<input type="submit" value="Submit" />
</form>
<script >
$.validator.addClassRules("name", {
required: true,
minlength: 2
});
</script >
<script >
$.validator.addClassRules({
name: {
required: true,
minlength: 2
},
zip: {
required: true,
digits: true,
minlength: 5,
maxlength: 5
}});
</script >
Передача опций при инициализации validate()
<script >
$(".validate").validate({
rules: {
name: "required",
email: {
required: true,
email: true
}
},
messages: {
name: "Please specify your name",
email: {
required: "Введите свой email",
email: "E-mail должен быть в формате name@domain.com"
}
}});
</script >
-
required — поле обязательное для заполнения (true или false);
-
remote — указывается файл для проверки поля (например: "check.php");
-
email — проверяет корректность e-mail адреса (true или false);
-
url — проверяет корректность url адреса (true или false);
-
date — проверка корректности даты (true или false);
-
dateISO — проверка корректности даты ISO (true или false);
-
number — проверка на число (true или false);
-
digits — только цифры (true или false);
-
creditcard — корректность номера кредитной карты (true или false);
-
equalTo — равное чему-то (например другому полю equalTo: "#pswd");
-
accept — проверка на правильное расширение (accept: "xls|csv");
-
maxlength — максимальное кол-во символов;
-
minlength — минимальное кол-во символов;
-
rangelength — кол-во символов от скольких и до скольких (rangelength: [2, 5]);
-
range — число должно быть в диапазоне от и до (range: [2, 12]);
-
max — максимальное значение числа;
-
min — минимальное значение числа.
Пример использования в XSL-шаблоне
<script >
$(".validate").validate({
rules: {
surname: "required",
name: "required",
email: {
required: true,
email: true
}
},
messages: {
surname: "Введите фамилию!",
name: "Введите имя!",
email: {
required: "Введите e-mail!",
email: "Адрес должен быть вида name@domain.com"
}
},
focusInvalid: true,
errorClass: "input_error"
});
</script>
Проверка валидации и заблокированного E-mail нежелательного Пользователя<SCRIPT>
$(document).ready(function() {
$('.select2').addClass('required');
$("#form<xsl:value-of select="@id" />").submit(function (event) {
event.preventDefault();
var eml = $('input[name=email]').val();
if(eml =='svinya.svintus@yandex.ru') {
alert ('Вы не можете отправлять нам письма');
$(location).attr('href', '/');
}else{
$(this).validate({
focusInvalid: true,
errorClass: "input_error"
});
}
});
});
</SCRIPT>
Модальное окно с формой подписки и сохранением куки на jQuery

Добавляем в макет код показа формы:
<?php
// add ФОРМА ПОДПИСКА ЗА СКИДКУ
$oForm = Core_Entity::factory('Form', 49); // заменить ID формы
$Form_Controller_Show = new Form_Controller_Show($oForm);
if (!is_null(Core_Array::getPost($oForm->button_name)))
{
$Form_Controller_Show
->values($_POST + $_FILES)
// 0 - html, 1- plain text
->mailType(0)
->mailXsl(
Core_Entity::factory('Xsl')->getByName('ПисьмоКураторуФормыВФорматеHTML')
)
->mailFromFieldName('email')
->process();
}
$Form_Controller_Show
->xsl(
Core_Entity::factory('Xsl')->getByName('ОтобразитьФормуВМодальномОкне')
)
->show();
?>
Подключаем в макете скрипт jquery.cookie.min.js:
<script src="/js/jquery.cookie.min.js"></script>
Проверяем куки:
<script>
$(document).ready(function($) {
if ($.cookie('was') == null) {
// Покажем всплывающее окно
setTimeout(function(){$('#popupModal').modal('show');}, 36000);
}
// Запомним в куках, что посетитель к нам уже заходил
$.cookie('was', 'value', { expires: 2, path: '/' });
});
</script>JavaScript / jQuery . jquery.cookie.min.js
Отправка формы в новую вкладку браузера
- 1. Отдельная кнопка
- 2. Скрытая форма
Иногда возникает вопрос – как отправить HTML-форму в новую вкладку браузера, например для отдельной страницы, где будет печать введённых данных? Как и у ссылки, у элемента можно применить атрибут target(валидный только в HTML-5), который устанавливает поведение окна, при отправки формы. Возможные значения:
|
_blank
|
Загружает страницу в новое окно браузера
|
|
_self
|
Загружает страницу в текущее окно (значение по умолчанию)
|
|
_parent
|
Загружает страницу во фрейм-родитель, если фреймов нет, то это значение работает как _self
|
|
_top
|
Отменяет все фреймы и загружает страницу в полном окне браузера, если фреймов нет, то это значение работает как _self.
|
Пример:
<form action="" method="post" target="_blank">
<input type="text" name="name">
<input type="text" name="surname">
<button type="submit" name="print">Распечатать</button>
<button type="submit" name="send">Далее</button>
</form>
Минусом является то, что при нажатии любой кнопки type="submit"форма отправится в новую вкладку браузера.
1. Отдельная кнопка
Если требуется разделить события кнопок, то можно добавлять атрибут target="_blank"только при нажатии на кнопку «Распечатать» и после отправки формы его удалять с помощью JQuery.
<form action="" method="post">
<input type="text" name="name">
<input type="text" name="surname">
<button type="button" name="print">Распечатать</button>
<button type="submit" name="send">Далее</button>
</form>
<script>
$(document).ready(function(){
$("input[name='print']").click(function(){
var form = $(this).closest('form');
form.attr('target', '_blank');
form.submit();
form.attr('target', '');
});
return false;
});
</script>
2. Скрытая форма
Следующий вариант поможет, когда нужно отправить форму в новую вкладку и на другой URL. В данном примере все поля основной формы копируются в скрытую.
<form style="display: none;" action="/new.php?print=1" target="_blank" method="post" id="form-print"></form>
<form action="" method="post" id="form-original">
<input type="text" name="name">
<input type="text" name="surname">
<button type="button" name="print">Распечатать</button>
<button type="submit" name="send">Далее</button>
</form>
<script>
$(document).ready(function(){
$("input[name='print']").click(function(){
$('#form-print').html($('#form-original').html());
$('#form-print').submit();
});
return false;
});
</script>Сохраняем в сессии введённые Пользователем данные и подставляем их в поля при перезагрузке страницы
Сохраняем в сессии (sessionStorage) значения, введённые в поля формы, для сохранения их в случае перезагрузки страницы.
JavaScript
// выбираем на странице все элементы типа textarea и input
document.querySelectorAll('textarea, input').forEach(function(e) {
// если данные значения уже записаны в sessionStorage, то вставляем их в поля формы
// путём этого мы как раз берём данные из памяти браузера, если страница была случайно перезагружена
if(e.value === '') e.value = window.sessionStorage.getItem(e.name, e.value);
// на событие ввода данных (включая вставку с помощью мыши) вешаем обработчик
e.addEventListener('input', function() {
// и записываем в sessionStorage данные, в качестве имени используя атрибут name поля элемента ввода
window.sessionStorage.setItem(e.name, e.value);
});
});
Строка поиска <input type="number"> name имя ключа параметра value значение ключа
Строка поиска <input type="number">
|
имя ключа параметра |
|
|
|
заблокировано изменение пользователем |
|
заблокированы доступ, изменение пользователем и передача данных текущего параметра |
|
поле не может быть пустым |
|
|
|
|
|
|
|
подсказка-заглушка |
|
|
|
автозаполнение. Можно его отключить или сделать более конкретизированным. |
|
список рекомендованных значений |
|
|
<form>
<input type="number">
<input type="submit">
</form>
- Поле
<input type="number">не подходит для текстовых строк, состоящих из 16 и более цифр, например, номера пластиковой карты, так как длинные числа от 9007199254740991 могут округляться.
Количество товара
-
увеличение и уменьшение значения числового поля с помощью кнопок пошагового изменения;
-
сообщение об ошибке при вводе букв и дробных чисел;
-
минимальное значение 1 шт.
<form><input type="number" min="1" value="1"> шт</form>
Чётные положительные целые числа
<form><input type="number" step="2" min="2"></form>
Нечётные положительные целые числа
<form><input type="number" step="2" min="1"></form>
Круглые числа
<form><input type="number" step="10"></form>
Десятичная дробь с плавающей запятой
<form><input type="number" step="any"></form>
Денежный формат цены: «рубли,копейки» с двумя знаками после запятой ₽
<form><input type="number" step="0.01" min="0" placeholder="0,00"> ₽</form>
Ограничить количество символов в поле до 5
<form><input type="number" min="-9999" max="99999"></form>
Уменьшить длину <input type=number>
Атрибуты minlength, maxlength и size не работают.
Необходимое количество символов в поле определяется атрибутами min, max и step:
<!-- Достаточно выделить место на 6 символов -->
<input type="number" min="0" max="100" step="0.01"/>
Указать ширину в CSS (свойство width):
<style>
#dva {
width: 6em;
}
</style>
<input type="number" min="0" max="100" step="any" id="dva"/>
Стрелки у <input type=number>
Чтобы стрелочки были изначально, а не только при :hover и :focus в Chrome
<style>
#pyat::-webkit-inner-spin-button,
#pyat::-webkit-outer-spin-button {
opacity: 1;
}
</style>
<input type="number" id="pyat"/>
Убрать стрелки
<style>
.raz {
-moz-appearance: textfield;
}
.raz::-webkit-inner-spin-button {
display: none;
}
</style>
<input type="number" class="raz"/>
Стилизация стрелок «вверх»/«вниз» CSS
<style>
#raz {
position: relative;
display: inline-block;
}
#raz input {
font-size: 1em;
-moz-appearance: textfield;
}
#raz input::-webkit-inner-spin-button {
display: none;
}
#raz span {
position: absolute;
}
@supports (clip-path: polygon(50% 30%, 10% 90%, 90% 90%)) {
#raz input {
padding-right: 1em;
}
#raz span {
right: 0;
width: 1em;
height: 50%;
background: rgb(70,70,70);
cursor: pointer;
}
#raz span:hover {
background: red;
}
#raz span:nth-of-type(1) {
top: 0;
clip-path: polygon(50% 30%, 10% 90%, 90% 90%);
}
#raz span:nth-of-type(2) {
bottom: 0;
clip-path: polygon(50% 70%, 10% 10%, 90% 10%);
}
}
</style>
<span id="raz">
<input type="number" value="0">
<span onclick="this.previousElementSibling.stepUp()"></span>
<span onclick="this.previousElementSibling.previousElementSibling.stepDown()"></span>
</span>
Запретить ввод в поле, чтобы можно было пользоваться только кнопками редактирования
<style>
.raz {
all: unset;
-moz-appearance: textfield;
width: 3em;
text-align: center;
}
.raz::-webkit-inner-spin-button {
display: none;
}
</style>
<button type="button" onclick="this.nextElementSibling.stepDown()">-</button>
<input type="number" min="0" max="100" value="1" readonly class="raz">
<button type="button" onclick="this.previousElementSibling.stepUp()">+</button>
Вместо <input type="number"> использовать <input type="text">
Виртуальная клавиатура с дробно-числовым вводом
Атрибут inputmode плохо поддерживается браузерами.
<input inputmode="decimal">
На IOS (iPhone) если атрибут patternимеет значение [0-9]* или \d*, то на мобильном телефоне будет дана цифровая клавиатура.
Для отправки формы, поле должно содержать только цифры
<form><input inputmode="decimal" pattern="-?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?"></form>
Функционал с JavaScript
При наборе не числа value возвратит пустое значение. Браузер может позволить/вынудить пользователя набрать число с запятой «20,5», но value примет значение с точкой «20.5», искл., IE.
value (строка) =""; valueAsNumber (число) ="";
Запретить ввод букв
<input type="number" id="check" step="any"/>
<script>
document.getElementById('check').onkeydown = function (e) {
return !(/^[А-Яа-яA-Za-z ]$/.test(e.key)); // IE > 9
}
</script>
Только одна точка или одна запятая
<input type="number" step="any" id="shest2"/>
<script>
document.getElementById('shest2').onkeydown = function (e) {
if (e.currentTarget.value.indexOf(".") != '-1' || e.currentTarget.value.indexOf(",") != '-1') {
return !(/[.,]/.test(e.key));
}
}
</script>
Ограничить ввод двумя знаками после запятой
Цифры, вносимые после 2-го символа после запятой, сразу обрезаются, дабы не совершать лишних телодвижений.
<input type="number" oninput="up(this)" step="0.01"/>
<script>
function up(e) {
if (e.value.indexOf(".") != '-1') {
e.value=e.value.substring(0, e.value.indexOf(".") + 3);
}
}
</script>
Обрезать последний лишний символ
<input type="number" step="any" id="shest1"/>
<script>
document.getElementById('shest1').oninput = function () {
if (this.value.length > 7) this.value = this.value.substr(0, 7); // в поле можно ввести только 7 символов
}
</script>
Разделение цифр пробелом
Наберите любое многозначное число
<input oninput="this.nextElementSibling.innerHTML = new Intl.NumberFormat('ru').format(this.valueAsNumber)" type="number">
<output> </output>ФОРМА "ЗАКАЗАТЬ ЗВОНОК" В МОДАЛЬНОМ ОКНЕ НА BOOTSTRAP
<button type="button" class="button" data-bs-toggle="modal" data-bs-target="#basicModal" >
<i class="fa fa-phone"></i> <span>Заказать звонок</span>
</button>
Добавить в Макет
<div class="modal fade" id="basicModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"><button class="close" type="button" data-dismiss="modal">x</button> </div>
<div class="modal-body">
<?php
// add ФОРМА ЗАКАЗАТЬ ЗВОНОК
$oForm = Core_Entity::factory('Form', 5); // Заменить id формы
$Form_Controller_Show = new Form_Controller_Show($oForm);
if (!is_null(Core_Array::getPost($oForm->button_name)))
{
$Form_Controller_Show
->values($_POST + $_FILES)
// 0 - html, 1- plain text
->mailType(1)
->mailXsl(
Core_Entity::factory('Xsl')->getByName('ПисьмоКураторуФормы')
)
->mailFromFieldName('mail@spartika.ru')
->process();
// Отправляем письмо-подтверждение пользователю
$Form_Controller_Show1 = clone $Form_Controller_Show;
$sEmail = Core_Array::get($Form_Controller_Show1->values, 'email');
if (Core_Valid::email($sEmail)){
ob_start();
$Form_Controller_Show1
->xsl(
Core_Entity::factory('Xsl')->getByName($Form_Controller_Show1->mailType == 0 ? 'ПисьмоПодтверждениеПользователюФормыВФорматеHTML' : 'ПисьмоПодтверждениеПользователюФормы')
)
->show();
$sMailText = ob_get_clean();
if (mb_strpos($sMailText, 'ERROR TRUE') === FALSE){
$subject = 'Вами была заполнена форма обратного звока на сайте jvern.club';// Тема письма отредактировать
// При текстовой отправке нужно преобразовать HTML-сущности в символы
$Form_Controller_Show->mailType == 1 && $sMailText = html_entity_decode(strip_tags($sMailText), ENT_COMPAT, 'UTF-8');
$oCore_Mail = Core_Mail::instance()
->to($sEmail)
->from(EMAIL_TO)
->subject($subject)
->message(trim($sMailText))
->contentType($Form_Controller_Show->mailType == 0 ? 'text/html' : 'text/plain')
->header('X-HostCMS-Reason', 'Form');
// Массив содержащий пути прикрепленных файлов и их имена
$aForm_Fields = $oForm->Form_Fields->findAll();
foreach ($aForm_Fields as $oForm_Field){
if ($oForm_Field->type == 2){// File
$value = Core_Array::get($Form_Controller_Show->values, $oForm_Field->name);
if (!is_null($value)){
if (is_array($value) && $value['size'] > 0){
$oForm_Fill_Fields = Core_Entity::factory('Form_Fill_Field');
$oForm_Fill_Fields->queryBuilder()
->where('form_field_id', '=', $oForm_Field->id)
->where('value', '=', $value['name'])
->limit(1);
$aForm_Fill_Fields = $oForm_Fill_Fields->findAll();
if (isset($aForm_Fill_Fields[0])){
$oCore_Mail->attach(array(
'filepath' => $aForm_Fill_Fields[0]->getPath(),
'filename' => $value['name']
));
}
}
}
}
}
$oCore_Mail->send();
}
}
// END add
}
$Form_Controller_Show
->xsl(
Core_Entity::factory('Xsl')->getByName('ОтобразитьФорму')
)
->show();
?>
</div>
</div>
</div>
</div>XSL
ФОРМА "КУПИТЬ В 1 КЛИК" на BOOTSTRAPE

<button type="button" class="button btn-primary send-zakaz" data-item="{name}" data-bs-toggle="modal" data-bs-target="#zakazModal">
<i class="fa fa-shopping-cart"></i>
<span>Купить</span>
</button >
<div class="modal fade" id="zakazModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Купить в 1 клик</h4>
<button class="btn-close" type="button" data-bs-dismiss="modal"></button>
</div>
<div class="box-content">
<form method="get" class="form_call1">
<div class="row">
<div class="col-xs-12 text">
<h6>Модель: <span id="item"></span></h6>
</div>
<div class="col-xs-12 text-center mess" id="form_err1"></div>
<div class="col-xs-12 text-center mess" id="form_right1"></div>
<div class="col-xs-12">
<input id="name" maxlength="80" placeholder="Ваше Имя" type="text" />
</div>
<div class="col-xs-12">
<input id="phone" maxlength="80" placeholder="Телефон *" type="text" required/>
</div>
<div class="col-xs-12">
<button type="submit" autocomplete="off" class="zakaz-submit">Отправить заказ</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
$(function() {
$('form.form_call1').submit(function(){
phone=$('input#phone').val();
name=$('input#name').val();
reg = /^\d[\d\(\)\ -]{5,14}\d$/;
item=$('#item').text();
err='';
if (phone =='') {err+='<span>Вы не указали свой телефон</span>';}
else if (!(reg.test(phone))) {err+=' <span>Неверно указан Телефон</span>';}
if (err!='') {
$('div#form_err').html(err); // показываем ошибку
} else {
$.get( "/forms/send-zakaz.php?phone="+phone+"&name="+name+"&item="+item, function( data ) { //указываем путь к обработчику отправки формы
$('div#form_right').html(data); // показываем подтверждение удачной отправки
setTimeout(function(){
location.reload();
}, 1000);
});
}
return false;
});
$('.send-zakaz').click(function() {
var nameg = $(this).data('item');
// Добавляем в id=item название товара
$('span#item').html(nameg);
// Добавляем в дополнительное поле input название товара
$('input[name=item]').val(nameg);
});
});
PHP . Обработчик отправки фоормы
Стили CSS
Форма с валидацией (в модальном окне)
Для валидации формы используем скрипт validate.js
$(function() {
var errorTxt = 'Ошибка отправки формы'; //Ошибка отправки формы
$('#form1').validate({
rules: {
name: "required",
phone: "required"
},
messages: {
name: "Заполните это поле", // Заполните это поле
phone: "Заполните это поле",
},
focusInvalid: true,
errorClass: "input_error",
submitHandler: function(form){
var form = document.forms.form1,
formData = new FormData(form),
xhr = new XMLHttpRequest();
xhr.open("POST", "/mform/send-zakazspec.php");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if(xhr.status == 200) {
$("#form1").html('<p style="text-align:center">Ваша Заявка отправлена!<p>');
setTimeout(function(){
location.reload();
}, 1000);
}
}
};
xhr.send(formData);
}
});
// Получаем значение из span.title и добавляем в поле формы название выбранной спецтехники
$('.predzakaz').click(function() {
var nameg = $(this).parent().children('span.title').text();
$('#predzakazModal').appendTo('body');//перемещаем по DOM в конец body
$('input#model').val(nameg);
$('#model-name').html(nameg);
});
});
HTML код формы
<div class="modal fade" id="predzakazModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header text-center"><button class="close" type="button" data-dismiss="modal"></button>
<div class="modal-title h3">РемонтССТ </div>
<p class="bold"> Узнать стоимость: <span id="model-name"></span></p>
</div>
<div class="box-content">
<form method="get" id="form1">
<div class="text-center mess" id="form_err1"></div>
<div class="text-center mess" id="form_right1"></div>
<input name="model" id="model" type="hidden" />
<input name="name" id="name" maxlength="80" placeholder="Ваше Имя" type="text" />
<input name="phone" id="phone" maxlength="80" placeholder="Телефон *" type="text" required/>
<button type="submit" autocomplete="off" class="btn btn-primary btn-lg btn-circle">Отправить заказ</button>
</form>
</div>
</div>
</div>
</div>
Обработчик отправки формы send-zakazspec.php
<?php
$to = "info@site.ru" ;
if ( isset( $_POST['phone'] ) ) {
$name= substr( $_POST['name'], 0, 40 );
$phone = substr( $_POST['phone'], 0, 15 );
$model = substr( $_POST['model'], 0, 250);
$body = "Имя: ".$name."\r\n";
$body .= "Телефон: ".$phone."\r\n";
$body .= "Спецтехника: ".$model."\r\n\r\n";
send_mail($to, $body, $email);
}
// Вспомогательная функция для отправки почтового сообщения с вложением
function send_mail($to, $body, $email)
{
$subject = 'Пользователь сайта SITE.RU заполнил форму Заказа спецтехники';
$boundary = "--".md5(uniqid(time())); // генерируем разделитель
$headers .= "From: ".$email."\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .="Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
$multipart = "--".$boundary."\r\n";
$multipart .= "Content-type: text/plain; charset=\"utf-8\"\r\n";
$multipart .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
$body = $body."\r\n\r\n";
$multipart .= $body;
mail($to, $subject, $multipart, $headers);
}
?>