I am using Twitter Bootstrap to style validation_errors for a registration page:
<?php
echo "<div class='alert alert-error span4'>";
echo validation_errors();
echo "</div>";
?>
The validations work and show up but part of the styling is always present (the div tag has a red background). Is there a way to have the styling show up ONLY when the validation_errors are present. I have tried a few things (embedding html in php tags and enclosing the php in div tags) but the result is the same.
The reason that the div structure still appears is because it's echoing without regard to whether there are errors or not.
You could set the value of a variable to the result of your validation_errors() function in your Controller, then only display the alert div in your View if you've actually got an error...
Your controller would assign the variable to hold the (potential) error:
$this->data['reported_error'] = validation_errors();
$this->load->view('view_name', $this->data);
Then your view would only display the alert div if there was an error:
if ( isset($reported_error) )
{
echo "<div class='alert alert-error span4'>".$reported_error."</div>";
}
This requires your validation_errors function to only return a value if there is an error.
You can try something like this it works for me.
<?php if(validation_errors()):?>
<div class='alert alert-error span4'><?php echo validation_errors(); ?></div>
<?php endif;?>
I use the following construct to put the errors with special classes next to the fields that they reference:
<div class="<?php echo my_error_class('fieldname') ?>">
<input type="whatever" name="fieldname" />
<span class="whatever"><?php echo my_error_msg('fieldname') ?></>
</div>
with the following functions in a CI helper:
<?php
if ( ! function_exists('my_error_class')) {
function my_error_class($field, $error_class = "error") {
if (FALSE === ($OBJ =& _get_validation_object())){
return '';
}
if(isset($OBJ->_field_data[$field]['error']) && !empty($OBJ->_field_data[$field]['error'])) {
return $error_class;
}
else {
return '';
}
}
}
if ( ! function_exists('my_error_msg')) {
function my_error_msg($field,$default = '') {
if (FALSE === ($OBJ =& _get_validation_object())){
return $default;
}
if(isset($OBJ->_field_data[$field]['error']) && !empty($OBJ->_field_data[$field]['error'])) {
return $OBJ->_field_data[$field]['error'];
}
else {
return $default;
}
}
}
I was having the same issue. I assigned validation_errors() to a variable in my controller and passed it to the view.
Going off James' solution, I had to change:
if ( isset($reported_error) )
to:
if (!empty($reported_error))
Once I did this, the alert block only displayed when there was an error.
I didn't find this in the guide but apparently validation_errors takes two optional args for a prefix and suffix... so you can do:
validation_errors('<p class="text-warning">', '</p>');
Related
I work on a project in PHP which does not use any kind of a framework for PHP. I come from Yii background and I've used:
Yii::app()->user->setFlash('flash_name', 'Flash value');
And checked it with:
Yii::app()->user->hasFlash('flash_name');
To check if it is present and if it exists, and to get the value of it I used:
Yii::app()->user->getFlash('flash_name', 'Default Flash value');
For now, I wrote these functions to set, check and get flash:
function set_flash($flash_name, $value) {
$_SESSION['flashes'][$flash_name] = $value;
}
function has_flash($flash_name) {
return isset($_SESSION['flashes'][$flash_name]) ? true : false;
}
function get_flash($flash_name, $default_value = null) {
if(has_flash($flash_name)) {
return $_SESSION['flashes'][$flash_name];
}
return $default_value;
}
However, when I use it in my post.php like this:
set_flash('success', true);
And check it in my index.php like this:
<div class="container">
<?php if(has_flash('success') && (get_flash('success') === true)): ?>
<div class="alert alert-success">
<h4>Success!</h4>
<hr />
<p>You have successfully posted new content on your website. Now you can edit or delete this post.</p>
</div>
<?php endif; ?>
</div>
whenever I refresh the page, the message would still appear there.
How can I remove the flash after it's been used or invoked?
Add a new line to get_flash:
function get_flash($flash_name, $default_value = null) {
if(has_flash($flash_name)) {
$retVal = $_SESSION['flashes'][$flash_name];
// don't unset before you get the vaue
unset($_SESSION['flashes'][$flash_name]);
return $retVal;
}
return $default_value;
}
probably a newb question here, but how do I return a CI anchor() call from within a function. I want to "hide" a button if a variable is set to a certain value.
CI's URL helper documentation: https://www.codeigniter.com/user_guide/general/helpers.html
A pseudo example that won't work (can't return the URL helper anchor('',''):
$prevAvailCompID = 0;
function hideButton($prevCompID)
{
if($prevCompID == 0)
{
return anchor('/getcomps/getSpecificComp/'.$prevCompID , 'PREV COMP');
//I've also tried return echo anchor(...)
}
}
further down on the page:
<div id="prevBtnContainer"><? hideButton($prevAvailCompID); ?></div>
You don't need to return the anchor() function. You can just use as this
UPDATED CODE
public function test(){
?>
<h1>test H1</h1>
<div id="prevBtnContainer"><?php $this->hideButton(0); ?></div>
<div id="1prevBtnContainer"><?php $this->hideButton(1); ?></div>
<?php
}
private function hideButton($prevCompID)
{
if($prevCompID == 0)
{
echo anchor('/getcomps/getSpecificComp/'.$prevCompID , 'PREV COMP');
}
}
I've tested this in my CodeIgniter and its working.
I have a small issue i have declared a variable of type Boolean in my controller.
$done=False
Now there is a trigger in the controller that would turn it to True and it is at this point i would like to send it to the corresponding view with this controller .. i have used the following.
$done=True;
$this->view->setVar("done", $done);
Now when i try to call it in the corresponding view it does not know anything of this varible.
if($done==True)
{
echo'
<div class="alert alert-success">
Add Another Here!
</div>
';
}
It gives me the following:
Notice: Undefined variable: done in >C:\xampp\htdocs\Blueware\app\views\addNewSkill\index.phtml on line 36
Now is there a better way of sending this varible through to the view or am i making a mistake?
Full Controller/Action Code:
<?php
class addNewSkillController extends \Phalcon\Mvc\Controller{
public function indexAction(){
}
public function confirmAction(){
$this->view->disable();
$done=False;
if($this->request->isPost()) {
$dataSent = $this->request->getPost();
$skill = new Skills();
$skill->technology = $dataSent["technology"];
$skill->skillName = $dataSent["skillName"];
$skill->description = $dataSent["description"];
$savedSuccessfully = $skill->save();
if($savedSuccessfully) {
$done=True;
$this->view->setVar("done", $done);
} else {
$messages = $skill->getMessages();
echo "Sorry, the following problems were generated: ";
foreach ($messages as $message) {
echo "$message <br/>";
}
}
} else {
echo "The request method should be POST!";
}
}
}
Full View Code:
<?php
if($done==True)
{
echo'
<div class="alert alert-success">
Add Another Here!
</div>
';
}
?>
if($savedSuccessfully) {
$done=True;
$this->view->setVar("done", $done);
} else {
You should be setting the variable there, But setting in the view after seems that its not saving and therefore not passing the variable on
similar to
if($savedSuccessfully) {
$done=True;
} else {
...later in code ...
$this->view->setVar("done", $done);
or even just
$this->view->setVar("done", $savedSuccessfully);
Ok, I have a registration form for my site.
When there are errors up pops a box with the errors. The box is made up of an html div, an h2 header, and php echoing my errors.
If I hit submit it shows the errors like it should, but the header and div show up no matter what.
I dont understand why.
Here is the code block that echoes the errors.
} else if (!empty($errors)){
echo '<div class="msg_module">';
echo '<h2>Registration Errors:</h2>';
echo $General->outputErrors($errors);
echo '</div>';
}
Thanks all!
Edit: I should mention that $errors is an array.
EDIT: My internet is back, here is the outputErrors function:
public function outputErrors($errors = ''){
if(is_array($errors)){
// handle for passed array
foreach ($errors as $error){
if(is_array($error)){
general::outputErrors($error);
} else{
general::$errStr.= ($error != '')?'<li>'.$error.'</li>':'';
}
}
} else if($errors != ''){
// handle for passed string
general::$errStr = $errors;
}
return '<ul id="error_list">'.general::$errStr.'</ul>';
}//outputErrors
Use var_dump($errors); and you will probably see that the variable is not empty.
From your comment, I assume that the variable is of type array
Read the PHP Manual for the empty function and you will see that it returns true for empty arrays (arrays not containing any element)
Now remember that if the variable is of type String, then most strings are considered non-empty.
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)
TL;DR
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'); ?>
Long answer:
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 :)
Some useful links into the #li3 philosophy:
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)