CodeIgniter: Всплывающая форма обратной связи на Ajax в Bootstrap Modal и проверкой Captcha
Делаем сквозную форму отправки сообщения на email из всплывающей в модальном окне Bootstrap Modal формы со всеми валидациями и проверкой капчи. Добавляем саму форму (в модальном окне) и ссылку-кнопку её открытия. Это в шаблон html
<div class="askquestion"><a class="searchbutton" href="#registerModal" data-toggle="modal">Задать вопрос онлайн</a></div>
<!-- Modal Question form -->
<div class="modal fade" id="registerModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Задать вопрос</h4>
</div>
<div class="modal-body clearfix">
<div id="registerModalerror" style="display: none;"></div>
<form class="" id="registerModalform" enctype="multipart/form-data" action = "" method="post">
<div class="row-fluid">
<div class="formField">Представьтесь, пожалуйста<span class="star"> *</span><br />
<span class="formFieldString"><input id="name" name="name" type="text" size="20" maxlength="255" value="<?php echo set_value('name');?>" /></span>
<span class="red"><?php echo form_error('name');?></span>
</div>
<div class="formField">Телефон<span class="star"> *</span><br />
<span class="formFieldString"><input name="phone" type="text" size="20" maxlength="255" value="<?php echo set_value('phone');?>" /></span>
<span class="red"><?php echo form_error('phone');?></span>
</div>
<div class="formField">Ваш e-mail<br />
<span class="formFieldString"><input name="email" type="text" size="20" maxlength="255" value="<?php echo set_value('email');?>" /></span>
<span class="red"><?php echo form_error('email');?></span>
</div>
<div class="formField">Желаемая программа<br />
<span class="formFieldString"><input name="program" type="text" size="20" maxlength="255" value="<?php echo set_value('program');?>" /></span>
<span class="red"><?php echo form_error('program');?></span>
</div>
<div class="formField">Ваше сообщение<span class="star"> *</span><br />
<textarea cols="80" rows="8" id="text" name="text"><?php echo set_value('text');?></textarea>
<span class="red"><?php echo form_error('text');?></span>
<div id="imag"><?=$imgcode?></div>
<label for="posCaptcha"><b>Текст на изображении<span class="star"> *</span></b>:<br /></label>
<span class="small">Просто дайте нам понять, что вы не спамер.</span>
<input class="text1" type="text" size="15" name="captcha" id="keystring" />
<span class="red"><?php echo form_error('captcha');?><span id="info"><?php echo $info;?><span></span>
</div>
</div>
<div class="modal-footer">
<button type="submit" name="send_message" class="btn btn-lg btn-primary" id="registerModalsubmit">Отправить</button>
</div>
</form>
</div>
</div>
</div>
</div>
Для капчи создал библиотеку libraries/Captcha.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Captcha
{
public function captcha_actions()
{
$CI =& get_instance ();
//Загружаем плагин Капча
$CI->load->helper('captcha');
//Загружаем хэлпер для генерирования случайной строки
$CI->load->helper('string');
$rnd_str = random_string('numeric',5);
//Записываем строку в сессию
$ses_data = array();
$ses_data['rnd_captcha'] = $rnd_str;
$CI->session->set_userdata($ses_data);
//Параметры картинки
$settings = array(
'word' => $rnd_str,
'img_path' => './images/captcha/',
'img_url' => base_url().'images/captcha/',
'font_path' => './css/fonts/Pilgiche.ttf',
'img_width' => 120,
'img_height' => 40,
'expiration' => 7200
);
//Создаем капчу
$captcha = create_captcha($settings);
//Получаем в переменную код картинки
$imgcode = $captcha['image'];
return $imgcode;
}
}
?>
А валидация полей происходит обращением к массиву в config/form_validation.php
<?php $config = array( 'contact_rules' => array( array ( 'field' => 'name', 'label' => 'Имя', 'rules' => 'trim|required|xss_clean|max_length[70]' ), array ( 'field' => 'phone', 'label' => 'Телефон', 'rules' => 'trim|required|xss_clean|max_length[70]' ), array ( 'field' => 'email', 'label' => 'Е-mail', 'rules' => 'trim|valid_email|xss_clean|max_length[70]' ), ... array ( 'field' => 'captcha', 'label' => 'Цифры с картинки', 'rules' => 'required|numeric|exact_length[5]' ) ) );
Дальше в контроллере (контроллер Request) создаём функцию, которая будет вызываться асинфронно по ajax соответствующим скриптом из html фаблона
public function register_ajax()
{
/*$this->form_validation->set_rules('full_name', 'Name', 'trim|required|min_length[4]|max_length[25]');
$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[4]|max_length[15]|is_unique[accounts.username]');
$this->form_validation->set_rules('password1', 'Password', 'trim|required|min_length[6]|max_length[25]');
$this->form_validation->set_rules('password2', 'Password Confirmation', 'trim|required|min_length[4]|max_length[25]|matches[password1]');
$this->form_validation->set_rules('email', 'Email', 'trim|required|min_length[4]|max_length[40]|valid_email|is_unique[accounts.email]');
$this->form_validation->set_message('is_unique', 'Sorry but that %s is already in use!');
*/
if($this->form_validation->run('contact_rules') === FALSE)
{
//$this->data['imgcode'] = $this->captcha->captcha_actions();
//$this->data['info'] = 'Неверно введены цифры с картинки';
echo json_encode(array('error' => '1', 'message' => validation_errors('<div class="alert alert-error"><strong>Ошибка!</strong> ', '</div>')));
} else {
//Получаем значение поля капча
$entered_captcha = $this->input->post('captcha');
//Если капча совпадает, отправляем письмо
if ($entered_captcha == $this->session->userdata('rnd_captcha'))
{
$this->load->library('typography');
$name = $this->input->post('name');
$phone = $this->input->post('phone');
$email = $this->input->post('email');
$program = $this->input->post('program');
$text = $this->input->post('text');
$text = wordwrap($text,70); //PHP
$text = $this->typography->auto_typography($text,TRUE);
$text = strip_tags($text); //PHP
$address = "admin@yoursite.ru";
$subject = "Sitename: $name написал(а) письмо";
$message = '
Имя: <b>'.$name.'</b><br />
Телефон: <b>'.$phone.'</b><br />
E-mail: <b>'.$email.'</b><br />
Желаемая программа: <b>'.$program.'</b><br />
<br />
<font size=+1>Сообщение:</font><br />
<b>'.$text.'</b>
';
// Для отправки HTML-почты вы можете установить шапку Content-type.
$headers = "MIME-Version: 1.0\r\n";
$headers .='From: '.$email."\n";
$headers .= "Content-type: text/html; charset=utf-8\r\n";
$headers .="Content-Transfer-Encoding: 8bit\n";
mail ($address,$subject,$message,$headers);
//$this->session->set_flashdata('message', '<div class="message_success">Ваше сообщение отправлено. Мы свяжемся с вами в кратчайшие сроки.</div>');
//Send the success to our javascript file.
echo json_encode(array('error' => '0', 'message' => '<div class="alert alert-success"><strong>Спасибо!</strong> Мы вам скоро ответим. Хорошего дня!</div>'));
}
// Если капча не совпадает
else
{
//Получаем код картинки;
$this->data['imgcode'] = $this->captcha->captcha_actions();
$this->data['info'] = 'Неверно введены цифры с картинки';
echo json_encode(array('info'=>$this->data['info'],'imgcode'=>$this->data['imgcode'],'error' => '1', 'message' => validation_errors('<div class="alert alert-error"><strong>Ошибка!</strong> ', '</div>')));
}
}
}
Теперь наш скрипт в представлении (в шаблоне)
<script type="text/javascript">
//Wait until the DOM is fully loaded
$(document).ready(function(){
//Listen for the form submit
$('#registerModalform').submit(registerUser);
});
//The function that handles the process
function registerUser(event)
{
//Stop the form from submitting
event.preventDefault();
//Collect our form data.
var form_data = {
name : $("[name='name']").val(),
phone : $("[name='phone']").val(),
email : $("[name='email']").val(),
program : $("[name='program']").val(),
text : $("[name='text']").val(),
captcha : $("[name='captcha']").val()
};
//Begin the ajax call
$.ajax({
url: "<?php echo base_url();?>request/register_ajax",
type: "POST",
data: form_data,
dataType: "json",
cache: false,
success: function (json) {
if (json.error==1)
{
//Show the user the errors.
$('#registerModalerror').html(json.message).show();
$('#imag').html(json.imgcode).show();
$('#info').html(json.info).show();
} else {
//Hide our form
$('#registerModalform').slideUp();
//Show the success message
$('#registerModalerror').html(json.message).show();
}
}
});
}
</script>
Здесь по id #imag и #info, будет асинхронно меняться картинка капчи и сообщение о неправильно введённой капче.
Также надо не забыть вставить (стили в начало, js - вконец)
<link type='text/css' href="<?php echo base_url();?>bootstrap/css/bootstrap.css" rel='Stylesheet' /> ... <script src="<?php echo base_url();?>bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
И я вынес задание капчи и сообщения info в главный контроллер (так как форма нужна на всех страницах сайта).
...
// Для формы Задать Вопрос онлайн
$this->load->library('captcha');
$this->data['info'] = ''; //Информационное сообщение, message: изначально пусты!
// Не нажата кнопка "Отправить"
if ( ! isset($_POST['send_message']))
{
//Получаем код картинки
$this->data['imgcode'] = $this->captcha->captcha_actions();
}
...
Решение успешно внедрено и работает на одном из наших проектов на CodeIgniter.

