import * as ko from "knockout" ; import * as Survey from "survey-knockout" ; import { SurveyPropertyEditorBase } from "./propertyEditorBase" ; import { editorLocalization } from "../editorLocalization" ; import { SurveyPropertyEditorFactory } from "./propertyEditorFactory" ; import { getNextValue } from "../utils/utils" ; import { SurveyQuestionEditorDefinition } from "../questionEditors/questionEditorDefinition" ; import { SurveyNestedPropertyEditor } from "./propertyNestedPropertyEditor" ; import { SurveyPropertyModalEditor , SurveyHelper } from "../entries" ; export class SurveyPropertyItemValuesEditor extends SurveyNestedPropertyEditor { private detailDefinition : any ; private optionsShowTextView : boolean = true ; koItemsText : any ; koShowTextView : any ; changeToTextViewClick : any ; changeToFormViewClick : any ; private koItemsTextDelayed : any ; private isUpdatingItemText : boolean = false ; constructor ( property ) { super ( property ) ; this . koShowTextView = ko . observable ( true ) ; var self = this ; if ( property ) { this . detailDefinition = SurveyQuestionEditorDefinition . definition [ this . getItemValueClassName ( ) ] ; } this . koItemsText = ko . observable ( "" ) ; this . koItemsTextDelayed = ko . pureComputed ( this . koItemsText ) . extend ( { rateLimit : { method : "notifyWhenChangesStop" , timeout : 400 } } ) ; this . koItemsTextDelayed . subscribe ( function ( newValue ) { self . updateItemsTextOnTyping ( newValue ) ; } ) ; this . koActiveView . subscribe ( function ( newValue ) { if ( newValue == "form" ) self . updateItems ( self . koItemsText ( ) ) ; else self . updateItemsText ( ) ; } ) ; this . changeToTextViewClick = function ( ) { self . koActiveView ( "text" ) ; } ; this . changeToFormViewClick = function ( ) { self . koActiveView ( "form" ) ; } ; this . modalName = "modelEditor" + "itemvalues" + SurveyPropertyModalEditor . idCounter ; SurveyPropertyModalEditor . idCounter ++ ; this . modalNameTarget = "#" + this . modalName ; } public get editorType ( ) : string { return "itemvalue[]" ; } public get editorTypeTemplate ( ) : string { return "item-values" ; } public get hasDetailButton ( ) : boolean { return ! ! this . detailDefinition ; } protected getItemValueClassName ( ) { return this . property ? this . editorType + "@" + this . property . name : "" ; } protected getEditorName ( ) { if ( ! this . koEditItem ( ) || ! this . koEditItem ( ) . obj ) return "" ; return editorLocalization . getString ( this . readOnly ( ) ? "pe.itemView" : "pe.itemEdit" ) [ "format" ] ( this . koEditItem ( ) . obj . value ) ; } public beforeShowCore ( ) { super . beforeShowCore ( ) ; this . updateShowTextViewVisibility ( ) ; } protected getColumnsProperties ( ) { var props = this . getDefinedProperties ( ) ; if ( ! ! props && props . length > 0 ) return props ; return this . getDefaultListProperties ( ) ; } protected getDefinedProperties ( ) { if ( ! this . property || ! this . object || ! this . object . getType ) return [ ] ; var properties = this . getDefinedListProperties ( this . object . getType ( ) + "@" + this . property . name ) ; var res = [ ] ; for ( var i = 0 ; i < properties . length ; i ++ ) { res . push ( properties [ i ] . property ) ; } return res ; } protected createEditorOptions ( ) { var options = super . createEditorOptions ( ) ; options . showTextView = true ; options . itemsEntryType = ( this . options [ "options" ] && this . options [ "options" ] . itemValuesEditorEntryType ) || "form" ; return options ; } protected onSetEditorOptions ( editorOptions ) { super . onSetEditorOptions ( editorOptions ) ; this . optionsShowTextView = editorOptions . showTextView ; this . updateShowTextViewVisibility ( ) ; this . koActiveView ( editorOptions . itemsEntryType || "form" ) ; } protected createNewItem ( ) { var nextValue = null ; var values = [ ] ; var items = this . originalValue ; if ( Array . isArray ( items ) ) { values = items . map ( function ( item ) { return item . value ; } ) ; } var itemText = this . property . getBaseValue ( ) ; if ( ! itemText ) { itemText = Survey . surveyLocalization . getString ( "choices_Item" ) ; } nextValue = getNextValue ( itemText , values ) ; var itemValue = this . createEditorItemValueCore ( nextValue ) ; if ( this . options ) { this . options . onItemValueAddedCallback ( this . object , this . editablePropertyName , itemValue , values ) ; } return itemValue ; } protected getItemClassName ( item ) { var className = this . getItemValueClassName ( ) ; return ! ! className ? className : item . getType ( ) ; } private createEditorItemValueCore ( item ) { var itemValue = Survey . Serializer . createClass ( this . property . className ) ; itemValue . setData ( item ) ; return itemValue ; } private isTextLocalized ( item ) { return Object . keys ( item . locText . values ) . length > 1 ; } protected onValueChanged ( ) { super . onValueChanged ( ) ; if ( this . isBeforeShowCalled ) { if ( this . koActiveView ( ) !== "form" ) { this . updateItemsText ( ) ; } } this . updateShowTextViewVisibility ( ) ; } private isUpdatingOnTyping : boolean = false ; private updateItemsTextOnTyping ( newValue ) { if ( this . isUpdatingItemText ) return ; this . isUpdatingOnTyping = true ; this . updateItems ( newValue ) ; this . isUpdatingOnTyping = false ; } private updateItemsText ( ) { if ( this . isUpdatingOnTyping ) return ; this . isUpdatingItemText = true ; this . koItemsText ( this . getItemsText ( ) ) ; this . isUpdatingItemText = false ; } protected onListDetailViewChanged ( ) { super . onListDetailViewChanged ( ) ; this . updateShowTextViewVisibility ( ) ; } protected updateItems ( text ) { var properties = this . getColumnsProperties ( ) ; var className = this . property . className ; var items = SurveyHelper . convertTextToItemValues ( text , properties , className ) ; this . updateArrayValue ( items ) ; } private updateArrayValue ( items ) { if ( ! this . originalValue ) return ; if ( ! items ) items = [ ] ; if ( Math . abs ( this . originalValue . length - items . length ) > 20 ) { this . object [ this . property . name ] = items ; } else { SurveyHelper . applyItemValueArray ( this . originalValue , items ) ; } this . doOnChanged ( this . originalValue ) ; } protected getItemsText ( ) { var items = [ ] ; for ( var i = 0 ; i < this . originalValue . length ; i ++ ) { items . push ( this . createItemViewModel ( this . originalValue [ i ] ) ) ; } return SurveyHelper . convertMatrixRowsToText ( items ) ; } private updateShowTextViewVisibility ( ) { if ( ! this . koShowTextView ) return ; if ( ! this . optionsShowTextView || this . columns . length == 0 ) { this . koShowTextView ( false ) ; return ; } this . koShowTextView ( this . isValuePropertyVisible ( ) && ! this . hasVisibleIfOrEnableIf ( ) && ! this . hasMultipleLanguage ( ) ) ; } private hasMultipleLanguage ( ) { var items = this . originalValue ; if ( ! items || ! Array . isArray ( items ) ) return false ; for ( var i = 0 ; i < items . length ; i ++ ) { if ( items [ i ] . locText . hasNonDefaultText ( ) ) return true ; } return false ; } private isValuePropertyVisible ( ) { var valueProp = Survey . Serializer . findProperty ( "itemvalue" , "value" ) ; return ! ! valueProp && valueProp . visible && ! valueProp . readOnly ; } private hasVisibleIfOrEnableIf ( ) { var items = this . originalValue ; if ( ! items || ! Array . isArray ( items ) ) return false ; for ( var i = 0 ; i < items . length ; i ++ ) { if ( ! ! items [ i ] . visibleIf || items [ i ] . enableIf ) return true ; } return false ; } protected hasDetailsProperties ( ) { return true ; } } SurveyPropertyEditorFactory . registerEditor ( "itemvalue[]" , function ( property ) : SurveyPropertyEditorBase { return new SurveyPropertyItemValuesEditor ( property ) ; } , "itemvalue" ) ;