Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #8452 Jquery Extraction (attempt 2) #14865

Merged
merged 15 commits into from
Dec 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions framework/UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@ Upgrade from Yii 2.0.x
If you are using `yii\web\Request::resolve()` or `yii\web\UrlManager::parseRequest()` directly, make sure that
all potential exceptions are handled correctly or set `yii\web\UrlNormalizer::$normalizer` to `false` to disable normalizer.
* `yii\base\InvalidParamException` was renamed to `yii\base\InvalidArgumentException`.
* Classes `yii\widgets\ActiveForm`, `yii\widgets\ActiveField`, `yii\grid\GridView`, `yii\web\View` have been refactored
to be more generic without including any 'JQuery' support and client-side processing (validation, automatic submit etc.).
You should use widget behaviors from `yii\jquery\*` package to make old code function as before. E.g. attach `yii\jquery\ActiveFormClientScript`
to `yii\widgets\ActiveForm`, `yii\jquery\GridViewClientScript` to `yii\grid\GridView` and so on.
* Fields `$enableClientScript` and `$attributes` have been removed from `yii\widgets\ActiveForm`. Make sure
you do not use them or specify them during `ActiveForm::begin()` invocation.
* Field `yii\grid\GridView::$filterSelector` has been removed. Make sure you do not use it or specify it during
`GridView::widget()` invocation. Use `yii\jquery\GridViewClientScript::$filterSelector` instead.
* Method `getClientOptions()` has been removed from `yii\validators\Validator` and all its descendants.
All implementations of `clientValidateAttribute()` around built-in validators now return `null`.
Use classes from `yii\jquery\validators\client\*` for building client validation (JavaScript) code.
* Assets `yii\web\JqueryAsset`, `yii\web\YiiAsset`, `yii\validators\ValidationAsset` have been moved under `yii\jquery\*`
namespace. Make sure you refer to the new full-qualified names of this classes.
* Methods `yii\validators\Validator::formatMessage()`, `yii\validators\IpValidator::getIpParsePattern()` and
`yii\validators\FileValidator::buildMimeTypeRegexp()` have been made `public`. Make sure you use correct
access level specification in case you override these methods.
* Default script position for the `yii\web\View::registerJs()` changed to `View::POS_END`.


Upgrade from Yii 2.0.13
Expand Down
6 changes: 2 additions & 4 deletions framework/captcha/CaptchaAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace yii\captcha;
Copy link
Member

@samdark samdark Dec 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Captcha should be moved to separate repository. Script should be adjusted not to use jQuery.

Could be done in separate pull request after this one is merged.


use yii\web\AssetBundle;
use yii\web\YiiAsset;
use yii\jquery\YiiAsset;

/**
* This asset bundle provides the javascript files needed for the [[Captcha]] widget.
Expand All @@ -21,13 +21,11 @@ class CaptchaAsset extends AssetBundle
/**
* @inheritdoc
*/
public $sourcePath = '@yii/assets';

public $sourcePath = '@yii/captcha/assets';
/**
* @inheritdoc
*/
public $js = ['yii.captcha.js',];

/**
* @inheritdoc
*/
Expand Down
39 changes: 0 additions & 39 deletions framework/grid/GridView.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
use yii\base\InvalidConfigException;
use yii\base\Model;
use yii\helpers\Html;
use yii\helpers\Json;
use yii\helpers\Url;
use yii\i18n\Formatter;
use yii\widgets\BaseListView;

Expand Down Expand Up @@ -215,10 +213,6 @@ class GridView extends BaseListView
* as GET parameters to this URL.
*/
public $filterUrl;
/**
* @var string additional jQuery selector for selecting filter input fields
*/
public $filterSelector;
/**
* @var string whether the filters should be displayed in the grid view. Valid values include:
*
Expand Down Expand Up @@ -278,20 +272,6 @@ public function init()
$this->initColumns();
}

/**
* Runs the widget.
*/
public function run()
{
$id = $this->options['id'];
$options = Json::htmlEncode($this->getClientOptions());
$view = $this->getView();
GridViewAsset::register($view);
$view->registerJs("jQuery('#$id').yiiGridView($options);");

return parent::run();
}

