Codeigniter - 提交后在验证失败时重新填充表单

时间:2009-12-29 09:55:19

标签: php codeigniter

我有一个表单,要求用户输入一些信息。如果他们未能完成所需的字段,则会重新显示该表单;页面顶部通知他们需要哪些字段,我已启用粘性表单(set_value()),因此他们的输入不会丢失。

我正在使用flashdata向用户显示消息(即,如果他们输入的内容已存在于数据库中)。

我的表单位于我的控制器的索引方法中。 当从我的视图中单击提交时,它会调用我的控制器中的add()方法。 add()方法执行验证,并根据结果提交到数据库或踢回用户以获取更多数据。

关于我这样做的方式,我有几个问题。 1.如果验证失败,我使用$ this-> index()返回到我的表单并显示验证错误。如果我尝试使用重定向,我会丢失验证错误和我的$ _POST []数据,因此我的粘性表单最终为空白。 2.使用$ this-> index()将'add'附加到我的url的末尾 3.使用$ this-> index()会导致flashdata出现问题。随机结果。

有什么想法吗?

<?php
class Restaurant extends Controller {

    function Restaurant() {
        parent::Controller();
    }

    function index() {

        // Load libraries and models
        $this->load->model('/restaurant/mRestaurantTypes');
        $this->load->model('/restaurant/mRestaurant');
        $this->load->model('/utilities/mUtilities');

        // Get states
        $stateSelect = array();
        $getStates = $this->mUtilities->getStates();

        if($getStates->num_rows() > 0) {
            foreach($getStates->result() as $row) {
                $stateSelect[$row->abbr] = $row->name;
            }
        }


        // Get restaurant types
        $restaurantTypes = array();
        $getRestaurantTypes = $this->mRestaurantTypes->getRestaurantTypes();

        if($getRestaurantTypes->num_rows() > 0) {
            foreach($getRestaurantTypes->result() as $row) {
                $restaurantTypes[$row->restaurant_types_id] = $row->type;
            }
        }

        // Create form elements
        $data['name'] = array(
            'name'      =>  'name',
            'id'        =>  'name',
            'value'     =>  set_value('name'),
            'maxlength' =>  '200',
            'size'      =>  '50'
        );

        $data['address'] = array(
            'name'      =>  'address',
            'id'        =>  'address',
            'value'     =>  set_value('address'),
            'maxlength' =>  '200',
            'size'      =>  '50'
        );

        $data['city'] = array(
            'name'      =>  'city',
            'id'        =>  'city',
            'value'     =>  set_value('city'),
            'maxlength' =>  '50',
            'size'      =>  '25'        
        );

        $data['state'] = $stateSelect;

        $data['zip'] = array(
            'name'      =>  'zip',
            'id'        =>  'zip',
            'value'     =>  set_value('zip'),
            'maxlength' =>  '10',
            'size'      =>  '10'    
        );

        $data['phone'] = array(
            'name'      =>  'phone',
            'id'        =>  'phone',
            'value'     =>  set_value('phone'),
            'maxlength' =>  '15',
            'size'      =>  '15'    
        );

        $data['url'] = array(
            'name'      =>  'url',
            'id'        =>  'url',
            'value'     =>  set_value('url'),
            'maxlength' =>  '255',
            'size'      =>  '50'    
        );

        $data['type'] = $restaurantTypes;

        $data['tags'] = array(
            'name'      =>  'tags',
            'id'        =>  'tags',
            'value'     =>  set_value('tags'),
            'maxlength' =>  '255',
            'size'      =>  '50'    
        );

        $data['active'] = array(
            'name'      =>  'active',
            'id'        =>  'active',
            'value'     =>  'Y',
            'maxlength' =>  '1',
            'size'      =>  '2' 
        );

        // Set page variables
        $data_h['title'] = "Add new restaurant";

        // Load views
        $this->load->view('/template/header', $data_h);
        $this->load->view('/restaurant/index', $data);
        $this->load->view('/template/footer');      

    }


