Skip to content

Conversation

terabytesoftw
Copy link
Member

@terabytesoftw terabytesoftw commented Sep 15, 2025

Q A
Is bugfix?
New feature? ✔️
Breaks BC?

This solution implements a way to make jQuery optional, while trying to keep BC as low as possible:

  • useJquery property is added to yii\base\Application, this allows you to control whether jQuery is used or not.
  • Gridview.
  • Validators.
  • ActiveForm.
  • ActiveField.
  • Add CDN all assets.
  • Add 100% test coverage.

I also think it would be a good idea to add the assets with CDN, and thus not depend on any package manager, if YII_DEBUG is true, it will be used without minification.

Minimum BC:

  • CheckboxColum => protected function getHeaderCheckBoxName() => public function getHeaderCheckBoxName()
  • ActiveField => protected function isClientValidationEnabled() => public function isClientValidationEnabled()
  • ActiveField => protected function isAjaxValidationEnabled() => public function isAjaxValidationEnabled()
  • private function buildMimeTypeRegexp($mask) => public function buildMimeTypeRegexp($mask)
  • private function getIpParsePattern() => public function getIpParsePattern()
// Application configuration
return [
    'useJquery' => false, // Disable jQuery globally
];

// Or dynamically
Yii::$app->useJquery = false;

// With jQuery default behavior
$form = ActiveForm::begin([]);

// Without jQuery custom client script
$form = ActiveForm::begin(['clientScript' => ActiveFormClientScript::class]);

Two interfaces have been added to add the clientScript to validators, widgets, components, etc.

<?php

declare(strict_types=1);

namespace yii\validators\client;

use yii\base\Model;
use yii\validators\Validator;
use yii\web\View;

interface ClientValidatorScriptInterface
{
    public function getClientOptions(Validator $validator, Model $model, string $attribute): array;
    public function register(Validator $validator, Model $model, string $attribute, View $view): string;
}
<?php


declare(strict_types=1);

namespace yii\web\client;

use yii\base\BaseObject;
use yii\web\View;

interface ClientScriptInterface
{
    public function getClientOptions(BaseObject $object): array;
    public function register(BaseObject $object, View $view): void;
}

Fixed generation of labels, whether custom or not, when enclosedByLabel === false, for both checkbox() and radio().

Example:

    public function testCheckboxEnclosedByLabelFalseWithCustomLabel(): void
    {
        $this->activeField->checkbox(
            [
                'label' => 'Custom Label',
                'labelOptions' => [
                    'class' => 'custom-label-class',
                    'data-test' => 'custom-label-data',
                ],
            ],
            false,
        );

        $this->assertEqualsWithoutLE(
            <<<HTML
            <div class="form-group field-activefieldtestmodel-attributename">
            <label class="custom-label-class" data-test="custom-label-data" for="activefieldtestmodel-attributename">Custom Label</label>
            <input type="hidden" name="ActiveFieldTestModel[attributeName]" value="0"><input type="checkbox" id="activefieldtestmodel-attributename" name="ActiveFieldTestModel[attributeName]" value="1">
            <div class="hint-block">Hint for attributeName attribute</div>
            <div class="help-block"></div>
            </div>
            HTML,
            $this->activeField->render(),
            'Failed asserting that checkbox renders correctly.',
        );
    }

    public function testCheckboxEnclosedByLabelFalseWithCustomLabelTag(): void
    {
        $this->activeField->checkbox(
            [
                'label' => 'Custom Label',
                'labelOptions' => [
                    'class' => 'custom-label-class',
                    'data-test' => 'custom-label-data',
                    'tag' => 'span',
                ],
            ],
            false,
        );

        $this->assertEqualsWithoutLE(
            <<<HTML
            <div class="form-group field-activefieldtestmodel-attributename">
            <span class="custom-label-class" data-test="custom-label-data">Custom Label</span>
            <input type="hidden" name="ActiveFieldTestModel[attributeName]" value="0"><input type="checkbox" id="activefieldtestmodel-attributename" name="ActiveFieldTestModel[attributeName]" value="1">
            <div class="hint-block">Hint for attributeName attribute</div>
            <div class="help-block"></div>
            </div>
            HTML,
            $this->activeField->render(),
            'Failed asserting that checkbox renders correctly.',
        );
    }

    public function testCheckboxEnclosedByLabelFalseWithCustomLabelTagFalse(): void
    {
        $this->activeField->checkbox(
            [
                'label' => 'Custom Label',
                'labelOptions' => [
                    'tag' => false,
                ],
            ],
            false,
        );

        $this->assertEqualsWithoutLE(
            <<<HTML
            <div class="form-group field-activefieldtestmodel-attributename">
            Custom Label
            <input type="hidden" name="ActiveFieldTestModel[attributeName]" value="0"><input type="checkbox" id="activefieldtestmodel-attributename" name="ActiveFieldTestModel[attributeName]" value="1">
            <div class="hint-block">Hint for attributeName attribute</div>
            <div class="help-block"></div>
            </div>
            HTML,
            $this->activeField->render(),
            'Failed asserting that checkbox renders correctly.',
        );
    }

