dynamictabularform Allows Dynamic Tabular Input using partial views

  1. Introduction
  2. Installation
  3. Screenshot
  4. Requirements
  5. Usage
  6. Example
  7. To Do
  8. Resources

Introduction

this extension allows us to create dynamic tabular inputs using partial views and adding more of it via Ajax/JS this also allows each row to have its own widgets like CJui. i will also teach how to save 1 header model + multiple related model as details in this article

Installation

  • extract the folder in protected/extensions/dynamictabularform

  • add this in your import array in the main.php

'ext.dynamictabularform.*',
  • done!

Screenshot

tabular

Requirements

Yii 1.1 or above

Usage

This extension uses a CAction to load each row of the tabular input via ajax. basic usage with controller

we need to add my custom action in the actions() method don't forget to allow the action in the accessRules()

DynamicTabularForm widget parameters:
  • rowUrl: the url of the ajax renderer
  • defaultRowView: the default view file for the row
DynamicTabularForm widget methods:
public function rowForm($models = array(), $rowView=null, $htmlOptions = array())

Parameters

  • $models: is the array of CModels to be used
  • $rowView: the view file to be used for initial rendering if $models contains data already
public function deleteRowButton($row_id, $key, $label='X', $htmlOptions = array())

Parameters

  • $row_id: the id of the div of the current row(see usage)
  • $key: the key of the current row

  • $label: label of the delete button

public function updateTypeField($model, $key, $attribute, $htmlOptions = array())

for example i have created 3 rows and saved it in my database, then i wanted to update it and i want to delete 1 row of entry. this is important to determine what fields are to be deleted. this is usually useful to determine what rows are for new entries, for deletion and for updating

Parameters

  • $model: model of the row
  • $key: the key of the current row
  • $attribute: to what attribute we will bind on what kind of update we will do if creation, deletion of updating
GetRowForm action parameters
  • view: the view file that it will renderPartial

  • modelClass: the class of the model that will be initialized and be passed to the partial view defined in view. this is passed as the variabe $model

Variables available for the partial view
  • $model: the initialized modelClass

  • $form: just an initialized DynamicTabularForm

  • $key: the counter that you can use in naming the inputs and the row

Example

Controller - SlaController.php
class SlaController extends Controller {
    
    public function actions() {
        return array(
            'getRowForm' => array(
                'class' => 'ext.dynamictabularform.actions.GetRowForm',
                'view' => '_rowForm',
                'modelClass' => 'SlaDetail'
            ),
        );
    }

    /**
     * without relation extension
     */
    public function actionCreate() {
        /**
         * a typical setup... SLA is my header and its details is the SlaDetail model
         * this i like a regular receipt
         */
        $sla = new Sla();
        $sladetails = array(new SlaDetail);

        if (isset($_POST['Sla'])) {
            $sla->attributes = $_POST['Sla'];

            /**
             * creating an array of sladetail objects
             */
            if (isset($_POST['SlaDetail'])) {
                $sladetails = array();
                foreach ($_POST['SlaDetail'] as $key => $value) {
                    /*
                     * sladetail needs a scenario wherein the fk sla_id
                     * is not required because the ID can only be
                     * linked after the sla has been saved
                     */
                    $sladetail = new SlaDetail('batchSave');
                    $sladetail->attributes = $value;
                    $sladetails[] = $sladetail;
                }
            }
            /**
             * validating the sla and array of sladetail
             */
            $valid = $sla->validate();
            foreach ($sladetails as $sladetail) {
                $valid = $sladetail->validate() & $valid;
            }

            if ($valid) {
                $transaction = $sla->getDbConnection()->beginTransaction();
                try {
                    $sla->save();
                    $sla->refresh();

                    foreach ($sladetails as $sladetail) {
                        $sladetail->sla_id = $sla->id;
                        $sladetail->save();
                    }
                    $transaction->commit();
                } catch (Exception $e) {
                    $transaction->rollback();
                }



                $this->redirect(array('view', 'id' => $sla->id));
            }
        }
        $this->render('create', array(
            'sla' => $sla,
            'sladetails' => $sladetails
        ));
    }

