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

CKEDITOR.ui.dialog.checkbox.setValue() should be chainable, but it actually isn't #5135

Closed
LordPachelbel opened this issue Mar 24, 2022 · 5 comments · Fixed by #5239 or #5241
Closed
Labels
status:confirmed An issue confirmed by the development team. type:bug A bug.
Milestone

Comments

@LordPachelbel
Copy link
Contributor

The documentation says CKEDITOR.ui.dialog.checkbox.setValue() is a chainable method, just like all of the the other CKEDITOR.ui.dialog.*.setValue() methods for the other form field types, but when I try to use it as a chainable method I get an "Uncaught TypeError" exception in the console.

Here's my onChange handler for a select box in a dialog which messes with some other select boxes and a checkbox; it has been stripped down to just the relevant portions of the code:

var typeSelectionChanged = function() {
    var dialog            = this.getDialog(),
        typeValue         = this.getValue(),
        tableSelection    = dialog.getContentElement( 'info', 'tableSelection' ),    // <select>
        groupSelection    = dialog.getContentElement( 'info', 'groupSelection' ),    // <select>
        rowSelection      = dialog.getContentElement( 'info', 'rowSelection' ),      // <select>
        fieldSelection    = dialog.getContentElement( 'info', 'fieldSelection' ),    // <select>
        headingsSelection = dialog.getContentElement( 'info', 'headingsSelection' ); // <input type="checkbox">

    if(typeValue === 'group') {
        tableSelection.setValue('', true).disable();    // chaining works here
        groupSelection.enable();
        rowSelection.setValue('', true).disable();      // chaining works here
        fieldSelection.setValue('', true).disable();    // chaining works here
        headingsSelection.setValue('', true).disable(); // chaining DOES NOT work here -- "Uncaught TypeError: headingsSelection.setValue(...) is undefined"
    }

    dialog.layout();
};

I added some console debug statements just above the line that causes the exception:

console.debug(fieldSelection.setValue.toString());
console.debug(headingsSelection.setValue.toString());

And here is the result:

> function(a,b){this.getInputElement().setValue(a);!b&&this.fire("change",{value:a});return this}
> function(b,a){this.getInputElement().$.checked=b;!a&&this.fire("change",{value:b})}

Because there's no return this in the checkbox's version of the method, it's not actually chainable.

@LordPachelbel
Copy link
Contributor Author

LordPachelbel commented Mar 24, 2022

I found the method source at

setValue: function( checked, noChangeEvent ) {
:

/**
 * Sets the state of the checkbox.
 *
 * @param {Boolean} checked `true` to tick the checkbox, `false` to untick it.
 * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element.
 */
setValue: function( checked, noChangeEvent ) {
    this.getInputElement().$.checked = checked;
    !noChangeEvent && this.fire( 'change', { value: checked } );
},

(By the way, the documentation's "View Source" link for the checkbox's setValue() method links to a different place, to the definition for CKEDITOR.ui.dialog.uiElement.prototype.setValue(), which is why I couldn't find the actual code at first and used that .toString() trick to output the actual source code to the browser console.)

@LordPachelbel
Copy link
Contributor Author

LordPachelbel commented Mar 24, 2022

The radio button version of setValue() also doesn't return anything, so it has the same problem.

If I'm understanding the code correctly, most of the form fields rely on the prototype version of setValue() and only the checkbox, radio button, and textInput classes have overridden versions of it. And the textInput version invokes the prototype version anyway after it does its custom stuff with return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply( this, arguments );

I think the checkbox and radio classes' overridden methods are deliberately not calling the prototype version of setValue() because its code ultimately alters the DOMNode .value property, which doesn't make sense to do in this context for radio buttons and checkboxes. And so I think the way to make the overridden methods chainable is to simply add return this; at the end of each of them, but I'm not familiar enough with CKEditor's API or source code to be confident enough about that to create my own pull request to do so.

@LordPachelbel
Copy link
Contributor Author

All that said, the obvious workaround I'm using right now is to simply un-chain the two methods:

headingsSelection.setValue('', true);
headingsSelection.disable();

@KarolDawidziuk
Copy link
Contributor

Hi, @LordPachelbel

Thank you for your report and investigation.
I can confirm that issue.

Like you said, adding return at the end of setValue() method inside CKEDITOR.ui.dialog.checkbox should solve this issue.

...but I'm not familiar enough with CKEditor's API or source code to be confident enough about that to create my own pull request to do so.

If you want and have time, I encourage you to create a pull request with a fix for this issue. We will try to help in case you encounter any problems.
Please see this guide for more information: https://ckeditor.com/docs/ckeditor4/latest/guide/dev_contributing_code.html

@KarolDawidziuk KarolDawidziuk added status:confirmed An issue confirmed by the development team. size:? labels Mar 27, 2022
@KarolDawidziuk KarolDawidziuk changed the title the documentation says CKEDITOR.ui.dialog.checkbox.setValue() is chainable, but it actually isn't CKEDITOR.ui.dialog.checkbox.setValue() is chainable, but it actually isn't Mar 27, 2022
@KarolDawidziuk KarolDawidziuk changed the title CKEDITOR.ui.dialog.checkbox.setValue() is chainable, but it actually isn't CKEDITOR.ui.dialog.checkbox.setValue() should be chainable, but it actually isn't Mar 27, 2022
@jacekbogdanski jacekbogdanski added the type:bug A bug. label Jun 9, 2022
@CKEditorBot CKEditorBot added this to the 4.19.1 milestone Jun 10, 2022
@CKEditorBot
Copy link
Collaborator

Closed in #5241

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:confirmed An issue confirmed by the development team. type:bug A bug.
Projects
None yet
4 participants