2013-04-16 20:50:43 +02:00
/ * *
* EGroupware eTemplate2 - JS Dialog Widget class
*
* @ license http : //opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @ package etemplate
* @ link http : //www.egroupware.org
* @ author Nathan Gray
* @ copyright Nathan Gray 2013
* @ version $Id$
* /
"use strict" ;
/ * e g w : u s e s
et2 _core _widget ;
jquery . jquery - ui ;
* /
/ * *
* A common dialog widget that makes it easy to imform users or prompt for information .
*
2013-12-05 09:53:11 +01:00
* It is possible to have a custom dialog by using a template , but you can also use
2013-04-16 20:50:43 +02:00
* the static method et2 _dialog . show _dialog ( ) . At its simplest , you can just use :
* < code >
* et2 _dialog . show _dialog ( false , "Operation completed" ) ;
* < / c o d e >
* Or a more complete example :
* < code >
* var callback = function ( button _id )
* {
* if ( button _id == et2 _dialog . YES _BUTTON )
* {
* // Do stuff
* }
* else if ( button _id == et2 _dialog . NO _BUTTON )
* {
* // Other stuff
* }
* else if ( button _id == et2 _dialog . CANCEL _BUTTON )
* {
* // Abort
* }
* } .
* var dialog = et2 _dialog . show _dialog (
2013-05-21 22:23:35 +02:00
* callback , "Erase the entire database?" , "Break things" , { } // value
2013-04-16 20:50:43 +02:00
* et2 _dialog . BUTTONS _YES _NO _CANCEL , et2 _dialog . WARNING _MESSAGE
* ) ;
* < / c o d e >
2013-12-05 09:53:11 +01:00
*
2013-04-16 20:50:43 +02:00
*
* The parameters for the above are all optional , except callback and message :
* callback - function called when the dialog closes , or false / null .
* The ID of the button will be passed . Button ID will be one of the et2 _dialog . * _BUTTON constants .
* The callback is _not _ called if the user closes the dialog with the X in the corner , or presses ESC .
2013-10-03 17:27:00 +02:00
* message - ( plain ) text to display
2013-04-16 20:50:43 +02:00
* title - Dialog title
2013-05-21 22:23:35 +02:00
* value ( for prompt )
2013-04-16 20:50:43 +02:00
* buttons - et2 _dialog BUTTONS _ * constant , or an array of button settings
2013-05-21 22:23:35 +02:00
* dialog _type - et2 _dialog * _MESSAGE constant
2013-04-16 20:50:43 +02:00
* icon - URL of icon
*
2013-12-05 09:53:11 +01:00
* Note that these methods will _not _ block program flow while waiting for user input .
2013-04-16 20:50:43 +02:00
* The user ' s input will be provided to the callback .
*
* You can also use the standard et2 _createWidget ( ) to create a custom dialog using an etemplate , even setting all
* the buttons yourself .
* < code >
* var dialog = et2 _createWidget ( "dialog" , {
* // If you use a template, the second parameter will be the value of the template, as if it were submitted.
* callback : function ( button _id , value ) { ... } ,
* buttons : [
* // These ones will use the callback, just like normal
* { text : egw . lang ( "OK" ) , id : "OK" , class = "ui-priority-primary" , default : true } ,
* { text : egw . lang ( "Yes" ) , id : "Yes" } ,
* { text : egw . lang ( "Sure" ) , id : "Sure" } ,
* { text : egw . lang ( "Maybe" ) , click : function ( ) {
* // If you override, 'this' will be the dialog DOMNode.
* // Things get more complicated.
* // Do what you like, but don't forget this line:
* $j ( this ) . dialog ( "close" )
* } , class = "ui-state-error" } ,
2013-12-05 09:53:11 +01:00
*
2013-04-16 20:50:43 +02:00
* ] ,
2013-08-26 21:10:26 +02:00
* title : 'Why would you want to do this?' ,
2013-04-16 20:50:43 +02:00
* template : "/egroupware/addressbook/templates/default/edit.xet" ,
* value : { content : { ... default values } , sel _options : { ... } ... }
* } ) ;
* < / c o d e >
* @ augments et2 _widget
* @ see http : //api.jqueryui.com/dialog/
* /
var et2 _dialog = et2 _widget . extend ( {
2013-12-05 09:53:11 +01:00
2013-04-16 20:50:43 +02:00
attributes : {
callback : {
name : "Callback" ,
type : "js" ,
description : "Callback function is called with the value when the dialog is closed" ,
"default" : function ( button _id ) { egw . debug ( "log" , "Button ID: %d" , button _id ) ; }
} ,
message : {
name : "Message" ,
type : "string" ,
2013-10-03 17:27:00 +02:00
description : "Dialog message (plain text, no html)" ,
2013-04-16 20:50:43 +02:00
"default" : "Somebody forgot to set this..." ,
} ,
dialog _type : {
name : "Dialog type" ,
type : "integer" ,
description : "To use a pre-defined dialog style, use et2_dialog.ERROR_MESSAGE, INFORMATION_MESSAGE,WARNING_MESSAGE,QUESTION_MESSAGE,PLAIN_MESSAGE constants. Default is et2_dialog.PLAIN_MESSAGE" ,
"default" : 0 , //this.PLAIN_MESSAGE
} ,
buttons : {
name : "Buttons" ,
type : "any" ,
"default" : 0 , //this.BUTTONS_OK,
description : "Buttons that appear at the bottom of the dialog. You can use the constants et2_dialog.BUTTONS_OK, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_OK_CANCEL, or pass in an array for full control" ,
} ,
icon : {
name : "Icon" ,
type : "string" ,
description : "URL of an icon for the dialog. If omitted, an icon based on dialog_type will be used." ,
"default" : ""
} ,
title : {
name : "Title" ,
type : "string" ,
2013-10-03 17:27:00 +02:00
description : "Title for the dialog box (plain text, no html)" ,
2013-04-16 20:50:43 +02:00
"default" : ""
} ,
modal : {
name : "Modal" ,
type : "boolean" ,
description : "Prevent the user from interacting with the page" ,
"default" : true
} ,
resizable : {
name : "Resizable" ,
type : "boolean" ,
description : "Allow the user to resize the dialog" ,
"default" : true
} ,
value : {
"name" : "Value" ,
"description" : "The (default) value of the dialog. Use with template." ,
"type" : "any" ,
"default" : et2 _no _init
} ,
template : {
"name" : "Template" ,
"description" : "Instead of displaying a simple message, a full template can be loaded instead. Set defaults with value." ,
"type" : "string" ,
"default" : et2 _no _init
}
} ,
/ * *
* Details for dialog type options
* /
_dialog _types : [
//PLAIN_MESSAGE: 0
2013-10-03 17:27:00 +02:00
"" ,
2013-04-16 20:50:43 +02:00
//INFORMATION_MESSAGE: 1,
2013-10-03 17:27:00 +02:00
"dialog_info" ,
2013-04-16 20:50:43 +02:00
//QUESTION_MESSAGE: 2,
2013-10-03 17:27:00 +02:00
"dialog_help" ,
2013-04-16 20:50:43 +02:00
//WARNING_MESSAGE: 3,
2013-10-03 17:27:00 +02:00
"dialog_warning" ,
2013-04-16 20:50:43 +02:00
//ERROR_MESSAGE: 4,
2013-10-03 17:27:00 +02:00
"dialog_error" ,
2013-04-16 20:50:43 +02:00
] ,
_buttons : [
/ *
Pre - defined Button combos
- button ids copied from et2 _dialog static , since the constants are not defined yet
2014-02-12 16:18:18 +01:00
- image get replaced by 'style="background-image: url(' + egw . image ( image ) + ')' for an image prefixing text
2013-04-16 20:50:43 +02:00
* /
//BUTTONS_OK: 0,
2014-02-12 16:18:18 +01:00
[ { "button_id" : 1 , "text" : 'ok' , id : 'dialog[ok]' , image : 'check' , "default" : true } ] ,
2013-04-16 20:50:43 +02:00
//BUTTONS_OK_CANCEL: 1,
[
2014-02-12 16:18:18 +01:00
{ "button_id" : 1 , "text" : 'ok' , id : 'dialog[ok]' , image : 'check' , "default" : true } ,
{ "button_id" : 0 , "text" : 'cancel' , id : 'dialog[cancel]' , image : 'cancel' }
2013-04-16 20:50:43 +02:00
] ,
//BUTTONS_YES_NO: 2,
[
2014-02-12 16:18:18 +01:00
{ "button_id" : 2 , "text" : 'yes' , id : 'dialog[yes]' , image : 'check' , "default" : true } ,
{ "button_id" : 3 , "text" : 'no' , id : 'dialog[no]' , image : 'cancelled' }
2013-04-16 20:50:43 +02:00
] ,
//BUTTONS_YES_NO_CANCEL: 3,
[
2014-02-12 16:18:18 +01:00
{ "button_id" : 2 , "text" : 'yes' , id : 'dialog[yes]' , image : 'check' , "default" : true } ,
{ "button_id" : 3 , "text" : 'no' , id : 'dialog[no]' , image : 'cancelled' } ,
{ "button_id" : 0 , "text" : 'cancel' , id : 'dialog[cancel]' , image : 'cancel' }
2013-04-16 20:50:43 +02:00
]
] ,
// Define this as null to avoid breaking any hierarchies (eg: destroy())
_parent : null ,
2013-04-20 11:51:52 +02:00
/ * *
* Constructor
2013-12-05 09:53:11 +01:00
*
2013-04-20 11:51:52 +02:00
* @ memberOf et2 _dialog
* /
2013-04-16 20:50:43 +02:00
init : function ( ) {
// Call the inherited constructor
this . _super . apply ( this , arguments ) ;
// Button callbacks need a reference to this
var self = this ;
for ( var i = 0 ; i < this . _buttons . length ; i ++ )
{
for ( var j = 0 ; j < this . _buttons [ i ] . length ; j ++ )
{
this . _buttons [ i ] [ j ] . click = ( function ( id ) {
return function ( event ) {
self . click ( event . target , id ) ;
2013-04-20 11:51:52 +02:00
} ;
2013-04-16 20:50:43 +02:00
} ) ( this . _buttons [ i ] [ j ] . button _id ) ;
2013-04-23 18:51:00 +02:00
// translate button texts, as translations are not available before
this . _buttons [ i ] [ j ] . text = egw . lang ( this . _buttons [ i ] [ j ] . text ) ;
2013-04-16 20:50:43 +02:00
}
}
this . div = $j ( document . createElement ( "div" ) ) ;
this . _createDialog ( ) ;
} ,
/ * *
* Clean up dialog
* /
destroy : function ( ) {
2013-07-20 19:20:55 +02:00
if ( this . div != null )
2013-04-16 20:50:43 +02:00
{
2013-07-20 19:20:55 +02:00
// Un-dialog the dialog
this . div . dialog ( "destroy" ) ;
2013-04-16 20:50:43 +02:00
2013-07-20 19:20:55 +02:00
if ( this . template )
{
this . template . clear ( ) ;
this . template = null ;
}
this . div = null ;
}
2013-04-16 20:50:43 +02:00
// Call the inherited constructor
2013-04-20 11:51:52 +02:00
this . _super . apply ( this , arguments ) ;
2013-04-16 20:50:43 +02:00
} ,
/ * *
* Internal callback registered on all standard buttons .
* The provided callback is called after the dialog is closed .
*
* @ param target DOMNode The clicked button
* @ param button _id integer The ID of the clicked button
* /
click : function ( target , button _id ) {
var value = this . options . value ;
if ( this . template )
{
value = this . template . getValues ( this . template . widgetContainer ) ;
}
if ( this . options . callback )
{
this . options . callback . call ( this , button _id , value ) ;
}
// Triggers destroy too
this . div . dialog ( "close" ) ;
} ,
/ * *
* Set the displayed prompt message
*
* @ param string New message for the dialog
* /
set _message : function ( message ) {
this . options . message = message ;
this . div . empty ( )
. append ( "<img class='dialog_icon' />" )
2013-10-03 17:27:00 +02:00
. append ( $j ( '<div/>' ) . text ( message ) ) ;
2013-04-16 20:50:43 +02:00
} ,
/ * *
* Set the dialog type to a pre - defined type
*
* @ param integer Type constant from et2 _dialog
* /
set _dialog _type : function ( type ) {
2013-10-03 17:27:00 +02:00
if ( this . options . dialog _type != type && typeof this . _dialog _types [ type ] == "string" )
2013-04-16 20:50:43 +02:00
{
this . options . dialog _type = type ;
}
2013-10-03 17:27:00 +02:00
this . set _icon ( this . _dialog _types [ type ] ? egw . image ( this . _dialog _types [ type ] ) : "" ) ;
2013-04-16 20:50:43 +02:00
} ,
/ * *
* Set the icon for the dialog
*
* @ param string icon
* /
set _icon : function ( icon _url ) {
if ( icon _url == "" )
{
$j ( "img.dialog_icon" , this . div ) . hide ( ) ;
}
else
{
$j ( "img.dialog_icon" , this . div ) . show ( ) . attr ( "src" , icon _url ) ;
}
} ,
/ * *
* Set the dialog buttons
*
* Use either the pre - defined options in et2 _dialog , or an array
* @ see http : //api.jqueryui.com/dialog/#option-buttons
* /
set _buttons : function ( buttons ) {
this . options . buttons = buttons ;
2013-07-20 15:05:03 +02:00
if ( buttons instanceof Array )
2013-04-16 20:50:43 +02:00
{
for ( var i = 0 ; i < buttons . length ; i ++ )
{
2014-02-12 16:18:18 +01:00
var button = buttons [ i ] ;
if ( ! button . click )
2013-04-16 20:50:43 +02:00
{
2014-02-12 16:18:18 +01:00
button . click = jQuery . proxy ( this . click , this , null , button . id ) ;
}
// set a default background image and css class based on buttons id
if ( button . id && typeof button . class == 'undefined' )
{
for ( var name in et2 _button . default _classes )
{
if ( button . id . match ( et2 _button . default _classes [ name ] ) )
{
button . class = ( typeof button . class == 'undefined' ? '' : button . class + ' ' ) + name ;
break ;
}
}
}
if ( button . id && typeof button . image == 'undefined' && typeof button . style == 'undefined' )
{
for ( var name in et2 _button . default _background _images )
{
if ( button . id . match ( et2 _button . default _background _images [ name ] ) )
{
button . image = name ;
break ;
}
}
}
if ( button . image )
{
button . style = 'background-image: url(' + this . egw ( ) . image ( button . image ) + ')' ;
delete button . image ;
2013-04-16 20:50:43 +02:00
}
}
2013-07-20 15:05:03 +02:00
}
2013-12-05 09:53:11 +01:00
2013-07-20 15:05:03 +02:00
// If dialog already created, update buttons
2013-07-20 15:54:31 +02:00
if ( this . div . data ( 'ui-dialog' ) )
2013-07-20 15:05:03 +02:00
{
2013-04-16 20:50:43 +02:00
this . div . dialog ( "option" , "buttons" , buttons ) ;
2013-12-05 09:53:11 +01:00
2013-07-20 15:05:03 +02:00
// Focus default button so enter works
2013-12-05 09:53:11 +01:00
$j ( '.ui-dialog-buttonpane button[default]' , this . div . parent ( ) ) . focus ( ) ;
2013-04-16 20:50:43 +02:00
}
} ,
/ * *
* Set the dialog title
*
* @ param string New title for the dialog
* /
set _title : function ( title ) {
this . options . title = title ;
this . div . dialog ( "option" , "title" , title ) ;
} ,
/ * *
* Block interaction with the page behind the dialog
*
* @ param boolean Block page behind dialog
* /
set _modal : function ( modal ) {
this . options . modal = modal ;
this . div . dialog ( "option" , "modal" , modal ) ;
} ,
/ * *
* Load an etemplate into the dialog
*
* @ param template String etemplate file name
* /
set _template : function ( template ) {
if ( this . template && this . options . template != template )
{
this . template . clear ( ) ;
}
this . template = new etemplate2 ( this . div [ 0 ] , false ) ;
this . template . load ( "" , template , this . options . value || { } ) ;
} ,
/ * *
* Actually create and display the dialog
* /
_createDialog : function ( ) {
if ( this . options . template )
{
this . set _template ( this . options . template ) ;
}
else
{
this . set _message ( this . options . message ) ;
this . set _dialog _type ( this . options . dialog _type ) ;
}
2014-02-12 16:18:18 +01:00
this . set _buttons ( typeof this . options . buttons == "number" ? this . _buttons [ this . options . buttons ] : this . options . buttons ) ;
2013-04-16 20:50:43 +02:00
this . div . dialog ( {
// Pass the internal object, not the option
2014-02-12 16:18:18 +01:00
buttons : this . options . buttons ,
2013-04-16 20:50:43 +02:00
modal : this . options . modal ,
resizable : this . options . resizable ,
2013-04-23 18:51:00 +02:00
width : "auto" ,
maxWidth : 640 ,
2013-04-16 20:50:43 +02:00
title : this . options . title ,
open : function ( ) {
// Focus default button so enter works
2013-12-05 09:53:11 +01:00
$j ( this ) . parents ( '.ui-dialog-buttonpane button[default]' ) . focus ( ) ;
2013-04-16 20:50:43 +02:00
} ,
2013-04-20 11:51:52 +02:00
close : jQuery . proxy ( function ( ) { this . destroy ( ) ; } , this )
2013-04-16 20:50:43 +02:00
} ) ;
}
} ) ;
et2 _register _widget ( et2 _dialog , [ "dialog" ] ) ;
// Static class stuff
2013-12-05 09:53:11 +01:00
jQuery . extend ( et2 _dialog ,
2013-04-16 20:50:43 +02:00
/** @lends et2_dialog */
{
// Some class constants //
/ * *
2013-12-05 09:53:11 +01:00
* Types
2013-04-16 20:50:43 +02:00
* @ constant
* /
PLAIN _MESSAGE : 0 ,
INFORMATION _MESSAGE : 1 ,
QUESTION _MESSAGE : 2 ,
WARNING _MESSAGE : 3 ,
ERROR _MESSAGE : 4 ,
/* Pre-defined Button combos */
BUTTONS _OK : 0 ,
BUTTONS _OK _CANCEL : 1 ,
BUTTONS _YES _NO : 2 ,
BUTTONS _YES _NO _CANCEL : 3 ,
/* Button constants */
CANCEL _BUTTON : 0 ,
OK _BUTTON : 1 ,
YES _BUTTON : 2 ,
NO _BUTTON : 3 ,
2014-01-23 11:52:44 +01:00
/ * *
* Create a parent to inject application specific egw object with loaded translations into et2 _dialog
*
* @ param { string | egw } _egw _or _appname = egw object with already laoded translations or application name to load translations for
* /
_create _parent : function ( _egw _or _appname )
{
if ( typeof _egw _or _appname == 'undefined' )
{
_egw _or _appname = egw _appName ;
}
// create a dummy parent with a correct reference to an application specific egw object
var parent = new et2 _widget ( ) ;
// if egw object is passed in because called from et2, just use it
if ( typeof _egw _or _appname == 'object' )
{
parent . _egw = _egw _or _appname ;
}
// otherwise use given appname to create app-specific egw instance and load default translations
else
{
parent . _egw = egw ( _egw _or _appname ) ;
parent . _egw . langRequireApp ( parent . _egw . window , _egw _or _appname ) ;
}
return parent ;
} ,
2013-04-16 20:50:43 +02:00
/ * *
* Show a confirmation dialog
*
2013-04-23 18:51:00 +02:00
* @ param function _callback Function called when the user clicks a button . The context will be the et2 _dialog widget , and the button constant is passed in .
2014-01-16 14:54:19 +01:00
* @ param String _message Message to be place in the dialog .
2013-04-23 18:51:00 +02:00
* @ param String _title Text in the top bar of the dialog .
* @ param any _value passed unchanged to callback as 2. parameter
* @ param integer | Array _buttons One of the BUTTONS _ constants defining the set of buttons at the bottom of the box
* @ param integer _type One of the message constants . This defines the style of the message .
* @ param String _icon URL of an icon to display . If not provided , a type - specific icon will be used .
2014-01-23 11:52:44 +01:00
* @ param { string | egw } _egw _or _appname = egw object with already laoded translations or application name to load translations for
2013-04-16 20:50:43 +02:00
* /
2014-01-23 11:52:44 +01:00
show _dialog : function ( _callback , _message , _title , _value , _buttons , _type , _icon , _egw _or _appname )
{
var parent = et2 _dialog . _create _parent ( _egw _or _appname ) ;
2013-04-23 18:51:00 +02:00
// Just pass them along, widget handles defaults & missing
return et2 _createWidget ( "dialog" , {
callback : _callback || function ( ) { } ,
message : _message ,
2014-01-23 11:52:44 +01:00
title : _title || parent . _egw . lang ( 'Confirmation required' ) ,
2014-01-20 14:07:11 +01:00
buttons : typeof _buttons != 'undefined' ? _buttons : et2 _dialog . BUTTONS _YES _NO ,
dialog _type : typeof _type != 'undefined' ? _type : et2 _dialog . QUESTION _MESSAGE ,
2013-04-23 18:51:00 +02:00
icon : _icon ,
value : _value
2014-01-23 11:52:44 +01:00
} , parent ) ;
2013-04-23 18:51:00 +02:00
} ,
2013-12-05 09:53:11 +01:00
2013-04-23 18:51:00 +02:00
/ * *
* Show a prompt dialog
*
* @ param function _callback Function called when the user clicks a button . The context will be the et2 _dialog widget , and the button constant is passed in .
2014-01-16 14:54:19 +01:00
* @ param String _message Message to be place in the dialog .
2013-04-23 18:51:00 +02:00
* @ param String _title Text in the top bar of the dialog .
* @ param String _value for prompt , passed to callback as 2. parameter
* @ param integer | Array _buttons One of the BUTTONS _ constants defining the set of buttons at the bottom of the box
2014-01-23 11:52:44 +01:00
* @ param { string | egw } _egw _or _appname = egw object with already laoded translations or application name to load translations for
2013-04-23 18:51:00 +02:00
* /
2014-01-23 11:52:44 +01:00
show _prompt : function ( _callback , _message , _title , _value , _buttons , _egw _or _appname )
2013-04-23 18:51:00 +02:00
{
var callback = _callback ;
2013-04-16 20:50:43 +02:00
// Just pass them along, widget handles defaults & missing
return et2 _createWidget ( "dialog" , {
2013-04-23 18:51:00 +02:00
callback : function ( _button _id , _value ) {
if ( typeof callback == "function" )
{
callback . call ( this , _button _id , _value . value ) ;
}
} ,
title : _title || egw . lang ( 'Input required' ) ,
buttons : _buttons || et2 _dialog . BUTTONS _OK _CANCEL ,
value : {
content : {
value : _value ,
message : _message
}
} ,
template : egw . webserverUrl + '/etemplate/templates/default/prompt.xet' ,
class : "et2_prompt"
2014-01-23 11:52:44 +01:00
} , et2 _dialog . _create _parent ( _egw _or _appname ) ) ;
2013-12-05 09:53:11 +01:00
} ,
/ * *
* Method to build a confirmation dialog only with
* YES OR NO buttons and submit content back to server
*
* @ param { widget } _senders widget that has been clicked
* @ param { String } _dialogMsg message shows in dialog box
* @ param { String } _titleMsg message shows as a title of the dialog box
2014-01-23 11:52:44 +01:00
* @ param { string | egw } _egw _or _appname = egw object with already laoded translations or application name to load translations for
2013-12-05 09:53:11 +01:00
*
* @ description submit the form contents including the button that has been pressed
* /
2014-01-23 11:52:44 +01:00
confirm : function ( _senders , _dialogMsg , _titleMsg , _egw _or _appname )
2013-12-05 09:53:11 +01:00
{
var senders = _senders ;
var buttonId = _senders . id ;
var dialogMsg = ( typeof _dialogMsg != "undefined" ) ? _dialogMsg : '' ;
var titleMsg = ( typeof _titleMsg != "undefined" ) ? _titleMsg : '' ;
2014-01-23 11:52:44 +01:00
var egw = _senders instanceof et2 _widget ? _senders . egw ( ) : et2 _dialog . _create _parent ( ) . _egw ;
2013-12-05 09:53:11 +01:00
var callbackDialog = function ( button _id )
{
if ( button _id == et2 _dialog . YES _BUTTON )
{
senders . getRoot ( ) . getInstanceManager ( ) . submit ( buttonId ) ;
}
2014-01-23 11:52:44 +01:00
} ;
et2 _dialog . show _dialog ( callbackDialog , egw . lang ( dialogMsg ) , egw . lang ( titleMsg ) , { } ,
et2 _dialog . BUTTON _YES _NO , et2 _dialog . WARNING _MESSAGE , undefined , egw ) ;
} ,
2013-12-05 09:53:11 +01:00
2014-01-16 14:54:19 +01:00
/ * *
* Show a dialog for a long - running , multi - part task
*
* Given a server url and a list of parameters , this will open a dialog with
* a progress bar , asynchronously call the url with each parameter , and update
* the progress bar .
* Any output from the server will be displayed in a box .
*
* When all tasks are done , the callback will be called with boolean true . It will
* also be called if the user clicks a button ( OK or CANCEL ) , so be sure to
* check to avoid executing more than intended .
*
* @ param function _callback Function called when the user clicks a button ,
* or when the list is done processing . The context will be the et2 _dialog
* widget , and the button constant is passed in .
* @ param String _message Message to be place in the dialog . Usually just
* text , but DOM nodes will work too .
* @ param String _title Text in the top bar of the dialog .
* @ param { string } _menuaction the menuaction function which should be called and
* which handles the actual request . If the menuaction is a full featured
* url , this one will be used instead .
* @ param { Array [ ] } _list - List of parameters , one for each call to the
* address . Multiple parameters are allowed , in an array .
2014-01-23 11:52:44 +01:00
* @ param { string | egw } _egw _or _appname = egw object with already laoded translations or application name to load translations for
2014-01-16 14:54:19 +01:00
*
* @ return { et2 _dialog }
* /
2014-01-23 11:52:44 +01:00
long _task : function ( _callback , _message , _title , _menuaction , _list , _egw _or _appname )
2014-01-16 14:54:19 +01:00
{
2014-02-10 18:02:54 +01:00
var parent = et2 _dialog . _create _parent ( _egw _or _appname ) ;
2014-01-23 11:52:44 +01:00
var egw = parent . _egw ;
2014-01-16 14:54:19 +01:00
// Special action for cancel
var buttons = [
{ "button_id" : et2 _dialog . OK _BUTTON , "text" : egw . lang ( 'ok' ) , "default" : true , "disabled" : true } ,
{ "button_id" : et2 _dialog . CANCEL _BUTTON , "text" : egw . lang ( 'cancel' ) , click : function ( ) {
// Cancel run
cancel = true ;
$j ( "button[button_id=" + et2 _dialog . CANCEL _BUTTON + "]" , dialog . div . parent ( ) ) . button ( "disable" ) ;
update . call ( _list . length , '' ) ;
} }
] ;
var dialog = et2 _createWidget ( "dialog" , {
template : egw . webserverUrl + '/etemplate/templates/default/long_task.xet' ,
value : {
content : {
message : _message
}
} ,
callback : function ( _button _id , _value ) {
if ( _button _id == et2 _dialog . CANCEL _BUTTON )
{
cancel = true ;
}
if ( typeof _callback == "function" )
{
_callback . call ( this , _button _id , _value . value ) ;
}
} ,
title : _title || egw . lang ( 'please wait...' ) ,
buttons : buttons
2014-01-23 11:52:44 +01:00
} , parent ) ;
2014-01-16 14:54:19 +01:00
// OK starts disabled
$j ( "button[button_id=" + et2 _dialog . OK _BUTTON + "]" , dialog . div . parent ( ) ) . button ( "disable" ) ;
var log = null ;
var progressbar = null ;
var cancel = false ;
// Updates progressbar & log, calls next step
var update = function ( response ) {
// context is index
var index = this || 0 ;
2014-01-23 11:52:44 +01:00
2014-01-16 14:54:19 +01:00
progressbar . set _value ( 100 * ( index / _list . length ) ) ;
// Display response information
switch ( response . type )
{
case 'error' :
log . append ( "<div class='message error'>" + response . data + "</div>" ) ;
break ;
default :
if ( response )
{
log . append ( "<div class='message'>" + response + "</div>" ) ;
}
}
// Scroll to bottom
var height = log [ 0 ] . scrollHeight ;
log . scrollTop ( height ) ;
// Fire next step
if ( ! cancel && index < _list . length )
{
var parameters = _list [ index ] ;
if ( typeof parameters != 'object' ) parameters = [ parameters ] ;
// Async request, we'll take the next step in the callback
egw . json ( _menuaction , parameters , update , index + 1 , true , index + 1 ) . sendRequest ( ) ;
}
else
{
// All done
if ( ! cancel ) progressbar . set _value ( 100 ) ;
$j ( "button[button_id=" + et2 _dialog . CANCEL _BUTTON + "]" , dialog . div . parent ( ) ) . button ( "disable" ) ;
$j ( "button[button_id=" + et2 _dialog . OK _BUTTON + "]" , dialog . div . parent ( ) ) . button ( "enable" ) ;
if ( ! cancel && typeof _callback == "function" )
{
_callback . call ( dialog , true ) ;
}
}
} ;
$j ( dialog . template . DOMContainer ) . on ( 'load' , function ( ) {
// Get access to template widgets
log = $j ( dialog . template . widgetContainer . getWidgetById ( 'log' ) . getDOMNode ( ) ) ;
progressbar = dialog . template . widgetContainer . getWidgetById ( 'progressbar' ) ;
// Start
window . setTimeout ( function ( ) { update . call ( 0 , '' ) ; } , 0 ) ;
} ) ;
return dialog ;
}
2013-04-16 20:50:43 +02:00
} ) ;