I am building a test Lithium app to learn how it works and I found that the form helper doesn't seem to recognise my data being passed back or any validation errors.
At the moment I'm having to manually pass back my errors and then process them in the view.
QuestionsController::ask
public function ask() {
if (!empty($this->request->data)) {
$question = Questions::create($this->request->data);
if ($question->save()) {
return $this->redirect(array('Questions::view', 'args'=>$question->id));
} else {
$errors = $question->errors();
}
if (empty($question)) {
$question = Questions::create();
}
return compact('question', 'errors');
}
}
views/questions/ask.html.php
<?php
// Assign the protected object to a variable so we can get at it
if(isset($question)){
$data = $question->data();
}else{
$data['title'] = '';
$data['text'] = '';
}
?>
<?=$this->form->create();?>
<?=$this->form->field('title', array('placeholder'=>'Title your question', 'value'=>$data['title']));?>
<?php if(isset($errors['title'])){
echo "<div class='alert alert-error'><a class='close' data-dismiss='alert' href='#'>×</a>";
foreach($errors['title'] as $e){
echo $e."<br/>";
}
echo "</div>";
}?>
<?=$this->form->field('text', array('placeholder'=>'Enter your question (supports Markdown)', 'type'=>'textarea', 'value'=>$data['text']));?>
<?php if(isset($errors['text'])){
echo "<div class='alert alert-error'><a class='close' data-dismiss='alert' href='#'>×</a>";
foreach($errors['text'] as $e){
echo $e."<br/>";
}
echo "</div>";
}?>
<p>Text input supports <?php echo $this->html->link('markdown', 'http://en.wikipedia.org/wiki/Markdown');?></p>
<?=$this->form->submit('Ask', array('class'=>'btn'));?>
<?=$this->form->end();?>
I can see from the lithium\template\helper\Form
that the field()
method can take a template
parameter, which in the example is <li{:wrap}>{:label}{:input}{:error}</li>
so there is capacity in the helper for displaying the validation messages.
So how do I organise my data in my controller so that it's passed back to the view in order for the helper to populate my fields and also display errors?
Edit
I should add that the example 'Sphere' app, also uses this method, so is it standard? (ref)
the short answer is that you can bind the form to a subclass of Entity, i.e. a Record or Document as shown in Form::create()
(link is shortened as ::
breaks the link parser).
your code would look like:
<?= $this->form->create($question); ?>
<?= $this->form->field('title'); ?>
<?= $this->form->field('text'); ?>
QuestionsController::ask()
:
public function ask() {
$question = Questions::create();
if (!empty($this->request->data)) {
if ($question->save($this->request->data)) {
return $this->redirect(array('Questions::view', 'args'=>$question->id));
}
}
return compact('question');
}
views/questions/ask.html.php
:
<?= $this->form->create($question); ?>
<?= $this->form->field('title', array('placeholder'=>'Title your question'));?>
<?= $this->form->field('text', array('placeholder'=>'Enter your question (supports Markdown)', 'type'=>'textarea'));?>
<p>Text input supports <?php echo $this->html->link('markdown', 'http://en.wikipedia.org/wiki/Markdown');?></p>
<?=$this->form->submit('Ask', array('class'=>'btn'));?>
<?=$this->form->end();?>
Note how the form helper will automatically display errors in case there are any :)
1 - http://www.slideshare.net/nateabele/lithium-the-framework-for-people-who-hate-frameworks
2 - Video of roughly the same presentation (w/ a good example on changing form templates)