    /**
     * Add the the new restaurant to the database.
     */
    function add() {

        // Load libraries and models
        $this->load->library('form_validation');
        $this->load->model('/restaurant/mRestaurant');

        // Define validation rules
        $this->form_validation->set_rules('name',       'Name',     'trim|required|max_length[255]|xss_clean');
        $this->form_validation->set_rules('address',    'Address',  'trim|required|max_length[100]|xss_clean');
        $this->form_validation->set_rules('city',       'City',     'trim|required|max_length[128]|xss_clean');
        //$this->form_validation->set_rules('state',        'State',    'trim|required');
        $this->form_validation->set_rules('zip',        'Zip',      'trim|required|max_length[128]|xss_clean');
        $this->form_validation->set_rules('phone',      'Phone',    'trim|required|max_length[10]|xss_clean');
        $this->form_validation->set_rules('url',        'URL',      'trim|required|max_length[255]|xss_clean');
        $this->form_validation->set_rules('tags',       'Tags',     'trim|xss_clean');


        // Form validation
        if ($this->form_validation->run() == FALSE) {

            // On failure
            $this->index();

        } else {

            // On success, prepare the data
            $data = array(
                'name'      =>  $_POST['name'],
                'address'   =>  $_POST['address'],
                'city'      =>  $_POST['city'],
                'state'     =>  $_POST['state'],
                'zip'       =>  $_POST['zip'],
                'phone'     =>  $_POST['phone'],
                'url'       =>  $_POST['url'],
                'type'      =>  $_POST['type'],
                'tags'      =>  $_POST['tags'],
                'active'    =>  $_POST['active'],
            );

            // Check if the restaurant already exists
            $check = $this->mRestaurant->getRestaurant($data['name'], $data['zip']);

            // If no records were returned add the new restaurant
            if($check->num_rows() == 0) {
                $query = $this->mRestaurant->addRestaurant($data);

                if ($query) {
                    // On success
                    $this->session->set_flashdata('status', '<div class="success">Added New Restaurant!</div>');
                } else {
                    // On failure
                    $this->session->set_flashdata('status', '<div class="error">Could not add a new restaurant.</div>');    
                }

                redirect('restaurant/confirm', 'refresh');
            } else {
                // Notify the user that the restaurant already exists in the database
                $this->session->set_flashdata('status', '<div class="notice">This restaurant already exists in the database.</div>');
                redirect('restaurant/index');
            }

        }

    }


    function confirm() {

        $data['title'] = "Confirm";

        $this->load->view('/template/header');
        $this->load->view('/restaurant/confirm', $data);
        $this->load->view('/template/footer');
    }
}
?>

4 个答案:

答案 0 :(得分:2)

------- -------控制器

$data['post'] = $_POST;
$this->load->view('view/view', $data);

然后在你看来

  

<input type="text" value="><?=$post['username'];?>" name="username">

答案 1 :(得分:2)

我将尝试帮助我一直使用的控制器中的逻辑:

function index()
{
  //set some default variables
  $data['error_message'] = '';
  //if this is to edit existing value, load it here
  // from database and assign to $data
  //...
  //set form validation rules
  $validation = array();
  $validation['field_name'] = array(
    'field' => 'field_name',
    'label' => 'Field label',
    'rules' => 'trim|required'
  );
  //more rules here
  //...
  $this->load->library('form_validation');
  $this->form_validation->set_rules($validation);
  //run validation
  if ($this->form_validation->run() == FALSE)
  {
    $data['error_message'] .= validation_errors();
  }
  else
  {
    //do insert/update
    //
    //it's better to do redirection after receiving post request
    //you can use flashdata for success message
    if ( $success )
    {
      $this->session_set_flashdata('success_message', MESSAGE_HERE);
    }
    redirect(RESULT_PAGE);
  }
  //reaching this block can have 2 meaning, direct page access, or not have valid form validation
  //assign required variables, such as form dropdown option, etc
  //...
  //load view
  $this->load->view(VIEW_FILE, $data);
}

查看文件:

...
<?php if ( $error_message ): ?>
  <?php echo $error_message; ?>
<?php endif; ?>
<?php echo form_open(current_url, array('id' => 'some_form_id')); ?>
<!-- form field here -->
<label for="field_name">Field label</label>
<input name="field_name" value="<?php echo set_value('field_name', $DEFAULT_FIELD_NAME_IF_NEEDED); ?>" />
<!-- more form field here -->
<?php echo form_close(); ?>
...

我希望这会对你有所帮助。

对于视图文件中的$DEFAULT_FIELD_NAME_IF_NEEDED,如果此表单页面用于编辑数据库中的现有数据,则使用此值传递默认值。您可以在控制器中加载数据,然后将其传递给视图文件并在表单字段中显示。

答案 2 :(得分:1)

我有类似的问题,我最终做了:

我的表单是创建新用户,但您应该明白这一点。

    if($this->form_validation->run() == FALSE) 
        {
            $this->data['title'] = "Add User";
            $this->load->vars($this->data);
            $this->load->view('head');
            $this->load->view('header');
            $this->load->view('admin/sidebar');
            $this->load->view('admin/add_user');
            $this->load->view('footer');
        }

如此有效而不是调用新函数我从同一个函数中显示新视图。 不是最好的解决方案,但它的工作原理。 此外,您可能想要使用这样的东西来检查餐厅是否已经存在:

function _check_username($str) 
{
    $this->db->where('username', $str);
    $query = $this->db->get('sm_users');

    if($query->num_rows() == 0)
    {
        return TRUE;
    }
    else
    {
        $this->form_validation->set_message('_check_username', "User '$str' already exists!");
        return FALSE;
    }
}

并使用回调验证功能:

$this->form_validation->set_rules('userName','User Name','trim|required|min_length[3]|callback__check_username');

答案 3 :(得分:0)

您可以尝试将表单发布到索引,并在索引方法中,如果表单已提交,请进行验证。然后渲染索引视图(如果有错误)或添加餐厅并渲染确认视图。