Битрикс ajax формы авторизации, восстановления пароля, регистрации связанные друг с другом + форма "Задать вопрос"
Последние записи
Данный материал не является исчерпывающим руководством, но содержит все файлы и скрипты для полноценной работы. У вас не получится просто взять и скопировать его, придется вносить минимальные изменения в ИБ, разметку и т.д. Код поставляется бесплатно и "как есть". Используйте его на свой страх и риск
Код форм
Размещаем перед закрывающим body в файле footer.php вашего шаблона
<?php
    $arSections = [];
    if(CModule::IncludeModule('iblock')) {
        $res = CIBlockSection::GetList(
            [
                'NAME' => 'ASC'
            ],
            [
                'IBLOCK_ID' => 1,
                'ACTIVE' => 'Y',
                'DEPTH_LEVEL' => 1
            ]
        );
        while($arRes = $res->GetNext()){
            $arSections[] = $arRes['NAME'];
        }
    }
    ?>
    <div class="topWindowOuter absoluteCenter" style="display:none">
        <div class="topWindowInner">
            <div class="modal-close js-close-form"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"><path d="M256,0C114.844,0,0,114.844,0,256s114.844,256,256,256s256-114.844,256-256S397.156,0,256,0z M256,490.667 C126.604,490.667,21.333,385.396,21.333,256S126.604,21.333,256,21.333S490.667,126.604,490.667,256S385.396,490.667,256,490.667 z"/><path d="M359.542,152.458c-4.167-4.167-10.917-4.167-15.083,0L256,240.917l-88.458-88.458c-4.167-4.167-10.917-4.167-15.083,0 c-4.167,4.167-4.167,10.917,0,15.083L240.917,256l-88.458,88.458c-4.167,4.167-4.167,10.917,0,15.083 c2.083,2.083,4.813,3.125,7.542,3.125s5.458-1.042,7.542-3.125L256,271.083l88.458,88.458c2.083,2.083,4.813,3.125,7.542,3.125 c2.729,0,5.458-1.042,7.542-3.125c4.167-4.167,4.167-10.917,0-15.083L271.083,256l88.458-88.458 C363.708,163.375,363.708,156.625,359.542,152.458z"/></svg></div>
            <div class="popup js-formDiv" id="registration">
                <form method="post" class="js-reg-form regForm formTabber" novalidate="novalidate">
                    <h2>Регистрация</h2>
                    <div class="row">
                        <div class="col-xs-6 input-row">
                            <label for="FIO">ФИО <span class="req">*</span></label>
                            <input type="text" name="FIO" id="FIO" value="" class="input-text field_FIO" placeholder="Ваше ФИО" autocomplete="name">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-6 input-row">
                            <label for="CITY">Город <span class="req">*</span> </label>
                            <input type="text" name="CITY" id="CITY" value="" class="input-text field_CITY" placeholder="Ваш город" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-6 input-row">
                            <label for="COMPANY">Название компании</label>
                            <input type="text" name="COMPANY" id="COMPANY" value="" class="input-text field_COMPANY" placeholder="Ваша компания" autocomplete="organization">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-6 input-row">
                            <label for="MAIL">Mail <span class="req">*</span></label>
                            <input type="text" name="MAIL" id="MAIL" value="" class="input-text field_MAIL" placeholder="Ваша почта" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-6 input-row">
                            <label for="EMAIL">Email <span class="req">*</span></label>
                            <input type="text" name="EMAIL" id="EMAIL" value="" class="input-text field_EMAIL"  placeholder="Ваша почта" autocomplete="email">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <label for="PHONE">Телефон <span class="req">*</span></label>
                            <input type="text" name="PHONE" id="PHONE" value="" placeholder="Ваш телефон" class="input-text field_PHONE" autocomplete="tel">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <hr class="clearfix" />
                            <div class="row input-row categoriesList">
                                <?
                                if(!empty($arSections)){
                                    ?><p>Выберите интересующие вас категории товара <span class="req">*</span></p><?
                                    foreach($arSections as $key=>$nameSection){
                                        ?><div class="col-xs-6">
                                            <input type="checkbox" id="o<?=$key?>" value="<?=$nameSection?>" name="s[]" style="display: none;">
                                            <label for="o<?=$key?>" class="check js-list">
                                                <svg width="18px" height="18px" viewBox="0 0 18 18">
                                                    <path d="M1,9 L1,3.5 C1,2 2,1 3.5,1 L14.5,1 C16,1 17,2 17,3.5 L17,14.5 C17,16 16,17 14.5,17 L3.5,17 C2,17 1,16 1,14.5 L1,9 Z"></path>
                                                    <polyline points="1 9 7 14 15 4"></polyline>
                                                </svg>
                                                <?=$nameSection?>
                                            </label>
                                        </div>
                                        <?
                                    }
                                }
                                ?>
                            </div>
                            <hr class="clearfix" />
                        </div>
                        <div class="col-xs-12 input-row orderPolitika active">
                            <input type="checkbox" id="cbx" style="display: none;" checked>
                            <label for="cbx" class="check">
                                <svg width="18px" height="18px" viewBox="0 0 18 18">
                                    <path d="M1,9 L1,3.5 C1,2 2,1 3.5,1 L14.5,1 C16,1 17,2 17,3.5 L17,14.5 C17,16 16,17 14.5,17 L3.5,17 C2,17 1,16 1,14.5 L1,9 Z"></path>
                                    <polyline points="1 9 7 14 15 4"></polyline>
                                </svg>
                                Я ознакомился с <a href="/politika-konfidentsialnosti.php" id="js-link-agree" target="_blank" rel="noopener noreferrer">Политикой конфиденциальности</a> и согласен со всеми пунктами
                            </label>
                        </div>
                        <br style="clear: both" />
                        <div class="col-xs-12 sRegSubmit">
                            <input type="submit" name="submit" class="js-order-submit" id="submit" value="Зарегистрироваться">
                        </div>
                        <div class="col-xs-12">
                            <p class="snoska">Поля, помеченные звездочкой (<span class="req">*</span>) обязательны для заполнения</p>
                        </div>
                    </div>
                    <div class="forgetPass">
                        <a href="#a" class="js-formLoad" data-attr="doLogin">Войти</a>
                    </div>
                    <?=bitrix_sessid_post();?>
                </form>
            </div>
            <div class="popup js-formDiv" id="registerSuccess">
                <h2>Поздравляем!</h2>
                <?/*?><p>Вы успешно зарегистрировались и вошли на сайт. Письмо с Вашим логином и паролем былт отправлены на вашу почту.</p>
                <p>Через несколько секунд страница будет перезагружена</p><?*/?>
                <p>Вы успешно зарегистрировались. Теперь вы можете войти на сайт используя логин и пароль из письма, которое мы отправили на указанную Вами почту.</p>
            </div>
            <div class="popup js-formDiv" id="registerError">
                <h2>Регистрация не удалась!</h2>
                <p>К сожалению, нам не удалось зарегистрировать ваш аккаунт. Пожалуйста, проверьте вводимые данные. Возможно такой пользователь уже существует или вы ошиблись при заполнении форм</p>
            </div>
            <div class="popup js-formDiv" id="recoveryPass">
                <form method="post" class="js-recovery-form regForm formTabber" novalidate="novalidate">
                    <h2>Восстановление пароля</h2>
                    <div class="row">
                        <div class="col-xs-6 input-row">
                            <label for="MAIL">Mail <span class="req">*</span></label>
                            <input type="text" name="MAIL" id="MAIL" value="" class="input-text field_MAIL" placeholder="Ваша почта" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <label for="EMAIL">Email <span class="req">*</span></label>
                            <input type="text" name="EMAIL" id="EMAIL" value="" class="input-text field_EMAIL"  placeholder="Ваша почта" autocomplete="email">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row orderPolitika active">
                            <input type="checkbox" id="cbx" style="display: none;" checked>
                            <label for="cbx" class="check">
                                <svg width="18px" height="18px" viewBox="0 0 18 18">
                                    <path d="M1,9 L1,3.5 C1,2 2,1 3.5,1 L14.5,1 C16,1 17,2 17,3.5 L17,14.5 C17,16 16,17 14.5,17 L3.5,17 C2,17 1,16 1,14.5 L1,9 Z"></path>
                                    <polyline points="1 9 7 14 15 4"></polyline>
                                </svg>
                                Я ознакомился с <a href="/politika-konfidentsialnosti.php" id="js-link-agree" target="_blank" rel="noopener noreferrer">Политикой конфиденциальности</a> и согласен со всеми пунктами
                            </label>
                        </div>
                        <br style="clear: both" />
                        <div class="col-xs-12 alignCenter">
                            <input type="submit" name="submit" class="js-recovery-submit" id="submit" value="Восстановить пароль">
                        </div>
                    </div>
                    <div class="forgetPass">
                        <a href="#a" class="js-formLoad" data-attr="doLogin">Войти</a>
                    </div>
                    <?=bitrix_sessid_post();?>
                </form>
            </div>
            <div class="popup js-formDiv" id="recoverySuccess">
                <h2>Успех!</h2>
                <?/*?><p>Вы успешно зарегистрировались и вошли на сайт. Письмо с Вашим логином и паролем былт отправлены на вашу почту.</p>
                <p>Через несколько секунд страница будет перезагружена</p><?*/?>
                <p>На Вашу почту были высланы новый логин и пароль</p>
            </div>
            <div class="popup js-formDiv" id="recoveryError">
                <h2>Неудача!</h2>
                <p>Нам не удалось восстановить Ваш пароль. Возможно, такого пользователя не существует</p>
            </div>
            <script>
                <?CJSCore::Init(['masked_input']);?>
                (function ($) {
                    //Активируем маску телефона
                    //$('#PHONE').inputmask({"mask": "+7 (999) 999-9999"});
                    BX.ready(function() {
                        var result = new BX.MaskedInput({
                            mask: '+7 (999) 999-99-99', // устанавливаем маску
                            input: BX('PHONE'),
                            placeholder: '_' // символ замены +7 ___ ___ __ __
                        });
                    });
                })(jQuery);
            </script>
            <div class="popup js-formDiv" id="doLogin">
                <form method="post" class="js-login-form regForm formTabber" novalidate="novalidate">
                    <h2>Авторизация</h2>
                    <p>Для входа Вам необходимо правильно указать логин и пароль</p><br style="clear: both" />
                    <div class="row">
                        <div class="col-xs-12 input-row">
                            <label for="EMAIL">Email <span class="req">*</span></label>
                            <input type="text" name="EMAIL" id="EMAIL" value="" class="input-text field_EMAIL"  placeholder="Ваша почта" autocomplete="email">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <label for="PASSWORD">Пароль <span class="req">*</span></label>
                            <input type="password" name="PASSWORD" id="PASSWORD" value="" class="input-text field_PASSWORD"  placeholder="Ваш пароль" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <br style="clear: both" />
                        <div class="col-xs-12 alignCenter">
                            <input type="submit" name="submit" class="js-login-submit" id="submit" value="Войти">
                        </div>
                    </div>
                    <div class="forgetPass">
                        <a href="#a" class="js-formLoad" data-attr="recoveryPass">Забыли пароль</a> / <a href="#a" class="js-formLoad" data-attr="registration">Еще не зарегистрировались</a>
                    </div>
                    <?=bitrix_sessid_post();?>
                </form>
            </div>
            <div class="popup js-formDiv" id="loginSuccess">
                <h2>Успех!</h2>
                <p>Вы успешно авторизовались. Через несколько секунд страница будет перезагружена</p>
            </div>
            <div class="popup js-formDiv" id="loginError">
                <h2>Неудача!</h2>
                <p>Вы ввели неправильный логин или пароль. Пожалуйста, проверьте данные и попытайтесь еще раз</p>
            </div>
            <div class="popup js-formDiv" id="doQuestion">
                <form method="post" class="js-question-form regForm formTabber" novalidate="novalidate">
                    <h2>Задать вопрос</h2>
                    <div class="row">
                        <div class="col-xs-6 input-row">
                            <label for="NAME">Имя <span class="req">*</span></label>
                            <input type="text" name="NAME" id="NAME" value="" class="input-text field_NAME" placeholder="Ваше имя" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-6 input-row">
                            <label for="PHONE">Телефон <span class="req">*</span></label>
                            <input type="text" name="PHONE" id="PHONE" value="" class="input-text field_PHONE" placeholder="Ваш телефон" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <label for="MAIL">Почта <span class="req">*</span></label>
                            <input type="text" name="MAIL" id="MAIL" value="" class="input-text field_MAIL" placeholder="Ваша почта" autocomplete="off">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <label for="EMAIL">Почта <span class="req">*</span></label>
                            <input type="text" name="EMAIL" id="EMAIL" value="" class="input-text field_EMAIL"  placeholder="Ваша почта" autocomplete="email">
                            <span class="js-error tooltip"></span>
                        </div>
                        <div class="col-xs-12 input-row">
                            <label for="MESSAGE">Ваш вопрос</label>
                            <textarea name="MESSAGE" id="MESSAGE" value="" class="input-text field_MESSAGE"  placeholder="Ваш вопрос"></textarea>
                            <span class="js-error tooltip"></span>
                        </div>
                        <br style="clear: both" />
                        <br style="clear: both" />
                        <div class="col-xs-12 alignCenter">
                            <input type="submit" name="submit" class="js-qusetion-submit" id="submit" value="Войти">
                        </div>
                        <br style="clear: both" /><br style="clear: both" />
                        <div class="col-xs-12">
                            <p class="snoska">Поля, помеченные звездочкой (<span class="req">*</span>) обязательны для заполнения</p>
                        </div>
                    </div>
                    <?=bitrix_sessid_post();?>
                </form>
            </div>
            <div class="popup js-formDiv" id="questionSuccess">
                <h2>Успех!</h2>
                <p>Вы задали свой вопрос. В ближайшее время мы свяжемся с Вами</p>
            </div>
            <div class="popup js-formDiv" id="questionError">
                <h2>Неудача!</h2>
                <p>Во время отправки запроса произошла ошибка. Пожалуйста, проверьте данные и попытайтесь еще раз</p>
            </div>
            <div class="popup js-formDiv" id="getPriceSuccess">
                <h2>Успех!</h2>
                <p>Вы успешно отправили заявку. Через несколько секунд страница перезагрузится и вы сможете скачать прайс-листы</p>
            </div>
        </div>
    </div>Вызов форм
