| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
- /**
- * @module ui/labeledinput/labeledinputview
- */
- import View from '../view';
- import uid from '@ckeditor/ckeditor5-utils/src/uid';
- import LabelView from '../label/labelview';
- import '../../theme/components/labeledinput/labeledinput.css';
- /**
- * The labeled input view class.
- *
- * @extends module:ui/view~View
- */
- export default class LabeledInputView extends View {
- /**
- * Creates an instance of the labeled input view class.
- *
- * @param {module:utils/locale~Locale} locale The locale instance.
- * @param {Function} InputView Constructor of the input view.
- */
- constructor( locale, InputView ) {
- super( locale );
- const inputUid = `ck-input-${ uid() }`;
- const statusUid = `ck-status-${ uid() }`;
- /**
- * The text of the label.
- *
- * @observable
- * @member {String} #label
- */
- this.set( 'label' );
- /**
- * The value of the input.
- *
- * @observable
- * @member {String} #value
- */
- this.set( 'value' );
- /**
- * Controls whether the component is in read-only mode.
- *
- * @observable
- * @member {Boolean} #isReadOnly
- */
- this.set( 'isReadOnly', false );
- /**
- * The validation error text. When set, it will be displayed
- * next to the {@link #inputView} as a typical validation error message.
- * Set it to `null` to hide the message.
- *
- * **Note:** Setting this property to anything but `null` will automatically
- * make the {@link module:ui/inputtext/inputtextview~InputTextView#hasError `hasError`}
- * of the {@link #inputView} `true`.
- *
- * **Note:** Typing in the {@link #inputView} which fires the
- * {@link module:ui/inputtext/inputtextview~InputTextView#event:input `input` event}
- * resets this property back to `null`, indicating that the input field can be re–validated.
- *
- * @observable
- * @member {String|null} #errorText
- */
- this.set( 'errorText', null );
- /**
- * The additional information text displayed next to the {@link #inputView} which can
- * be used to inform the user about the purpose of the input, provide help or hints.
- *
- * Set it to `null` to hide the message.
- *
- * **Note:** This text will be displayed in the same place as {@link #errorText} but the
- * latter always takes precedence: if the {@link #errorText} is set, it replaces
- * {@link #errorText} for as long as the value of the input is invalid.
- *
- * @observable
- * @member {String|null} #infoText
- */
- this.set( 'infoText', null );
- /**
- * The label view.
- *
- * @member {module:ui/label/labelview~LabelView} #labelView
- */
- this.labelView = this._createLabelView( inputUid );
- /**
- * The input view.
- *
- * @member {module:ui/inputtext/inputtextview~InputTextView} #inputView
- */
- this.inputView = this._createInputView( InputView, inputUid, statusUid );
- /**
- * The status view for the {@link #inputView}. It displays {@link #errorText} and
- * {@link #infoText}.
- *
- * @member {module:ui/view~View} #statusView
- */
- this.statusView = this._createStatusView( statusUid );
- /**
- * The combined status text made of {@link #errorText} and {@link #infoText}.
- * Note that when present, {@link #errorText} always takes precedence in the
- * status.
- *
- * @see #errorText
- * @see #infoText
- * @see #statusView
- * @private
- * @observable
- * @member {String|null} #_statusText
- */
- this.bind( '_statusText' ).to(
- this, 'errorText',
- this, 'infoText',
- ( errorText, infoText ) => errorText || infoText
- );
- const bind = this.bindTemplate;
- this.setTemplate( {
- tag: 'div',
- attributes: {
- class: [
- 'ck',
- 'ck-labeled-input',
- bind.if( 'isReadOnly', 'ck-disabled' )
- ]
- },
- children: [
- this.labelView,
- this.inputView,
- this.statusView
- ]
- } );
- }
- /**
- * Creates label view class instance and bind with view.
- *
- * @private
- * @param {String} id Unique id to set as labelView#for attribute.
- * @returns {module:ui/label/labelview~LabelView}
- */
- _createLabelView( id ) {
- const labelView = new LabelView( this.locale );
- labelView.for = id;
- labelView.bind( 'text' ).to( this, 'label' );
- return labelView;
- }
- /**
- * Creates input view class instance and bind with view.
- *
- * @private
- * @param {Function} InputView Input view constructor.
- * @param {String} inputUid Unique id to set as inputView#id attribute.
- * @param {String} statusUid Unique id of the status for the input's `aria-describedby` attribute.
- * @returns {module:ui/inputtext/inputtextview~InputTextView}
- */
- _createInputView( InputView, inputUid, statusUid ) {
- const inputView = new InputView( this.locale, statusUid );
- inputView.id = inputUid;
- inputView.ariaDescribedById = statusUid;
- inputView.bind( 'value' ).to( this );
- inputView.bind( 'isReadOnly' ).to( this );
- inputView.bind( 'hasError' ).to( this, 'errorText', value => !!value );
- inputView.on( 'input', () => {
- // UX: Make the error text disappear and disable the error indicator as the user
- // starts fixing the errors.
- this.errorText = null;
- } );
- return inputView;
- }
- /**
- * Creates the status view instance. It displays {@link #errorText} and {@link #infoText}
- * next to the {@link #inputView}. See {@link #_statusText}.
- *
- * @private
- * @param {String} statusUid Unique id of the status, shared with the input's `aria-describedby` attribute.
- * @returns {module:ui/view~View}
- */
- _createStatusView( statusUid ) {
- const statusView = new View( this.locale );
- const bind = this.bindTemplate;
- statusView.setTemplate( {
- tag: 'div',
- attributes: {
- class: [
- 'ck',
- 'ck-labeled-input__status',
- bind.if( 'errorText', 'ck-labeled-input__status_error' ),
- bind.if( '_statusText', 'ck-hidden', value => !value )
- ],
- id: statusUid,
- role: bind.if( 'errorText', 'alert' )
- },
- children: [
- {
- text: bind.to( '_statusText' )
- }
- ]
- } );
- return statusView;
- }
- /**
- * Moves the focus to the input and selects the value.
- */
- select() {
- this.inputView.select();
- }
- /**
- * Focuses the input.
- */
- focus() {
- this.inputView.focus();
- }
- }
|