Twitter Bootstrap en CodeIgniter’s form validation

Door 16 mei 2013Tips & Trucs

Ik ben een grootte fan van Twitter Bootstrap en gebruik dit dan ook graag, het ziet er goed uit en ermee werken is kinderlijk eenvoudig. Voor het functionele gedeelte maak ik graag gebruik van het CodeIgniter framework waarin allerlei handige functionaliteiten, waaronder Form Validation. Deze PHP class of “library” genoemd in CodeIgniter maakt het valideren van een formulier stukken makkelijker. Als voorbeeld:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// De controller welke de controller van CodeIgniter uitbreid
class Formulier extends CI_Controller
{
	// De index functie welke als eerst aangesproken wordt
	// wanneer de controller geladen is
	public function index()
	{
		// De library laden zodat deze gebruikt kan worden
		// Eventueel ook automatisch te laden via autoload.php
		$this->load->library('form_validation');

		// De p-tags verwijderen rondom validatie foutmeldingen
		// Normaal is dit: <p>Foutmelding...</p>
		$this->form_validation->set_error_delimiters('', '');

		// Regels instellen voor ingevulde velden
		// De eerste waarde is de "name" van de input
		// De tweede waarde is de volledige naam van het veld
		// De derde waarde zijn de validatie regels:
		// - required = Verplicht in te vullen
		// - max_length[255] = Maximaal 255 karakters lang
		// - valid_email = Een geldig email adres
		// - trim = De PHP trim functie
		$this->form_validation->set_rules('name', 'Naam', 'required|max_length[255]|trim');
		$this->form_validation->set_rules('email', 'Email', 'required|valid_email|max_length[255]|trim');

		// Is het formulier verstuurd en is de validatie geslaagd?
		if( $this->form_validation->run()  )
		{
			// Ja!
			// Doe iets met de waardes,
			// opslaan in een database bijvoorbeeld
		}
		else
		{
			// Nee!
			// Het formulier weergeven
			$this->load->view('header');
			$this->load->view('formulier');
			$this->load->view('footer');
		}
	}
}

De “header” en “footer” view laten we even achterwege, door naar het formulier! Om de eventuele foutmeldingen weer te geven is de validation_errors functie, maar deze set alle foutmeldingen onder elkaar. Bij een mooi formulier ziet het er stukken beter uit als achter het veld een eventuele foutmelding komt te staan. Zie ook de voorbeelden van Twitter Bootstrap (vrij onderaan, je kan beter eerst naar buttons gaan en dan naar boven scrollen). Om dit voor elkaar te krijgen is er de form_error functie. Deze in combinatie met de set_value functie maakt het af. Deze laatste zorgt er namelijk voor dat de ingevulde waardes blijven, wanneer de validatie mislukt is, na het versturen van het formulier. Dit bij elkaar gestopt resulteert in het volgende:

<h1>Gebruiker <?=(isset($id) ? 'bewerken' : 'toevoegen');?></h1>
<hr>
<?=form_open('',array('class' => 'form-horizontal'));?>
	<div class="control-group<?=form_error('name') ? ' error' : '';?>">
		<label class="control-label" for="name">Naam</label>
		<div class="controls">
			<input type="text" id="name" name="name" placeholder="Naam" value="<?=set_value('name',(isset($name) ? $name : '')); ?>">
			<span class="help-inline"><?=form_error('name'); ?></span>
		</div>
	</div>
	<div class="control-group<?=form_error('email') ? ' error' : '';?>">
		<label class="control-label" for="email">Email</label>
		<div class="controls">
			<input type="email" id="email" name="email" placeholder="Email adres" value="<?=set_value('email',(isset($email) ? $email : '')); ?>">
			<span class="help-inline"><?=form_error('email'); ?></span>
		</div>
	</div>
	<div class="control-group">
		<div class="controls">
			<button type="submit" class="btn btn-success"><i class="icon-ok icon-white"></i> Opslaan</button>
		</div>
	</div>
</form>

Eén ding heb ik nog niet uitgelegd! Programmeren volgens DRY houd dus ook géén dubbele formulieren in. Vandaar de isset functies. Het formulier om iets toe te voegen en iets te bewerken kan dus samengevoegd worden. Wanneer dit formulier vanuit de controller geladen wordt zijn er geen waardes ingevuld. Willen we deze wel ingevuld hebben; dienen we deze enkel door te geven. De aangevulde en iets bewerkte controller:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// De controller welke de controller van CodeIgniter uitbreid
class Formulier extends CI_Controller
{
	// De "constructor", deze wordt altijd voor de losse functies uitgevoerd
	public function __construct()
	{
		// Zorgen dat de "constructor" van de CI_Controller eerst uitgevoerd wordt
		parent::__construct();

		// De library laden zodat deze gebruikt kan worden
		// Eventueel ook automatisch te laden via autoload.php
		$this->load->library('form_validation');

		// De p-tags verwijderen rondom validatie foutmeldingen
		// Normaal is dit: <p>Foutmelding...</p>
		$this->form_validation->set_error_delimiters('', '');

		// Regels instellen voor ingevulde velden
		// De eerste waarde is de "name" van de input
		// De tweede waarde is de volledige naam van het veld
		// De derde waarde zijn de validatie regels:
		// - required = Verplicht in te vullen
		// - max_length[255] = Maximaal 255 karakters lang
		// - valid_email = Een geldig email adres
		// - trim = De PHP trim functie
		$this->form_validation->set_rules('name', 'Naam', 'required|max_length[255]|trim');
		$this->form_validation->set_rules('email', 'Email', 'required|valid_email|max_length[255]|trim');
	}

	// De index functie welke als eerst aangesproken wordt
	// wanneer de controller geladen is, dus:
	// http://website.nl/formulier
	public function index()
	{
		// Is het formulier verstuurd en is de validatie geslaagd?
		if( $this->form_validation->run()  )
		{
			// Ja! Opslaan in de database
			$this->db->insert('gebruikers',$this->input->post());

			// Doorsturen naar de begin pagina
			redirect( site_url() );
		}
		else
		{
			// Nee! Het formulier weergeven
			$this->load->view('header');
			$this->load->view('formulier');
			$this->load->view('footer');
		}
	}

	// De bijwerken functie
	// http://website.nl/formulier/edit/1
	public function edit($id = 0)
	{
		// Gegevens uit de database halen
		$data = $this->db->get_where('gebruikers',array('id' => $id))->row();

		// Niets gevonden in de database?
		if(empty($data))
		{
			// Foutmelding weergeven
			show_404();
		}

		// Is het formulier verstuurd en is de validatie geslaagd?
		if( $this->form_validation->run()  )
		{
			// Ja! Bewerken in de database
			$this->db->where('id',$id);
			$this->db->update('gebruikers',$this->input->post());

			// Doorsturen naar de begin pagina
			redirect( site_url() );
		}
		else
		{
			// Nee! Het formulier weergeven
			// Deze keer de waardes uit de database meegeven
			$this->load->view('header');
			$this->load->view('formulier',$data);
			$this->load->view('footer');
		}
	}
}