Битрикс ajax формы авторизации, восстановления пароля, регистрации связанные друг с другом + форма "Задать вопрос"
Rus
Eng
Битрикс 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}

Финальный результат выглядит примерно так:

Форма регистрации

Ответить
Отменить

Комментарии

Антон
Антон
|Ответить
Авторизация - огонь! Это надо умудриться отключить встроенную защиту от перебора. Или это специально сделано, чтобы потом сайты ломать?
Александр
Александр
|Ответить
Поскольку в данной статье не используются стандартные компоненты, то странно, что вы пишите, что я отключил встроенную защиту. Защита от перебора в этом коде отсутствовала всегда. Данная статья была опубликована как простейший пример работы с авторизацией, регистрацией, восстановлением пароля. Вы можете совершенствовать код как вашей душе угодно

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

На сайте используется система премодерирования комментариев, поэтому ваше сообщение будет опубликовано лишь после одобрения модератором

Вы отвечаете на комментарий пользователя

Отправить

ОБРАТНАЯ СВЯЗЬ

Напишите мне

Вы разрабатываете новый сервис, вносите доработки в существующий и хотите лучше чем у конкурентов? Вы обратились по адресу. Предлагаю вам комплексную разработку сайтов студийного уровня. У меня вы можете заказать дизайн, верстку, програмированние, разработку нетрадиционного функционала, реализацию связи между CMS, CRM и Data Analitics, а так же все остальное касаемое сайтов, кроме продвижения.

Обращайтесь, я всегда проконсультирую по всем вопросам и помогу подобрать наиболее эффективное решение для Вашего бизнеса. Я занимаюсь созданием сайтов в Новосибирске и в других регионах России, также работаю со странами СНГ. Вы останетесь довольны нашим сотрудничеством

Во время отправки произошла ошибка, пожалуйста попробуйте еще раз через некоторое время
Сообщение отправлено успешно

Телефоны

+7(993) 007-18-96

Email

info@tichiy.ru

Адрес

Россия, г. Москва

Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта

Написать мне
Отправить
Отправляя форму Вы автоматически подтверждаете, что ознакомились и принимаете Политику конфиденциальности сайта
Отправка успешна!
Thank you for your feedback. I will answer you within the next working hours
Отправка не удалась
Во время отправки запроса произошла ошибка. Пожалуйста, подождите и попробуйте снова через некоторое время или свяжитесь со мной