    public function actionUpdate($id) {
        $sla = $this->loadModel($id);
        $sladetails = $sla->slaDetails;

        if (isset($_POST['Sla'])) {
            $sla->attributes = $_POST['Sla'];

            if (isset($_POST['SlaDetail'])) {
                $sladetails = array();
                foreach ($_POST['SlaDetail'] as $key => $value) {
                    /**
                     * here we will take advantage of the updateType attribute so
                     * that we will be able to determine what we want to do 
                     * to a specific row
                     */
                    
                    if ($value['updateType'] == DynamicTabularForm::UPDATE_TYPE_CREATE)
                        $sladetails[$key] = new SlaDetail();

                    else if ($value['updateType'] == DynamicTabularForm::UPDATE_TYPE_UPDATE)
                        $sladetails[$key] = SlaDetail::model()->findByPk($value['id']);

                    else if ($value['updateType'] == DynamicTabularForm::UPDATE_TYPE_DELETE) {
                        $delete = SlaDetail::model()->findByPk($value['id']);
                        if ($delete->delete()) {
                            unset($sladetails[$key]);
                            continue;
                        }
                    }
                    $sladetails[$key]->attributes = $value;
                }
            }
            
            $valid = $sla->validate();
            foreach ($sladetails as $sladetail) {
                $valid = $sladetail->validate() & $valid;
            }

            if ($valid) {
                $transaction = $sla->getDbConnection()->beginTransaction();
                try {
                    $sla->save();
                    $sla->refresh();

                    foreach ($sladetails as $sladetail) {
                        $sladetail->sla_id = $sla->id;
                        $sladetail->save();
                    }
                    $transaction->commit();
                } catch (Exception $e) {
                    $transaction->rollback();
                }



                $this->redirect(array('view', 'id' => $sla->id));
            }
        }

        $this->render('create', array(
            'sla' => $sla,
            'sladetails' => $sladetails
        ));
    }

}
create.php
<div class="content">
    <?php
    /* @var $this SlaController */
    ?>

    <p>
        Example form of a one to many models with dynamic inputs!
    </p>
    <?php
    $form = $this->beginWidget('DynamicTabularForm', array(
        'defaultRowView'=>'_rowForm',
    ));
    echo "<h3>Header</h3>";
    echo $form->errorSummary($sla);
    ?>
    <div class="row-fluid">
        <div class="span4">
            <?php
            echo $form->labelEx($sla, 'name');
            echo $form->textField($sla, 'name');
            echo $form->error($sla, 'name');
            ?>
        </div>

        <div class="span4">
            <?php
            echo $form->labelEx($sla, 'customer_id');
            echo $form->dropDownList($sla, 'customer_id', Customer::getList());
            echo $form->error($sla, 'customer_id');
            ?>
        </div>
        <div class="span4">
            <?php
            echo $form->labelEx($sla, 'owner_id');
            echo $form->dropDownList($sla, 'owner_id', User::getList());
            echo $form->error($sla, 'owner_id');
            ?>
        </div>

    </div>
    <h3>Details</h3>
<?php
/**
 * this is the main feature!!
 */
echo $form->rowForm($sladetails);

echo CHtml::submitButton('create');

$this->endWidget();
?>
</div>
_rowForm.php
<?php $row_id = "sladetail-" . $key ?>
<div class='row-fluid' id="<?php echo $row_id ?>">
    <?php
    echo $form->hiddenField($model, "[$key]id");
    echo $form->updateTypeField($model, $key, "updateType", array('key' => $key));
    ?>
    <div class="span3">
        <?php
        echo $form->labelEx($model, "[$key]location");
        echo $form->textField($model, "[$key]location");
        echo $form->error($model, "[$key]location");
        ?>

    </div>

    <div class="span3">
        <?php
        echo $form->labelEx($model, "[$key]remarks");
        echo $form->textField($model, "[$key]remarks");
        echo $form->error($model, "[$key]remarks");
        ?>
    </div>

    <div class="span3">
        <?php
        echo $form->labelEx($model, "[$key]schedule");

        $this->widget('zii.widgets.jui.CJuiDatePicker', array(
            'model' => $model,
            'attribute' => "[$key]schedule",
            'options' => array(
                'showAnim' => 'fold',
            ),
            'htmlOptions' => array(
                'style' => 'height:20px;'
            ),
        ));
        echo $form->error($model, "[$key]schedule");
        ?>
        

    </div>
    <div class="span2">

            <?php echo $form->deleteRowButton($row_id, $key); ?>
        </div>
</div>

Add the following to the model that is used in the rows

public $updateType;

To Do

  • Add actionUpdate tutorial
  • Improve Documentation

Resources

Github Page

3 0
16 followers
2 180 downloads
Yii Version: Unknown
License: BSD-2-Clause
Category: User Interface
Developed by: ezekielnoob
Created on: Aug 3, 2013
Last updated: 10 years ago

Downloads

show all

Related Extensions