Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [CI] Edycja danych z bazy a form_validation
Forum PHP.pl > Forum > PHP > Frameworki
abort
W kontrolerze definiuję sobie za pomocą $this->form_validation->set_rules, jakie mogą być dopuszczalne wartości pól w formatce, następnie wywołuję widok:
  1. $hw = $this->sprzet->get_hwdata ($id); // id to numer indeksu w bazie (auto_increment)
  2. $data['hw'] = $hw;
  3. if ($this->form_validation->run() == FALSE) {
  4. $this->load->view('/hardware/edit', $data);
  5. } else {
  6. [...]
  7. }

I fajnie - do widoku zostały przekazane dane. Chciałbym jednak, aby wprowadzenie błędnych danych skutkowało zmianą np. koloru wyświetlenia elementu "<input type=text>", z zachowaniem (wyświetleniem) danych wprowadzonych przez użytkownika. Wymyśliłem sobie więc, że w widoku wpakuję ciukę kodu, efekt:
  1. foreach (array ( [tu indeksy przekazywane przez HTTP_POST] ) as $key) {
  2. if (isset ($_POST [$key])) {
  3. $hw[$key] = set_value ($key);
  4. } else {
  5. $hw[$key] = $db[$key];
  6. }
  7. }
  8.  
  9. // a dalej w kodzie sprawdzam, co wprowadził user, i jeśli jest źle, to wizualnie mu to sygnalizuję
  10. // (np. przez zmianę backgroundu elementu INPUT TYPE=TEXT)
  11.  
  12. $manufact = array (
  13. 'name' => 'manufact',
  14. 'id' => 'manufact',
  15. 'value' => $hw['manufact'],
  16. 'class' => ''
  17. );
  18. if (form_error ('manufact')) {
  19. $manufact['class'] .= 'error';
  20. }
  21. echo '<div class="manufact">Producent:' . form_input ($manufact) . '</div>';


Pytania:
1. Czy da się prościej?
2. kłuje w oczy użycie $_POST, ale taka konstrukcja działa, podczas gdy użycie if (isset ($this->input->post($key))) wyrzuca błąd: Fatal error: Can't use method return value in write context in [...] - o co kaman, przecież nic nie zapisuję, tylko testuję, czy "coś" istnieje...
3. Da się (to co chcę) zrobić inaczej, prościej, bardziej elegancko?

P.S.
CodeIgniter 2.1.0, więc całkiem nowy.
phpion
1 + 3. Ja stosuję taki mechanizm (pseudokod):
  1. $form = array();
  2. $errors = array();
  3.  
  4. if (wyslano_postem()) {
  5. if (dane_sa_poprawne()) {
  6. // zapis danych do bazy
  7. // przekierowanie czy cokolwiek
  8. }
  9. else {
  10. $form = przeslane_dane();
  11. $errors = wykryte_bledy();
  12. }
  13. }
  14. else {
  15. // ustawienie poczatkowych wartosci $form
  16. }
  17.  
  18. $view->form = $form;
  19. $view->errors = $errros;


2. Spróbuj samo:
  1. if ($this->input->post($key))
