Welcome Guest, Not a member yet? Register   Sign In
Add / Edit control with 1 view file
#1

[eluser]Unknown[/eluser]
Hi

can anyone help with a issue which I believe is a simple Newbie question....

I want to have 1 view file set up for both add and edit options on a form. How do I combine the way CI holds the validation values for a new form compared to when you want it to return the values from a database for editting?

IE

Setting up the controller for a "New" form subbmission

Code:
function index()
    {
        
        $pageData = array();
        $rules = $this->setRules();
        
        $this->validation->set_rules($rules);
        
        $fields = $this->setFields();
        
        $this->validation->set_fields($fields);
        $this->validation->set_error_delimiters('<div class="error">', '</div>');
        
        if ($this->validation->run() == FALSE) {
            $pageData['formAttributes']     = array('id' => 'contact-form');
            $pageData['pageTitle']        = 'New Booking Repair Request';
            $pageData['booking']        = "";

            $this->load->view('Repair/booking_form', $pageData);
        } else {
            //$this->sendEmail();
            
            $this->load->model('repair_model');
            
            // save to database
            if($this->repair_model->saveBooking()){
                redirect('/repair/confirmation', 'refresh');
            }else{
                $this->load->view('Repair/booking_form', $pageData);
            }
        }
    }

This is a snippet from the setFields method

Code:
private function setFields()
{
    $fields['firstName']= '';

}


This is the code for setting up the "EDIT" view

Code:
public function edit()
    {
        $pageData['formAttributes'] = array('id' => 'contact-form');
        $pageData['pageTitle']        = 'Edit Booking Repair Request';
        $repairId                     = $this->uri->segment(3);
        
        if (!isset($repairId)) {
            redirect('/repair/','refresh');
        } else {
            $this->load->model('repair_model');
            
            $pageData['booking']         = $this->repair_model->loadBooking($repairId);
                    
            $rules = $this->setRules();
            $this->validation->set_rules($rules);
        
            //$fields = $this->setFields();
            $this->validation->set_fields($fields);
            
            if ($this->validation->run() == FALSE) {
                
                $this->load->view('Repair/booking_form', $pageData);
                
            } else {
                
                $fields = $this->setFields();        
                $this->validation->set_fields($fields);
                $this->validation->set_error_delimiters('<p class="hint error"><span>', '</span></p>');
                
                $this->repair_model->saveBooking($repairId);
                $this->load->view('Repair/booking_form', $pageData);
                
            }
        }
    }

This is a snippet from my view

Code:
<div class="form-field">
                &lt;? $firstName = @field($this->validation->firstName, $booking->firstName);?&gt;
                &lt;input type="text" value="&lt;?= $firstName ?&gt;" id="firstName" maxlength="" name="firstName"  /&gt;
            </div>

At the moment.

This is the code from my helper

Code:
&lt;?php
    function field($validation, $database = NULL, $last = ''){
      $value = (isset($validation)) ? $validation : ( (isset($database)) ? $database : $last);
      return $value;
    }

So the problem is that the helper is always trying to show the value of the validation variable instead of the object from the $booking object.

Am I doing something completing wrong and barking up the wrong tree. Is there a simplier way to reuse the same view for add and edit actions?

thanks

simon
#2

[eluser]xwero[/eluser]
The easiest way to create a new/edit functionality is to use a not visible controller method, prefix the method with an underscore.
Code:
class acontroller extends Controller
{
   function add()
   {
      $this->_form();
   }
  
   function edit($id)
   {
     $this->_form($id);
   }