/**
* Renders validator errors of filter model.
* @return string the rendering result.
Expand All @@ -318,25 +298,6 @@ public function renderSection($name)
}
}

/**
* Returns the options for the grid view JS widget.
* @return array the options
*/
protected function getClientOptions()
{
$filterUrl = isset($this->filterUrl) ? $this->filterUrl : Yii::$app->request->url;
$id = $this->filterRowOptions['id'];
$filterSelector = "#$id input, #$id select";
if (isset($this->filterSelector)) {
$filterSelector .= ', ' . $this->filterSelector;
}

return [
'filterUrl' => Url::to($filterUrl),
'filterSelector' => $filterSelector,
];
}

/**
* Renders the data models for the grid view.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
* @license http://www.yiiframework.com/license/
*/

namespace yii\widgets;
namespace yii\jquery;

use yii\web\AssetBundle;
use yii\web\YiiAsset;

/**
* The asset bundle for the [[ActiveForm]] widget.
Expand All @@ -21,13 +20,11 @@ class ActiveFormAsset extends AssetBundle
/**
* @inheritdoc
*/
public $sourcePath = '@yii/assets';

public $sourcePath = '@yii/jquery/assets';
/**
* @inheritdoc
*/
public $js = ['yii.activeForm.js'];

/**
* @inheritdoc
*/
Expand Down
113 changes: 113 additions & 0 deletions framework/jquery/ActiveFormClientScript.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

namespace yii\jquery;

use Yii;
use yii\helpers\Json;

/**
* ActiveFormClientScript is a behavior for [[\yii\widgets\ActiveForm]], which allows composition
* of the client-side and AJAX form validation via underlying JQuery plugin.
*
* Usage example:
*
* ```php
* <?php $form = \yii\widgets\ActiveForm::begin([
* 'id' => 'example-form',
* 'as clientScript' => \yii\jquery\ActiveFormClientScript::class,
Copy link
Member

@samdark samdark Dec 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are pros compared to extending ActiveFormClientScript from ActiveForm instead of making it a behavior?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. That was 1st approach. Cons are described here: #13839 That's why behaviors.

* // ...
* ]); ?>
* ...
* <?php \yii\widgets\ActiveForm::end(); ?>
* ```
*
* @see \yii\widgets\ActiveForm
* @see \yii\widgets\ActiveFormClientScriptBehavior
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.1.0
*/
class ActiveFormClientScript extends \yii\widgets\ActiveFormClientScript
{
/**
* {@inheritdoc}
*/
protected function defaultClientValidatorMap()
{
return [
\yii\validators\BooleanValidator::class => \yii\jquery\validators\client\BooleanValidator::class,
\yii\validators\CompareValidator::class => \yii\jquery\validators\client\CompareValidator::class,
\yii\validators\EmailValidator::class => \yii\jquery\validators\client\EmailValidator::class,
\yii\validators\FilterValidator::class => \yii\jquery\validators\client\FilterValidator::class,
\yii\validators\IpValidator::class => \yii\jquery\validators\client\IpValidator::class,
\yii\validators\NumberValidator::class => \yii\jquery\validators\client\NumberValidator::class,
\yii\validators\RangeValidator::class => \yii\jquery\validators\client\RangeValidator::class,
\yii\validators\RegularExpressionValidator::class => \yii\jquery\validators\client\RegularExpressionValidator::class,
\yii\validators\RequiredValidator::class => \yii\jquery\validators\client\RequiredValidator::class,
\yii\validators\StringValidator::class => \yii\jquery\validators\client\StringValidator::class,
\yii\validators\UrlValidator::class => \yii\jquery\validators\client\UrlValidator::class,
\yii\validators\ImageValidator::class => \yii\jquery\validators\client\ImageValidator::class,
\yii\validators\FileValidator::class => \yii\jquery\validators\client\FileValidator::class,
\yii\captcha\CaptchaValidator::class => \yii\jquery\validators\client\CaptchaClientValidator::class,
];
}

/**
* {@inheritdoc}
*/
protected function registerClientScript()
{
$id = $this->owner->options['id'];
$options = Json::htmlEncode($this->getClientOptions());
$attributes = Json::htmlEncode($this->attributes);
$view = $this->owner->getView();
ActiveFormAsset::register($view);
$view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);");
}

