2020-01-21 15:12:29 +01:00
"use strict" ;
2011-08-07 15:43:46 +02:00
/ * *
2013-04-13 21:00:13 +02:00
* EGroupware eTemplate2 - JS Textbox object
2011-08-07 15:43:46 +02:00
*
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @ package etemplate
* @ subpackage api
* @ link http : //www.egroupware.org
* @ author Andreas Stöckel
* /
2020-01-21 15:12:29 +01:00
var _ _extends = ( this && this . _ _extends ) || ( function ( ) {
var extendStatics = function ( d , b ) {
extendStatics = Object . setPrototypeOf ||
( { _ _proto _ _ : [ ] } instanceof Array && function ( d , b ) { d . _ _proto _ _ = b ; } ) ||
function ( d , b ) { for ( var p in b ) if ( b . hasOwnProperty ( p ) ) d [ p ] = b [ p ] ; } ;
return extendStatics ( d , b ) ;
} ;
return function ( d , b ) {
extendStatics ( d , b ) ;
function _ _ ( ) { this . constructor = d ; }
d . prototype = b === null ? Object . create ( b ) : ( _ _ . prototype = b . prototype , new _ _ ( ) ) ;
} ;
} ) ( ) ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2011-08-07 15:43:46 +02:00
/ * e g w : u s e s
2020-01-21 15:12:29 +01:00
/ v e n d o r / b o w e r - a s s e t / j q u e r y / d i s t / j q u e r y . j s ;
et2 _core _inputWidget ;
et2 _core _valueWidget ;
2011-08-07 15:43:46 +02:00
* /
2020-01-21 15:12:29 +01:00
require ( "./et2_core_common" ) ;
var et2 _core _inheritance _1 = require ( "./et2_core_inheritance" ) ;
var et2 _core _widget _1 = require ( "./et2_core_widget" ) ;
var et2 _core _DOMWidget _1 = require ( "./et2_core_DOMWidget" ) ;
var et2 _core _valueWidget _1 = require ( "./et2_core_valueWidget" ) ;
var et2 _core _inputWidget _1 = require ( "./et2_core_inputWidget" ) ;
require ( "./et2_types" ) ;
2011-08-07 15:43:46 +02:00
/ * *
* Class which implements the "textbox" XET - Tag
2014-01-29 16:55:18 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _inputWidget
2014-01-29 16:55:18 +01:00
* /
2020-01-21 15:54:26 +01:00
var et2 _textbox = /** @class */ ( function ( _super ) {
_ _extends ( et2 _textbox , _super ) ;
2020-01-21 15:12:29 +01:00
/ * *
* Constructor
* /
function et2 _textbox ( _parent , _attrs , _child ) {
var _this =
// Call the inherited constructor
2020-01-21 15:54:26 +01:00
_super . call ( this , _parent , _attrs , et2 _core _inheritance _1 . ClassWithAttributes . extendAttributes ( et2 _core _DOMWidget _1 . et2 _DOMWidget . _attributes , _child || { } ) ) || this ;
2020-01-21 15:12:29 +01:00
_this . legacyOptions = [ "size" , "maxlength" , "validator" ] ;
_this . input = null ;
_this . input = null ;
_this . createInputWidget ( ) ;
return _this ;
}
et2 _textbox . prototype . createInputWidget = function ( ) {
if ( this . options . multiline || this . options . rows > 1 || this . options . cols > 1 ) {
this . input = jQuery ( document . createElement ( "textarea" ) ) ;
if ( this . options . rows > 0 ) {
this . input . attr ( "rows" , this . options . rows ) ;
}
if ( this . options . cols > 0 ) {
this . input . attr ( "cols" , this . options . cols ) ;
}
}
else {
this . input = jQuery ( document . createElement ( "input" ) ) ;
switch ( this . options . type ) {
case "passwd" :
this . input . attr ( "type" , "password" ) ;
// Make autocomplete default value off for password field
// seems browsers not respecting 'off' anymore and started to
// impelement a new key called "new-password" considered as switching
// autocomplete off.
// https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
if ( this . options . autocomplete === "" || this . options . autocomplete == "off" )
this . options . autocomplete = "new-password" ;
break ;
case "hidden" :
this . input . attr ( "type" , "hidden" ) ;
break ;
}
if ( this . options . autocomplete )
this . input . attr ( "autocomplete" , this . options . autocomplete ) ;
}
if ( this . options . size ) {
this . set _size ( this . options . size ) ;
}
if ( this . options . blur ) {
this . set _blur ( this . options . blur ) ;
}
if ( this . options . readonly ) {
this . set _readonly ( true ) ;
}
this . input . addClass ( "et2_textbox" ) ;
this . setDOMNode ( this . input [ 0 ] ) ;
if ( this . options . value ) {
this . set _value ( this . options . value ) ;
}
if ( this . options . onkeypress && typeof this . options . onkeypress == 'function' ) {
var self = this ;
this . input . keypress ( function ( _ev ) {
return self . options . onkeypress . call ( this , _ev , self ) ;
} ) ;
}
} ;
/ * *
* Override the parent set _id method to manuipulate the input DOM node
*
* @ param { type } _value
* @ returns { undefined }
* /
et2 _textbox . prototype . set _id = function ( _value ) {
2020-01-21 15:54:26 +01:00
_super . prototype . set _id . call ( this , _value ) ;
2020-01-21 15:12:29 +01:00
// Remove the name attribute inorder to affect autocomplete="off"
// for no password save. ATM seems all browsers ignore autocomplete for
// input field inside the form
if ( this . options . type === "passwd"
&& this . options . autocomplete === "off" )
this . input . removeAttr ( 'name' ) ;
} ;
et2 _textbox . prototype . destroy = function ( ) {
var node = this . getInputNode ( ) ;
if ( node )
jQuery ( node ) . unbind ( "keypress" ) ;
2020-01-21 15:54:26 +01:00
_super . prototype . destroy . call ( this ) ;
2020-01-21 15:12:29 +01:00
} ;
et2 _textbox . prototype . getValue = function ( ) {
if ( this . options && this . options . blur && this . input . val ( ) == this . options . blur )
return "" ;
2020-01-21 15:54:26 +01:00
return _super . prototype . getValue . call ( this ) ;
2020-01-21 15:12:29 +01:00
} ;
/ * *
* Clientside validation using regular expression in "validator" attribute
*
* @ param { array } _messages
* /
et2 _textbox . prototype . isValid = function ( _messages ) {
var ok = true ;
// Check input is valid
if ( this . options && this . options . validator && ! this . options . readonly && ! this . disabled ) {
if ( typeof this . options . validator == 'string' ) {
var parts = this . options . validator . split ( '/' ) ;
var flags = parts . pop ( ) ;
if ( parts . length < 2 || parts [ 0 ] !== '' ) {
_messages . push ( this . egw ( ) . lang ( "'%1' has an invalid format !!!" , this . options . validator ) ) ;
return false ; // show invalid expression
}
parts . shift ( ) ;
this . options . validator = new RegExp ( parts . join ( '/' ) , flags ) ;
}
var value = this . getValue ( ) ;
if ( ! ( ok = this . options . validator . test ( value ) ) ) {
_messages . push ( this . egw ( ) . lang ( "'%1' has an invalid format !!!" , value ) ) ;
}
}
2020-01-21 15:54:26 +01:00
return _super . prototype . isValid . call ( this , _messages ) && ok ;
2020-01-21 15:12:29 +01:00
} ;
/ * *
* Set input widget size
* @ param _size Rather arbitrary size units , approximately characters
* /
et2 _textbox . prototype . set _size = function ( _size ) {
if ( this . options . multiline || this . options . rows > 1 || this . options . cols > 1 ) {
this . input . css ( 'width' , _size + "em" ) ;
}
2020-01-21 15:54:26 +01:00
else if ( typeof _size != 'undefined' && _size != parseInt ( this . input . attr ( "size" ) ) ) {
2020-01-21 15:12:29 +01:00
this . size = _size ;
this . input . attr ( "size" , this . size ) ;
}
} ;
/ * *
* Set maximum characters allowed
* @ param _size Max characters allowed
* /
et2 _textbox . prototype . set _maxlength = function ( _size ) {
2020-01-21 15:54:26 +01:00
if ( typeof _size != 'undefined' && _size != parseInt ( this . input . attr ( "maxlength" ) ) ) {
2020-01-21 15:12:29 +01:00
this . maxLength = _size ;
this . input . attr ( "maxLength" , this . maxLength ) ;
}
} ;
/ * *
* Set HTML readonly attribute .
* Do not confuse this with etemplate readonly , which would use et _textbox _ro instead
* @ param _readonly Boolean
* /
et2 _textbox . prototype . set _readonly = function ( _readonly ) {
this . input . attr ( "readonly" , _readonly ) ;
this . input . toggleClass ( 'et2_textbox_ro' , _readonly ) ;
} ;
et2 _textbox . prototype . set _blur = function ( _value ) {
if ( _value ) {
this . input . attr ( "placeholder" , this . egw ( ) . lang ( _value ) + "" ) ; // HTML5
if ( ! this . input [ 0 ] . placeholder ) {
// Not HTML5
if ( this . input . val ( ) == "" )
this . input . val ( this . egw ( ) . lang ( this . options . blur ) ) ;
this . input . focus ( this , function ( e ) {
if ( e . data . input . val ( ) == e . data . egw ( ) . lang ( e . data . options . blur ) )
e . data . input . val ( "" ) ;
} ) . blur ( this , function ( e ) {
if ( e . data . input . val ( ) == "" )
e . data . input . val ( e . data . egw ( ) . lang ( e . data . options . blur ) ) ;
} ) ;
}
}
else {
if ( ! this . getValue ( ) )
this . input . val ( '' ) ;
this . input . removeAttr ( "placeholder" ) ;
}
this . options . blur = _value ;
} ;
et2 _textbox . prototype . set _autocomplete = function ( _value ) {
this . options . autocomplete = _value ;
this . input . attr ( 'autocomplete' , _value ) ;
} ;
et2 _textbox . prototype . resize = function ( _height ) {
if ( _height && this . options . multiline ) {
// apply the ratio
_height = ( this . options . resize _ratio != '' ) ? _height * this . options . resize _ratio : _height ;
if ( _height != 0 ) {
this . input . height ( this . input . height ( ) + _height ) ;
// resize parent too, so mailvelope injected into parent inherits its height
this . input . parent ( ) . height ( this . input . parent ( ) . height ( ) + _height ) ;
}
}
} ;
et2 _textbox . _attributes = {
"multiline" : {
"name" : "multiline" ,
"type" : "boolean" ,
"default" : false ,
"description" : "If true, the textbox is a multiline edit field."
} ,
"size" : {
"name" : "Size" ,
"type" : "integer" ,
"default" : et2 _no _init ,
"description" : "Field width"
} ,
"maxlength" : {
"name" : "Maximum length" ,
"type" : "integer" ,
"default" : et2 _no _init ,
"description" : "Maximum number of characters allowed"
} ,
"blur" : {
"name" : "Placeholder" ,
"type" : "string" ,
"default" : "" ,
"description" : "This text get displayed if an input-field is empty and does not have the input-focus (blur). It can be used to show a default value or a kind of help-text."
} ,
// These for multi-line
"rows" : {
"name" : "Rows" ,
"type" : "integer" ,
"default" : - 1 ,
"description" : "Multiline field height - better to use CSS"
} ,
"cols" : {
"name" : "Size" ,
"type" : "integer" ,
"default" : - 1 ,
"description" : "Multiline field width - better to use CSS"
} ,
"validator" : {
"name" : "Validator" ,
"type" : "string" ,
"default" : et2 _no _init ,
"description" : "Perl regular expression eg. '/^[0-9][a-f]{4}$/i'"
} ,
"autocomplete" : {
"name" : "Autocomplete" ,
"type" : "string" ,
"default" : "" ,
"description" : "Weither or not browser should autocomplete that field: 'on', 'off', 'default' (use attribute from form). Default value for type password is set to off."
} ,
onkeypress : {
name : "onKeypress" ,
type : "js" ,
default : et2 _no _init ,
description : "JS code or app.$app.$method called when key is pressed, return false cancels it."
}
} ;
return et2 _textbox ;
} ( et2 _core _inputWidget _1 . et2 _inputWidget ) ) ;
2020-01-21 15:54:26 +01:00
exports . et2 _textbox = et2 _textbox ;
2020-01-21 15:12:29 +01:00
et2 _core _widget _1 . et2 _register _widget ( et2 _textbox , [ "textbox" , "passwd" , "hidden" ] ) ;
2011-08-16 14:31:18 +02:00
/ * *
* et2 _textbox _ro is the dummy readonly implementation of the textbox .
2014-01-29 16:55:18 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _valueWidget
2011-08-16 14:31:18 +02:00
* /
2020-01-21 15:54:26 +01:00
var et2 _textbox _ro = /** @class */ ( function ( _super ) {
_ _extends ( et2 _textbox _ro , _super ) ;
2020-01-21 15:12:29 +01:00
/ * *
* Constructor
* /
function et2 _textbox _ro ( _parent , _attrs , _child ) {
var _this =
// Call the inherited constructor
2020-01-21 15:54:26 +01:00
_super . call ( this , _parent , _attrs , et2 _core _inheritance _1 . ClassWithAttributes . extendAttributes ( et2 _core _DOMWidget _1 . et2 _DOMWidget . _attributes , _child || { } ) ) || this ;
2020-01-21 15:12:29 +01:00
_this . value = "" ;
_this . span = jQuery ( document . createElement ( "label" ) )
. addClass ( "et2_label" ) ;
_this . value _span = jQuery ( document . createElement ( "span" ) )
. addClass ( "et2_textbox_ro" )
. appendTo ( _this . span ) ;
_this . setDOMNode ( _this . span [ 0 ] ) ;
return _this ;
}
et2 _textbox _ro . prototype . set _label = function ( label ) {
// Remove current label
this . span . contents ( )
. filter ( function ( ) { return this . nodeType == 3 ; } ) . remove ( ) ;
var parts = et2 _csvSplit ( label , 2 , "%s" ) ;
this . span . prepend ( parts [ 0 ] ) ;
this . span . append ( parts [ 1 ] ) ;
this . label = label ;
// add class if label is empty
this . span . toggleClass ( 'et2_label_empty' , ! label || ! parts [ 0 ] ) ;
} ;
et2 _textbox _ro . prototype . set _value = function ( _value ) {
this . value = _value ;
if ( ! _value ) {
_value = "" ;
}
if ( this . label != "" ) {
this . span . removeClass ( 'et2_label_empty' ) ;
}
else {
this . span . addClass ( 'et2_label_empty' ) ;
}
this . value _span . text ( _value ) ;
} ;
/ * *
* Code for implementing et2 _IDetachedDOM
*
* @ param { array } _attrs array to add further attributes to
* /
et2 _textbox _ro . prototype . getDetachedAttributes = function ( _attrs ) {
_attrs . push ( "value" , "label" ) ;
} ;
et2 _textbox _ro . prototype . getDetachedNodes = function ( ) {
return [ this . span [ 0 ] , this . value _span [ 0 ] ] ;
} ;
et2 _textbox _ro . prototype . setDetachedAttributes = function ( _nodes , _values ) {
this . span = jQuery ( _nodes [ 0 ] ) ;
this . value _span = jQuery ( _nodes [ 1 ] ) ;
if ( typeof _values [ "label" ] != 'undefined' ) {
this . set _label ( _values [ "label" ] ) ;
}
if ( typeof _values [ "value" ] != 'undefined' ) {
this . set _value ( _values [ "value" ] ) ;
}
} ;
/ * *
* Ignore all more advanced attributes .
* /
et2 _textbox _ro . _attributes = {
"multiline" : {
"ignore" : true
} ,
"maxlength" : {
"ignore" : true
} ,
"onchange" : {
"ignore" : true
} ,
"rows" : {
"ignore" : true
} ,
"cols" : {
"ignore" : true
} ,
"size" : {
"ignore" : true
} ,
"needed" : {
"ignore" : true
}
} ;
return et2 _textbox _ro ;
} ( et2 _core _valueWidget _1 . et2 _valueWidget ) ) ;
et2 _core _widget _1 . et2 _register _widget ( et2 _textbox _ro , [ "textbox_ro" ] ) ;
2016-02-15 19:30:40 +01:00
/ * *
* et2 _searchbox is a widget which provides a collapsable input search
* with on searching indicator and clear handler regardless of any browser limitation .
* /
2020-01-21 15:54:26 +01:00
var et2 _searchbox = /** @class */ ( function ( _super ) {
_ _extends ( et2 _searchbox , _super ) ;
2020-01-21 15:12:29 +01:00
/ * *
* Constructor
* /
function et2 _searchbox ( _parent , _attrs , _child ) {
var _this =
// Call the inherited constructor
2020-01-21 15:54:26 +01:00
_super . call ( this , _parent , _attrs , et2 _core _inheritance _1 . ClassWithAttributes . extendAttributes ( et2 _core _DOMWidget _1 . et2 _DOMWidget . _attributes , _child || { } ) ) || this ;
_this . value = "" ;
2020-01-21 15:12:29 +01:00
_this . value = "" ;
_this . div = jQuery ( document . createElement ( 'div' ) )
. addClass ( 'et2_searchbox' ) ;
_this . flex = jQuery ( document . createElement ( 'div' ) )
. addClass ( 'flex' )
. appendTo ( _this . div ) ;
//this._super.apply(this, arguments);
_this . setDOMNode ( _this . div [ 0 ] ) ;
_this . _createWidget ( ) ;
return _this ;
}
et2 _searchbox . prototype . _createWidget = function ( ) {
var self = this ;
if ( this . options . overlay )
this . flex . addClass ( 'overlay' ) ;
// search button indicator
// no need to create search button if it's a fix search field
if ( ! this . options . fix ) {
this . button = et2 _core _widget _1 . et2 _createWidget ( 'button' , { image : "search" , "background_image" : "1" } , this ) ;
this . button . onclick = function ( ) {
self . _show _hide ( jQuery ( self . flex ) . hasClass ( 'hide' ) ) ;
self . search . input . focus ( ) ;
} ;
this . div . prepend ( this . button . getDOMNode ( ) ) ;
}
// input field
this . search = et2 _core _widget _1 . et2 _createWidget ( 'textbox' , { "blur" : egw . lang ( "search" ) ,
onkeypress : function ( event ) {
if ( event . which == 13 ) {
event . preventDefault ( ) ;
self . getInstanceManager ( ) . autocomplete _fixer ( ) ;
// Use a timeout to make sure we get the autocomplete value,
// if one was chosen, instead of what was actually typed.
// Chrome doesn't need this, but FF does.
window . setTimeout ( function ( ) {
self . set _value ( self . search . input . val ( ) ) ;
self . change ( ) ;
} , 0 ) ;
}
} } , this ) ;
// Autocomplete needs name
this . search . input . attr ( 'name' , this . id || 'searchbox' ) ;
this . search . input . on ( {
keyup : function ( event ) {
self . clear . toggle ( self . get _value ( ) != '' || ! self . options . fix ) ;
if ( event . which == 27 ) // Escape
{
// Excape clears search
self . set _value ( '' ) ;
}
} ,
blur : function ( event ) {
if ( egwIsMobile ( ) )
return ;
if ( ! event . relatedTarget || ! jQuery ( event . relatedTarget . parentNode ) . hasClass ( 'et2_searchbox' ) ) {
self . _show _hide ( ( ! self . options . overlay && self . get _value ( ) ) ) ;
}
if ( typeof self . oldValue != 'undefined' && self . _oldValue != self . get _value ( ) ) {
self . change ( ) ;
}
} ,
mousedown : function ( event ) {
2020-01-21 15:54:26 +01:00
if ( event . target . tagName == 'span' )
event . stopImmediatePropagation ( ) ;
2020-01-21 15:12:29 +01:00
}
} ) ;
this . flex . append ( this . search . getDOMNode ( ) ) ;
// clear button implementation
this . clear = jQuery ( document . createElement ( 'span' ) )
. addClass ( 'ui-icon clear' )
. toggle ( ! this . options . fix || ( this . _oldValue != '' && ! jQuery . isEmptyObject ( this . _oldValue ) ) )
. on ( 'mousedown' , function ( event ) {
event . preventDefault ( ) ;
} )
. on ( 'click' , function ( event ) {
if ( self . get _value ( ) ) {
self . search . input . val ( '' ) ;
self . search . input . focus ( ) ;
self . _show _hide ( true ) ;
if ( self . _oldValue )
self . change ( ) ;
}
else {
self . _show _hide ( false ) ;
}
if ( self . options . fix )
self . clear . hide ( ) ;
} )
. appendTo ( this . flex ) ;
} ;
/ * *
* Show / hide search field
* @ param { boolean } _stat true means show and false means hide
* /
et2 _searchbox . prototype . _show _hide = function ( _stat ) {
// Not applied for fix option
if ( this . options . fix )
return ;
jQuery ( this . flex ) . toggleClass ( 'hide' , ! _stat ) ;
jQuery ( this . getDOMNode ( ) ) . toggleClass ( 'expanded' , _stat ) ;
} ;
/ * *
* toggle search button status based on value
* /
et2 _searchbox . prototype . _searchToggleState = function ( ) {
if ( this . options . fix || egwIsMobile ( ) )
return ;
if ( ! this . get _value ( ) ) {
jQuery ( this . button . getDOMNode ( ) ) . removeClass ( 'toolbar_toggled' ) ;
this . button . set _statustext ( '' ) ;
}
else {
jQuery ( this . button . getDOMNode ( ) ) . addClass ( 'toolbar_toggled' ) ;
this . button . set _statustext ( egw . lang ( "search for '%1'" , this . get _value ( ) ) ) ;
}
} ;
/ * *
* override change function in order to preset the toggle state
* /
et2 _searchbox . prototype . change = function ( ) {
this . _searchToggleState ( ) ;
2020-01-21 15:54:26 +01:00
_super . prototype . change . apply ( this , arguments ) ;
2020-01-21 15:12:29 +01:00
} ;
et2 _searchbox . prototype . get _value = function ( ) {
return this . search . input . val ( ) ;
} ;
et2 _searchbox . prototype . set _value = function ( _value ) {
2020-01-21 15:54:26 +01:00
_super . prototype . set _value . call ( this , _value ) ;
2020-01-21 15:12:29 +01:00
if ( this . search )
this . search . input . val ( _value ) ;
} ;
/ * *
* override doLoadingFinished in order to set initial state
* /
et2 _searchbox . prototype . doLoadingFinished = function ( ) {
2020-01-21 15:54:26 +01:00
var ret = _super . prototype . doLoadingFinished . call ( this ) ;
2020-01-21 15:12:29 +01:00
if ( ! this . get _value ( ) ) {
this . _show _hide ( false ) ;
}
else {
this . _show _hide ( ! this . options . overlay ) ;
this . _searchToggleState ( ) ;
}
2020-01-21 15:54:26 +01:00
return ret ;
2020-01-21 15:12:29 +01:00
} ;
/ * *
* Overrride attachToDOM in order to unbind change handler
* /
et2 _searchbox . prototype . attachToDOM = function ( ) {
2020-01-21 15:54:26 +01:00
var ret = _super . prototype . attachToDOM . call ( this ) ;
2020-01-21 15:12:29 +01:00
var node = this . getInputNode ( ) ;
if ( node ) {
jQuery ( node ) . off ( '.et2_inputWidget' ) ;
}
2020-01-21 15:54:26 +01:00
return ret ;
2020-01-21 15:12:29 +01:00
} ;
/ * *
* Advanced attributes
* /
et2 _searchbox . _attributes = {
overlay : {
name : "Overlay searchbox" ,
type : "boolean" ,
default : false ,
description : "Define wheter the searchbox overlays while it's open (true) or stay as solid box infront of the search button (false). Default is false."
} ,
fix : {
name : "Fix searchbox" ,
type : "boolean" ,
default : true ,
description : "Define wheter the searchbox should be a fix input field or flexible search button. Default is true (fix)."
}
} ;
return et2 _searchbox ;
} ( et2 _textbox ) ) ;
et2 _core _widget _1 . et2 _register _widget ( et2 _searchbox , [ "searchbox" ] ) ;
2020-01-21 19:45:21 +01:00
//# sourceMappingURL=et2_widget_textbox.js.map