Я пытаюсь создать многоступенчатую / страничную форму в PHP и CodeIgniter, и мне было интересно, сможет ли кто-нибудь из вас помочь мне.
Как я могу создать многоступенчатую форму в CI, которая обновляет, а не вставляет снова, когда вы возвращаетесь к предыдущему шагу с помощью кнопки «Назад»? Как я могу получить форму, у которой нет такой кнопки отправки POST-формы для отправки сообщений?
Редактировать: без JS, если возможно
Благодаря!
Создайте уникальный идентификатор, который вы используете на всех этапах вашего мастера. Сохраните этот идентификатор в базе данных при первоначальной сохранности вашей формы. Переместите этот идентификатор на следующие шаги, используя input type="hidden"
.
При сохранении шага сначала попробуйте сопоставить идентификатор и, если вы найдете его в базе данных, выполните обновление вместо вставки.
Чтобы избежать «повторной отправки почтовых данных», выполните каждый шаг мастера в двух действиях контроллера CodeIgniter:
Вот мой ответ из другого вопроса. Это дает вам возможность вперед / назад без возможности потерять данные, мгновенно перескакивать между страницами, ЛЕГКО кодировать, не требует сеансов и не зависит от структуры (может использоваться в любой ситуации):
Я разрабатываю продукт для рынка психологии, который делает 250 вопросов психологического тестирования. Чтобы сделать тест, который не является полностью подавляющим, я разбиваю форму на 25 сегментов вопросов, выводя их в цикле через теги div с добавленным последовательным идентификатором (т.е. div1, div2, div3). Каждый div установлен для отображения: никто, кроме первого.
Затем я предоставляю пользователю кнопку, которая переключает текущий div + 1 (т. $(#div2).show()
Если на div 1 он будет делать $(#div2).show()
и т. Д. Обратные кнопки делают наоборот.
Важная часть состоит в том, что форма охватывает ВСЕ div. Тогда это просто вопрос замены кнопки «вперед / назад» в конце кнопкой отправки.
Вуаля! Да, низкотехнологичные. Но FAST …. и нет шансов, что EVER потеряет ценности, идущие вперед или назад.
Итак, грубый усеченный пример:
<form> <div id="div1"> First 25 Questions <input type="button">shows next div</input> </div> <div id="div2" style="display:none"> Second 25 Questions <input type="submit">Submit Form</input> </div> </form>
Если вы хотите избежать сообщений, которые предупреждают пользователя о повторных сообщениях, и вы также хотите иметь несколько правильных страниц, а не просто разные шаги в javascript, вы можете поместить ответы в URL как параметры GET .. так что после первой формы вы получите form2.php? в URL .. вы можете добавить эти ответы как скрытые переменные в form2 и так далее.
Однако это не очень изящное решение. Я бы рекомендовал вам использовать javascript: добавьте настраиваемый обработчик для отправки формы и отправьте содержимое формы через ajax, а затем загрузите следующую форму в ajax complete.
Кроме того, как и любой другой человек, на сервере, вам понадобится уникальный идентификатор, который извлекает / обновляет данные представления в базе данных.
Мне нравится подход ожидания обновления базы данных до тех пор, пока все этапы не будут завершены. Вы можете хранить все данные на промежуточных этапах сеанса. Я полагаю, что вы даже можете сохранить используемый объект модели (если вы используете его) в сеансе, и после того, как все шаги будут выполнены, вы можете выполнить вставку базы данных.
У меня есть модель для хранения данных моего мастера с переменной для каждого поля в форме:
class Class_signup_data extends CI_Model { const table_name="signups_in_progress"; public $market_segment; // there is a field named 'market_segment' in the wizard view
… …
У меня есть один контроллер для обработки всего процесса с параметрами session_id и этапом процесса, на котором мы находимся:
class Signup extends CI_Controller { public function in_progress($session_id=NULL,$stage=1) { $this->index($session_id,$stage); } public function index($session_id=NULL,$stage=1) { if ($session_id===NULL) $session_id=$this->session->userdata('session_id'); ... ...
В этом контроллере у меня есть переключатель, на каком этапе мы находимся – он сначала ищет кнопку «Prev»:
switch ($stage) { case 2: if ($this->input->post('prev')) { // if they click Previuous, the validations DON'T need to be met: $signup_data->save_to_db(array_merge(array('ip'=>$_SERVER['REMOTE_ADDR'],'session_id'=>$session_id,'signup_stage' => '1', 'signup_complete' =>'0'),$this->input->post()),$this->db,$session_id); $this->load->helper('url'); redirect("/signup/in_progress/".$session_id."/1");
И позже в коммутаторе я использую CI's Validations для отображения формы и процесса «Далее», если она была нажата, или просто вызывается с / signup / in_progress / session / 2:
$this->form_validation->set_rules("your rules"); if ($this->form_validation->run() == FALSE) { $this->load->view('signupStage2',array('signup_data'=>$signup_data)); } else { $signup_data->save(array_merge(array('ip'=>$_SERVER['REMOTE_ADDR'],'session_id'=>$session_id,'signup_stage' => '3', 'signup_complete' =>'0'),$this->input->post()),$this->db,$session_id); $this->load->helper('url'); redirect("/signup/in_progress/".$session_id."/3"); };
В нижней части каждого представления (например, «signupStage2.php») у меня есть предыдущие и следующие кнопки:
<span class="align-left"><p><input type="submit" name="prev" class="big-button" value="<- Prev" /><input type="submit" name="next" class="big-button" value="Next ->" /></p></span>