/**
* {@inheritdoc}
*/
protected function getFieldClientOptions($field)
{
$options = parent::getFieldClientOptions($field);

// only get the options that are different from the default ones (set in yii.activeForm.js)
return array_diff_assoc($options, [
'validateOnChange' => true,
'validateOnBlur' => true,
'validateOnType' => false,
'validationDelay' => 500,
'encodeError' => true,
'error' => '.help-block',
'updateAriaInvalid' => true,
]);
}

/**
* {@inheritdoc}
*/
protected function getClientOptions()
{
$options = parent::getClientOptions();

// only get the options that are different from the default ones (set in yii.activeForm.js)
return array_diff_assoc($options, [
'encodeErrorSummary' => true,
'errorSummary' => '.error-summary',
'validateOnSubmit' => true,
'errorCssClass' => 'has-error',
'successCssClass' => 'has-success',
'validatingCssClass' => 'validating',
'ajaxParam' => 'ajax',
'ajaxDataType' => 'json',
'scrollToError' => true,
'scrollToErrorOffset' => 0,
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
* @license http://www.yiiframework.com/license/
*/

namespace yii\grid;
namespace yii\jquery;

use yii\web\AssetBundle;
use yii\web\YiiAsset;

/**
* This asset bundle provides the javascript files for the [[GridView]] widget.
Expand All @@ -21,13 +20,11 @@ class GridViewAsset extends AssetBundle
/**
* @inheritdoc
*/
public $sourcePath = '@yii/assets';

public $sourcePath = '@yii/jquery/assets';
/**
* @inheritdoc
*/
public $js = ['yii.gridView.js'];

/**
* @inheritdoc
*/
Expand Down
94 changes: 94 additions & 0 deletions framework/jquery/GridViewClientScript.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

namespace yii\jquery;

use Yii;
use yii\base\Behavior;
use yii\base\Widget;
use yii\helpers\Json;
use yii\helpers\Url;

/**
* GridViewClientScript is a behavior for [[\yii\grid\GridView]] widget, which allows automatic filter submission via jQuery component.
*
* A basic usage looks like the following:
*
* ```php
* <?= yii\grid\GridView::widget([
* 'dataProvider' => $dataProvider,
* 'as clientScript' => [
* 'class' => yii\jquery\GridViewClientScript::class
* ],
* 'columns' => [
* 'id',
* 'name',
* 'created_at:datetime',
* // ...
* ],
* ]) ?>
* ```
*
* @see \yii\grid\GridView
* @see GridViewAsset
*
* @property \yii\grid\GridView $owner the owner of this behavior.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.1.0
*/
class GridViewClientScript extends Behavior
{
/**
* @var string additional jQuery selector for selecting filter input fields.
*/
public $filterSelector;


/**
* @inheritdoc
*/
public function events()
{
return [
Widget::EVENT_BEFORE_RUN => 'beforeRun'
];
}

/**
* Handles [[Widget::EVENT_BEFORE_RUN]] event, registering related client script.
* @param \yii\base\Event $event event instance.
*/
public function beforeRun($event)
{
$id = $this->owner->options['id'];
$options = Json::htmlEncode($this->getClientOptions());
$view = $this->owner->getView();
GridViewAsset::register($view);
$view->registerJs("jQuery('#$id').yiiGridView($options);");
}

/**
* Returns the options for the grid view JS widget.
* @return array the options
*/
protected function getClientOptions()
{
$filterUrl = isset($this->owner->filterUrl) ? $this->owner->filterUrl : Yii::$app->request->url;
$id = $this->owner->filterRowOptions['id'];
$filterSelector = "#$id input, #$id select";
if (isset($this->filterSelector)) {
$filterSelector .= ', ' . $this->filterSelector;
}

return [
'filterUrl' => Url::to($filterUrl),
'filterSelector' => $filterSelector,
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* @license http://www.yiiframework.com/license/
*/

namespace yii\web;
namespace yii\jquery;

use yii\web\AssetBundle;

/**
* This asset bundle provides the [jQuery](http://jquery.com/) JavaScript library.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @license http://www.yiiframework.com/license/
*/

namespace yii\validators;
namespace yii\jquery;

use yii\web\AssetBundle;

Expand Down
Loading