clonnablefields

allows to add an unlimited number of dynamic input fields
14 followers

ClonnableField is a extension that allows users to add an unlimited number of dynamic input fields. For example, typing the recipe, you can add an unlimited number of ingredients.

Requirements

e.g. Yii 1.1 or above

Usage

Copy clonnableFields folder to your Extensions Folder

Simple example

$this->widget (
      'ext.clonnableFields.ClonnableFields',
      array (
          'models'=>Model->mayors, //required, one to many model relation or array
          'rowGroupName'=>'Mayors', //required, all fields will be with this key number
          'startRows'=>3, //optional, default: 1 - The number of rows at widget start
          'labelsMode'=>2, //optional, default: 1 - (0 - never, 1 - always, 2 - only if rows exist)
          'fields'=>array( //required
              array
              (
                  'label'=>array(
                      'title'=>'Mayor\'s name',
                  ),
                  'field'=>array(
                      'class'=>'TemplateTextField',
                      'attribute'=>'mayor_name',
                  ),
              ),
          ),
      )
  );

More complex example with multiple fields on each row. This example will only work correctly if you have installed the YiiBooster extension, because some kinds of fields using its components (TemplateTypeaheadField, TemplateSelect2Field, TemplateToggleButtonField).

$this->widget (
        'ext.clonnableFields.ClonnableFields',
        array (
            'models'=>Model->mayors, //required, one to many model relation or array
            'rowGroupName'=>'Mayors', //required, all fields will be with this key number
            'startRows'=>1, //optional, default: 1 - The number of rows at widget start
            'labelsMode'=>2, //optional, default: 1 - (0 - never, 1 - always, 2 - only if rows exist)
            'addButtonLabel' => '<i class="icon-plus"></i> Add person to list', //optionall, default: "Add"
            'removeButtonLabel' => '<i class="icon-remove"></i>', //optional, default: "Remove"
            'removeButtonHtmlOptions' => array('class'=>'pull-right'), //optional
            'fields'=>array( //required
                //---------first field------------------------
                array(
                    'label'=>array( //optional
                        'title'=>'#',
                    ),
                    'field'=>array(
                        'class'=>'TemplateAutonumerationField', //required
                        'attribute'=>'id', //required, model attribute or field name
                        'params'=>array( //optional, default: '{num}'
                            'template'=>'Row {num}',
                        ),
                        'htmlOptions'=>array('class'=>'span12'), //optional - field options
                    ),
                    'fieldHtmlOptions' => array('class'=>'span1'), //optional - field block options
                ),
                //---------second field------------------------
                array(
                    'label'=>array(
                        'title'=>'City',
                        'htmlOptions'=>array('required'=>true, 'data-toggle' => 'popover', 'title'=>'Bootstrap Typeahead field', 'data-content' => 'Try to enter city name. Example: Moscow', 'data-trigger' => 'hover', 'data-placement' => 'top'),
                    ),
                    'field'=>array(
                        'class'=>'TemplateTypeaheadField',
                        'attribute'=>'city', //required, model attribute or field name
                        'htmlOptions'=>array('class'=>'span12', 'maxlength'=>'128'), //optional
                        'data'=>array('Moscow', 'New York', 'London', 'Paris', 'Tokio', 'Bangkok', 'Beijing'),
                        'params'=>array( //optionally, Bootstrap Typeahead parameters
                            'items'=>10, //optionally, default 5 - max founded items in the list
                            'minLength'=>1, //optionally, default 1 - min simbols to start search
                            'highlightWrong'=>true //optionally, default: false - Highlight entered value, if not in a list, bool or array('styleWrong'=>'color:xxx', 'styleOk'=>'color:xxx')
                        ),
                    ),
                    'fieldHtmlOptions' => array('class'=>'span2'),
                ),
                //---------third field------------------------
                array(
                    'label'=>array(
                        'title'=>'Mayor\'s name',
                        'htmlOptions'=>array('data-toggle' => 'popover', 'title'=>'Simple text field', 'data-content' => 'Enter mayor\'s name (plain text)', 'data-trigger' => 'hover', 'data-placement' => 'top'),
                    ),
                    'field'=>array(
                        'class'=>'TemplateTextField',
                        'attribute'=>'mayor_name', //required, model attribute or field name
                        'htmlOptions'=>array('class'=>'span12', 'maxlength'=>'128'),
                    ),
                    'fieldHtmlOptions' => array('class'=>'span3'),
                ),
                //---------fourth field------------------------
                array(
                    'label'=>array(
                        'title'=>'Gender',
                        'htmlOptions'=>array('data-toggle' => 'popover', 'title'=>'Select2 field', 'data-content' => 'Select gender from the list', 'data-trigger' => 'hover', 'data-placement' => 'top'),
                    ),
                    'field'=>array( //required
                        'class'=>'TemplateSelect2Field', //required.
                        'attribute'=>'gender_id', //required, model attribute or field name
                        'htmlOptions'=>array('class'=>'span12', 'maxlength'=>'128'), //optional
                        'data'=>array('0'=>'unset', '1'=>'male', '2'=>'female'),
                        'params'=>array( //optional
                            'asDropDownList'=>true,
                        ),
                    ),
                    'fieldHtmlOptions' => array('class'=>'span2'),
                ),
                //---------fifth field------------------------
                array(
                    'label'=>array(
                        'title'=>'Votes',
                        'htmlOptions'=>array('data-toggle' => 'popover', 'title'=>'Number field', 'data-content' => 'Enter votes quantity', 'data-trigger' => 'hover', 'data-placement' => 'top'),
                    ),
                    'field'=>array(
                        'class'=>'TemplateNumberField',
                        'attribute'=>'quantity',
                        'htmlOptions'=>array('class'=>'span12'),
                    ),
                    'fieldHtmlOptions' => array('class'=>'span2'),
                ),
                //---------sixth field------------------------
                array(
                    'label'=>array(
                        'title'=>'Pass',
                        'htmlOptions'=>array('data-toggle' => 'popover', 'title'=>'Toggle Button field','data-content' => 'Check or uncheck person.', 'data-trigger' => 'hover', 'data-placement' => 'top'),
                    ),
                    'field'=>array(
                        'class'=>'TemplateToggleButtonField',
                        'attribute'=>'important',
                        'start_value'=>1,
                        'params'=>array(
                            'width'=>70,
                            'height'=>29,
                            'label'=>array('enabled'=>'Yes', 'disabled'=>'No'),
                        ),
                    ),
                    'fieldHtmlOptions' => array('class'=>'span1'),
                ),
            ),
        )
    );