<div class="js-formLoad" data-attr="registration" style="cursor: pointer">Регистрация</div><br>
<div class="js-formLoad" data-attr="recoveryPass" style="cursor: pointer">Восстановление пароля</div>
<div class="js-formLoad" data-attr="doLogin" style="cursor: pointer">Логин</div>
<div class="js-formLoad" data-attr="doQuestion" style="cursor: pointer">Задать вопрос</div>Код вашего скрипта
Размещаем в файле scripts.js вашего шаблона
//############ CHANGE START ############//
function IsJsonString(str) {
	try {
		JSON.parse(str);
	} catch (e) {
		return false;
	}
	return true;
}
//Показываем всплывающее окно
function showModal(el){
	el.stop().css("display", "flex").hide().fadeIn(600);
}
//При нажатии Esc скрываем форму
$(document).keydown(function(e) {
	if( e.keyCode === 27 ) {
		var popup=$('.topWindowOuter:visible');
		if (popup){
			closeGallery(popup);
			return false;
		}
	}
});
//Скрываем форму
function closeGallery(){
	$('.topWindowOuter').fadeOut(400,function(){
		$('.js-formDiv').removeClass('active').fadeOut(0);
		$('.js-oneClickForm').addClass('active').fadeIn(0);
	});
}
//Делаем валидацию формы
function formSubmit(form){//универсальная функция валидации форм
	var THIS_FORM = form;
	var req_input = $(THIS_FORM).find(".input-text");
	var flag = 0;
	$.each(req_input, function(index) {
		var THIS_VALUE = $(this).val(),
			reg_email = /^[a-zA-Z0-9\._-]+@[a-zA-Z0-9_\.-]{2,45}\.[a-zA-Z]{2,20}$/ ;
		reg_phone = /^(\s*)?(\+)?([- _():=+]?\d[- _():=+]?){10,14}(\s*)?$/,
			cc = /[0-9]{4} {0,1}[0-9]{4} {0,1}[0-9]{4} {0,1}[0-9]{4}/, //Credit card number
			cdate = /^\d{2}[./-]\d{2}$/, //Credit card Date
			smsCode = /^\d{3} \d{3}$/, //SMS Code Verification
			cvc = /^[0-9]{3,4}$/; //Credit card CVC
		if($(this).is(".field_PHONE")){
			if (reg_phone.test(THIS_VALUE)){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_EMAIL")){
			if (reg_email.test(THIS_VALUE)){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_FIO")){
			if (THIS_VALUE.length>2){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_pass") || $(this).is(".field_pass_confirm")){
			if($(".field_pass_confirm").length>0){
				if (THIS_VALUE.length>5 && ($(".field_pass").val()==$(".field_pass_confirm").val())){
					$(".field_pass").removeClass('error').addClass('succeed');
					$(".field_pass_confirm").removeClass('error').addClass('succeed');
				}
				else {
					$(".field_pass").addClass('error').removeClass('succeed');
					$(".field_pass_confirm").addClass('error').removeClass('succeed');
					flag++;
				}
			}else{
				if (THIS_VALUE.length>5){
					$(".field_pass").removeClass('error').addClass('succeed');
				}
				else {
					$(".field_pass").addClass('error').removeClass('succeed');
					flag++;
				}
			}
		}else if($(this).is(".field_card_number")){
			$('.field_card_number').mask('0000 0000 0000 0000');
			if (cc.test(THIS_VALUE)){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_card_date")){
			$('.field_card_date').mask('00/00');
			if (cdate.test(THIS_VALUE)){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_card_cvc")){
			$('.field_card_cvc').mask('000');
			if (THIS_VALUE){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_sms_verify")){
			if (smsCode.test(THIS_VALUE)){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_check")){
			if($(this).prop("checked") == true){
				$(this).next().removeClass('error').addClass('succeed');
			}
			else {
				$(this).next().addClass('error').removeClass('succeed');
				flag++;
			}
		}else if($(this).is(".field_MAIL") || $(this).is(".field_COMPANY") || $(this).is(".field_MESSAGE")){
			//Пропускаем фиктивное поля для остановки ботов
			//Рекомендую вам сменить имя и тип проверки на ботов
		}else{
			if (THIS_VALUE){
				$(this).removeClass('error').addClass('succeed');
			}
			else {
				$(this).addClass('error').removeClass('succeed');
				flag++;
			}
		}
	});
	if (flag){ return false;}
	else { return true;}
}
//Для сокращения кода и повышения читабельности выносим данный фрагмент в отдельную функцию
function formError(form){
	$('.js-formDiv.active').fadeOut(400,function(){
		$('.js-formDiv').removeClass('active');
		$('#'+form).fadeIn(400,function(){
			$(this).addClass('active');
		});
	});
}
//Для сокращения кода и повышения читабельности выносим данный фрагмент в отдельную функцию
function formSuccess(form){
	$('.js-formDiv.active').fadeOut(400,function(){
		$('.js-formDiv').removeClass('active');
		$('#'+form).fadeIn(400,function(){
			$(this).addClass('active');
		});
	});
}
/*********************************/
/* Обработка форм */
/*********************************/
(function ($) {
	$(document).ready(function () {
		/*********************************/
		/* Общие функции для работы с формой */
		/*********************************/
//При изменении состоянии input всплывающей формы делаем валидацию
		$('body').on('keyup input change', '.topWindowOuter input,.topWindowOuter textarea', function () {//Вызываем изменения состояние полей ввода при их редактировании
			formSubmit($(this).parents('form'));
		});
//Закрываем окно при клике вовне
		$('body').on('click', '.topWindowOuter', function (e) {
			if ($('.topWindowOuter').has(e.target).length === 0) {//Отслеживаем клик именно по элементу
				closeGallery();
			}
		});
		//показываем форму
		$('body').on('click', '.js-formLoad', function (e) {
			e.preventDefault();
			//Скрываем все формы всплывающего окна
			$('.js-formDiv').removeClass('active');
			//Показываем вызванную форму
			$('#' + $(this).attr('data-attr')).addClass('active').fadeIn(0);
			//Показываем форму
			showModal($('.topWindowOuter'));
		});
		//показываем форму
		$('body').on('click', '.js-forgotPass', function (e) {
			e.preventDefault();
			$('.js-formLoad[data-attr="recoveryPass"]').click();
		});
		//Клик на кнопку закрыть форму
		$('body').on('click', '.js-close-form', function (e) {
			e.preventDefault();
			closeGallery();
		});
		//отмечаем checkbox как отмеченный. Скрипт нужен поскольку checkbox скрыт и используется его эмуляция
		$('body').on('click', 'label[for="politika"]', function (e) {
			e.preventDefault();
			var el = $(this),
				parents = el.parents('.orderPolitika'),
				input = parents.find('input[type="checkbox"]');
			parents.toggleClass('active');
			if (parents.hasClass('active')) {
				input.prop('checked', true).val('Y');
			} else {
				input.prop('checked', false).val('N');
			}
			input.trigger("change");
		});
		//Кнопка отправить
		$('body').on('click', '.js-list', function (e) {
			e.preventDefault();
			var el = $(this),
				input = el.prev();
			if (el.hasClass('active')) {
				el.removeClass('active');
				input.prop('checked', false).attr('checked', false);
			} else {
				el.addClass('active');
				input.prop('checked', true).attr('checked', true);
			}
		});
		$('body').on('click', '.js-order-submit', function (e) {
			e.preventDefault();
			var el = $(this),
				parents = el.parents('form');
			if (formSubmit(parents)) {
				var data = parents.serialize();
				$.ajax({
					type: 'post',
					url: '/local/ajax/addNewUser.php',
					data: data,
					//dataType: 'json',
					success: function (data) {
						console.log(data);
						if (IsJsonString(data)) {
							data = JSON.parse(data);
							if (data.success === 'ok') {
								//Ошибок не было, заказ оформлен
								formSuccess('registerSuccess');
							} else if (data.success === 'Пользователь уже существует') {
								//Ошибок не было, заказ оформлен
								formError('registerError');
							} else {
								//Был возвращен флаг с ошибкой
								formSuccess('registerSuccess');
							}
						} else {
							//Не json, значит произошла ошибка
							formError('registerError');
						}
						setTimeout(() => closeGallery(), 5000);
					},
					error: function (XMLHttpRequest, textStatus, errorThrown) {
						console.log("Status: " + textStatus);
					}
				});
			}
		});
		$('body').on('click', '.js-recovery-submit', function (e) {
			e.preventDefault();
			var el = $(this),
				parents = el.parents('form');
			if (formSubmit(parents)) {
				var data = parents.serialize();
				$.ajax({
					type: 'post',
					url: '/local/ajax/recovery.php',
					data: data,
					//dataType: 'json',
					success: function (data) {
						console.log(data);
						if (IsJsonString(data)) {
							data = JSON.parse(data);
							if (data.success === 'ok') {
								//Ошибок не было, заказ оформлен
								formSuccess('recoverySuccess');
							} else if (data.success === 'Y') {
								//Ошибок не было, заказ оформлен
								formError('recoveryError');
							} else {
								//Был возвращен флаг с ошибкой
								formSuccess('recoverySuccess');
							}
						} else {
							//Не json, значит произошла ошибка
							formError('recoveryError');
						}
						setTimeout(() => closeGallery(), 5000);
					},
					error: function (XMLHttpRequest, textStatus, errorThrown) {
						console.log("Status: " + textStatus);
					}
				});
			}
		});
		$('body').on('click', '.js-login-submit', function (e) {
			e.preventDefault();
			var el = $(this),
				parents = el.parents('form');
			if (formSubmit(parents)) {
				var data = parents.serialize();
				console.log(data);
				$.ajax({
					type: 'post',
					url: '/local/ajax/login.php',
					data: data,
					//dataType: 'json',
					success: function (data) {
						console.log(data);
						if (IsJsonString(data)) {
							data = JSON.parse(data);
							if (data.success === 'ok') {
								//Ошибок не было, заказ оформлен
								formSuccess('loginSuccess');
								setTimeout(() => location.reload(), 5000);
							} else {
								//Был возвращен флаг с ошибкой
								formSuccess('loginError');
							}
						} else {
							//Не json, значит произошла ошибка
							formError('loginError');
						}
					},
					error: function (XMLHttpRequest, textStatus, errorThrown) {
						console.log("Status: " + textStatus);
					}
				});
			}
		});
		$('body').on('click', '.js-qusetion-submit', function (e) {
			e.preventDefault();
			var el = $(this),
				parents = el.parents('form');
			if (formSubmit(parents)) {
				var data = parents.serialize();
				$.ajax({
					type: 'post',
					url: '/local/ajax/addQuestion.php',
					data: data,
					//dataType: 'json',
					success: function (data) {
						console.log(data);
						if (IsJsonString(data)) {
							data = JSON.parse(data);
							if (data.success === 'ok') {
								//Ошибок не было, заказ оформлен
								formSuccess('questionSuccess');
								setTimeout(() => closeGallery(), 5000);
							} else {
								//Был возвращен флаг с ошибкой
								formSuccess('questionError');
							}
						} else {
							//Не json, значит произошла ошибка
							formError('questionError');
						}
					},
					error: function (XMLHttpRequest, textStatus, errorThrown) {
						console.log("Status: " + textStatus);
					}
				});
			}
		});
		/*
            $.ajax({
                type: 'post',
                url: '/local/ajax/isAuthorized.php', //Запоминаем размещение файла buyOneClick.php
                data: {},
                //dataType: 'json',
                success: function (data) {
                    console.log(data);
                    $('.right-authorization-block').html(data)
                },
                error:function(XMLHttpRequest, textStatus, errorThrown) {
                    console.log("Status: " + textStatus);
                }
            });
            */
	});
})(jQuery);Файл addNewUser.php
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
function sendNotification($arData){
    global $USER;
    $arEventFields = array(
        "EMAIL_TO"         => $arData['EMAIL'],
        "PASSWORD"         => $arData['PASSWORD'],
        "MESSAGE"          => 'Вы зарегистрировались!'
    );
    CEvent::Send("REGISTRATION_SITE", 's1', $arEventFields, "N"); //Уведомления админа о новом заказе
    $arEventFields = array(
        "USER_ID"           => $arData['USER_ID'],
        "NAME"              => $arData['FIO'],
        "EMAIL"             => $arData['EMAIL'],
        "CITY"              => $arData['CITY'],
        "PHONE"             => $arData['PHONE'],
        "COMPANY"           => $arData['COMPANY'],
        "SECTIONS"          => $arData['SECTIONS'],
        "LOGIN"             => $arData['EMAIL'],
    );
    CEvent::Send("NEW_USER", 's1', $arEventFields, "N"); //Уведомления админа о новом заказе
}
$arResult = array('success'=>'Y');
if (check_bitrix_sessid() && $_SERVER["REQUEST_METHOD"] == "POST" && !$_POST['MAIL']) {
    //Флаг проверки на бота
    $arData = array(
        'FIO' => htmlspecialchars($_POST['FIO']),
        'CITY' => htmlspecialchars($_POST['CITY']),
        'COMPANY' => htmlspecialchars($_POST['COMPANY']),
        'EMAIL' => htmlspecialchars($_POST['EMAIL']),
        'PHONE' => htmlspecialchars($_POST['PHONE']),
    );
    foreach ($_POST['s'] as $v){
        $arData['SECTIONS'] .= '- '.$v.'<br>';
    }
    if(!$arData['SECTIONS']){
        $arData['SECTIONS'] = 'Пользователь не выбирал интересных ему категорий';
    }
    $rand = randString(15);
    $registeredUserID = $USER->Add(array(
        "NAME"              => $arData['FIO'],
        "EMAIL"             => $arData['EMAIL'],
        "LOGIN"             => $arData['EMAIL'],
        "PERSONAL_PHONE"    => $arData['PHONE'],
        "LID"               => "ru",
        "ACTIVE"            => "Y",
        "GROUP_ID"          => array(3,4),
        "PASSWORD"          => $rand,
        "CONFIRM_PASSWORD"  => $rand,
        "WORK_COMPANY"      => $arData['COMPANY'],
        "PERSONAL_CITY"     => $arData['CITY'],
    ));
    if(!$registeredUserID){
        $arResult['success'] = 'Пользователь уже существует';
    }else{
        $arData['USER_ID'] = $registeredUserID;
        $arData['PASSWORD'] = $rand;
        sendNotification($arData);
        $arResult['success'] = 'ok';
    }
}
echo json_encode($arResult);Файл recovery.php
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
$arResult = array('success'=>'Y');
if (check_bitrix_sessid() && $_SERVER["REQUEST_METHOD"] == "POST") {
    //Флаг проверки на бота
    if(!$_POST['MAIL']){
        $arData = array(
            'EMAIL' => htmlspecialchars($_POST['EMAIL'])
        );
        //Отправляет контрольную точку для смены пароля
        //CUser::SendPassword($arData['EMAIL'],$arData['EMAIL'])
        global $USER;
        if (!is_object($USER))
            $USER = new CUser;
        $filter = [
            "ACTIVE" => "Y",
            "EMAIL"  => $arData['EMAIL']
        ];
        $user = CUser::GetList(($by = "timestamp_x"), ($order = "desc"), $filter)->Fetch();
        if (count($user) > 1) {
            $password = mb_substr(md5(uniqid(rand(), true)), 0, 9);
            $USER->Update($user['ID'], ["PASSWORD" => $password, "CONFIRM_PASSWORD" => $password]);
            $arEventFields = [
                "EMAIL_TO" => $arData['EMAIL'],
                "MESSAGE"  => 'Пароль успешно восстановлен.',
                "PASSWORD" => $password,
            ];
            CEvent::Send("USER_PASS_RECOVERY", 's1', $arEventFields, "N");
            $arResult['success'] = 'ok';
        } else {
            $arResult = [
                'success'   => 'Y',
                'MESSAGE' => 'Такой пользователь не найден'
            ];
        };
    }
}
echo json_encode($arResult);Файл login.php
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);
define("NEED_AUTH", true);
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");
/**
 * Проверяем, является ли $password текущим паролем пользователя.
 *
 * @param int $userId
 * @param string $password
 *
 * @return bool
 */
function isUserPassword($userId, $password)
{
    $userData = CUser::GetByID($userId)->Fetch();
    $salt = substr($userData['PASSWORD'], 0, (strlen($userData['PASSWORD']) - 32));
    $realPassword = substr($userData['PASSWORD'], -32);
    $password = md5($salt.$password);
    return ($password == $realPassword);
}
$arResult = array('success'=>'Y');
global $USER;
if (check_bitrix_sessid() && $_SERVER["REQUEST_METHOD"] == "POST") {
    //$arAuthResult = $USER->Login(htmlspecialchars($_POST['EMAIL']), htmlspecialchars($_POST['PASSWORD']));
    //Флаг проверки на бота
    $arData = array(
        'EMAIL' => $_POST['EMAIL'],
        'PASSWORD' => $_POST['PASSWORD'],
    );
    $rsUser = CUser::GetByLogin($arData['EMAIL']);
    $arUser = $rsUser->Fetch();
    if(isUserPassword($arUser['ID'],$arData['PASSWORD'])!=1){
        $arResult['success'] = 'Данные неверны';
    }else{
        $USER->Login($arData['EMAIL'], $arData['PASSWORD'], 'Y');
        $USER->Authorize($arUser['ID']);
        $arResult['success'] = 'ok';
    }
}
echo json_encode($arResult);
Файл addQuestion.php
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
$arResult = array('success'=>'Y');
if (check_bitrix_sessid() && $_SERVER["REQUEST_METHOD"] == "POST" && !$_POST['MAIL'] && CModule::IncludeModule('iblock')) {
    //Флаг проверки на бота
    $el = new CIBlockElement;
    $PROP = [];
    if(strlen($_REQUEST['EMAIL']) > 0)
        $PROP['EMAIL'] = $_REQUEST['EMAIL'];
    if(strlen($_REQUEST['PHONE']) > 0)
        $PROP['PHONE'] = $_REQUEST['PHONE'];
    $arLoadProductArray = [
        "IBLOCK_SECTION_ID" => false,
        "IBLOCK_ID"         => IBLOCK_QUESTIONS,
        "PROPERTY_VALUES"   => $PROP,
        "NAME"              => "Вопрос от " . $_REQUEST['NAME'],
        "ACTIVE"            => "Y",
        "PREVIEW_TEXT"      => $_REQUEST['MESSAGE'],
    ];
    if ($PRODUCT_ID = $el->Add($arLoadProductArray)) {
        $arEventFields = [
            'NAME' => $_REQUEST['NAME'],
            'EMAIL'  => $_REQUEST['EMAIL'],
            'PHONE' => $_REQUEST['PHONE'],
            'QUESTION' => $_REQUEST['MESSAGE'],
        ];
        CEvent::Send("ADD_QUESTION", 's1', $arEventFields);
        $arResult['success'] = 'ok';
    } else {
        $arResult = [
            'ERROR'   => 'Y',
            'MESSAGE' => '1'.$el->LAST_ERROR
        ];
    }
}
echo json_encode($arResult);Стили css
.absoluteCenter { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-align: center; -moz-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -moz-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; text-align: center; flex-direction: column}
.topWindowInner .forgetPass a {-moz-transition: all 0.5s;-webkit-transition: all 0.5s;-o-transition: all 0.5s;-ms-transition: all 0.5s}
.topWindowOuter{display: flex;background-color: rgba(0,0,0,0.5);position: fixed;top:0;left:0;width:100%;height:100%;z-index: 1000;}
.topWindowInner {background-color: #fff;padding:40px 40px;position: relative;min-width: 320px;max-width: 500px;max-height:90vh;overflow-y:auto;-webkit-box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.2); -moz-box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.2); box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.2);text-align: left;border-radius: 5px}
.topWindowInner h2{font-family: 'Roboto Condensed',Verdana,sans-serif;font-size: 24px; font-weight: 600;line-height: 32px;margin-bottom:14px;text-align: left}
.topWindowInner .formClose{position: absolute;right: 0;top:0;background-color: #E31D23;border-radius: 50%;width: 28px;height:28px; -webkit-transform: translate(50%,-50%); -moz-transform: translate(50%,-50%); -ms-transform: translate(50%,-50%); -o-transform: translate(50%,-50%); transform: translate(50%,-50%);cursor:pointer}
.topWindowInner .formClose .svgBox{margin-top:3px;}
.topWindowInner .formClose svg{width: 8px;height:8px;fill:#fff;stroke:#fff;}
.topWindowInner .formClose:hover{background-color: #d21a20}
.topWindowInner input[type="text"],.topWindowInner input[type="password"],.topWindowInner textarea{width: 100%;display: block;border: 1px solid #b7b7b7;font-family: Roboto,Verdana,sans-serif;padding: 5px 13px;font-size: 14px;}
.topWindowInner input[type="text"],.topWindowInner input[type="password"]{margin-bottom: 16px;position: relative;}
.topWindowInner input[type="text"].error,.topWindowInner input[type="password"].error{color:#d21a20;border:1px solid #d21a20;}
.topWindowInner input[type="checkbox"]{display: none}
.topWindowInner label{width: 100%;font-family: Roboto,Verdana,sans-serif;font-weight: 400;font-size: 12px;line-height: 1.5;color: #2d2d2d;margin-bottom: 4px;border-bottom:1px solid transparent}
.topWindowInner .orderPolitika {padding-top: 10px}
.topWindowInner .orderPolitika a{color:#428bca}
.topWindowInner .orderPolitika a:hover{color:#3b9ac3;border-bottom:1px dotted #3b9ac3}
.topWindowInner .row {margin-left: -10px;margin-right:-10px;}
.topWindowInner .col-xs-6,.topWindowInner .col-xs-12 {padding-left:10px;padding-right: 10px;}
.topWindowInner a{color:#e62d19}
.topWindowInner p{color:#333333;font-family: Verdana,Sans-serif;font-size: 12px}
.topWindowInner hr{margin:10px 0;}
.topWindowInner input[type="submit"]{font-weight:400;font-family: "UbuntuBold";text-transform: uppercase;text-align: center;padding:5px 15px;background-color: #7776ba;outline: 0;box-shadow: none;color:#fff;border:none;border-radius: 3px;}
.topWindowInner input[type="submit"]:hover{background-color: #3b9ac3;}
.topWindowInner input,.topWindowInner a,.topWindowInner textarea{-moz-transition: all 0.5s;-webkit-transition: all 0.5s;-o-transition: all 0.5s;-ms-transition: all 0.5s}
.topWindowInner .sRegSubmit{padding:15px 0;text-align: center}
.topWindowInner .forgetPass{text-align: right;font-size: 12px;margin-top:20px}
.topWindowInner .forgetPass a{color:#428bca;border-bottom:1px dotted #428bca}
.topWindowInner .forgetPass a:hover{border-bottom:1px dotted transparent}
.topWindowInner .input-text{border:1px solid #ebebeb;border-radius: 3px}
.topWindowInner .input-text:hover,.topWindowInner .input-text:focus{max-width:100%;}
.topWindowInner .input-text:hover,.topWindowInner .input-text:focus{border:1px solid #fff;-webkit-box-shadow:0 0 10px 3px #b9e9fa;box-shadow:0 0 10px 3px #b9e9fa}
.topWindowInner .input-text:focus::placeholder{color:#dfdede;}
.topWindowInner .input-text::-webkit-input-placeholder {color:#808080;font-weight:400;font-size:14px;font-family:'PT Sans Regular',Verdana;}
.topWindowInner .input-text:focus::-webkit-input-placeholder {color:#dfdede;}
/* Firefox < 19 */
.topWindowInner .input-text:-moz-placeholder{color:#808080;font-weight:400;font-size:14px;font-family:'PT Sans Regular',Verdana;}
.topWindowInner .input-text:focus:-moz-placeholder{color:#dfdede;}
/* Firefox > 19 */
.topWindowInner .input-text::-moz-placeholder{color:#808080;font-weight:400;font-size:14px;font-family:'PT Sans Regular',Verdana;}
.topWindowInner .input-text:focus::-moz-placeholder{color:#dfdede;}
/* Internet Explorer 10 */
.topWindowInner .input-text:-ms-input-placeholder {color:#808080;font-weight:400;font-size:14px;font-family:'PT Sans Regular',Verdana;}
.topWindowInner .input-text:focus:-ms-input-placeholder{color:#dfdede;}
.js-formDiv {display: none}
.js-formDiv.active {display: block}
.modal-close {position: absolute;top: 12px;right: 24px;cursor: pointer;width: 24px;height:24px;fill:#85cceb}
.modal-close:hover {fill:#15628d}
.modal-close svg{-moz-transition: all 0.5s;-webkit-transition: all 0.5s;-o-transition: all 0.5s;-ms-transition: all 0.5s}
@media all and (max-width: 545px) {
	.topWindowInner {min-width: 320px;max-width: 320px;padding: 40px 20px 40px 20px;}
}
.req{color:#d15959}
.check {cursor: pointer;position: relative;margin: auto;width: 18px;height: 18px;-webkit-tap-highlight-color: transparent;transform: translate3d(0, 0, 0);}
.check:before {content: "";position: absolute;top: -3px;left: -3px;width: 24px;height: 24px;border-radius: 50%;background: rgba(34,50,84,0.03);opacity: 0;transition: opacity 0.2s ease;}
.check svg {position: relative;z-index: 1;fill: none;stroke-linecap: round;stroke-linejoin: round;stroke: #c8ccd4;stroke-width: 1.5;transform: translate3d(0, 0, 0) translateY(3px);transition: all 0.2s ease;}
.check svg path {stroke-dasharray: 60;stroke-dashoffset: 0;}
.check svg polyline {stroke-dasharray: 22;stroke-dashoffset: 66;}
.check:hover:before {opacity: 1;}
.check:hover svg {stroke: #85cceb;}
#cbx:checked + .check svg, #o0:checked + .check svg, #o1:checked + .check svg, #o2:checked + .check svg, #o3:checked + .check svg, #o4:checked + .check svg, #o5:checked + .check svg, #o6:checked + .check svg, #o7:checked + .check svg
{stroke: #85cceb;}
#cbx:checked + .check svg path, #o0:checked + .check svg path, #o1:checked + .check svg path, #o2:checked + .check svg path, #o3:checked + .check svg path, #o4:checked + .check svg path, #o5:checked + .check svg path, #o6:checked + .check svg path, #o7:checked + .check svg path
{stroke-dashoffset: 60;transition: all 0.3s linear;}
#cbx:checked + .check svg polyline, #o0:checked + .check svg polyline, #o1:checked + .check svg polyline, #o2:checked + .check svg polyline, #o3:checked + .check svg polyline, #o4:checked + .check svg polyline, #o5:checked + .check svg polyline, #o6:checked + .check svg polyline, #o7:checked + .check svg polyline
{stroke-dashoffset: 42;transition: all 0.2s linear;transition-delay: 0.15s;}
.regForm > .row > .col-xs-6:nth-child(4){display: none}
.regForm #PHONE{width: 100%}
.js-recovery-form > .row > .col-xs-6:nth-child(1){display: none}
.clearfix:after {content: "";display: table;clear: both;}
.alignCenter {text-align: center}
.categoriesList p{margin-bottom: 10px}
.snoska {font-size: 12px;color:#828282}
.orderPolitika label {display: table}
/*.js-login-form > .row > .col-xs-12:nth-child(1){display: none}*/
.js-question-form .input-row:nth-child(3){display: none}Финальный результат выглядит примерно так:

Комментарии