Difference between #5 and #6 of
How to create/save more Model inputs and make them repeatable with jQuery

Revision #6 has been created by wei on Oct 25, 2010, 3:01:59 AM with the memo:

formatting, spelling
« previous (#5) next (#7) »

Changes

Title unchanged

How to create/save more Model inputs and make them repeatable with jQuery

Category unchanged

Tutorials

Yii version unchanged

Tags unchanged

Content changed

[...]
Let's view an example. We have two tables: Event and PhotoEvent. When we want to create an Event we want to add some photos to it.
This is the database tables example:
![Alt text](http://i40.tinypic.com/eap9xi.jpg)


 
How can we add N photos input field in the form diynalmically?

First of all you have to create your IMG_DIR_PATH directory where to save the images and give it the rights to write inside.
[...]
```php
<?php
 
'image'=>array(        'class'=>'application.extensions.image.CImageComponent',          // GD or ImageMagick          'driver'=>'GD',          // ImageMagick setup path          'params'=>array('directory'=>'/opt/local/bin'),         )
 
 
?>
 
```
 
 
)
 
```


This is how is made the html page to collect the inputs:
[...]
[html]
<h2>New Event</h2>

 
<div class="actionBar">     [<?php echo CHtml::link('Event List',array('list')); ?>]     [<?php echo CHtml::link('Manage Event',array('admin')); ?>] </div>
 
<div class="yiiForm">
 
  <p>   Fields with <span class="required">*</span> are required.   </p>  <?php echo CHtml::form('','post',array('enctype'=>'multipart/form-data')); ?>       <?php echo CHtml::errorSummary(array_merge( array($event), $photosEvent)); ?>   <div class="simple">       <?php echo CHtml::activeLabelEx($event,'name'); ?>       <?php echo CHtml::activeTextField($event,'name'); ?>  </div>   <div class="simple">       <?php echo CHtml::activeLabelEx($event,'description'); ?>       <?php echo CHtml::activeTextField($event,'description'); ?>  </div>   <div class="simple">       <?php echo CHtml::activeLabelEx($event,'expireDate'); ?>       <?php echo CHtml::activeTextField($event,'expireDate'); ?>  </div>    
 
  <?php echo CHtml::button('add Photos', array('name'=>'addPhotos', 'id'=>'addPhotos')); ?>       <?php foreach($photosEvent as $i => $photo): ?>  <div id="photo-<?php echo $i ?>">   <div class="simple">           <?php echo CHtml::activeLabelEx($photo,'photoUrl'); ?>           <?php echo CHtml::activeFileField($photo, "photoUrl[$i]"); ?>       </div>    <br />  </div>   <?php endforeach; ?>
 
  
<div class="row action">       <?php echo CHtml::submitButton($update ? 'Save' : 'Create', array('name'=>'submitDatas')); ?>
 
  
</div>
 
 
   
</form> </div>
 
<script type="text/javascript">
 
   /*<![CDATA[*/
 
   
// I need to know how many photos I've already added when the validate return FALSE    var photosAdded = <?php echo $photosNumber; ?>;    // Add the event to the period's add button    $('#addPhotos').click(function () {    // I'm going to clone the first div containing the Model input couse I don't want to create a new div and add every single structure    var divCloned = $('#photo-0').clone();   // I'm attaching the div to the last input created   $('#photo-'+(photosAdded++)).after(divCloned);   // Changin the div id    divCloned.attr('id', 'photo-'+photosAdded);   // Initializing the div contents   initNewInputs(divCloned.children('.simple'), photosAdded);    });    
 
   

 
function initNewInputs( divs, idNumber ) {   // Taking the div labels and resetting them. If you send wrong information,    // Yii will show the errors. If you than clone that div, the css will be cloned too, so we have to reset it   var labels = divs.children('label').get();    for ( var i in labels )  labels[i].setAttribute('class', 'required');          // Taking all inputs and resetting them.    // We have to set value to null, set the class attribute to null and change their id and name with the right id.   var inputs = divs.children('input').get();       
 
  

 
for ( var i in inputs ) {  inputs[i].value = "";   inputs[i].setAttribute('class', '');   inputs[i].id = inputs[i].id.replace(/\d+/, idNumber);  inputs[i].name = inputs[i].name.replace(/\d+/, idNumber);   }    }
 
   
 
   /*]]>*/
 
      
}
</script>
~~~
[...]
```php
<?php
 
public function actionCreate() {
 
    // Adding jQuery to the view page.     Yii::app()->getClientScript()->registerCoreScript('jquery');
 

 
    
$event = new Event;       
 
  

 
// Adding an empty PhotoEvent to the form    $photosEvent = array( new PhotoEvent, );
 

 
    
// If everything is setted I will check and process the inputs    if( isset( $_POST['submitDatas'] ) && isset( $_POST['PhotoEvent'], $_POST['Event'] ) )    {   $event->attributes = $_POST['Event'];   // DB date layout   $event->expireDate = date_format(date_create($event->expireDate), 'Y-m-d');   $valid = $event->validate();          
 
         
 
         
 
 

 
// This is the crappy part of the script that I need to improve and make it more elegance   // I've to add to the photoEvent array a new PhotoEvent for every istance in $_POST['PhotoEvent']   foreach ( $_POST['PhotoEvent'] as $i => $photo ) { $photosEvent[$i] = new PhotoEvent; if ( isset( $_POST['PhotoEvent'][$i] ) )      $photosEvent[$i]->photoUrl = CUploadedFile::getInstance($photosEvent[$i], "photoUrl[$i]" );    //$photosEvent[$i]->photoUrl = CUploadedFile::getIstance($photosEvent[$i], "photoUrl[$i]" ); $valid = $valid && $photosEvent[$i]->validate();  }             
 
 

 
if( $valid && $event->save(false) ) {
 
         
   // You will need this if you want to resize and play around images :) //Yii::import('application.extensions.image.Image');              // Saving each period ( i've to change the date format couse in Italy we use dd/mm/yyyy foreach ( $photosEvent as $i => $photo ) {   $photo->eventId = $event->id;  // Taking and saving the image in the filesystem in the IMG_DIR_PATH/ directory path.   // In this case IMG_DIR_PATH is in the root of the   // site and you need to give it rights to write the image :)               $photo->photoUrl->saveAs('IMG_DIR_PATH/'.$photo->photoUrl->getName());               /* If you need to resize the image use this path of code                  $image = new Image('IMG_DIR_PATH/'.$photo->photoUrl->getName());                  $image->resize(200, 200);                  $image->save();                */   $photo->save(false); }             
 
            
 
$this->redirect(array('show','id'=>$event->id));             
 
 
}    }   $this->render('create', array(  'event' => $event,  'photosEvent' => $photosEvent,    'photosNumber' => isset($_POST['PhotoEvent']) ? count($_POST['PhotoEvent'])-1 : 0, //How many PhotoEvent the user added   'update' => false,    )); }
 
?>
} ``` I wish you will enjoy my guide :) Please gimme some feedback to improve it :) See ya! Emanuele "StErMi" Ricci.
11 0
16 followers
Viewed: 51 409 times
Version: 1.1
Category: Tutorials
Tags:
Written by: qiang
Last updated by: Yang He
Created on: Apr 21, 2009
Last updated: 11 years ago
Update Article

Revisions

View all history