2009-12-29 3 views
6

У меня есть форма, которая требует, чтобы пользователь вводил некоторую информацию. Если они не смогут заполнить обязательные поля, они будут повторно представлены формой; в верхней части страницы уведомления о том, какие поля необходимы, и я включил липкие формы (set_value()), чтобы их вход не был потерян.Codeigniter - повторно заполняющая форма при неудачной проверке после отправки

Я использую 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'); 
    } 
} 
?> 

ответ

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 в файле просмотра я использую это, чтобы передать значение по умолчанию, если эта страница формы предназначена для редактирования существующих данных из базы данных. Вы можете загрузить данные в контроллере, затем передать его для просмотра файла и отображения его в поле формы.

0

Вы можете попробовать иметь сообщение о форме для индексации и в методе индекса выполнить проверку, если форма была отправлена. Затем либо визуализируйте индексный указатель (если есть ошибки), либо добавьте ресторан и отобразите подтверждение.

+0

Я переместил весь код из метода add() в index(), затем попытался проверить, было ли отправлено: if (isset ($ _ POST ['add'])) {~~} Это работает в первый раз, когда форма отображается; однако, поскольку $ _POST ['add'] установлен, в следующий раз, когда пользователь нажимает add, а правила проверки еще не встречаются, он будет зацикливаться. Я бы все же хотел использовать метод add() вместо того, чтобы компилировать весь код в индексе. – mazer

+0

Я думаю, вы хотите, чтобы он зацикливался до тех пор, пока все правила проверки не пройдут, верно? И вы можете перенести всю свою проверку и добавить код к приватным методам или библиотечным методам, а затем при необходимости вызвать их из метода индекса. – Coomer

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'); 
+0

У меня была такая же проблема, '$ this-> load-> library ('form_validation');' переместил эту строку в '__constructor', и она работает –

2

------- контроллер ---- ---

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

затем на ваш взгляд

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