CodeIgniter: Всплывающая форма обратной связи на Ajax в Bootstrap Modal и проверкой Captcha

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">&times;</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.

codeigniter форма связи на ajax с капчей в bootstrap modal

Замечу, я писал ранее о том, как в Yii выводить модальное окно. Если сравнить как это делается в Yii и в CodeIgniter, то всё таки в Yii это проще реализуется, и с капчей меньше проблем, но по количеству кода примерно одинаково.

Отвлечёмся - красивые места: Норвегия. Лофотенские острова.

Норвегия, Лофотенские острова

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (1)     Подпишитесь на RSS комментариев к этой статье.

1 комментарий

#1168
Юлия говорит:
June 20, 2014 at 10:22 am

А где  в контроллере нужно прописать проверку, что запрос пришел по AJAX (is_ajax или как-то так), а не просто набором

в строке url:  ww.имя сайта/request/register_ajax ?