Resources

Total 6 comments

#18303 report it
blackrobe89 at 2014/10/14 02:22am
TemplateFineUploaderField

How to use file upload field?

Everytime it is included, the application returns an error:

Class 'ImageObject' not found in /.../protected/extensions/clonnableFields/components/TemplateFineUploaderField.php on line 26

Any Ideas?

#17412 report it
morteza at 2014/06/07 01:16pm
Thank you! Change in Class "ClonnableFields.php"

Line 217 $value=""; replace to
$value = isset($field['field']['start_value'])?$field['field']['start_value']:'';
for start_value in minCloneRows>0,

#16241 report it
Krin at 2014/02/02 06:05pm
RE: RE: RE: Not working when more than two widgets exist

Thank you pointed out the error. Fixed and uploaded the corrected version. Now

'sortable' => false,

should work

#16240 report it
blackrobe89 at 2014/02/02 12:52pm
RE: RE: Not working when more than two widgets exist

Figured that out and I've checked it on your provided demo page and works nicely. However for some reason (which I predict due to loading different JQuery UI libraries by my application) the sortable attribute is causing problems even when setting

'sortable' => false,
#16237 report it
Krin at 2014/02/02 04:09am
RE: Not working when more than two widgets exist

Thank you! This extension uses jQuery UI Library (sortable) for sorting by dragging and dropping. Make sure that you are using jquery-ui.js If you don't need this feature, then you can simply specify the widget setting 'sortable' => false (true by default). There is no need to modify ClonnableFields.php.

#16236 report it
blackrobe89 at 2014/02/02 03:36am
Not working when more than two widgets exist

Its a great extension, however for some reason if I add two of these widgets within the same form, they render fine, but the add button for the 2nd widget doesn't clone rows.

JQuery returns an error

Uncaught TypeError: Object [object Object] has no method 'sortable'

Fix

Fixed it by changing line 346 in ClonnableFields.php from

initClonnableFields(widgetId, maxCloneRows, minCloneRows, afterSortRowsCustomAction, beforeAddRowCustomAction, afterAddRowCustomAction, beforeRemoveRowCustomAction, afterRemoveRowCustomAction, dinamicLabels, showLastDivider, $this->sortable);

to

initClonnableFields(widgetId, maxCloneRows, minCloneRows, afterSortRowsCustomAction, beforeAddRowCustomAction, afterAddRowCustomAction, beforeRemoveRowCustomAction, afterRemoveRowCustomAction, dinamicLabels, showLastDivider);

Leave a comment

Please to leave your comment.

Create extension
  • Yii Version:
  • License: New BSD License
  • Developed by: Krin
  • Category: User Interface
  • Votes: +13
  • Downloaded: 380 times
  • Created on: Nov 30, 2013
  • Last updated: Dec 4, 2013