Перейти к содержимому


Блок формы обратной связи на AJAX

AJAX форма обратной связи

  • Вы не можете ответить в тему
Сообщений в теме: 4

#1 VerstkaShopcms

    Пользователь

  • Download User
  • PipPip
  • 20 сообщений
Репутация: 4
Начинающий

Отправлено 02 December 2014 - 11:16 PM

Цель данной статьи показать как можно использовать родные файлы шопцмс версии VIP (должен быть не закодированный файл index.php) для создания блоков посредством аякс-запроса

Для начала нужно сделать файл для блока. Копируем файл feedback.tpl.html в папку blocks и называем его feedback_block.tpl.html

Отрываем его и немного дополняем. Во первых нужно дописать инпут-маркер с названием feedback_block и во вторых поместить весь блок в див с айди result_feedback

Должно получится следующее:

<div id="result_feedback">
{if $sent eq NULL}
	{if $error ne NULL}<div class="error cattop" align="center">{if $error eq 2}{$smarty.const.ERR_WRONG_CCODE}{elseif $error eq 3}{$smarty.const.ERR_WRONG_POST}{else}{$smarty.const.FEEDBACK_ERROR_FILL_IN_FORM}{/if}</div>{/if}
	  <form name="formfeedbackblk" id="formfeedback" method="post" action="index.php">
	  <input type="hidden" name="send" value="yes"><input type="hidden" name="feedback" value="yes"><input type="hidden" name="feedback_block" value="yes">
		<input name="customer_name" class="lblfy" type="text" maxlength="80" value="{if $customer_name|escape|convert:'UTF-8':'CP1251':false != $smarty.const.FEEDBACK_CUSTOMER_NAME}{$customer_name|escape|convert:'UTF-8':'CP1251':false}{/if}" {if $customer_name|escape|convert:'UTF-8':'CP1251':false == "" || $customer_name|escape|convert:'UTF-8':'CP1251':false == $smarty.const.FEEDBACK_CUSTOMER_NAME}title="{$smarty.const.FEEDBACK_CUSTOMER_NAME}"{/if}>
		<input name="customer_email" class="lblfy" type="text" maxlength="80" value="{if $customer_email|escape|convert:'UTF-8':'CP1251':false != $smarty.const.CUSTOMER_EMAIL}{$customer_email|escape|convert:'UTF-8':'CP1251':false}{/if}" {if $customer_email|escape|convert:'UTF-8':'CP1251':false == "" || $customer_email|escape|convert:'UTF-8':'CP1251':false == $smarty.const.CUSTOMER_EMAIL}title="{$smarty.const.CUSTOMER_EMAIL}"{/if}>
		<input name="message_subject" class="lblfy" type="text" maxlength="200" value="{if $message_subject|escape|convert:'UTF-8':'CP1251':false != $smarty.const.FEEDBACK_CUSTOMER_MESSAGE_SUBJ}{$message_subject|escape|convert:'UTF-8':'CP1251':false}{/if}" {if $message_subject|escape|convert:'UTF-8':'CP1251':false == "" || $message_subject|escape|convert:'UTF-8':'CP1251':false == $smarty.const.FEEDBACK_CUSTOMER_MESSAGE_SUBJ}title="{$smarty.const.FEEDBACK_CUSTOMER_MESSAGE_SUBJ}"{/if}>
		<textarea name="message_text" class="lblfy" {if $message_text|escape|convert:'UTF-8':'CP1251':false == "" || $message_text|escape|convert:'UTF-8':'CP1251':false == $smarty.const.FEEDBACK_CUSTOMER_MESSAGE_TEXT}title="{$smarty.const.FEEDBACK_CUSTOMER_MESSAGE_TEXT}"{/if}>{if $message_text|escape|convert:'UTF-8':'CP1251':false != $smarty.const.FEEDBACK_CUSTOMER_MESSAGE_TEXT}{$message_text|escape|convert:'UTF-8':'CP1251':false}{/if}</textarea>
		  {if $smarty.const.CONF_ENABLE_CONFIRMATION_CODE eq 1}
		  <div id="capcha"><img src="index.php?do=captcha&amp;{php}echo session_name();{/php}={php}echo session_id();{/php}?anti_cache={php}echo rand(5, 15);{/php}" alt="code"></div>
		  <input name="fConfirmationCode" value="{$smarty.const.STR_ENTER_CCODE}" type="text" style="color: #aaaaaa;" onfocus="if(this.value=='{$smarty.const.STR_ENTER_CCODE}')
						{literal}
						{this.style.color='#000000';this.value='';}
						{/literal}" onblur="if(this.value=='')
						{literal}{{/literal}this.style.color='#aaaaaa';this.value='{$smarty.const.STR_ENTER_CCODE}'{literal}}{/literal}">
		  {/if}
	  </form>
	  <div class="clear"></div>
