multiple instances of widget on same view

I created a widget to display a file upload form.

works great when I call a widget in any view… but if I try to call multiple instances of that widget in the same view there’s something strange that happens…

if I run this code in a view… every single instance of the widget will use the first definition of the dir variable (i.e. ‘dir’=>‘docs/results/day4/’)

is this normal?


 

$this->widget('application.components.upload',array('dir'=>'docs/results/day4/')); 

$this->widget('application.components.upload',array('dir'=>'docs/results/day5/'));

$this->widget('application.components.upload',array('dir'=>'docs/results/day6/'));



can you paste your widget code

in protected/components I have




<?php

class upload extends CWidget

{

    public $dir=NULL;

    

    

	

    public function run()

    {

        // this method is called by CController::endWidget()

		$form = new UploadForm;

		if (isset($_POST['UploadForm'])) {

			if ($form->validate()) {

				$form->image = CUploadedFile::getInstance($form, 'image');

				$file= dirname(Yii::app()->request->scriptFile).DIRECTORY_SEPARATOR.$this->dir.$form->image->name;

				$form->image->saveAs($file);

        }

    }

	$this->render('upload', array('form'=>$form,'dir'=>$this->dir));

    }

}

?>



in protected/components/views I have




<!--protected/views/site/upload.php-->

<div class="yiiForm">

<?php echo CHtml::form('', 'post', array('enctype'=>'multipart/form-data')); ?>

 

<?php echo CHtml::errorSummary($form); ?>

 

<div class="simple">

<?php echo CHtml::activeLabel($form,'image'); ?>

<?php echo CHtml::activeFileField($form, 'image'); ?>

<br/>

<?php echo CHtml::submitButton('Upload'); ?>

</div>

 

<?php echo CHtml::endForm(); ?>

 

</div>



in protected/models/ I have




<?php

// protected/models/UploadForm.php

class UploadForm extends CFormModel {

    public $image;

    

	

 

    public function rules() {

        return array(

            array('image', 'file', 'types' => 'pdf, doc'),

        );

    }

}

?>



then from any view I can cal my widget with this line


<?php $this->widget('application.components.upload',array('dir'=>'docs/results/day6/')); ?>

and I can make the content of ‘dir’ whatever I want and it will work. it will upload the file to whatever folder I point it too.

The problems happens when I call the widget more than once in one view, as in:




<?php $this->widget('application.components.upload',array('dir'=>'docs/results/day6/')); ?>

<?php $this->widget('application.components.upload',array('dir'=>'docs/results/day5/')); ?>



I get 2 forms in my view and regardless which one I use all the files go to the directory set in the first call (in this example they would all go to docs/results/day6/)

that’s what I’m trying to figure out… .why it won’t take the setting from the next widget call??

After submit your form posted twice. Please check following workaround.

Replace protected/component/views/upload.php




<?php echo CHtml::form('', 'post', array('enctype'=>'multipart/form-data')); ?>

with

<?php echo CHtml::form(CHtml::normalizeUrl(array('', 'view'=>$_GET['view'], 'fid'=>$this->id)), 'post', array('enctype'=>'multipart/form-data')); ?>



And protected/upload.php




if (isset($_POST['UploadForm'])) {

with

if (isset($_POST['UploadForm']) && $_REQUEST['fid']==$this->id) {



It is a good idea in general to assign unique ids to every widget you create. In your case the id could then be used to create a unique name for the underlying form. So if you hit one submit button all forms will be submitted but you are only looking for $_POST[$this->id] to get the right data. That should solve your problem

thanks guys… I’ll try that this weekend…

actually did a work around by using a pop up window to load the widget… it actually fits well for the functionality I was looking for,… but I still want to be able to load multiple instances in one view so I’ll try what you guys suggest

I’ll post with an update

thanks