Skip to content

Commit

Permalink
Enh #25: Added enhancements to better support for nested widgets.
Browse files Browse the repository at this point in the history
  • Loading branch information
wbraganca committed May 17, 2015
1 parent fcd5ce8 commit 7299ad6
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 37 deletions.
35 changes: 18 additions & 17 deletions CHANGELOG.md
Expand Up @@ -3,44 +3,45 @@ yii2-dynamicform change Log

dev-master
----------
- enh #24: Added support for "jquery.inputmask". It only works with Yii 2.0.4 or higher.
- enh: Remove "error/success" class css template to be cloned.
- bug: Fixes for: checkbox(), checkboxList(), radio() and radioList()
- Enh #25: Added enhancements to better support for nested widgets.
- Enh #24: Added support for "jquery.inputmask". It only works with Yii 2.0.4 or higher.
- Enh: Remove "error/success" class css template to be cloned.
- Bug: Fixes for: checkbox(), checkboxList(), radio() and radioList()


version 2.0.2
-------------
**Date:** 25-Fev-2015
- bug #22: Correct reset attributes (id, name) when we have more than two nested widgets
- Bug #22: Correct reset attributes (id, name) when we have more than two nested widgets


version 2.0.1
-------------
**Date:** 23-Fev-2015
- bug: Fixed error for the use of multiple nested widgets with zero initial elements
- Bug: Fixed error for the use of multiple nested widgets with zero initial elements


version 2.0.0
-------------
**Date:** 22-Fev-2015
- enh #20: Added trigger 'beforeDelete'
- bug #19: Fixes checkboxes on new items
- enh #15: Added support for multiple nested widgets
- Enh #20: Added trigger 'beforeDelete'
- Bug #19: Fixes checkboxes on new items
- Enh #15: Added support for multiple nested widgets


version 1.1.0
-------------
**Date:** 16-Dez-2014

- bug #7: Added support for "kartik-v/yii2-widget-depdrop" for working with type DepDrop::TYPE_SELECT2
- bug #8: Fixes to support the latest version of kartik-v widgets
- bug: Fixed client validation
- bug #6: Fixed settings for datepicker
- enh: Added support for "kartik-v/yii2-widget-depdrop"
- enh: Added support for "kartik-v/yii2-widget-select2"
- bug: Fixed html name attribute for "kartik-v/yii2-widget-colorinput"
- enh: Added support for "kartik-v/yii2-widget-timepicker"
- enh: Added support for "kartik-v/yii2-widget-colorinput"
- Bug #7: Added support for "kartik-v/yii2-widget-depdrop" for working with type DepDrop::TYPE_SELECT2
- Bug #8: Fixes to support the latest version of kartik-v widgets
- Bug: Fixed client validation
- Bug #6: Fixed settings for datepicker
- Enh: Added support for "kartik-v/yii2-widget-depdrop"
- Enh: Added support for "kartik-v/yii2-widget-select2"
- Bug: Fixed html name attribute for "kartik-v/yii2-widget-colorinput"
- Enh: Added support for "kartik-v/yii2-widget-timepicker"
- Enh: Added support for "kartik-v/yii2-widget-colorinput"


version 1.0.0
Expand Down
18 changes: 12 additions & 6 deletions README.md
Expand Up @@ -3,14 +3,11 @@ yii2-dynamicform