abort
Rada dotycząca pytania 2 pomogła, dzięki.
Natomiast jeśli chodzi o pytania 1 i 3, to mam lekkie wątpliwości: wygląda mi na to, że w CI walidacja wprowadzonych widoków wykonuje się w kontrolerze - wszak w kontrolerze tworzę callbacki do niestandardowej weryfikacji danych (http://codeigniter.com/user_guide/libraries/form_validation.html i poszukać po "Callbacks: Your own Validation Functions"). Widzę też, że Ty rozumujesz podobnie (jeśli dobrze czytam kod): robisz to w kontrolerze, w którym testujesz dane, ustawiasz parametry widoku, czy zapisujesz do bazy (przecież z widoku nikt nie zapisuje do bazy, prawda?)

Natomiast ja swoje proste foreach dopisałem już w samym widoku - i tu mam lekki zgryz, bo z jednej strony jest to krótsze, poza tym sam mój kod odwołuje się (jak by na to nie patrzeć) do PREZENTACJI danych (dane zostały wprowadzone źle, więc wyświetlmy je użytkownikowi w WIZUALNY sposób używając odpowiedniej klasy CSS). Choć z drugiej strony operuję niejako na poprawności danych (choć ich nie sprawdzam, bo tę robotę odwala kontroler).

No i pozostaje pytanie: co lepsze? A może ja nie rozumiem OOP (wszak dopiero zaczynam) smile.gif
phpion
Reguły walidacji możesz przypisywać w modelu, a w kontrolerze jedynie sterować "przepływem" danych w sposób, jaki opisałem. Nie musisz dawać żadnych foreachów ani w widoku, ani w kontrolerze.

W dokumentacji CI nie znalazłem prawdziwego kodu pasującego do mojego pseudokodu, ale spójrz na na ten z Kohany:
http://kohanaframework.org/3.2/guide/kohan...rity/validation (sekcja "A Complete Example")

PS: To, że w dokumentacji większość rzeczy pokazana jest w kontrolerach nie znaczy, że tak musi być. Zapewne chodziło o prostotę przekazu i maksymalnie uproszczenie przedstawianego kodu.
abort
Dzięki za wytłumaczenie w prosty sposób.
Niestety, nie programuję zawodowo (i nie zamierzam - za stary jestem, by zmieniać zawód), więc chyba aktualnie nie poradzę sobie z przerobieniem mojego kodu na taki, który zakłada robienie wszystkiego w modelu. Pomimo tego, że czuję, że tak to powinno wyglądać.

Odnośnie Kohany - być może spróbuję poznać tego frameworka, jednak to też jest sprawa "na potem". Bo na razie, skoro już wybrałem CI, to chciałbym skończyć to, co zacząłem - potem w ramach nauki Kohany mogę spróbować zmigrować swój kod z CI na Kohana.
szok
Zrób tak:

Plik:
application/librares/MY_Form_validation.php
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3.  * MY_Form_validation
  4.  *
  5.  * @package CodeIgniter
  6.  * @subpackage Libraries
  7.  * @category form validation
  8.  * @author Jarolewski Piotr (aka szok) jarolewski.piotr@gmail.com
  9.  */
  10.  
  11. class MY_Form_validation extends CI_Form_validation {
  12.  
  13. /**
  14.   * Class Constructor
  15.   */
  16.  
  17. public function __construct()
  18. {
  19. parent::__construct();
  20. /*
  21.   * Podmiana domyslnego wysweitlania bledow
  22.   */
  23. $this->set_error_delimiters('class="error"', '');
  24. }
  25.  
  26. public function error($field = '', $prefix = '', $suffix = '')
  27. {
  28. if($prefix == TRUE)
  29. {
  30. if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
  31. {
  32. return '';
  33. }
  34. else
  35. {
  36. return 'error';
  37. }
  38. }
  39. else
  40. {
  41. if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
  42. {
  43. return '';
  44. }
  45.  
  46. if ($prefix == '')
  47. {
  48. $prefix = $this->_error_prefix;
  49. }
  50.  
  51. if ($suffix == '')
  52. {
  53. $suffix = $this->_error_suffix;
  54. }
  55.  
  56. return $prefix.$this->_field_data[$field]['error'].$suffix;
  57. }
  58. }
  59.  
  60. }
  61. /* End of file MY_Form_validation.php */
  62. /* Location: ./application/librares/MY_Form_validation.php */


Następnie w controlerze wszystko tak jak miałeś do tej porty w form validatorze.
W widoku jak tworzysz formularz to:

  1. <?php echo form_input('nazwa', set_value('nazwa') ,form_error('nazwa', TRUE))); ?>
  2.  


Funkcja form_error('nazwa', TRUE) z drugim parametrem na TRUE zwraca nazwę klasy CSS zadeklarowaną w: $this->set_error_delimiters('class="error'', '');
Wtedy robisz sobie taki styl w CSS i masz podświetlone.
form_error('nazwapola'); bez drugiego parametru zwróci Ci opis błędu dla danego pola.
abort
Trochę nie to, czego potrzebowałem, ale dzięki za naprowadzenie na trop (tropem jest stworzenie klasy pochodnej do CI_Form_validation i wrzucenie mojej logiki własnie tam). Ale tak to jest, jak się programista strukturalny bierze za obiektówkę i zapomina o paradygmatach pisania kodu obiektowego... smile.gif Myślę, że dalej poradzę sobie sam.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.