Friday, 31 January 2020

Form with multiple steps php

1. If you want to create a multiple step form you can follow below step , i am using codeigniter as my framwork php , index function is a single function which will handle your request and process your form , $form_process_id,$form_id,$step_id_u,$is_previous_action is the main variable other variable are my custom variable which i am passing , you can assign your variable as per your requirement.

2. fpi short means form process id, multiple if else in index function is for like when you in step1 include only step1 data , if you in step 2 include only step2 data by fetching records from mysql.

3. if you see the screenshot there is a table which contain post_values,post_values_front fields in mysql , post_values fields store form data as serialize at user end and post_values_front store the html which you can be save from your admin panel.

4. $data['main'] in index function just get the in which step you are and fetch accordingly. you have to create a directory stepforms , where step1.php , step2.php.... etc file will be created as per multi form you want to create , Please see below what html they will containstep1.php ...etc. i have included my custom variable also for query to database you can remove those. I commented the $save_step_data in else statement because for front end user update query always fire not new record will be added because from your admin panel step data , html already saved, for admin panel you have to enable those line , because admin side iif fpi found then update if not then insert/save will goes accordinlgy. you can also include js/jquery in step1.php or step2.php etc. you can use below function for any kind of multiple user registration or where you need any kind of multiple form submission.

class MultiStep extends MY_Controller {
    public function index() {
        $search_gstin_id = (int) isset($_GET['sid']) ? trim($this->input->get('sid', TRUE)) 
: trim($this->input->post('sid', TRUE));
      $financial_year = isset($_GET['fy']) ? $this->input->get('fy', TRUE) : $this->input->post('fy', TRUE);
      $form_process_id = (int) $this->input->get('fpi');
      $is_previous_action = $this->input->get('p');
      $form_id = $this->uri->segment(3, 0);
      $step_id_u = $this->uri->segment(4, 1);
      $step_id_p = isset($_POST['step_id']) ? (int) $step_id_u : $step_id_u;
      $this->load->model('AuditCustomForms');
      $total_steps = $this->AuditCustomForms->get_total_form($form_id);
      $form_name_info = $this->AuditCustomForms->get_form_name($form_id);
      if ($step_id_p != '') {
          if ($is_previous_action != '') {
              $field_id = (int) $step_id_p;
          } else {
              $field_id = (int) $step_id_p;
          }
      } else {
          $field_id = $step_id_u;
      }
      $form_info = $this->AuditCustomForms->get_step_from($form_id, $field_id);
      $form_data = $this->AuditCustomForms->get_from_data($form_process_id, $field_id);
      $save_id = '';
      if (!empty($_POST) && is_array($_POST)) {
          $sdata = $this->input->post();
          unset($sdata['step_id']);
          unset($sdata['form_id']);
          if ($this->input->get('isf') == 'yes') {
              if (!empty($form_data)) {
                $save_step_data = array('post_values_front' => serialize($sdata), 'status' => 1,
 'search_gstin_id' => $search_gstin_id, 'gst_financial_year' => $_POST['fy']);
                $save_id = $this->AuditCustomForms->do_update_records('audit_post_values',
 $save_step_data, array('form_process_id' => $form_process_id, 'field_id' => $step_id_u));
              } else {
               //$save_step_data = array('status' => 1, 'form_process_id' => $form_process_id
, 'user_id' => $this->user_id, 'form_id' => $form_id, 'field_id' => $step_id_u,
 'post_values_front' => serialize($sdata), 
'created_date' => $this->today, 'search_gstin_id' => $_POST['sid'], 'gst_financial_year' => $_POST['fy']);
                //$save_id = $this->AuditCustomForms->do_save_records('audit_post_values', $save_step_data);
              }
            $_SESSION['markfront'] = alertmessage($message_type = 'alert-success', 
$message = 'TaxAudit have been saved successfully.');
              $this->session->mark_as_flash('markfront');
              redirect(base_url() . '/dashboard/');
              exit;
           } else {
           if (!empty($form_data)) {
              $save_step_data = array('status' => 1, 'post_values_front' => serialize($sdata),
 'search_gstin_id' => $search_gstin_id, 'gst_financial_year' => $_POST['fy']);
             $save_id = $this->AuditCustomForms->do_update_records('audit_post_values'
, $save_step_data, array('form_process_id' => $form_process_id, 'field_id' => $step_id_u - 1));
           } else {
            //$save_step_data = array('status' => 1, 
'form_process_id' => $form_process_id, 'user_id' => $this->user_id, 'form_id' => $form_id,
'field_id' => $step_id_u, 'post_values_front' => serialize($sdata),
'created_date' => $this->today, 'search_gstin_id' => $_POST['sid'], 'gst_financial_year' => $_POST['fy']);
            //$save_id = $this->AuditCustomForms->do_save_records('audit_post_values', $save_step_data);
           }
          }
        }
        if ($step_id_u == 2) {
        } else if ($step_id_u == 3) {
        } else if ($step_id_u == 4) {
        } else if ($step_id_u == 5) {
        } else if ($step_id_u == 6) {
        } else if ($step_id_u == 7) {
        } else if ($step_id_u == 8) {
        } else if ($step_id_u == 9) {
        } else if ($step_id_u == 10) {
        } else if ($step_id_u == 11) {
        } else if ($step_id_u == 12) {
        } else {
        }
        $data['search_gstin_id'] = $search_gstin_id;
        $data['financial_year'] = $financial_year;
        $data['form_process_id'] = $form_process_id;
        $data['form_info'] = $form_info;
        $data['form_data'] = $form_data;
        $data['form_id'] = $form_id;
        $data['next_step'] = count($form_info) > 0 ? $form_info[0]->field_id : '';
        $data['actual_step_id_p'] = $step_id_p;
        $data['post_id'] = $save_id;
        $data['form_name_info'] = $form_name_info;
        $data['header'] = 'dashboard/header';
        $data['main'] = 'stepforms/' . $form_id . '/' . $form_info[0]->step;
        $data['footer'] = 'front/footer';
        $this->load->vars($data);
        $this->load->view($this->user_dashboard);
    }
}