<a href="#" class="fdbsbm sendfeedback_button">{$smarty.const.OK_BUTTON3}</a>
{else}
	<div class="oki pad" align="center">{$smarty.const.FEEDBACK_SENT_SUCCESSFULLY}</div>
{/if}
</div>

Следующим шагом требуется можифицировать файл index.php
Открываем его и почти в самом конце находим строки:

//show Smarty output
  $smarty->display("index.tpl.html");

Вместо этого вставляем код:

$tpl_for_output ='';
if (isset($_REQUEST['feedback_block'])) { // Проверка на наличие инпута маркера
  $tpl_for_output = 'blocks/feedback_block.tpl.html';  // и присвоение имени шаблона для вывода
}

if ($tpl_for_output == '')  // Проверка имени шаблона
  {
	  $smarty->display("index.tpl.html");  //  если нет то выводим как обычно
  }
else  
  {
		$ajax_request = @($_SERVER["HTTP_AJAX_REQUEST"] == "true");  // если есть объявляем что у нас аякс запрос
		$smarty->display($ajax_request ? $tpl_for_output : 'index.tpl.html');  //и выводим в файл шаблона блока
  }

С этим файлом всё.

Далее подключим файл джаваквери в шапку, в файле head.tpl.html

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>  {* если хотим грузить с гугля *}

или

<script type="text/javascript" src="data/{$smarty.const.TPL}/jquery.min.js"></script>  {* Если не поленились и сохраниди этот файл в папку с шаблоном, рекомендую это сделать *}


Следующий файл для правки файл шаблона index.tpl.html

Под самый конец пропишем джаваскрипт обработки отправки аякс запроса

<script type="text/javascript">
{literal}
	  function SendFeedbackBlock() {		  //Функция обработки запроса на отправку заявки через блок в футере
				var form_cart = $("form[name=formfeedbackblk]");
				$.ajax({
					type: "POST",
					url: form_cart.action ? form_cart.action : document.URL,
			  cache: false,
					data: $(form_cart).serialize(),
					dataType: "text",
			  timeout: 5000,
					beforeSend: function(xhr) {
					xhr.setRequestHeader("Ajax-Request", "true");
					},
					success: function(response) {
				{/literal}
				$("#result_feedback").replaceWith(response);
				{literal}
						}
				});
			return false;
			}
	  
$(document).ready(function() {
	  $(document).delegate(".sendfeedback_button", "click", function(event) {   //Функция нажатия на кнопку отправить сообщение
	  event.preventDefault();
	  SendFeedbackBlock(); {/literal}

	  {literal}
});
	  });
{/literal}
</script>


Также нам понадобится еще один файл для смарти, который будет конвертировать запрос из кодировки UTF-8 в 1251, этот модификатор есть в коде шаблона блока

Его листинг:

<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Файл: modifier.convert.php
* Тип: modifier
* Имя: convert
* Назначение: Конвертация из одной кодировки в другую функцией iconv или mb_convert_encoding.
* Использование в шаблоне: {$templ_var|convert:'UTF-8':'CP1251':false}
* -------------------------------------------------------------
*/
function smarty_modifier_convert( $string, $from = 'UTF-8', $to = 'CP1251', $mb = false )
{
if (!$mb){
$conv_string = iconv($from, $to, $string);
} else {
$conv_string = mb_convert_encoding($string, $to, $from);
}
return $conv_string;
}
?>

