2011-08-18 19:34:01 +02:00
/ * *
2013-04-13 21:00:13 +02:00
* EGroupware eTemplate2 - JS Radiobox object
2011-08-18 19:34:01 +02:00
*
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @ package etemplate
* @ subpackage api
2021-06-07 17:33:53 +02:00
* @ link https : //www.egroupware.org
2011-08-18 19:34:01 +02:00
* @ author Nathan Gray
* @ copyright Nathan Gray 2011
* /
/ * e g w : u s e s
2020-01-23 15:14:46 +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 ;
2011-08-18 19:34:01 +02:00
* /
2021-06-07 17:33:53 +02:00
import { et2 _inputWidget } from "./et2_core_inputWidget" ;
import { ClassWithAttributes } from "./et2_core_inheritance" ;
import { et2 _createWidget , et2 _register _widget } from "./et2_core_widget" ;
import { et2 _valueWidget } from './et2_core_valueWidget' ;
2011-08-18 19:34:01 +02:00
/ * *
* Class which implements the "radiobox" XET - Tag
2014-02-13 10:50:49 +01:00
*
2013-10-09 18:22:35 +02:00
* A radio button belongs to same group by giving all buttons of a group same id !
2014-02-13 10:50:49 +01:00
*
2013-10-09 18:22:35 +02:00
* set _value iterates over all of them and ( un ) checks them depending on given value .
2014-02-13 10:50:49 +01:00
*
2013-04-13 21:00:13 +02:00
* @ augments et2 _inputWidget
2014-02-13 10:50:49 +01:00
* /
2021-06-07 17:33:53 +02:00
export class et2 _radiobox extends et2 _inputWidget {
2020-01-23 15:14:46 +01:00
/ * *
* Constructor
*
* @ memberOf et2 _radiobox
* /
2021-06-07 17:33:53 +02:00
constructor ( _parent , _attrs , _child ) {
super ( _parent , _attrs , ClassWithAttributes . extendAttributes ( et2 _radiobox . _attributes , _child || { } ) ) ;
this . input = null ;
this . id = "" ;
this . createInputWidget ( ) ;
2020-01-23 15:14:46 +01:00
}
2021-06-07 17:33:53 +02:00
transformAttributes ( _attrs ) {
super . transformAttributes ( _attrs ) ;
let readonly = this . getArrayMgr ( 'readonlys' ) . getEntry ( this . id ) ;
2020-01-23 15:14:46 +01:00
if ( readonly && readonly . hasOwnProperty ( _attrs . set _value ) ) {
_attrs . readonly = readonly [ _attrs . set _value ] ;
}
2021-06-07 17:33:53 +02:00
}
createInputWidget ( ) {
2020-01-23 15:14:46 +01:00
this . input = jQuery ( document . createElement ( "input" ) )
. val ( this . options . set _value )
. attr ( "type" , "radio" )
. attr ( "disabled" , this . options . readonly ) ;
this . input . addClass ( "et2_radiobox" ) ;
this . setDOMNode ( this . input [ 0 ] ) ;
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Overwritten to set different DOM level ids by appending set _value
*
* @ param _id
* /
2021-06-07 17:33:53 +02:00
set _id ( _id ) {
super . set _id ( _id ) ;
2020-01-23 15:14:46 +01:00
this . dom _id = this . dom _id . replace ( '[]' , '' ) + '-' + this . options . set _value ;
if ( this . input )
this . input . attr ( 'id' , this . dom _id ) ;
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Default for radio buttons is label after button
*
* @ param _label String New label for radio button . Use % s to locate the radio button somewhere else in the label
* /
2021-06-07 17:33:53 +02:00
set _label ( _label ) {
2020-01-23 15:14:46 +01:00
if ( _label . length > 0 && _label . indexOf ( '%s' ) == - 1 ) {
_label = '%s' + _label ;
}
2021-06-07 17:33:53 +02:00
super . set _label ( _label ) ;
}
2020-01-23 15:14:46 +01:00
/ * *
* Override default to match against set / unset value AND iterate over all siblings with same id
*
* @ param { string } _value
* /
2021-06-07 17:33:53 +02:00
set _value ( _value ) {
2020-01-23 15:14:46 +01:00
this . getRoot ( ) . iterateOver ( function ( radio ) {
if ( radio . id == this . id ) {
2020-08-18 13:20:29 +02:00
radio . input . prop ( 'checked' , _value == radio . options . set _value ) ;
2020-01-23 15:14:46 +01:00
}
} , this , et2 _radiobox ) ;
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Override default to iterate over all siblings with same id
*
* @ return { string }
* /
2021-06-07 17:33:53 +02:00
getValue ( ) {
let val = this . options . value ; // initial value, when form is loaded
let values = [ ] ;
2020-01-23 15:14:46 +01:00
this . getRoot ( ) . iterateOver ( function ( radio ) {
values . push ( radio . options . set _value ) ;
if ( radio . id == this . id && radio . input && radio . input . prop ( 'checked' ) ) {
val = radio . options . set _value ;
}
} , this , et2 _radiobox ) ;
return val && val . indexOf ( values ) ? val : null ;
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Overridden from parent so if it ' s required , only 1 in a group needs a value
*
* @ param { array } messages
* @ returns { Boolean }
* /
2021-06-07 17:33:53 +02:00
isValid ( messages ) {
let ok = true ;
2020-01-23 15:14:46 +01:00
// Check for required
if ( this . options && this . options . needed && ! this . options . readonly && ! this . disabled &&
( this . getValue ( ) == null || this . getValue ( ) . valueOf ( ) == '' ) ) {
if ( jQuery . isEmptyObject ( this . getInstanceManager ( ) . getValues ( this . getInstanceManager ( ) . widgetContainer ) [ this . id . replace ( '[]' , '' ) ] ) ) {
messages . push ( this . egw ( ) . lang ( 'Field must not be empty !!!' ) ) ;
ok = false ;
}
}
return ok ;
2021-06-07 17:33:53 +02:00
}
2020-05-13 11:55:22 +02:00
/ * *
* Set radio readonly attribute .
2020-05-13 11:56:49 +02:00
*
2020-05-13 11:55:22 +02:00
* @ param _readonly Boolean
* /
2021-06-07 17:33:53 +02:00
set _readonly ( _readonly ) {
2020-05-13 11:56:49 +02:00
this . options . readonly = _readonly ;
2020-05-13 11:55:22 +02:00
this . getRoot ( ) . iterateOver ( function ( radio ) {
if ( radio . id == this . id ) {
radio . input . prop ( 'disabled' , _readonly ) ;
}
} , this , et2 _radiobox ) ;
2021-06-07 17:33:53 +02:00
}
}
et2 _radiobox . _attributes = {
"set_value" : {
"name" : "Set value" ,
"type" : "string" ,
"default" : "true" ,
"description" : "Value when selected"
} ,
"ro_true" : {
"name" : "Read only selected" ,
"type" : "string" ,
"default" : "x" ,
"description" : "What should be displayed when readonly and selected"
} ,
"ro_false" : {
"name" : "Read only unselected" ,
"type" : "string" ,
"default" : "" ,
"description" : "What should be displayed when readonly and not selected"
}
} ;
et2 _radiobox . legacyOptions = [ "set_value" , "ro_true" , "ro_false" ] ;
et2 _register _widget ( et2 _radiobox , [ "radio" ] ) ;
2013-04-13 21:00:13 +02:00
/ * *
* @ augments et2 _valueWidget
* /
2021-06-07 17:33:53 +02:00
export class et2 _radiobox _ro extends et2 _valueWidget {
2020-01-23 15:14:46 +01:00
/ * *
* Constructor
*
* @ memberOf et2 _radiobox _ro
* /
2021-06-07 17:33:53 +02:00
constructor ( _parent , _attrs , _child ) {
2020-01-23 15:14:46 +01:00
// Call the inherited constructor
2021-06-07 17:33:53 +02:00
super ( _parent , _attrs , ClassWithAttributes . extendAttributes ( et2 _radiobox _ro . _attributes , _child || { } ) ) ;
this . value = "" ;
this . span = null ;
this . span = jQuery ( document . createElement ( "span" ) )
2020-01-23 15:14:46 +01:00
. addClass ( "et2_radiobox" ) ;
2021-06-07 17:33:53 +02:00
this . setDOMNode ( this . span [ 0 ] ) ;
2020-01-23 15:14:46 +01:00
}
/ * *
* Override default to match against set / unset value
*
* @ param { string } _value
* /
2021-06-07 17:33:53 +02:00
set _value ( _value ) {
2020-01-23 15:14:46 +01:00
this . value = _value ;
if ( _value == this . options . set _value ) {
this . span . text ( this . options . ro _true ) ;
}
else {
this . span . text ( this . options . ro _false ) ;
}
2021-06-07 17:33:53 +02:00
}
set _label ( _label ) {
2021-01-26 21:09:39 +01:00
// no label for ro radio, we show label of checked option as content, unless it's x
// then we need the label for things to make sense
if ( this . options . ro _true == "x" ) {
2021-06-07 17:33:53 +02:00
return super . set _label ( _label ) ;
2021-01-26 21:09:39 +01:00
}
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Code for implementing et2 _IDetachedDOM
*
* @ param { array } _attrs
* /
2021-06-07 17:33:53 +02:00
getDetachedAttributes ( _attrs ) {
2020-01-23 15:14:46 +01:00
// Show label in nextmatch instead of just x
this . options . ro _true = this . options . label ;
_attrs . push ( "value" ) ;
2021-06-07 17:33:53 +02:00
}
getDetachedNodes ( ) {
2020-01-23 15:14:46 +01:00
return [ this . span [ 0 ] ] ;
2021-06-07 17:33:53 +02:00
}
setDetachedAttributes ( _nodes , _values ) {
2020-01-23 15:14:46 +01:00
this . span = jQuery ( _nodes [ 0 ] ) ;
this . set _value ( _values [ "value" ] ) ;
2021-06-07 17:33:53 +02:00
}
}
et2 _radiobox _ro . _attributes = {
"set_value" : {
"name" : "Set value" ,
"type" : "string" ,
"default" : "true" ,
"description" : "Value when selected"
} ,
"ro_true" : {
"name" : "Read only selected" ,
"type" : "string" ,
"default" : "x" ,
"description" : "What should be displayed when readonly and selected"
} ,
"ro_false" : {
"name" : "Read only unselected" ,
"type" : "string" ,
"default" : "" ,
"description" : "What should be displayed when readonly and not selected"
} ,
"label" : {
"name" : "Label" ,
"default" : "" ,
"type" : "string"
}
} ;
et2 _radiobox _ro . legacyOptions = [ "set_value" , "ro_true" , "ro_false" ] ;
et2 _register _widget ( et2 _radiobox _ro , [ "radio_ro" ] ) ;
2012-03-23 19:57:13 +01:00
/ * *
* A group of radio buttons
2014-02-13 10:50:49 +01:00
*
2013-06-18 22:55:13 +02:00
* @ augments et2 _valueWidget
2014-02-13 10:50:49 +01:00
* /
2021-06-07 17:33:53 +02:00
export class et2 _radioGroup extends et2 _valueWidget {
2020-01-23 15:14:46 +01:00
/ * *
* Constructor
*
* @ param parent
* @ param attrs
* @ memberOf et2 _radioGroup
* /
2021-06-07 17:33:53 +02:00
constructor ( _parent , _attrs , _child ) {
2020-01-23 15:14:46 +01:00
// Call the inherited constructor
2021-06-07 17:33:53 +02:00
super ( _parent , _attrs , ClassWithAttributes . extendAttributes ( et2 _radioGroup . _attributes , _child || { } ) ) ;
this . node = null ;
this . value = null ;
this . node = jQuery ( document . createElement ( "div" ) )
2020-01-23 15:14:46 +01:00
. addClass ( "et2_vbox" )
. addClass ( "et2_box_widget" ) ;
2021-06-07 17:33:53 +02:00
if ( this . options . needed ) {
2020-01-23 15:14:46 +01:00
// This isn't strictly allowed, but it works
2021-06-07 17:33:53 +02:00
this . node . attr ( "required" , "required" ) ;
2020-01-23 15:14:46 +01:00
}
2021-06-07 17:33:53 +02:00
this . setDOMNode ( this . node [ 0 ] ) ;
2020-01-23 15:14:46 +01:00
// The supported widget classes array defines a whitelist for all widget
// classes or interfaces child widgets have to support.
2021-06-07 17:33:53 +02:00
this . supportedWidgetClasses = [ et2 _radiobox , et2 _radiobox _ro ] ;
2020-01-23 15:14:46 +01:00
}
2021-06-07 17:33:53 +02:00
set _value ( _value ) {
2020-01-23 15:14:46 +01:00
this . value = _value ;
2021-06-07 17:33:53 +02:00
for ( let i = 0 ; i < this . _children . length ; i ++ ) {
let radio = this . _children [ i ] ;
2020-01-23 15:14:46 +01:00
radio . set _value ( _value ) ;
}
2021-06-07 17:33:53 +02:00
}
getValue ( ) {
2020-01-23 15:14:46 +01:00
return jQuery ( "input:checked" , this . getDOMNode ( ) ) . val ( ) ;
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Set a bunch of radio buttons
*
* @ param { object } _options object with value : label pairs
* /
2021-06-07 17:33:53 +02:00
set _options ( _options ) {
2020-01-23 15:14:46 +01:00
// Call the destructor of all children
2021-06-07 17:33:53 +02:00
for ( let i = this . _children . length - 1 ; i >= 0 ; i -- ) {
2020-01-31 21:07:27 +01:00
this . _children [ i ] . destroy ( ) ;
2020-01-23 15:14:46 +01:00
}
this . _children = [ ] ;
// create radio buttons for each option
2021-06-07 17:33:53 +02:00
for ( let key in _options ) {
let attrs = {
2020-01-23 15:14:46 +01:00
// Add index so radios work properly
"id" : ( this . options . readonly ? this . id : this . id + "[" + "]" ) ,
set _value : key ,
label : _options [ key ] ,
ro _true : this . options . ro _true ,
ro _false : this . options . ro _false ,
readonly : this . options . readonly
} ;
if ( typeof _options [ key ] === 'object' && _options [ key ] . label ) {
attrs . set _value = _options [ key ] . value ;
attrs . label = _options [ key ] . label ;
}
// Can't have a required readonly, it will warn & be removed later, so avoid the warning
if ( attrs . readonly === false ) {
attrs [ 'needed' ] = this . options . needed ;
}
et2 _createWidget ( "radio" , attrs , this ) ;
}
this . set _value ( this . value ) ;
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Set a label on the group of radio buttons
*
* @ param { string } _value
* /
2021-06-07 17:33:53 +02:00
set _label ( _value ) {
2020-01-23 15:14:46 +01:00
// Abort if ther was no change in the label
if ( _value == this . label ) {
return ;
}
if ( _value ) {
// Create the label container if it didn't exist yet
if ( this . _labelContainer == null ) {
this . _labelContainer = jQuery ( document . createElement ( "label" ) ) ;
this . getSurroundings ( ) . insertDOMNode ( this . _labelContainer [ 0 ] ) ;
}
// Clear the label container.
this . _labelContainer . empty ( ) ;
// Create the placeholder element and set it
var ph = document . createElement ( "span" ) ;
this . getSurroundings ( ) . setWidgetPlaceholder ( ph ) ;
this . _labelContainer
. append ( document . createTextNode ( _value ) )
. append ( ph ) ;
}
else {
// Delete the labelContainer from the surroundings object
if ( this . _labelContainer ) {
this . getSurroundings ( ) . removeDOMNode ( this . _labelContainer [ 0 ] ) ;
}
this . _labelContainer = null ;
}
2021-06-07 17:33:53 +02:00
}
2020-01-23 15:14:46 +01:00
/ * *
* Code for implementing et2 _IDetachedDOM
* This doesn ' t need to be implemented .
* Individual widgets are detected and handled by the grid , but the interface is needed for this to happen
*
* @ param { object } _attrs
* /
2021-06-07 17:33:53 +02:00
getDetachedAttributes ( _attrs ) {
}
getDetachedNodes ( ) {
2020-01-23 15:14:46 +01:00
return [ this . getDOMNode ( ) ] ;
2021-06-07 17:33:53 +02:00
}
setDetachedAttributes ( _nodes , _values ) {
}
}
et2 _radioGroup . _attributes = {
"label" : {
"name" : "Label" ,
"default" : "" ,
"type" : "string" ,
"description" : "The label is displayed above the list of radio buttons. The label can contain variables, as descript for name. If the label starts with a '@' it is replaced by the value of the content-array at this index (with the '@'-removed and after expanding the variables)." ,
"translate" : true
} ,
"value" : {
"name" : "Value" ,
"type" : "string" ,
"default" : "true" ,
"description" : "Value for each radio button"
} ,
"ro_true" : {
"name" : "Read only selected" ,
"type" : "string" ,
"default" : "x" ,
"description" : "What should be displayed when readonly and selected"
} ,
"ro_false" : {
"name" : "Read only unselected" ,
"type" : "string" ,
"default" : "" ,
"description" : "What should be displayed when readonly and not selected"
} ,
"options" : {
"name" : "Radio options" ,
"type" : "any" ,
"default" : { } ,
"description" : "Options for radio buttons. Should be {value: label, ...}"
} ,
"needed" : {
"name" : "Required" ,
"default" : false ,
"type" : "boolean" ,
"description" : "If required, the user must select one of the options before the form can be submitted"
}
} ;
2012-03-23 19:57:13 +01:00
// No such tag as 'radiogroup', but it needs something
2021-06-07 17:33:53 +02:00
et2 _register _widget ( et2 _radioGroup , [ "radiogroup" ] ) ;
2020-01-23 15:14:46 +01:00
//# sourceMappingURL=et2_widget_radiobox.js.map