   function _form($id=0)
   {
      // add all your validation code here

      if($id == 0)
      {
         $data['item'] = $this->amodel->mock_item();
      }
      else
      {
         $data['item'] = $this->amodel->item($id);
      }

      $this->load->view('form',$data);
   }

The model mock_item method can be as simple as
Code:
function mock_item()
{
   $obj = new stdClass;

   foreach($this->db->list_fields as $field){ $obj->$field = ''; }

   return $obj;
}
This prevents errors in the view where you use the set_value function, which is loaded by the form-validation class. So your view will look like this.
Code:
&lt;input type="text" value="&lt;?= set_value('firstName',$item-&gt;firstName) ?&gt;" id="firstName" maxlength="" name="firstName"  />
#3

[eluser]n0xie[/eluser]
I don't know if this is the 'right' way but for simple forms I usually do it like this:

Simple example:
You have a database which holds an id field, and a catagoryId. I assume the id field is a primary key which has an autoincrement on it. So it's the identifying key. If we want to add a new entry, then this id will be 0 in our view. Else our id will be our primary key value.

To explain what's going on:
In the add function I just pull up data that's Necessary to render the form. Then I pass it on the renderform private method which 'renders the form'.
If I want to edit the page I need to collect the data that's already in the database. Therefor our edit function retrieves this data, then passes on to add to collect the normal data.
The save function validates the $_POST data. If it fails it check if the primairy Id was present and decides based on that whether it redirects to add or edit.
If the save function passes I sanitize the userinput before passing it off to a model that saves it to a database using the method save (which checks inside the model if the $id parameter passed was larger than 0. If so it performs an UPDATE else it performs an INSERT.

In the view I just check if an $edit array is present (this is namespaced in our company). If so it matches against the available options in the dropdown and selects the one that matches.

I'm curious how others do this that's why I posted 'my way'.

Code:
&lt;?php
/*
* Controller
*/
class Somecontroller extends Controller {

    function Somecontroller()
    {
        parent::Controller();
    }

    public function add()
    {
        /* example some dropdown from database */
        $this->load->model('category_model','category');
        $this->formdata['categories']    = $this->category->findAll();

        $this->_renderform();
    }
    
    public function edit($id=NULL)
    {
        /* function to check for real integer
         * see: http://nl3.php.net/manual/en/function.is-int.php#82857
         */
        if(isInteger($id))
        {
            /* load the model with the data to edit */
            $this->load->model();
            $this->formdata['edit']        = $this->...->read($id);
        }
        $this->add();
    }
        
    public function save()
    {
        $this->load->library('form_validation');
        
        /* your form validation rules here */
        $this->form_validation->...

        if ($this->form_validation->run() == FALSE){
            /* we need to check id since it might have been triggered by form_validation */
            $id = $this->input->post('id');
            if ($id > 0 && isInteger($id)) {
                $this->edit($this->input->post('id'));
            } else {
                $this->add();
            }
        }
        else
        {
            /* sanitize data */
            $id = ($_POST['id'] != 0) ? filter_var($_POST['ID_Task'], FILTER_SANITIZE_NUMBER_INT) : NULL;
            $data['ID_User'] = ($_POST['ID_User'] != 0) ? filter_var($_POST['ID_User'], FILTER_SANITIZE_NUMBER_INT) : NULL;
            
            /* load whatever model you're going to save your data to */
            $this->load->model();
            $this->...->save($data, $id);

            /* after a POST it's better to user redirect instead of $this->index because
             * people tend to press F5 or refresh which gives us unsuspected behaviour
             */
            redirect('/somecontroller');
        }

        private function _renderform()
        {
            $this->load->library('form_validation');

            $data = $this->_getPageStuff();
            $data['form'] = $this->load->view('forms/exampleform_view',$this->formdata,TRUE);

            $this->load->view('templateview', $data);
        }


        private function _getPageStuff()
        {
           /* load page wide settings like custom title, metatags, description etc etc. */
           $data[''] = $this->...
           return $data;
        }
}
?&gt;

And the view

Code:
/**
* forms/exampleform_view
*/
<h3>An example form</h3>
&lt;form action="/somecontroller/save" method="post"&gt;
    <fieldset>
    &lt;?php echo validation_errors(); ?&gt;
    <p>
        <label for="categoryId">Category</label>
        <select name="categoryId">
            &lt;?php foreach ($categories as $category) {
                echo "<option value=\"".$category['categoryId']."\" ".set_select('categoryId', $category['categoryId'], (isset($edit['categoryId'])&& $category['id']==$edit['categoryId']) ? TRUE : FALSE).">".$category['name']."</option>\n";
            } ?&gt;
        </select>
    </p>
        &lt;input type="hidden" name="id" value="&lt;?php echo (isset($edit['id'])) ? $edit['id'] : 0; ?&gt;" /&gt;

        &lt;input type="submit" value="Submit" /&gt;

    </fieldset>
&lt;/form&gt;
#4

[eluser]Unknown[/eluser]
OK, thanks.

So there is no built-in handler for this type of action? If thats the case, then I'll take influence from your suggestions and come up with a suitable solution...

Is this a common issue, or am I approaching from the wrong direction.

thanks for the support, much appreciated

Simon
#5

[eluser]xwero[/eluser]
No there is no build-in handler because this limits the possibilities of the developer to sculpt the code the way (s)he wants.
Some people prefer to have two separate forms.




Theme © iAndrew 2016 - Forum software by © MyBB