Сохраняем его под именем modifier.convert.php в папку core/smarty/plugins/

И последнее осталось подправить немного файл feedback.php из папки core/includes/

Листинг его ниже
<?php
	    if (isset($_GET["feedback"]) || isset($_POST["feedback"]))
	    {
			    if (isset($_POST["feedback"]))
			    {
					    $customer_name = $_POST["customer_name"];
					    $customer_email = $_POST["customer_email"];
					    $message_subject = $_POST["message_subject"];
					    $message_text = $_POST["message_text"];
					    if (isset($_POST["feedback_block"])) $mail_block = $_POST["feedback_block"];
			    }
			    else
			    {
					    $customer_name = "";
					    $customer_email = "";
					    $message_subject = "";
					    $message_text = "";
					    if (isset($_POST["feedback_block"])) $mail_block = $_POST["feedback_block"];
			    }

			    //validate input data
			    if (trim($customer_email)!="" && trim($customer_name)!="" && trim($message_subject)!="" && trim($message_text)!="" && preg_match("/^[_\.a-z0-9-]{1,20}@(([a-z0-9-]+\.)+(com|net|org|mil|edu|gov|arpa|info|biz|inc|name|[a-z]{2})|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/is",$customer_email))
			    {
					    if(CONF_ENABLE_CONFIRMATION_CODE){
								   $error_f = 1;
						  if(!$_POST['fConfirmationCode'] || !isset($_SESSION['captcha_keystring']) || $_SESSION['captcha_keystring'] !==  $_POST['fConfirmationCode']) {
								   $error_f = 2;
								   $smarty->assign("error",$error_f);
						  }
						  unset($_SESSION['captcha_keystring']);
						  if($error_f == 1){
						  if (xMailTxtHTML(CONF_GENERAL_EMAIL, $message_subject, $message_text, $customer_email, $customer_name)){
						    if (trim($mail_block)!="")
							  {$smarty->assign("sent",1);}
						    else
						    {
							  Redirect("index.php?feedback=1&sent=1");
						    }
						  }else{
						  $smarty->assign("error",3);
						  }
						  }
					    }else{
						  if (xMailTxtHTML(CONF_GENERAL_EMAIL, $message_subject, $message_text, $customer_email, $customer_name)){
						    if (trim($mail_block)!="")
							  {$smarty->assign("sent",1);}
						    else
						    {
							  Redirect("index.php?feedback=1&sent=1");
						    }
						  }else{
						  $smarty->assign("error",3);
						  }
					    }
			    }
			    else if (isset($_POST["feedback"])) $smarty->assign("error",1);

			    //extract input to Smarty
			    $smarty->hassign("customer_name",$customer_name);
			    $smarty->hassign("customer_email",$customer_email);
			    $smarty->hassign("message_subject",$message_subject);
			    $smarty->hassign("message_text",$message_text);

			    if (isset($_GET["sent"])) $smarty->assign("sent",1);

			    $smarty->assign("main_content_template", "feedback.tpl.html");
	    }

?>

Подитожим - поправили 2 файла шаблона, один создали новый + добавили модификатор смарти и добавили джаваквери.

На этом всё! Сохраняем, подключаем и проверяем работу. Кому хочется посмотреть как это работает могу дать ссылку где я это реализовал. Но смотреть особо не на что. Форма как форма, работает на аяксе.

Чуть было не забыл. Есть глючок с капчей в мозилле (картинка берется из кеша, причем как-то хитро), возможно и в других браузерах. При вводе которой постоянно пишет что введенный код не верный. Этот момент я решил в файле блока а именно в пути картинки я дописал код ?anti_cache={php}echo rand(5, 15);{/php}
который будет каждый раз добавлять к пути картинки ?anti_cache=(случайное число). Таким образом для браузера картинка будет в большинстве случаев новая и их кеша браться не будет, а будет грузиться всегда с сервера. Если кому то потребуется использовать форму на странице где будет еще одна капча то это дело можно на джаваквери подменить. То есть после загрузки страницы и последней капчи просто последнюю капчу скопировать на джаваквери в первую.