5. Below is the model which contain function for saving and updating form data ,generateFormToken function will generate a unique fpi for your form. model is just fetching records from mysql database.

class AuditCustomForms extends CI_Model {
    function __construct() {
        parent::__construct();
        $this->load->database();
    }
    function generateFormToken() {
        $query = $this->db->query('SELECT LPAD(FLOOR(RAND()*99999), 5, 0) AS random_num FROM 
        audit_post_values WHERE "random_num" NOT IN (SELECT post_id FROM audit_post_values) LIMIT 1');
        $row = $query->row();
        if (isset($row)) {
            return $row->random_num;
        } else {
            $query = $this->db->query('SELECT LPAD(FLOOR(RAND()*99999), 5, 0) AS random_num');
            $row = $query->row();
            return $row->random_num;
        }
    }
    function get_step_from($form_id, $field_id) {
        $this->db->select('ff.*');
        $this->db->from('audit_form_fields ff');
        $this->db->where('ff.form_id', $form_id);
        $this->db->where('ff.field_id', $field_id);
        $query = $this->db->get();
        return $query->result();
    }
    function do_update_records($table, $data, $where) {
        $this->db->where($where);
        if ($this->db->update($table, $data)) {
            $query_id = $this->db->select('post_id')->where($where)->get($table);
            return $query_id;
        } else {
            return NULL;
        }
    }
    function do_save_records($table, $data) {
        if ($this->db->insert($table, $data)) {
            return $this->db->insert_id();
        } else {
            return NULL;
        }
    }
    function get_from_data($form_process_id, $field_id) {
        $this->db->select('*');
        $this->db->from('audit_post_values pv');
        $this->db->where('pv.form_process_id', $form_process_id);
        $this->db->where('pv.field_id', $field_id);
        $query = $this->db->get();
        if ($query->num_rows() > 0) {
            return $query->result();
        } else {
            return NULL;
        }
    }
}

6. Below is the first step form , either you can include html directly to below view file or if you want to fetch html from database for example you have a admin panel where you manage content , you can also make or use same function for your admin panel which store only html in post_values fields as serialised and them you can use it like below or replace "//your html element , form will go here step 1" by below line , so what ever html you saved from your admin panel it will display that html for step1 , step2.....etc.

$str_template=!empty($form_html['auditforms']) ? html_entity_decode($form_html['auditforms']) : '';
<?php
if (!empty($form_data)) {
    $form_html = unserialize($form_data[0]->post_values);
    $post_values_front = unserialize($form_data[0]->post_values_front);
}
?><section class="section novi-background sec_nw">
    <div class="container">
        <div class="section-sm-41 row justify-content-sm-center align-items-sm-center">
            <div class="card section-34">
                <?php echo form_open(base_url() . 'MultiStep/index/
' . $form_id . '/2/?fpi=' . $form_process_id . '&sid=' . $search_gstin_id . '&fy=' . $financial_year . ''
, array('class' => "", 'autocomplete' => "on", 'id' => 'form1', 'name' => 'form1', 'method' => 'post')); ?>
                <input type="hidden" name="form_id" id="form_id" 
value="<?php echo!empty($form_info) ? $form_info[0]->form_id : ''; ?>"> 
                <input type="hidden" name="step_id" id="step_id" value="<?php echo $next_step; ?>"> 
                <input type="hidden" name="sid" id="sid" value="<?php echo $search_gstin_id; ?>"> 
                <input type="hidden" name="fy" id="fy" value="<?php echo $financial_year; ?>"> 
                //your html element , form will go here step 1
                <input type="submit" class="btn bg-orange btn-flat pull-right" value="Next"/>
                <?php echo form_close(); ?> 
            </div>
        </div>
    </div>
</section>

7. Below is the step2 so previous and next value assign accordingly. you can set previous and next value or step_id, only your html part will be dynamic from mysql.

<section>
    <div class="container profile-edit">
        <div class="section-sm-41 row justify-content-sm-center align-items-sm-center">
            <div class="card section-34">
                <?php echo form_open(base_url() . 'MultiStep/index/
' . $form_id . '/3?fpi=' . $form_process_id . '&sid=' . $search_gstin_id . '&fy=' . $financial_year . ''
, array('class' => "", 'autocomplete' => "on", 
'enctype' => "multipart/form-data", 'id' => 'step1', 'name' => 'step1', 'method' => 'post')); ?>
                <input type="hidden" name="form_id" id="form_id" 
value="<?php echo!empty($form_info) ? $form_info[0]->form_id : ''; ?>"> 
                <input type="hidden" name="step_id" id="step_id" value="<?php echo $next_step; ?>">
                <input type="hidden" name="sid" id="sid" value="<?php echo $search_gstin_id; ?>"> 
                <input type="hidden" name="fy" id="fy" value="<?php echo $financial_year; ?>"> 
                //your html element , form will go here step 2
                <div class="col-offset-10">
                    <a href="<?php echo base_url() . 'MultiStep/index/
' . $form_info[0]->form_id . '/1/?sid=' . $search_gstin_id . 
'&fpi=' . $form_process_id . '&p=' . $actual_step_id_p . '&audit_form_id=' . $form_id . 
'&fy=' . $financial_year; ?>" class="btn bg-orange btn-flat pull-left">Prev</a>
                    <input type="submit" class="btn bg-orange btn-flat pull-right" value="Next"/>
                </div>
                <?php echo form_close(); ?> 
            </div>
        </div>
    </div>
</section>

8.In my project there are 24 steps so that is my last step , may in your case there is less step then mine , if you are making your last step so &isf=yes should be added in rest of step isf will not add to recognise last we are in last request.

<section class="section novi-background sec_tab">
    <div class="container profile-edit">
        <div class="section-sm-41 row justify-content-sm-center align-items-sm-center">
            <div class="card section-34 ">
                <?php echo form_open(base_url() . 'TaxAudit/index/
' . $form_id . '/24/?fpi=' . $form_process_id . '&isf=yes', array('class' => "", 
'autocomplete' => "on", 'id' => 'form1', 'name' => 'form1', 'method' => 'post')); ?>
                <input type="hidden" name="form_id" id="form_id" 
value="<?php echo!empty($form_info) ? $form_info[0]->form_id : ''; ?>"> 
         <input type="hidden" name="step_id" id="step_id" value="<?php echo $next_step; ?>"> 
         <input type="hidden" name="sid" id="sid" value="<?php echo $search_gstin_id; ?>"> 
         <input type="hidden" name="fy" id="fy" value="<?php echo $financial_year; ?>"> 
          //your html element , form will go here step finished
        <div class="col-offset-10">
        <a href="<?php echo base_url() . 'TaxAudit/index/
' . $form_info[0]->form_id . '/23/?sid=' . $search_gstin_id . '&fpi=
' . $form_process_id . '&p=' . $actual_step_id_p.'&
audit_form_id=' . $form_id . '&fy=' . $financial_year; ?>" class="btn bg-orange btn-flat pull-left">Prev</a>
           <input type="submit" class="btn bg-orange btn-flat pull-right" value="Finished"/>
           </div>
           <?php echo form_close(); ?> 
     </div>
     </div>
    </div>
</section>

9. The screenshot will show you the table structure to manange multi step form.