Замечу, я писал ранее о том, как в Yii выводить модальное окно. Если сравнить как это делается в Yii и в CodeIgniter, то всё таки в Yii это проще реализуется, и с капчей меньше проблем, но по количеству кода примерно одинаково.
almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.
Вы можете почитать все статьи от almix'а.
- 0 Yii: Bootstrap tabs, делаем активной вкладку на которую выполняется переход по ссылке (20.03.2014)
- 0 CodeIgniter: Всплывающая форма обратной связи на Ajax в Bootstrap Modal и проверкой Captcha (18.02.2014) ← вы тут
- 0 Opencart: Модуль Filter Product OpenCart_v1.5.x: Как скрывать недоступные опции в фильтре (23.10.2013)
- 0 WordPress: Добавить ссылку "Сохранить фото" для галереи на NextGen с эффектом Lightbox (12.04.2013)
- Выдвигающаяся из значка форма поиска на сайте (27.11.2017)
- Как убрать placeholder при клике по input (04.11.2017)
- Свой дизайн кнопок социальных сетей для сайта. Кнопки "Поделиться" (19.06.2017)
- Загрузка файлов (картинок) по ajax через форму для Opencart (04.09.2016)
- Замена текста при наведении на него мышью. События onmouseover и onmouseout (25.03.2016)
- Прилипание блока к верху сайта при его прокручивании (17.02.2016)
- Разделитель тысяч в эффекте наматываемого счётчика jquery countTo (05.04.2015)
- Сделать слайдер на Owl Carousel c текстом справа (03.02.2015)
- Скролл-эффекты CSS3 и JQuery при прокрутке страницы (13.01.2015)
- Модальное окно Bootstrap 3 с формой, отправляющей email по Ajax (JQuery/PHP/HTML5/JqBootstrapValidation) (20.08.2015)
- Несколько функций в body onload (08.03.2013)
- Как в iframe показывать только определённую область страницы (04.03.2013)
- Как правильно обновить ExpressionEngine до последней версии 2.5.5 (05.02.2013)
- Team Sense: Доступна отправка сообщения/письма на email сотрудника. (18.01.2013)
- TeamSense: username (логин) в регистрации пользователя. Внедрили библиотеку DHTMLX в TeamSense. (11.01.2013)
- Team Sense: В календарь добавлена возможность указывать место проведения уроков (в офисе, на выезде) (12.12.2012)
- jQuery Tooltips от Jörn Zaefferer. Всплывающие подсказки с помощью jQuery (08.12.2012)
- Team Sense: Многопользовательский календарь, заменяем радиокнопки на чекбоксы в выборе преподавателей. Массивы в Javascript. (06.12.2012)
- Team Sense: В календарь-расписание уроков добавлено разделение по преподавателям, которым присвоены свои цвета. (04.12.2012)
- CodeIgniter не передаёт $this->uri->segment(3) в функцию контроллера (передача переменной PHP->JavaScript->PHP) (28.11.2012)
- Случаи возникновения ошибки в IE: "Предполагается наличие идентификатора, строки или числа" (Expected identifier, string...) (23.11.2012)

1 комментарий
А где в контроллере нужно прописать проверку, что запрос пришел по AJAX (is_ajax или как-то так), а не просто набором
в строке url: ww.имя сайта/request/register_ajax ?