Код примерно следующий

<script type="text/javascript">
jQuery(document).ready(function()
{literal}
{
   jQuery.exists = function(selector) {
	return ($(selector).length > 0);
   }
	if ($.exists("#captcha_disc_img")) {
	  var img_cph = $('#formfeedback div#capcha').html();
	  //alert (img_cph);
	  $('#captcha_disc_img').replaceWith(img_cph);
	}
}
{/literal});
</script>

Сначала забыл а потом благодаря одному пользователю вспомнил. Нужно еще подключить в файле head.tpl.html джаваквери скрипт labelify. Скачать его можно как с сайта автора.

И также в конце файла index.tpl.html, желатtльно после кода самой формы добавить код:

<script type="text/javascript">
jQuery(document).ready(function()
{literal}
{
	$("#result_feedback .lblfy").labelify({labelledClass: "labelHighlight"});
	$("#result_feedback textarea.lblfy").labelify({labelledClass: "labelHighlight"});
});
{/literal}
</script>

Плюс добавить в файл стиля сам класс labelHighlight

У меня такие правила прописаны для этого класса в css

input[type=text].labelHighlight, textarea.labelHighlight{color:#8E8E8E;}
#result_feedback input[type=text].labelHighlight, #result_feedback textarea.labelHighlight{text-transform:uppercase;}

На этом вроде всё. У кого нет времени читать много буков и делать или просто лень - я всегда готов пойти навстречу и помочь, за символическое вознаграждение ;)
  • 0

#2 FusSheva

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 210 сообщений
Репутация: 7
Начинающий

Отправлено 02 December 2014 - 11:22 PM

Посмотреть пример работы где нибудь можно?
  • 0
Каждый человек способен на многое. Но к сожалению, не каждый знает на что он способен.

#3 VerstkaShopcms

    Пользователь

  • Download User
  • PipPip
  • 20 сообщений
Репутация: 4
Начинающий

Отправлено 02 December 2014 - 11:43 PM

на сайте для которого я делал столовое серебро - форма в подвале
Только есть просьба - не отправляйте плиз через форму ничего (заказчику не понравится наверное спам :) ), для проверки достаточно не верно указать капчу
  • 0

#4 kery

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 134 сообщений
Репутация: 17
Начинающий

Отправлено 20 February 2015 - 08:43 PM

попробовал установить, только сделал чтобы сначала этот блок был скрытым а по кнопке в футере блок выезжал на jquery:
$(".feedback").hide();
$(".button").click(function(){ $(".feedback").toggle(2000)});
сам блок подключил:
	 <div class="feedback">
	 {include file="blocks/feedback_block.tpl.html"}
	  </div>

но у меня почему то все константы не отображаются вообще в полях
$smarty.const.FEEDBACK_CUSTOMER_NAME
и т.д. т.е. инпуты чистые.

попробовал без открывающего окошка сделать и такаяже фигня, думал может что с кодировкой и пробовал менять кодировку самого блока на utf8 но опять все в полях формы чисто, ваш плагин для smarty добавил.
  • 0

#5 VerstkaShopcms

    Пользователь

  • Download User
  • PipPip
  • 20 сообщений
Репутация: 4
Начинающий

Отправлено 23 February 2015 - 10:24 PM

Не отображаются при загрузке или после отправки или неполной отправке(не все поля заполнены)?
Я понял. Забыл описать один плагин на джаваквери который подключал и использовал - labelify. Скачать его можно как с сайта автора так и на сайте на котором есть эта форма.

И подключить нужно к форме его так

<script type="text/javascript">
jQuery(document).ready(function()
{literal}
{
	$("#result_feedback .lblfy").labelify({labelledClass: "labelHighlight"});
	$("#result_feedback textarea.lblfy").labelify({labelledClass: "labelHighlight"});
});
{/literal}
</script>
Класс описал в начале темы.

Поправил описание модуля, благодарю!
  • 0