CakePHP Part 5 - Creating a Separate Add View

Skill

CakePHP Part 5 - Creating a Separate Add View

Posted in:

In our last tutorial, we created a form that gave us the ability to add products to our product database. To save time, we just created the form in the main page. While this was fine then, now we are going to take that form and give it a page of its own. This will allow us to view products on one page and add products on another, plus it is more professional and user-friendly. So dig in and get started!

Creating the Page

As things currently stand, the index page is a multitasking paradise, allowing you to add products and view all your products all at the same time. Obviously we can't have this type of page forever, we need to organize the site a little better. To start, let's go ahead and take the add form, and put it on its own page.

To do this, we need to first create an add.ctp file in the views folder. Once we have that, we can move the add form from the index page to the new add.ctp page. So the modified index page will end up like this:

<?php
echo $html->css('default');
?>

<table>

<?php

echo $html->tableHeaders(
    array(
      'Product ID',
      'Product',
      'Description',
      'Price'
    )
  );

foreach($data as $product)
{
  echo $html->tableCells(
      array(
        array(
          $product['Product']['product_id'],
          $product['Product']['product_name'],
          $product['Product']['product_desc'],
          $product['Product']['product_price']
        )
      )
    );
}

?>

</table>

And your add.ctp will look like this:

<?php

echo $form->create();
echo $form->input('product_name');
echo $form->input('product_desc');  
echo $form->input('product_price');      
echo $form->end('Add');

?>

As you can see, all we did was take the form from the top of index.ctp and essentially created a new file for it. Since we already have an add action, we have very little left to do.

Right now, our add action should look something like this:

function add()
{
  $this->Product->set($this->data);
 
  if ($this->Product->validates())
  {
    if($this->Product->save())
      $this->Session->setFlash('Data Saved Successfully!');        
  }
  else
  {
    $errors = $this->Product->invalidFields();
    $this->Session->setFlash(implode(',', $errors));    
  }
   
  $this->redirect(array(
    'controller' => 'products',
    'action' => 'index'
    )
  );  
}

The main issue with keeping it like this is that it redirects to index.ctp at the end of any call to this action, even if you did not enter anything in the form. Effectively we have created an alias for our index page. However, to fix this, all we have to do is test for form data. With the addition of a simple if statement, our shiny new page is one step closer to complete:

function add()
{
   if(isset($this->data))
  {
    $this->Product->set($this->data);
   
    if ($this->Product->validates())
    {
      if($this->Product->save())
        $this->Session->setFlash('Data Saved Successfully!');        
    }
    else
    {
      $errors = $this->Product->invalidFields();
      $this->Session->setFlash(implode(',', $errors));    
    }

    $this->redirect(array(
      'controller' => 'products',
      'action' => 'index'
      )
    );
  }    
}

With the addition of our if statement, we have stopped anything in the action from taking place unless there is data to submit. This way, we are not just redirected back to the index page all the time, but instead it only redirects if there is form data. There is, however, one more hole in our code.

The way it is laid out right now, the page redirects, even if there is a validation error. To fix this, all we have to do is move the redirect statement inside the validation if statement.

The last thing we need to do is remove the else statement in the validation test. Since we are not redirecting on errors, Cake's validation system will take care of displaying errors, therefore we don't need to use the flash to display errors across the pages. So the final add action will look like so:

function add()
{
  if(isset($this->data))
  {
    $this->Product->set($this->data);
   
    if ($this->Product->validates())
    {
      if($this->Product->save())
        $this->Session->setFlash('Data Saved Successfully!');

      $this->redirect(array(
        'controller' => 'products',
        'action' => 'index'
        )
      );          
    }
  }    
}

Our New, Separate Add Page

The New Add Form, Complete with Errors!

With a few changes, we have created a handy new page just for adding new products to our database, and the great thing is that CakePHP allows us to do it in no time flat.

Linking to the New Page

Now that we have our new page, we can go ahead and add a link from the index page. Doing this is an incredibly simple process. What we need to do is use the link() method in the html helper. With a couple of lines, we have our link:

<?php
echo $html->css('default');
 
echo $html->link(
    'Add New Product',
    array(
      'controller' => 'Products',
      'action'     => 'add',
    ),
    array(),
    null
);
?>

<table>

<?php

echo $html->tableHeaders(
    array(
      'Product ID',
      'Product',
      'Description',
      'Price'
    )
  );

foreach($data as $product)
{
  echo $html->tableCells(
      array(
        array(
          $product['Product']['product_id'],
          $product['Product']['product_name'],
          $product['Product']['product_desc'],
          $product['Product']['product_price']
        )
      )
    );
}

?>

</table>

Notice that it is added right below our CSS include. This puts the link right above the table of products, easily seen and accessed. When you click on the link, you are taken to the add page. Once you submit some valid data, you are redirected back to the index page.

The Add Link

New and Improved 'Add New Product' Link

Well, that about wraps up this tutorial. Thanks again to CakePHP, we have made our site better, more professional, and increasingly user friendly. Just remember, when you need coding help, all you have to do is Switch On The Code.

*This tutorial was created using CakePHP v1.2.

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.

Sponsors