[![Latest Version](https://img.shields.io/github/release/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://github.com/wbraganca/yii2-dynamicform/releases)
[![Software License](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Build Status](https://img.shields.io/travis/wbraganca/yii2-dynamicform/master.svg?style=flat-square)](https://travis-ci.org/wbraganca/yii2-dynamicform)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://scrutinizer-ci.com/g/wbraganca/yii2-dynamicform/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://scrutinizer-ci.com/g/wbraganca/yii2-dynamicform)
[![Total Downloads](https://img.shields.io/packagist/dt/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://packagist.org/packages/wbraganca/yii2-dynamicform)


It is widget to yii2 framework to clone form elements in a nested manner, maintaining accessibility.
![yii2-dynamicform](http://wbraganca.com/img/yii2-dynamicform-2.0.0.jpg)
![yii2-dynamicform](http://wbraganca.com/img/yii2-dynamicform/sample.jpg)

Installation
------------
Expand All @@ -32,10 +29,19 @@ or add
to the require section of your `composer.json` file.


Demos
-----

* [Demo 1](http://wbraganca.com/yii2extensions/dynamicform-demo1/) - (Address Book).
* [Demo 2](http://wbraganca.com/yii2extensions/dynamicform-demo2/) - (File Upload).
* [Demo 3](http://wbraganca.com/yii2extensions/dynamicform-demo3/) - (Nested Dynamic Form).


Usage
----------
-----

###Hypothetical Scenario
![Database](http://wbraganca.com/img/yii2--db.png)
![Database](http://wbraganca.com/img/yii2-dynamicform/hypothetical-scenario.jpg)

###The View

Expand Down
90 changes: 77 additions & 13 deletions src/DynamicFormWidget.php
Expand Up @@ -7,6 +7,7 @@

namespace wbraganca\dynamicform;

use Yii;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\CssSelector\CssSelector;
use yii\helpers\Json;
Expand All @@ -20,7 +21,7 @@
*/
class DynamicFormWidget extends \yii\base\Widget
{
const HASH_VAR_BASE_NAME = 'dynamicform_';
const WIDGET_NAME = 'dynamicform';
/**
* @var string
*/
Expand Down Expand Up @@ -74,18 +75,23 @@ class DynamicFormWidget extends \yii\base\Widget
*/
private $_insertPositions = ['bottom', 'top'];
/**
* @var string the hashed global variable name storing the pluginOptions
* @var string the hashed global variable name storing the pluginOptions.
*/
private $_hashVar;
/**
* @var string the Json encoded options.
*/
private $_encodedOptions = '';

/**
* Initializes the widget
* Initializes the widget.
*
* @throws \yii\base\InvalidConfigException
*/
public function init()
{
parent::init();

if (empty($this->widgetContainer) || (preg_match('/^\w{1,}$/', $this->widgetContainer) === 0)) {
throw new InvalidConfigException('Invalid configuration to property "widgetContainer".
Allowed only alphanumeric characters plus underline: [A-Za-z0-9_]');
Expand All @@ -108,11 +114,12 @@ public function init()
if (empty($this->formFields) || !is_array($this->formFields)) {
throw new InvalidConfigException("The 'formFields' property must be set.");
}

$this->initOptions();
}

/**
* Initializes the widget options
* Initializes the widget options.
*/
protected function initOptions()
{
Expand All @@ -138,22 +145,62 @@ protected function initOptions()
ob_implicit_flush(false);
}

/**
* Registers plugin options by storing it in a hashed javascript variable.
*
* @param View $view The View object
*/
protected function registerOptions($view)
{
$encOptions = Json::encode($this->_options);
$this->_hashVar = DynamicFormWidget::HASH_VAR_BASE_NAME . hash('crc32', $encOptions);
$view->registerJs("var {$this->_hashVar} = {$encOptions};\n", $view::POS_HEAD);
$view->registerJs("var {$this->_hashVar} = {$this->_encodedOptions};\n", $view::POS_HEAD);
}

/**
* Registers the needed assets
* Generates a hashed variable to store the options.
*/
public function registerAssets()
protected function hashOptions()
{
$this->_encodedOptions = Json::encode($this->_options);
$this->_hashVar = self::WIDGET_NAME . '_' . hash('crc32', $this->_encodedOptions);
}

/**
* Returns the hashed variable.
*
* @return string
*/
protected function getHashVarName()
{
if (isset(Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer])) {
return Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer];
}

return $this->_hashVar;
}

/**
* Register the actual widget.
*
* @return boolean
*/
public function registerHashVarWidget()
{
if (!isset(Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer])) {
Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer] = $this->_hashVar;
return true;
}

return false;
}

/**
* Registers the needed assets.
*
* @param View $view The View object
*/
public function registerAssets($view)
{
$view = $this->getView();
DynamicFormAsset::register($view);
$options = Json::encode($this->_options);
$this->registerOptions($view);

// add a click handler for the clone button
$js = 'jQuery("#' . $this->formId . '").on("click", "' . $this->insertButton . '", function(e) {'. "\n";
Expand All @@ -174,6 +221,9 @@ public function registerAssets()
$view->registerJs($js, $view::POS_LOAD);
}

/**
* @inheritdoc
*/
public function run()
{
$content = ob_get_clean();
Expand All @@ -188,10 +238,24 @@ public function run()
$content = $this->removeItems($content);
}

$this->registerAssets();
$this->hashOptions();
$view = $this->getView();
$widgetRegistered = $this->registerHashVarWidget();
$this->_hashVar = $this->getHashVarName();

if ($widgetRegistered) {
$this->registerOptions($view);
$this->registerAssets($view);
}

echo Html::tag('div', $content, ['class' => $this->widgetContainer, 'data-dynamicform' => $this->_hashVar]);
}

/**
* Clear HTML widgetBody. Required to work with zero or more items.
*
* @param string $content
*/
private function removeItems($content)
{
$document = new \DOMDocument('1.0', \Yii::$app->charset);
Expand Down

0 comments on commit 7299ad6

Please sign in to comment.