To install the assets, i added php-forge/foxy, which i maintain and allows you to install assets easily using the composer installer. i think it would be great to use CDN to manage the assets, so we don't depend on anything external.

Issues related:

Copy link

codecov bot commented Sep 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.74%. Comparing base (9f5b6ee) to head (68e1499).
⚠️ Report is 18 commits behind head on 22.0.

Additional details and impacted files
@@             Coverage Diff              @@
##               22.0   #20528      +/-   ##
============================================
+ Coverage     65.42%   66.74%   +1.31%     
- Complexity    11266    11372     +106     
============================================
  Files           428      445      +17     
  Lines         37064    37364     +300     
============================================
+ Hits          24250    24937     +687     
+ Misses        12814    12427     -387     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@terabytesoftw terabytesoftw changed the title Allow optional jQuery in Validators, widgets and components. Allow optional jQuery in Validators and Widgets. Sep 15, 2025
…ield`, `ActiveForm`, fix customLabel for `checkbox` and `radio` methods.
…ryClientScriptTest` for stricter comparison.
…ooleanValidatorJqueryClientScriptTest` for clarity.
…age assertions and improve clarity in validation checks.
@terabytesoftw terabytesoftw marked this pull request as ready for review September 24, 2025 14:00
*
* @since 2.2.0
*/
public bool $useJquery = false;
Copy link
Member

Choose a reason for hiding this comment

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

I don't think it is needed. Anything breaks if it's removed?

*
* @since 2.2.0
*/
public bool $useJquery = true;
Copy link
Member

Choose a reason for hiding this comment

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

Should it be for web application only?

* @return string
*/
protected function formatMessage($message, $params)
public function formatMessage($message, $params)
Copy link
Member

Choose a reason for hiding this comment

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

Why changing it to public?

* @since 2.0.11
*/
protected function isClientValidationEnabled()
public function isClientValidationEnabled()
Copy link
Member

Choose a reason for hiding this comment

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

Why is it public now?

* @since 2.0.11
*/
protected function isAjaxValidationEnabled()
public function isAjaxValidationEnabled()
Copy link
Member

Choose a reason for hiding this comment

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

Why is it public now?

* @since 2.0.7
*/
protected function getInputId()
public function getInputId()
Copy link
Member

Choose a reason for hiding this comment

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

Why is it public now?

@samdark samdark requested a review from Copilot September 29, 2025 22:34
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces optional jQuery functionality for Yii2 validators and widgets, allowing developers to disable jQuery while maintaining backward compatibility. The implementation adds a useJquery property to yii\base\Application and provides alternative client script implementations that work without jQuery.

  • Main feature: Optional jQuery support controlled by Yii::$app->useJquery setting
  • Enhanced widgets: ActiveForm, ActiveField, and GridView components now support jQuery-free operation
  • Comprehensive validation: All core validators can function without jQuery through new client script interfaces

Reviewed Changes

Copilot reviewed 83 out of 84 changed files in this pull request and generated no comments.

Show a summary per file
File Description
framework/widgets/ActiveForm.php Adds client script interface and conditional jQuery dependency
framework/widgets/ActiveField.php Implements jQuery-optional validation and enhanced label rendering
framework/web/View.php Updates jQuery usage to reference global application setting
framework/validators/*.php Adds client script interfaces to all validators for jQuery independence
framework/jquery/validators/*.php New jQuery-specific client script implementations
tests/framework/**/*.php Comprehensive test coverage for new functionality

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants