2011-08-03 14:09:14 +00:00
/ *
2011-06-20 10:05:57 +00:00
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
2011-08-03 14:09:14 +00:00
to use it in not GPL project . Please contact sales @ dhtmlx . com for details
* /
window . dhtmlx || ( dhtmlx = function ( obj ) {
for ( var a in obj ) dhtmlx [ a ] = obj [ a ] ;
return dhtmlx ; //simple singleton
} )
dhtmlx . extend _api = function ( name , map , ext ) {
var t = window [ name ] ;
if ( ! t ) return ; //component not defined
window [ name ] = function ( obj ) {
if ( obj && typeof obj == "object" && ! obj . tagName && ! ( obj instanceof Array ) ) {
var that = t . apply ( this , ( map . _init ? map . _init ( obj ) : arguments ) ) ;
//global settings
for ( var a in dhtmlx )
if ( map [ a ] ) this [ map [ a ] ] ( dhtmlx [ a ] ) ;
//local settings
for ( var a in obj ) {
if ( map [ a ] ) this [ map [ a ] ] ( obj [ a ] ) ;
else if ( a . indexOf ( "on" ) == 0 ) {
this . attachEvent ( a , obj [ a ] ) ;
}
}
} else
var that = t . apply ( this , arguments ) ;
if ( map . _patch ) map . _patch ( this ) ;
return that || this ;
} ;
window [ name ] . prototype = t . prototype ;
if ( ext )
dhtmlXHeir ( window [ name ] . prototype , ext ) ;
} ;
2011-04-07 16:41:06 +00:00
dhtmlxAjax = {
get : function ( url , callback ) {
var t = new dtmlXMLLoaderObject ( true ) ;
t . async = ( arguments . length < 3 ) ;
t . waitCall = callback ;
t . loadXML ( url )
return t ;
} ,
post : function ( url , post , callback ) {
var t = new dtmlXMLLoaderObject ( true ) ;
t . async = ( arguments . length < 4 ) ;
t . waitCall = callback ;
t . loadXML ( url , true , post )
return t ;
} ,
getSync : function ( url ) {
return this . get ( url , null , true )
} ,
postSync : function ( url , post ) {
return this . post ( url , post , null , true ) ;
}
}
/ * *
* @ desc : xmlLoader object
* @ type : private
* @ param : funcObject - xml parser function
* @ param : object - jsControl object
* @ param : async - sync / async mode ( async by default )
* @ param : rSeed - enable / disable random seed ( prevent IE caching )
* @ topic : 0
* /
function dtmlXMLLoaderObject ( funcObject , dhtmlObject , async , rSeed ) {
this . xmlDoc = "" ;
if ( typeof ( async ) != "undefined" )
this . async = async ;
else
this . async = true ;
this . onloadAction = funcObject || null ;
this . mainObject = dhtmlObject || null ;
this . waitCall = null ;
this . rSeed = rSeed || false ;
return this ;
} ;
/ * *
* @ desc : xml loading handler
* @ type : private
* @ param : dtmlObject - xmlLoader object
* @ topic : 0
* /
dtmlXMLLoaderObject . prototype . waitLoadFunction = function ( dhtmlObject ) {
var once = true ;
this . check = function ( ) {
if ( ( dhtmlObject ) && ( dhtmlObject . onloadAction != null ) ) {
if ( ( ! dhtmlObject . xmlDoc . readyState ) || ( dhtmlObject . xmlDoc . readyState == 4 ) ) {
if ( ! once )
return ;
once = false ; //IE 5 fix
if ( typeof dhtmlObject . onloadAction == "function" )
dhtmlObject . onloadAction ( dhtmlObject . mainObject , null , null , null , dhtmlObject ) ;
if ( dhtmlObject . waitCall ) {
dhtmlObject . waitCall . call ( this , dhtmlObject ) ;
dhtmlObject . waitCall = null ;
}
}
}
} ;
return this . check ;
} ;
/ * *
* @ desc : return XML top node
* @ param : tagName - top XML node tag name ( not used in IE , required for Safari and Mozilla )
* @ type : private
* @ returns : top XML node
* @ topic : 0
* /
dtmlXMLLoaderObject . prototype . getXMLTopNode = function ( tagName , oldObj ) {
if ( this . xmlDoc . responseXML ) {
var temp = this . xmlDoc . responseXML . getElementsByTagName ( tagName ) ;
if ( temp . length == 0 && tagName . indexOf ( ":" ) != - 1 )
var temp = this . xmlDoc . responseXML . getElementsByTagName ( ( tagName . split ( ":" ) ) [ 1 ] ) ;
var z = temp [ 0 ] ;
} else
var z = this . xmlDoc . documentElement ;
if ( z ) {
this . _retry = false ;
return z ;
}
if ( ( _isIE ) && ( ! this . _retry ) ) {
//fall back to MS.XMLDOM
var xmlString = this . xmlDoc . responseText ;
var oldObj = this . xmlDoc ;
this . _retry = true ;
this . xmlDoc = new ActiveXObject ( "Microsoft.XMLDOM" ) ;
this . xmlDoc . async = false ;
this . xmlDoc [ "loadXM" + "L" ] ( xmlString ) ;
return this . getXMLTopNode ( tagName , oldObj ) ;
}
dhtmlxError . throwError ( "LoadXML" , "Incorrect XML" , [
( oldObj || this . xmlDoc ) ,
this . mainObject
] ) ;
return document . createElement ( "DIV" ) ;
} ;
/ * *
* @ desc : load XML from string
* @ type : private
* @ param : xmlString - xml string
* @ topic : 0
* /
dtmlXMLLoaderObject . prototype . loadXMLString = function ( xmlString ) {
{
try {
var parser = new DOMParser ( ) ;
this . xmlDoc = parser . parseFromString ( xmlString , "text/xml" ) ;
}
catch ( e ) {
this . xmlDoc = new ActiveXObject ( "Microsoft.XMLDOM" ) ;
this . xmlDoc . async = this . async ;
this . xmlDoc [ "loadXM" + "L" ] ( xmlString ) ;
}
}
this . onloadAction ( this . mainObject , null , null , null , this ) ;
if ( this . waitCall ) {
this . waitCall ( ) ;
this . waitCall = null ;
}
}
/ * *
* @ desc : load XML
* @ type : private
* @ param : filePath - xml file path
* @ param : postMode - send POST request
* @ param : postVars - list of vars for post request
* @ topic : 0
* /
dtmlXMLLoaderObject . prototype . loadXML = function ( filePath , postMode , postVars , rpc ) {
if ( this . rSeed )
filePath += ( ( filePath . indexOf ( "?" ) != - 1 ) ? "&" : "?" ) + "a_dhx_rSeed=" + ( new Date ( ) ) . valueOf ( ) ;
this . filePath = filePath ;
if ( ( ! _isIE ) && ( window . XMLHttpRequest ) )
this . xmlDoc = new XMLHttpRequest ( ) ;
else {
this . xmlDoc = new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
}
if ( this . async )
this . xmlDoc . onreadystatechange = new this . waitLoadFunction ( this ) ;
this . xmlDoc . open ( postMode ? "POST" : "GET" , filePath , this . async ) ;
if ( rpc ) {
this . xmlDoc . setRequestHeader ( "User-Agent" , "dhtmlxRPC v0.1 (" + navigator . userAgent + ")" ) ;
this . xmlDoc . setRequestHeader ( "Content-type" , "text/xml" ) ;
}
else if ( postMode )
this . xmlDoc . setRequestHeader ( 'Content-type' , 'application/x-www-form-urlencoded' ) ;
this . xmlDoc . setRequestHeader ( "X-Requested-With" , "XMLHttpRequest" ) ;
this . xmlDoc . send ( null || postVars ) ;
if ( ! this . async )
( new this . waitLoadFunction ( this ) ) ( ) ;
} ;
/ * *
* @ desc : destructor , cleans used memory
* @ type : private
* @ topic : 0
* /
dtmlXMLLoaderObject . prototype . destructor = function ( ) {
this . onloadAction = null ;
this . mainObject = null ;
this . xmlDoc = null ;
return null ;
}
dtmlXMLLoaderObject . prototype . xmlNodeToJSON = function ( node ) {
var t = { } ;
for ( var i = 0 ; i < node . attributes . length ; i ++ )
t [ node . attributes [ i ] . name ] = node . attributes [ i ] . value ;
t [ "_tagvalue" ] = node . firstChild ? node . firstChild . nodeValue : "" ;
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
var name = node . childNodes [ i ] . tagName ;
if ( name ) {
if ( ! t [ name ] ) t [ name ] = [ ] ;
t [ name ] . push ( this . xmlNodeToJSON ( node . childNodes [ i ] ) ) ;
}
}
return t ;
}
/ * *
* @ desc : Call wrapper
* @ type : private
* @ param : funcObject - action handler
* @ param : dhtmlObject - user data
* @ returns : function handler
* @ topic : 0
* /
function callerFunction ( funcObject , dhtmlObject ) {
this . handler = function ( e ) {
if ( ! e )
e = window . event ;
funcObject ( e , dhtmlObject ) ;
return true ;
} ;
return this . handler ;
} ;
/ * *
* @ desc : Calculate absolute position of html object
* @ type : private
* @ param : htmlObject - html object
* @ topic : 0
* /
function getAbsoluteLeft ( htmlObject ) {
return getOffset ( htmlObject ) . left ;
}
/ * *
* @ desc : Calculate absolute position of html object
* @ type : private
* @ param : htmlObject - html object
* @ topic : 0
* /
function getAbsoluteTop ( htmlObject ) {
return getOffset ( htmlObject ) . top ;
}
function getOffsetSum ( elem ) {
var top = 0 , left = 0 ;
while ( elem ) {
top = top + parseInt ( elem . offsetTop ) ;
left = left + parseInt ( elem . offsetLeft ) ;
elem = elem . offsetParent ;
}
return { top : top , left : left } ;
}
function getOffsetRect ( elem ) {
var box = elem . getBoundingClientRect ( ) ;
var body = document . body ;
var docElem = document . documentElement ;
var scrollTop = window . pageYOffset || docElem . scrollTop || body . scrollTop ;
var scrollLeft = window . pageXOffset || docElem . scrollLeft || body . scrollLeft ;
var clientTop = docElem . clientTop || body . clientTop || 0 ;
var clientLeft = docElem . clientLeft || body . clientLeft || 0 ;
var top = box . top + scrollTop - clientTop ;
var left = box . left + scrollLeft - clientLeft ;
return { top : Math . round ( top ) , left : Math . round ( left ) } ;
}
function getOffset ( elem ) {
if ( elem . getBoundingClientRect && ! _isChrome ) {
return getOffsetRect ( elem ) ;
} else {
return getOffsetSum ( elem ) ;
}
}
/ * *
* @ desc : Convert string to it boolean representation
* @ type : private
* @ param : inputString - string for covertion
* @ topic : 0
* /
function convertStringToBoolean ( inputString ) {
if ( typeof ( inputString ) == "string" )
inputString = inputString . toLowerCase ( ) ;
switch ( inputString ) {
case "1" :
case "true" :
case "yes" :
case "y" :
case 1 :
case true :
return true ;
break ;
default : return false ;
}
}
/ * *
* @ desc : find out what symbol to use as url param delimiters in further params
* @ type : private
* @ param : str - current url string
* @ topic : 0
* /
function getUrlSymbol ( str ) {
if ( str . indexOf ( "?" ) != - 1 )
return "&"
else
return "?"
}
function dhtmlDragAndDropObject ( ) {
if ( window . dhtmlDragAndDrop )
return window . dhtmlDragAndDrop ;
this . lastLanding = 0 ;
this . dragNode = 0 ;
this . dragStartNode = 0 ;
this . dragStartObject = 0 ;
this . tempDOMU = null ;
this . tempDOMM = null ;
this . waitDrag = 0 ;
window . dhtmlDragAndDrop = this ;
return this ;
} ;
dhtmlDragAndDropObject . prototype . removeDraggableItem = function ( htmlNode ) {
htmlNode . onmousedown = null ;
htmlNode . dragStarter = null ;
htmlNode . dragLanding = null ;
}
dhtmlDragAndDropObject . prototype . addDraggableItem = function ( htmlNode , dhtmlObject ) {
htmlNode . onmousedown = this . preCreateDragCopy ;
htmlNode . dragStarter = dhtmlObject ;
this . addDragLanding ( htmlNode , dhtmlObject ) ;
}
dhtmlDragAndDropObject . prototype . addDragLanding = function ( htmlNode , dhtmlObject ) {
htmlNode . dragLanding = dhtmlObject ;
}
dhtmlDragAndDropObject . prototype . preCreateDragCopy = function ( e ) {
if ( ( e || event ) && ( e || event ) . button == 2 )
return ;
if ( window . dhtmlDragAndDrop . waitDrag ) {
window . dhtmlDragAndDrop . waitDrag = 0 ;
document . body . onmouseup = window . dhtmlDragAndDrop . tempDOMU ;
document . body . onmousemove = window . dhtmlDragAndDrop . tempDOMM ;
return false ;
}
window . dhtmlDragAndDrop . waitDrag = 1 ;
window . dhtmlDragAndDrop . tempDOMU = document . body . onmouseup ;
window . dhtmlDragAndDrop . tempDOMM = document . body . onmousemove ;
window . dhtmlDragAndDrop . dragStartNode = this ;
window . dhtmlDragAndDrop . dragStartObject = this . dragStarter ;
document . body . onmouseup = window . dhtmlDragAndDrop . preCreateDragCopy ;
document . body . onmousemove = window . dhtmlDragAndDrop . callDrag ;
window . dhtmlDragAndDrop . downtime = new Date ( ) . valueOf ( ) ;
if ( ( e ) && ( e . preventDefault ) ) {
e . preventDefault ( ) ;
return false ;
}
return false ;
} ;
dhtmlDragAndDropObject . prototype . callDrag = function ( e ) {
if ( ! e )
e = window . event ;
dragger = window . dhtmlDragAndDrop ;
if ( ( new Date ( ) ) . valueOf ( ) - dragger . downtime < 100 ) return ;
if ( ( e . button == 0 ) && ( _isIE ) )
return dragger . stopDrag ( ) ;
if ( ! dragger . dragNode && dragger . waitDrag ) {
dragger . dragNode = dragger . dragStartObject . _createDragNode ( dragger . dragStartNode , e ) ;
if ( ! dragger . dragNode )
return dragger . stopDrag ( ) ;
dragger . dragNode . onselectstart = function ( ) { return false ; }
dragger . gldragNode = dragger . dragNode ;
document . body . appendChild ( dragger . dragNode ) ;
document . body . onmouseup = dragger . stopDrag ;
dragger . waitDrag = 0 ;
dragger . dragNode . pWindow = window ;
dragger . initFrameRoute ( ) ;
}
if ( dragger . dragNode . parentNode != window . document . body ) {
var grd = dragger . gldragNode ;
if ( dragger . gldragNode . old )
grd = dragger . gldragNode . old ;
//if (!document.all) dragger.calculateFramePosition();
grd . parentNode . removeChild ( grd ) ;
var oldBody = dragger . dragNode . pWindow ;
// var oldp=dragger.dragNode.parentObject;
if ( _isIE ) {
var div = document . createElement ( "Div" ) ;
div . innerHTML = dragger . dragNode . outerHTML ;
dragger . dragNode = div . childNodes [ 0 ] ;
} else
dragger . dragNode = dragger . dragNode . cloneNode ( true ) ;
dragger . dragNode . pWindow = window ;
// dragger.dragNode.parentObject=oldp;
dragger . gldragNode . old = dragger . dragNode ;
document . body . appendChild ( dragger . dragNode ) ;
oldBody . dhtmlDragAndDrop . dragNode = dragger . dragNode ;
}
dragger . dragNode . style . left = e . clientX + 15 + ( dragger . fx
? dragger . fx * ( - 1 )
: 0 )
+ ( document . body . scrollLeft || document . documentElement . scrollLeft ) + "px" ;
dragger . dragNode . style . top = e . clientY + 3 + ( dragger . fy
? dragger . fy * ( - 1 )
: 0 )
+ ( document . body . scrollTop || document . documentElement . scrollTop ) + "px" ;
if ( ! e . srcElement )
var z = e . target ;
else
z = e . srcElement ;
dragger . checkLanding ( z , e ) ;
}
dhtmlDragAndDropObject . prototype . calculateFramePosition = function ( n ) {
//this.fx = 0, this.fy = 0;
if ( window . name ) {
var el = parent . frames [ window . name ] . frameElement . offsetParent ;
var fx = 0 ;
var fy = 0 ;
while ( el ) {
fx += el . offsetLeft ;
fy += el . offsetTop ;
el = el . offsetParent ;
}
if ( ( parent . dhtmlDragAndDrop ) ) {
var ls = parent . dhtmlDragAndDrop . calculateFramePosition ( 1 ) ;
fx += ls . split ( '_' ) [ 0 ] * 1 ;
fy += ls . split ( '_' ) [ 1 ] * 1 ;
}
if ( n )
return fx + "_" + fy ;
else
this . fx = fx ;
this . fy = fy ;
}
return "0_0" ;
}
dhtmlDragAndDropObject . prototype . checkLanding = function ( htmlObject , e ) {
if ( ( htmlObject ) && ( htmlObject . dragLanding ) ) {
if ( this . lastLanding )
this . lastLanding . dragLanding . _dragOut ( this . lastLanding ) ;
this . lastLanding = htmlObject ;
this . lastLanding = this . lastLanding . dragLanding . _dragIn ( this . lastLanding , this . dragStartNode , e . clientX ,
e . clientY , e ) ;
this . lastLanding _scr = ( _isIE ? e . srcElement : e . target ) ;
} else {
if ( ( htmlObject ) && ( htmlObject . tagName != "BODY" ) )
this . checkLanding ( htmlObject . parentNode , e ) ;
else {
if ( this . lastLanding )
this . lastLanding . dragLanding . _dragOut ( this . lastLanding , e . clientX , e . clientY , e ) ;
this . lastLanding = 0 ;
if ( this . _onNotFound )
this . _onNotFound ( ) ;
}
}
}
dhtmlDragAndDropObject . prototype . stopDrag = function ( e , mode ) {
dragger = window . dhtmlDragAndDrop ;
if ( ! mode ) {
dragger . stopFrameRoute ( ) ;
var temp = dragger . lastLanding ;
dragger . lastLanding = null ;
if ( temp )
temp . dragLanding . _drag ( dragger . dragStartNode , dragger . dragStartObject , temp , ( _isIE
? event . srcElement
: e . target ) ) ;
}
dragger . lastLanding = null ;
if ( ( dragger . dragNode ) && ( dragger . dragNode . parentNode == document . body ) )
dragger . dragNode . parentNode . removeChild ( dragger . dragNode ) ;
dragger . dragNode = 0 ;
dragger . gldragNode = 0 ;
dragger . fx = 0 ;
dragger . fy = 0 ;
dragger . dragStartNode = 0 ;
dragger . dragStartObject = 0 ;
document . body . onmouseup = dragger . tempDOMU ;
document . body . onmousemove = dragger . tempDOMM ;
dragger . tempDOMU = null ;
dragger . tempDOMM = null ;
dragger . waitDrag = 0 ;
}
dhtmlDragAndDropObject . prototype . stopFrameRoute = function ( win ) {
if ( win )
window . dhtmlDragAndDrop . stopDrag ( 1 , 1 ) ;
for ( var i = 0 ; i < window . frames . length ; i ++ ) {
try {
if ( ( window . frames [ i ] != win ) && ( window . frames [ i ] . dhtmlDragAndDrop ) )
window . frames [ i ] . dhtmlDragAndDrop . stopFrameRoute ( window ) ;
} catch ( e ) { }
}
try {
if ( ( parent . dhtmlDragAndDrop ) && ( parent != window ) && ( parent != win ) )
parent . dhtmlDragAndDrop . stopFrameRoute ( window ) ;
} catch ( e ) { }
}
dhtmlDragAndDropObject . prototype . initFrameRoute = function ( win , mode ) {
if ( win ) {
window . dhtmlDragAndDrop . preCreateDragCopy ( { } ) ;
window . dhtmlDragAndDrop . dragStartNode = win . dhtmlDragAndDrop . dragStartNode ;
window . dhtmlDragAndDrop . dragStartObject = win . dhtmlDragAndDrop . dragStartObject ;
window . dhtmlDragAndDrop . dragNode = win . dhtmlDragAndDrop . dragNode ;
window . dhtmlDragAndDrop . gldragNode = win . dhtmlDragAndDrop . dragNode ;
window . document . body . onmouseup = window . dhtmlDragAndDrop . stopDrag ;
window . waitDrag = 0 ;
if ( ( ( ! _isIE ) && ( mode ) ) && ( ( ! _isFF ) || ( _FFrv < 1.8 ) ) )
window . dhtmlDragAndDrop . calculateFramePosition ( ) ;
}
try {
if ( ( parent . dhtmlDragAndDrop ) && ( parent != window ) && ( parent != win ) )
parent . dhtmlDragAndDrop . initFrameRoute ( window ) ;
} catch ( e ) { }
for ( var i = 0 ; i < window . frames . length ; i ++ ) {
try {
if ( ( window . frames [ i ] != win ) && ( window . frames [ i ] . dhtmlDragAndDrop ) )
window . frames [ i ] . dhtmlDragAndDrop . initFrameRoute ( window , ( ( ! win || mode ) ? 1 : 0 ) ) ;
} catch ( e ) { }
}
}
2011-08-03 14:09:14 +00:00
_isFF = false ;
_isIE = false ;
_isOpera = false ;
_isKHTML = false ;
_isMacOS = false ;
_isChrome = false ;
_KHTMLrv = false ;
_OperaRv = false ;
_FFrv = false ;
2011-04-07 16:41:06 +00:00
if ( navigator . userAgent . indexOf ( 'Macintosh' ) != - 1 )
_isMacOS = true ;
if ( navigator . userAgent . toLowerCase ( ) . indexOf ( 'chrome' ) > - 1 )
_isChrome = true ;
if ( ( navigator . userAgent . indexOf ( 'Safari' ) != - 1 ) || ( navigator . userAgent . indexOf ( 'Konqueror' ) != - 1 ) ) {
var _KHTMLrv = parseFloat ( navigator . userAgent . substr ( navigator . userAgent . indexOf ( 'Safari' ) + 7 , 5 ) ) ;
if ( _KHTMLrv > 525 ) { //mimic FF behavior for Safari 3.1+
_isFF = true ;
var _FFrv = 1.9 ;
} else
_isKHTML = true ;
} else if ( navigator . userAgent . indexOf ( 'Opera' ) != - 1 ) {
_isOpera = true ;
_OperaRv = parseFloat ( navigator . userAgent . substr ( navigator . userAgent . indexOf ( 'Opera' ) + 6 , 3 ) ) ;
}
else if ( navigator . appName . indexOf ( "Microsoft" ) != - 1 ) {
_isIE = true ;
if ( navigator . appVersion . indexOf ( "MSIE 8.0" ) != - 1 && document . compatMode != "BackCompat" ) _isIE = 8 ;
} else {
_isFF = true ;
var _FFrv = parseFloat ( navigator . userAgent . split ( "rv:" ) [ 1 ] )
}
//multibrowser Xpath processor
dtmlXMLLoaderObject . prototype . doXPath = function ( xpathExp , docObj , namespace , result _type ) {
if ( _isKHTML || ( ! _isIE && ! window . XPathResult ) )
return this . doXPathOpera ( xpathExp , docObj ) ;
if ( _isIE ) { //IE
if ( ! docObj )
if ( ! this . xmlDoc . nodeName )
docObj = this . xmlDoc . responseXML
else
docObj = this . xmlDoc ;
if ( ! docObj )
dhtmlxError . throwError ( "LoadXML" , "Incorrect XML" , [
( docObj || this . xmlDoc ) ,
this . mainObject
] ) ;
if ( namespace != null )
docObj . setProperty ( "SelectionNamespaces" , "xmlns:xsl='" + namespace + "'" ) ; //
if ( result _type == 'single' ) {
return docObj . selectSingleNode ( xpathExp ) ;
}
else {
return docObj . selectNodes ( xpathExp ) || new Array ( 0 ) ;
}
} else { //Mozilla
var nodeObj = docObj ;
if ( ! docObj ) {
if ( ! this . xmlDoc . nodeName ) {
docObj = this . xmlDoc . responseXML
}
else {
docObj = this . xmlDoc ;
}
}
if ( ! docObj )
dhtmlxError . throwError ( "LoadXML" , "Incorrect XML" , [
( docObj || this . xmlDoc ) ,
this . mainObject
] ) ;
if ( docObj . nodeName . indexOf ( "document" ) != - 1 ) {
nodeObj = docObj ;
}
else {
nodeObj = docObj ;
docObj = docObj . ownerDocument ;
}
var retType = XPathResult . ANY _TYPE ;
if ( result _type == 'single' )
retType = XPathResult . FIRST _ORDERED _NODE _TYPE
var rowsCol = new Array ( ) ;
var col = docObj . evaluate ( xpathExp , nodeObj , function ( pref ) {
return namespace
} , retType , null ) ;
if ( retType == XPathResult . FIRST _ORDERED _NODE _TYPE ) {
return col . singleNodeValue ;
}
var thisColMemb = col . iterateNext ( ) ;
while ( thisColMemb ) {
rowsCol [ rowsCol . length ] = thisColMemb ;
thisColMemb = col . iterateNext ( ) ;
}
return rowsCol ;
}
}
function _dhtmlxError ( type , name , params ) {
if ( ! this . catches )
this . catches = new Array ( ) ;
return this ;
}
_dhtmlxError . prototype . catchError = function ( type , func _name ) {
this . catches [ type ] = func _name ;
}
_dhtmlxError . prototype . throwError = function ( type , name , params ) {
if ( this . catches [ type ] )
return this . catches [ type ] ( type , name , params ) ;
if ( this . catches [ "ALL" ] )
return this . catches [ "ALL" ] ( type , name , params ) ;
alert ( "Error type: " + arguments [ 0 ] + "\nDescription: " + arguments [ 1 ] ) ;
return null ;
}
window . dhtmlxError = new _dhtmlxError ( ) ;
//opera fake, while 9.0 not released
//multibrowser Xpath processor
dtmlXMLLoaderObject . prototype . doXPathOpera = function ( xpathExp , docObj ) {
//this is fake for Opera
var z = xpathExp . replace ( /[\/]+/gi , "/" ) . split ( '/' ) ;
var obj = null ;
var i = 1 ;
if ( ! z . length )
return [ ] ;
if ( z [ 0 ] == "." )
obj = [ docObj ] ; else if ( z [ 0 ] == "" ) {
obj = ( this . xmlDoc . responseXML || this . xmlDoc ) . getElementsByTagName ( z [ i ] . replace ( /\[[^\]]*\]/g , "" ) ) ;
i ++ ;
} else
return [ ] ;
for ( i ; i < z . length ; i ++ ) obj = this . _getAllNamedChilds ( obj , z [ i ] ) ;
if ( z [ i - 1 ] . indexOf ( "[" ) != - 1 )
obj = this . _filterXPath ( obj , z [ i - 1 ] ) ;
return obj ;
}
dtmlXMLLoaderObject . prototype . _filterXPath = function ( a , b ) {
var c = new Array ( ) ;
var b = b . replace ( /[^\[]*\[\@/g , "" ) . replace ( /[\[\]\@]*/g , "" ) ;
for ( var i = 0 ; i < a . length ; i ++ )
if ( a [ i ] . getAttribute ( b ) )
c [ c . length ] = a [ i ] ;
return c ;
}
dtmlXMLLoaderObject . prototype . _getAllNamedChilds = function ( a , b ) {
var c = new Array ( ) ;
if ( _isKHTML )
b = b . toUpperCase ( ) ;
for ( var i = 0 ; i < a . length ; i ++ ) for ( var j = 0 ; j < a [ i ] . childNodes . length ; j ++ ) {
if ( _isKHTML ) {
if ( a [ i ] . childNodes [ j ] . tagName && a [ i ] . childNodes [ j ] . tagName . toUpperCase ( ) == b )
c [ c . length ] = a [ i ] . childNodes [ j ] ;
}
else if ( a [ i ] . childNodes [ j ] . tagName == b )
c [ c . length ] = a [ i ] . childNodes [ j ] ;
}
return c ;
}
function dhtmlXHeir ( a , b ) {
for ( var c in b )
if ( typeof ( b [ c ] ) == "function" )
a [ c ] = b [ c ] ;
return a ;
}
function dhtmlxEvent ( el , event , handler ) {
if ( el . addEventListener )
el . addEventListener ( event , handler , false ) ;
else if ( el . attachEvent )
el . attachEvent ( "on" + event , handler ) ;
}
//============= XSL Extension ===================================
dtmlXMLLoaderObject . prototype . xslDoc = null ;
dtmlXMLLoaderObject . prototype . setXSLParamValue = function ( paramName , paramValue , xslDoc ) {
if ( ! xslDoc )
xslDoc = this . xslDoc
if ( xslDoc . responseXML )
xslDoc = xslDoc . responseXML ;
var item =
this . doXPath ( "/xsl:stylesheet/xsl:variable[@name='" + paramName + "']" , xslDoc ,
"http:/\/www.w3.org/1999/XSL/Transform" , "single" ) ;
if ( item != null )
item . firstChild . nodeValue = paramValue
}
dtmlXMLLoaderObject . prototype . doXSLTransToObject = function ( xslDoc , xmlDoc ) {
if ( ! xslDoc )
xslDoc = this . xslDoc ;
if ( xslDoc . responseXML )
xslDoc = xslDoc . responseXML
if ( ! xmlDoc )
xmlDoc = this . xmlDoc ;
if ( xmlDoc . responseXML )
xmlDoc = xmlDoc . responseXML
//MOzilla
if ( ! _isIE ) {
if ( ! this . XSLProcessor ) {
this . XSLProcessor = new XSLTProcessor ( ) ;
this . XSLProcessor . importStylesheet ( xslDoc ) ;
}
var result = this . XSLProcessor . transformToDocument ( xmlDoc ) ;
} else {
var result = new ActiveXObject ( "Msxml2.DOMDocument.3.0" ) ;
try {
xmlDoc . transformNodeToObject ( xslDoc , result ) ;
} catch ( e ) {
result = xmlDoc . transformNode ( xslDoc ) ;
}
}
return result ;
}
dtmlXMLLoaderObject . prototype . doXSLTransToString = function ( xslDoc , xmlDoc ) {
var res = this . doXSLTransToObject ( xslDoc , xmlDoc ) ;
if ( typeof ( res ) == "string" )
return res ;
return this . doSerialization ( res ) ;
}
dtmlXMLLoaderObject . prototype . doSerialization = function ( xmlDoc ) {
if ( ! xmlDoc )
xmlDoc = this . xmlDoc ;
if ( xmlDoc . responseXML )
xmlDoc = xmlDoc . responseXML
if ( ! _isIE ) {
var xmlSerializer = new XMLSerializer ( ) ;
return xmlSerializer . serializeToString ( xmlDoc ) ;
} else
return xmlDoc . xml ;
}
/ * *
* @ desc :
* @ type : private
* /
dhtmlxEventable = function ( obj ) {
obj . dhx _SeverCatcherPath = "" ;
obj . attachEvent = function ( name , catcher , callObj ) {
name = 'ev_' + name . toLowerCase ( ) ;
if ( ! this [ name ] )
this [ name ] = new this . eventCatcher ( callObj || this ) ;
return ( name + ':' + this [ name ] . addEvent ( catcher ) ) ; //return ID (event name & event ID)
}
obj . callEvent = function ( name , arg0 ) {
name = 'ev_' + name . toLowerCase ( ) ;
if ( this [ name ] )
return this [ name ] . apply ( this , arg0 ) ;
return true ;
}
obj . checkEvent = function ( name ) {
return ( ! ! this [ 'ev_' + name . toLowerCase ( ) ] )
}
obj . eventCatcher = function ( obj ) {
var dhx _catch = [ ] ;
var z = function ( ) {
var res = true ;
for ( var i = 0 ; i < dhx _catch . length ; i ++ ) {
if ( dhx _catch [ i ] != null ) {
var zr = dhx _catch [ i ] . apply ( obj , arguments ) ;
res = res && zr ;
}
}
return res ;
}
z . addEvent = function ( ev ) {
if ( typeof ( ev ) != "function" )
ev = eval ( ev ) ;
if ( ev )
return dhx _catch . push ( ev ) - 1 ;
return false ;
}
z . removeEvent = function ( id ) {
dhx _catch [ id ] = null ;
}
return z ;
}
obj . detachEvent = function ( id ) {
if ( id != false ) {
var list = id . split ( ':' ) ; //get EventName and ID
this [ list [ 0 ] ] . removeEvent ( list [ 1 ] ) ; //remove event
}
}
2011-08-03 14:09:14 +00:00
obj . detachAllEvents = function ( ) {
for ( var name in this ) {
if ( name . indexOf ( "ev_" ) == 0 )
delete this [ name ] ;
}
}
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
/ * *
* @ desc : constructor , data processor object
* @ param : serverProcessorURL - url used for update
* @ type : public
* /
function dataProcessor ( serverProcessorURL ) {
this . serverProcessor = serverProcessorURL ;
this . action _param = "!nativeeditor_status" ;
this . object = null ;
this . updatedRows = [ ] ; //ids of updated rows
this . autoUpdate = true ;
this . updateMode = "cell" ;
this . _tMode = "GET" ;
this . post _delim = "_" ;
this . _waitMode = 0 ;
this . _in _progress = { } ; //?
this . _invalid = { } ;
this . mandatoryFields = [ ] ;
this . messages = [ ] ;
this . styles = {
updated : "font-weight:bold;" ,
inserted : "font-weight:bold;" ,
deleted : "text-decoration : line-through;" ,
invalid : "background-color:FFE0E0;" ,
invalid _cell : "border-bottom:2px solid red;" ,
error : "color:red;" ,
clear : "font-weight:normal;text-decoration:none;"
} ;
this . enableUTFencoding ( true ) ;
dhtmlxEventable ( this ) ;
return this ;
}
dataProcessor . prototype = {
/ * *
* @ desc : select GET or POST transaction model
* @ param : mode - GET / POST
* @ param : total - true / false - send records row by row or all at once ( for grid only )
* @ type : public
* /
setTransactionMode : function ( mode , total ) {
this . _tMode = mode ;
this . _tSend = total ;
} ,
escape : function ( data ) {
if ( this . _utf )
return encodeURIComponent ( data ) ;
else
return escape ( data ) ;
} ,
/ * *
* @ desc : allows to set escaping mode
* @ param : true - utf based escaping , simple - use current page encoding
* @ type : public
* /
enableUTFencoding : function ( mode ) {
this . _utf = convertStringToBoolean ( mode ) ;
} ,
/ * *
* @ desc : allows to define , which column may trigger update
* @ param : val - array or list of true / false values
* @ type : public
* /
setDataColumns : function ( val ) {
this . _columns = ( typeof val == "string" ) ? val . split ( "," ) : val ;
} ,
/ * *
* @ desc : get state of updating
* @ returns : true - all in sync with server , false - some items not updated yet .
* @ type : public
* /
getSyncState : function ( ) {
return ! this . updatedRows . length ;
} ,
/ * *
* @ desc : enable / disable named field for data syncing , will use column ids for grid
* @ param : mode - true / false
* @ type : public
* /
enableDataNames : function ( mode ) {
this . _endnm = convertStringToBoolean ( mode ) ;
} ,
/ * *
* @ desc : enable / disable mode , when only changed fields and row id send to the server side , instead of all fields in default mode
* @ param : mode - true / false
* @ type : public
* /
enablePartialDataSend : function ( mode ) {
this . _changed = convertStringToBoolean ( mode ) ;
} ,
/ * *
* @ desc : set if rows should be send to server automaticaly
* @ param : mode - "row" - based on row selection changed , "cell" - based on cell editing finished , "off" - manual data sending
* @ type : public
* /
setUpdateMode : function ( mode , dnd ) {
this . autoUpdate = ( mode == "cell" ) ;
this . updateMode = mode ;
this . dnd = dnd ;
} ,
ignore : function ( code , master ) {
this . _silent _mode = true ;
code . call ( master || window ) ;
this . _silent _mode = false ;
} ,
/ * *
* @ desc : mark row as updated / normal . check mandatory fields , initiate autoupdate ( if turned on )
* @ param : rowId - id of row to set update - status for
* @ param : state - true for "updated" , false for "not updated"
* @ param : mode - update mode name
* @ type : public
* /
setUpdated : function ( rowId , state , mode ) {
if ( this . _silent _mode ) return ;
var ind = this . findRow ( rowId ) ;
mode = mode || "updated" ;
var existing = this . obj . getUserData ( rowId , this . action _param ) ;
if ( existing && mode == "updated" ) mode = existing ;
if ( state ) {
this . set _invalid ( rowId , false ) ; //clear previous error flag
this . updatedRows [ ind ] = rowId ;
this . obj . setUserData ( rowId , this . action _param , mode ) ;
if ( this . _in _progress [ rowId ] )
this . _in _progress [ rowId ] = "wait" ;
} else {
if ( ! this . is _invalid ( rowId ) ) {
this . updatedRows . splice ( ind , 1 ) ;
this . obj . setUserData ( rowId , this . action _param , "" ) ;
}
}
//clear changed flag
if ( ! state )
this . _clearUpdateFlag ( rowId ) ;
this . markRow ( rowId , state , mode ) ;
if ( state && this . autoUpdate ) this . sendData ( rowId ) ;
} ,
_clearUpdateFlag : function ( id ) { } ,
markRow : function ( id , state , mode ) {
var str = "" ;
var invalid = this . is _invalid ( id ) ;
if ( invalid ) {
str = this . styles [ invalid ] ;
state = true ;
}
if ( this . callEvent ( "onRowMark" , [ id , state , mode , invalid ] ) ) {
//default logic
str = this . styles [ state ? mode : "clear" ] + str ;
this . obj [ this . _methods [ 0 ] ] ( id , str ) ;
if ( invalid && invalid . details ) {
str += this . styles [ invalid + "_cell" ] ;
for ( var i = 0 ; i < invalid . details . length ; i ++ )
if ( invalid . details [ i ] )
this . obj [ this . _methods [ 1 ] ] ( id , i , str ) ;
}
}
} ,
getState : function ( id ) {
return this . obj . getUserData ( id , this . action _param ) ;
} ,
is _invalid : function ( id ) {
return this . _invalid [ id ] ;
} ,
set _invalid : function ( id , mode , details ) {
if ( details ) mode = { value : mode , details : details , toString : function ( ) { return this . value . toString ( ) ; } } ;
this . _invalid [ id ] = mode ;
} ,
/ * *
* @ desc : check mandatory fields and varify values of cells , initiate update ( if specified )
* @ param : rowId - id of row to set update - status for
* @ type : public
* /
checkBeforeUpdate : function ( rowId ) {
return true ;
} ,
/ * *
* @ desc : send row ( s ) values to server
* @ param : rowId - id of row which data to send . If not specified , then all "updated" rows will be send
* @ type : public
* /
sendData : function ( rowId ) {
if ( this . _waitMode && ( this . obj . mytype == "tree" || this . obj . _h2 ) ) return ;
if ( this . obj . editStop ) this . obj . editStop ( ) ;
if ( typeof rowId == "undefined" || this . _tSend ) return this . sendAllData ( ) ;
if ( this . _in _progress [ rowId ] ) return false ;
this . messages = [ ] ;
if ( ! this . checkBeforeUpdate ( rowId ) && this . callEvent ( "onValidatationError" , [ rowId , this . messages ] ) ) return false ;
this . _beforeSendData ( this . _getRowData ( rowId ) , rowId ) ;
} ,
_beforeSendData : function ( data , rowId ) {
if ( ! this . callEvent ( "onBeforeUpdate" , [ rowId , this . getState ( rowId ) , data ] ) ) return false ;
this . _sendData ( data , rowId ) ;
} ,
serialize : function ( data , id ) {
if ( typeof data == "string" )
return data ;
if ( typeof id != "undefined" )
return this . serialize _one ( data , "" ) ;
else {
var stack = [ ] ;
var keys = [ ] ;
for ( var key in data )
if ( data . hasOwnProperty ( key ) ) {
stack . push ( this . serialize _one ( data [ key ] , key + this . post _delim ) ) ;
keys . push ( key ) ;
}
stack . push ( "ids=" + this . escape ( keys . join ( "," ) ) ) ;
return stack . join ( "&" ) ;
}
} ,
serialize _one : function ( data , pref ) {
if ( typeof data == "string" )
return data ;
var stack = [ ] ;
for ( var key in data )
if ( data . hasOwnProperty ( key ) )
stack . push ( this . escape ( ( pref || "" ) + key ) + "=" + this . escape ( data [ key ] ) ) ;
return stack . join ( "&" ) ;
} ,
_sendData : function ( a1 , rowId ) {
if ( ! a1 ) return ; //nothing to send
if ( ! this . callEvent ( "onBeforeDataSending" , rowId ? [ rowId , this . getState ( rowId ) , a1 ] : [ null , null , a1 ] ) ) return false ;
if ( rowId )
this . _in _progress [ rowId ] = ( new Date ( ) ) . valueOf ( ) ;
var a2 = new dtmlXMLLoaderObject ( this . afterUpdate , this , true ) ;
var a3 = this . serverProcessor + ( this . _user ? ( getUrlSymbol ( this . serverProcessor ) + [ "dhx_user=" + this . _user , "dhx_version=" + this . obj . getUserData ( 0 , "version" ) ] . join ( "&" ) ) : "" ) ;
if ( this . _tMode != "POST" )
a2 . loadXML ( a3 + ( ( a3 . indexOf ( "?" ) != - 1 ) ? "&" : "?" ) + this . serialize ( a1 , rowId ) ) ;
else
a2 . loadXML ( a3 , true , this . serialize ( a1 , rowId ) ) ;
this . _waitMode ++ ;
} ,
sendAllData : function ( ) {
if ( ! this . updatedRows . length ) return ;
this . messages = [ ] ; var valid = true ;
for ( var i = 0 ; i < this . updatedRows . length ; i ++ )
valid &= this . checkBeforeUpdate ( this . updatedRows [ i ] ) ;
if ( ! valid && ! this . callEvent ( "onValidatationError" , [ "" , this . messages ] ) ) return false ;
if ( this . _tSend )
this . _sendData ( this . _getAllData ( ) ) ;
else
for ( var i = 0 ; i < this . updatedRows . length ; i ++ )
if ( ! this . _in _progress [ this . updatedRows [ i ] ] ) {
if ( this . is _invalid ( this . updatedRows [ i ] ) ) continue ;
this . _beforeSendData ( this . _getRowData ( this . updatedRows [ i ] ) , this . updatedRows [ i ] ) ;
if ( this . _waitMode && ( this . obj . mytype == "tree" || this . obj . _h2 ) ) return ; //block send all for tree
}
} ,
_getAllData : function ( rowId ) {
var out = { } ;
var has _one = false ;
for ( var i = 0 ; i < this . updatedRows . length ; i ++ ) {
var id = this . updatedRows [ i ] ;
if ( this . _in _progress [ id ] || this . is _invalid ( id ) ) continue ;
if ( ! this . callEvent ( "onBeforeUpdate" , [ id , this . getState ( id ) ] ) ) continue ;
out [ id ] = this . _getRowData ( id , id + this . post _delim ) ;
has _one = true ;
this . _in _progress [ id ] = ( new Date ( ) ) . valueOf ( ) ;
}
return has _one ? out : null ;
} ,
/ * *
* @ desc : specify column which value should be varified before sending to server
* @ param : ind - column index ( 0 based )
* @ param : verifFunction - function ( object ) which should verify cell value ( if not specified , then value will be compared to empty string ) . Two arguments will be passed into it : value and column name
* @ type : public
* /
setVerificator : function ( ind , verifFunction ) {
this . mandatoryFields [ ind ] = verifFunction || ( function ( value ) { return ( value != "" ) ; } ) ;
} ,
/ * *
* @ desc : remove column from list of those which should be verified
* @ param : ind - column Index ( 0 based )
* @ type : public
* /
clearVerificator : function ( ind ) {
this . mandatoryFields [ ind ] = false ;
} ,
findRow : function ( pattern ) {
var i = 0 ;
for ( i = 0 ; i < this . updatedRows . length ; i ++ )
if ( pattern == this . updatedRows [ i ] ) break ;
return i ;
} ,
/ * *
* @ desc : define custom actions
* @ param : name - name of action , same as value of action attribute
* @ param : handler - custom function , which receives a XMl response content for action
* @ type : private
* /
defineAction : function ( name , handler ) {
if ( ! this . _uActions ) this . _uActions = [ ] ;
this . _uActions [ name ] = handler ;
} ,
/ * *
* @ desc : used in combination with setOnBeforeUpdateHandler to create custom client - server transport system
* @ param : sid - id of item before update
* @ param : tid - id of item after up0ate
* @ param : action - action name
* @ type : public
* @ topic : 0
* /
afterUpdateCallback : function ( sid , tid , action , btag ) {
var marker = sid ;
var correct = ( action != "error" && action != "invalid" ) ;
if ( ! correct ) this . set _invalid ( sid , action ) ;
if ( ( this . _uActions ) && ( this . _uActions [ action ] ) && ( ! this . _uActions [ action ] ( btag ) ) )
return ( delete this . _in _progress [ marker ] ) ;
if ( this . _in _progress [ marker ] != "wait" )
this . setUpdated ( sid , false ) ;
var soid = sid ;
switch ( action ) {
2011-08-03 14:09:14 +00:00
case "update" :
case "updated" :
2011-04-07 16:41:06 +00:00
case "inserted" :
case "insert" :
if ( tid != sid ) {
this . obj [ this . _methods [ 2 ] ] ( sid , tid ) ;
sid = tid ;
}
break ;
case "delete" :
case "deleted" :
this . obj . setUserData ( sid , this . action _param , "true_deleted" ) ;
this . obj [ this . _methods [ 3 ] ] ( sid ) ;
delete this . _in _progress [ marker ] ;
return this . callEvent ( "onAfterUpdate" , [ sid , action , tid , btag ] ) ;
break ;
}
if ( this . _in _progress [ marker ] != "wait" ) {
if ( correct ) this . obj . setUserData ( sid , this . action _param , '' ) ;
delete this . _in _progress [ marker ] ;
} else {
delete this . _in _progress [ marker ] ;
this . setUpdated ( tid , true , this . obj . getUserData ( sid , this . action _param ) ) ;
}
this . callEvent ( "onAfterUpdate" , [ sid , action , tid , btag ] ) ;
} ,
/ * *
* @ desc : response from server
* @ param : xml - XMLLoader object with response XML
* @ type : private
* /
afterUpdate : function ( that , b , c , d , xml ) {
xml . getXMLTopNode ( "data" ) ; //fix incorrect content type in IE
if ( ! xml . xmlDoc . responseXML ) return ;
var atag = xml . doXPath ( "//data/action" ) ;
for ( var i = 0 ; i < atag . length ; i ++ ) {
var btag = atag [ i ] ;
var action = btag . getAttribute ( "type" ) ;
var sid = btag . getAttribute ( "sid" ) ;
var tid = btag . getAttribute ( "tid" ) ;
that . afterUpdateCallback ( sid , tid , action , btag ) ;
}
that . finalizeUpdate ( ) ;
} ,
finalizeUpdate : function ( ) {
if ( this . _waitMode ) this . _waitMode -- ;
if ( ( this . obj . mytype == "tree" || this . obj . _h2 ) && this . updatedRows . length )
this . sendData ( ) ;
this . callEvent ( "onAfterUpdateFinish" , [ ] ) ;
if ( ! this . updatedRows . length )
this . callEvent ( "onFullSync" , [ ] ) ;
} ,
/ * *
* @ desc : initializes data - processor
* @ param : anObj - dhtmlxGrid object to attach this data - processor to
* @ type : public
* /
init : function ( anObj ) {
this . obj = anObj ;
if ( this . obj . _dp _init )
this . obj . _dp _init ( this ) ;
} ,
setOnAfterUpdate : function ( ev ) {
this . attachEvent ( "onAfterUpdate" , ev ) ;
} ,
enableDebug : function ( mode ) {
} ,
setOnBeforeUpdateHandler : function ( func ) {
this . attachEvent ( "onBeforeDataSending" , func ) ;
} ,
/ * ! s t a r t s a u t o u p d a t e m o d e
@ param interval
time interval for sending update requests
* /
setAutoUpdate : function ( interval , user ) {
interval = interval || 2000 ;
this . _user = user || ( new Date ( ) ) . valueOf ( ) ;
this . _need _update = false ;
this . _loader = null ;
this . _update _busy = false ;
this . attachEvent ( "onAfterUpdate" , function ( sid , action , tid , xml _node ) {
this . afterAutoUpdate ( sid , action , tid , xml _node ) ;
} ) ;
this . attachEvent ( "onFullSync" , function ( ) {
this . fullSync ( ) ;
} ) ;
var self = this ;
window . setInterval ( function ( ) {
self . loadUpdate ( ) ;
} , interval ) ;
} ,
/ * ! p r o c e s s u p d a t i n g r e q u e s t a n s w e r
if status == collision version is depricated
set flag for autoupdating immidiatly
* /
afterAutoUpdate : function ( sid , action , tid , xml _node ) {
if ( action == 'collision' ) {
this . _need _update = true ;
return false ;
} else {
return true ;
}
} ,
/ * ! c a l l b a c k f u n c t i o n f o r o n F i l l S y n c e v e n t
call update function if it ' s need
* /
fullSync : function ( ) {
if ( this . _need _update == true ) {
this . _need _update = false ;
this . loadUpdate ( ) ;
}
return true ;
} ,
/ * ! s e n d s q u e r y t o t h e s e r v e r a n d c a l l c a l l b a c k f u n c t i o n
* /
getUpdates : function ( url , callback ) {
if ( this . _update _busy )
return false ;
else
this . _update _busy = true ;
this . _loader = this . _loader || new dtmlXMLLoaderObject ( true ) ;
this . _loader . async = true ;
this . _loader . waitCall = callback ;
this . _loader . loadXML ( url ) ;
} ,
/ * ! r e t u r n s x m l n o d e v a l u e
@ param node
xml node
* /
_v : function ( node ) {
if ( node . firstChild ) return node . firstChild . nodeValue ;
return "" ;
} ,
/ * ! r e t u r n s v a l u e s a r r a y o f x m l n o d e s a r r a y
@ param arr
array of xml nodes
* /
_a : function ( arr ) {
var res = [ ] ;
for ( var i = 0 ; i < arr . length ; i ++ ) {
res [ i ] = this . _v ( arr [ i ] ) ;
} ;
return res ;
} ,
/ * ! l o a d s u p d a t e s a n d p r o c e s s e s t h e m
* /
loadUpdate : function ( ) {
var self = this ;
var version = this . obj . getUserData ( 0 , "version" ) ;
var url = this . serverProcessor + getUrlSymbol ( this . serverProcessor ) + [ "dhx_user=" + this . _user , "dhx_version=" + version ] . join ( "&" ) ;
url = url . replace ( "editing=true&" , "" ) ;
this . getUpdates ( url , function ( ) {
var vers = self . _loader . doXPath ( "//userdata" ) ;
self . obj . setUserData ( 0 , "version" , self . _v ( vers [ 0 ] ) ) ;
var upds = self . _loader . doXPath ( "//update" ) ;
if ( upds . length ) {
self . _silent _mode = true ;
for ( var i = 0 ; i < upds . length ; i ++ ) {
var status = upds [ i ] . getAttribute ( 'status' ) ;
var id = upds [ i ] . getAttribute ( 'id' ) ;
var parent = upds [ i ] . getAttribute ( 'parent' ) ;
switch ( status ) {
case 'inserted' :
self . callEvent ( "insertCallback" , [ upds [ i ] , id , parent ] ) ;
break ;
case 'updated' :
self . callEvent ( "updateCallback" , [ upds [ i ] , id , parent ] ) ;
break ;
case 'deleted' :
self . callEvent ( "deleteCallback" , [ upds [ i ] , id , parent ] ) ;
break ;
}
}
self . _silent _mode = false ;
}
self . _update _busy = false ;
self = null ;
} ) ;
}
} ;
2011-08-03 14:09:14 +00:00
//(c)dhtmlx ltd. www.dhtmlx.com
2011-04-07 16:41:06 +00:00
dataProcessor . prototype . _o _init = dataProcessor . prototype . init ;
dataProcessor . prototype . init = function ( obj ) {
this . _console = this . _console || this . _createConsole ( ) ;
this . attachEvent ( "onValidatationError" , function ( rowId ) {
this . _log ( "Validation error for ID=" + ( rowId || "[multiple]" ) ) ;
return true ;
} ) ;
return this . _o _init ( obj ) ;
}
dataProcessor . prototype . _createConsole = function ( ) {
var c = document . createElement ( "DIV" ) ;
c . style . cssText = 'width:450px; height:420px; overflow:auto; position:absolute; z-index:99999; background-color:white; top:0px; right:0px; border:1px dashed black; font-family:Tahoma; Font-size:10pt;' ;
c . innerHTML = "<div style='width:100%; background-color:gray; font-weight:bold; color:white;'><span style='cursor:pointer;float:right;' onclick='this.parentNode.parentNode.style.display=\"none\"'><sup>[close] </sup></span><span style='cursor:pointer;float:right;' onclick='this.parentNode.parentNode.childNodes[2].innerHTML=\"\"'><sup>[clear] </sup></span> DataProcessor</div><div style='width:100%; height:200px; overflow-Y:scroll;'> Current state</div><div style='width:100%; height:200px; overflow-Y:scroll;'> Log:</div>" ;
if ( document . body ) document . body . insertBefore ( c , document . body . firstChild ) ;
else dhtmlxEvent ( window , "load" , function ( ) {
document . body . insertBefore ( c , document . body . firstChild ) ;
} )
dhtmlxEvent ( window , "dblclick" , function ( ) {
c . style . display = '' ;
} )
return c ;
}
dataProcessor . prototype . _error = function ( data ) {
this . _log ( "<span style='color:red'>" + data + "</span>" ) ;
}
dataProcessor . prototype . _log = function ( data ) {
var div = document . createElement ( "DIV" ) ;
div . innerHTML = data ;
var parent = this . _console . childNodes [ 2 ] ;
parent . appendChild ( div ) ;
parent . scrollTop = parent . scrollHeight ;
if ( window . console && window . console . log )
window . console . log ( "DataProcessor :: " + data . replace ( " " , " " ) . replace ( "<b>" , "" ) . replace ( "</b>" , "" ) ) ;
}
dataProcessor . prototype . _updateStat = function ( data ) {
var data = [ " Current state" ] ;
for ( var i = 0 ; i < this . updatedRows . length ; i ++ )
data . push ( " ID:" + this . updatedRows [ i ] + " Status: " + ( this . obj . getUserData ( this . updatedRows [ i ] , "!nativeeditor_status" ) || "updated" ) + ", " + ( this . is _invalid ( this . updatedRows [ i ] ) || "valid" ) )
this . _console . childNodes [ 1 ] . innerHTML = data . join ( "<br/>" ) + "<hr/>Current mode: " + this . updateMode ;
}
dataProcessor . prototype . xml _analize = function ( xml ) {
if ( _isFF ) {
if ( ! xml . xmlDoc . responseXML )
this . _error ( "Not an XML, probably incorrect content type specified ( must be text/xml ), or some text output was started before XML data" ) ;
else if ( xml . xmlDoc . responseXML . firstChild . tagName == "parsererror" )
this . _error ( xml . xmlDoc . responseXML . firstChild . textContent ) ;
else return true ;
} else if ( _isIE ) {
if ( xml . xmlDoc . responseXML . parseError . errorCode )
this . _error ( "XML error : " + xml . xmlDoc . responseXML . parseError . reason ) ;
else if ( ! xml . xmlDoc . responseXML . documentElement )
this . _error ( "Not an XML, probably incorrect content type specified ( must be text/xml ), or some text output was started before XML data" ) ;
else return true ;
}
return false ;
}
dataProcessor . wrap = function ( name , before , after ) {
var d = dataProcessor . prototype ;
if ( ! d . _wrap ) d . _wrap = { } ;
d . _wrap [ name ] = d [ name ] ;
d [ name ] = function ( ) {
if ( before ) before . apply ( this , arguments ) ;
var res = d . _wrap [ name ] . apply ( this , arguments ) ;
if ( after ) after . apply ( this , [ arguments , res ] ) ;
return res ;
}
} ;
dataProcessor . wrap ( "setUpdated" , function ( rowId , state , mode ) {
this . _log ( " row <b>" + rowId + "</b> " + ( state ? "marked" : "unmarked" ) + " [" + ( mode || "updated" ) + "," + ( this . is _invalid ( rowId ) || "valid" ) + "]" ) ;
} , function ( ) {
this . _updateStat ( ) ;
} ) ;
dataProcessor . wrap ( "sendData" , function ( rowId ) {
if ( rowId ) {
this . _log ( " Initiating data sending for <b>" + rowId + "</b>" ) ;
if ( this . obj . mytype == "tree" ) {
if ( ! this . obj . _idpull [ rowId ] )
this . _log ( " Error! item with such ID not exists <b>" + rowId + "</b>" ) ;
} else {
2011-08-03 14:09:14 +00:00
if ( this . rowsAr && ! this . obj . rowsAr [ rowId ] )
2011-04-07 16:41:06 +00:00
this . _log ( " Error! row with such ID not exists <b>" + rowId + "</b>" ) ;
}
}
} , function ( ) {
} ) ;
dataProcessor . wrap ( "sendAllData" , function ( ) {
this . _log ( " Initiating data sending for <b>all</b> rows " ) ;
} , function ( ) {
} ) ;
dataProcessor . logSingle = function ( data , id ) {
var tdata = { } ;
if ( id )
tdata [ id ] = data ;
else
tdata = data ;
var url = [ ] ;
for ( var key in tdata ) {
url . push ( "<fieldset><legend>" + key + "</legend>" ) ;
var suburl = [ ] ;
for ( var ikey in tdata [ key ] )
suburl . push ( ikey + " = " + tdata [ key ] [ ikey ] ) ;
url . push ( suburl . join ( "<br>" ) ) ;
url . push ( "</fieldset>" ) ;
}
return url . join ( "" ) ;
}
dataProcessor . wrap ( "_sendData" , function ( data , rowId ) {
if ( rowId )
this . _log ( " Sending in one-by-one mode, current ID = " + rowId ) ;
else
this . _log ( " Sending all data at once" ) ;
this . _log ( " Server url: " + this . serverProcessor + " <a onclick='this.parentNode.nextSibling.firstChild.style.display=\"block\"' href='#'>parameters</a>" ) ;
var url = [ ] ;
this . _log ( "<blockquote style='display:none;'>" + dataProcessor . logSingle ( data , rowId ) + "<blockquote>" ) ;
} , function ( ) {
} ) ;
dataProcessor . wrap ( "afterUpdate" , function ( that , b , c , d , xml ) {
that . _log ( " Server response received <a onclick='this.nextSibling.style.display=\"block\"' href='#'>details</a><blockquote style='display:none'><code>" + ( xml . xmlDoc . responseText || "" ) . replace ( /\&/g , "&" ) . replace ( /</g , "<" ) . replace ( />/g , ">" ) + "</code></blockquote>" ) ;
if ( ! that . xml _analize ( xml ) ) return ;
var atag = xml . doXPath ( "//data/action" ) ;
if ( ! atag ) {
that . _log ( " No actions found" ) ;
var atag = xml . getXMLTopNode ( "data" ) ;
if ( ! atag ) that . _log ( " XML not valid" ) ;
else that . _log ( " Incorrect content type - need to be text/xml" ) ;
}
} , function ( ) {
} ) ;
dataProcessor . wrap ( "afterUpdateCallback" , function ( sid , tid , action ) {
if ( this . obj . mytype == "tree" ) {
if ( ! this . obj . _idpull [ sid ] ) this . _log ( "Incorrect SID, item with such ID not exists in grid" ) ;
} else {
2011-08-03 14:09:14 +00:00
if ( this . obj . rowsAr && ! this . obj . rowsAr [ sid ] ) this . _log ( "Incorrect SID, row with such ID not exists in grid" ) ;
2011-04-07 16:41:06 +00:00
}
this . _log ( " Action: " + action + " SID:" + sid + " TID:" + tid ) ;
} , function ( ) {
} ) ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
/ *
dhx _sort [ index ] = direction
dhx _filter [ index ] = mask
* /
if ( window . dhtmlXGridObject ) {
dhtmlXGridObject . prototype . _init _point _connector = dhtmlXGridObject . prototype . _init _point ;
dhtmlXGridObject . prototype . _init _point = function ( ) {
var clear _url = function ( url ) {
url = url . replace ( /(\?|\&)connector[^\f]*/g , "" ) ;
2011-08-03 14:09:14 +00:00
return url + ( url . indexOf ( "?" ) != - 1 ? "&" : "?" ) + "connector=true" + ( this . hdr . rows . length > 0 ? "&dhx_no_header=1" : "" ) ;
2011-04-07 16:41:06 +00:00
} ;
var combine _urls = function ( url ) {
2011-08-03 14:09:14 +00:00
return clear _url . call ( this , url ) + ( this . _connector _sorting || "" ) + ( this . _connector _filter || "" ) ;
2011-04-07 16:41:06 +00:00
} ;
var sorting _url = function ( url , ind , dir ) {
this . _connector _sorting = "&dhx_sort[" + ind + "]=" + dir ;
return combine _urls . call ( this , url ) ;
} ;
var filtering _url = function ( url , inds , vals ) {
for ( var i = 0 ; i < inds . length ; i ++ )
inds [ i ] = "dhx_filter[" + inds [ i ] + "]=" + encodeURIComponent ( vals [ i ] ) ;
this . _connector _filter = "&" + inds . join ( "&" ) ;
return combine _urls . call ( this , url ) ;
} ;
this . attachEvent ( "onCollectValues" , function ( ind ) {
if ( this . _con _f _used [ ind ] ) {
if ( typeof ( this . _con _f _used [ ind ] ) == "object" )
return this . _con _f _used [ ind ] ;
else
return false ;
}
return true ;
} ) ;
this . attachEvent ( "onDynXLS" , function ( ) {
this . xmlFileUrl = combine _urls . call ( this , this . xmlFileUrl ) ;
return true ;
} ) ;
this . attachEvent ( "onBeforeSorting" , function ( ind , type , dir ) {
if ( type == "connector" ) {
var self = this ;
this . clearAndLoad ( sorting _url . call ( this , this . xmlFileUrl , ind , dir ) , function ( ) {
self . setSortImgState ( true , ind , dir ) ;
} ) ;
return false ;
}
return true ;
} ) ;
this . attachEvent ( "onFilterStart" , function ( a , b ) {
if ( this . _con _f _used . length ) {
this . clearAndLoad ( filtering _url . call ( this , this . xmlFileUrl , a , b ) ) ;
return false ;
}
return true ;
} ) ;
this . attachEvent ( "onXLE" , function ( a , b , c , xml ) {
if ( ! xml ) return ;
} ) ;
if ( this . _init _point _connector ) this . _init _point _connector ( ) ;
} ;
dhtmlXGridObject . prototype . _con _f _used = [ ] ;
dhtmlXGridObject . prototype . _in _header _connector _text _filter = function ( t , i ) {
if ( ! this . _con _f _used [ i ] )
this . _con _f _used [ i ] = 1 ;
return this . _in _header _text _filter ( t , i ) ;
} ;
dhtmlXGridObject . prototype . _in _header _connector _select _filter = function ( t , i ) {
if ( ! this . _con _f _used [ i ] )
this . _con _f _used [ i ] = 2 ;
return this . _in _header _select _filter ( t , i ) ;
} ;
dhtmlXGridObject . prototype . load _connector = dhtmlXGridObject . prototype . load ;
dhtmlXGridObject . prototype . load = function ( url , call , type ) {
if ( ! this . _colls _loaded && this . cellType ) {
var ar = [ ] ;
for ( var i = 0 ; i < this . cellType . length ; i ++ )
if ( this . cellType [ i ] . indexOf ( "co" ) == 0 || this . _con _f _used [ i ] == 2 ) ar . push ( i ) ;
if ( ar . length )
arguments [ 0 ] += ( arguments [ 0 ] . indexOf ( "?" ) != - 1 ? "&" : "?" ) + "connector=true&dhx_colls=" + ar . join ( "," ) ;
}
return this . load _connector . apply ( this , arguments ) ;
} ;
dhtmlXGridObject . prototype . _parseHead _connector = dhtmlXGridObject . prototype . _parseHead ;
dhtmlXGridObject . prototype . _parseHead = function ( url , call , type ) {
this . _parseHead _connector . apply ( this , arguments ) ;
if ( ! this . _colls _loaded ) {
var cols = this . xmlLoader . doXPath ( "./coll_options" , arguments [ 0 ] ) ;
for ( var i = 0 ; i < cols . length ; i ++ ) {
var f = cols [ i ] . getAttribute ( "for" ) ;
var v = [ ] ;
var combo = null ;
if ( this . cellType [ f ] == "combo" )
combo = this . getColumnCombo ( f ) ;
if ( this . cellType [ f ] . indexOf ( "co" ) == 0 )
combo = this . getCombo ( f ) ;
var os = this . xmlLoader . doXPath ( "./item" , cols [ i ] ) ;
for ( var j = 0 ; j < os . length ; j ++ ) {
var val = os [ j ] . getAttribute ( "value" ) ;
if ( combo ) {
var lab = os [ j ] . getAttribute ( "label" ) || val ;
if ( combo . addOption )
combo . addOption ( [ [ val , lab ] ] ) ;
else
combo . put ( val , lab ) ;
v [ v . length ] = lab ;
} else
v [ v . length ] = val ;
}
if ( this . _con _f _used [ f * 1 ] )
this . _con _f _used [ f * 1 ] = v ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
this . _colls _loaded = true ;
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
}
if ( window . dataProcessor ) {
dataProcessor . prototype . init _original = dataProcessor . prototype . init ;
dataProcessor . prototype . init = function ( obj ) {
this . init _original ( obj ) ;
obj . _dataprocessor = this ;
this . setTransactionMode ( "POST" , true ) ;
this . serverProcessor += ( this . serverProcessor . indexOf ( "?" ) != - 1 ? "&" : "?" ) + "editing=true" ;
} ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
dhtmlxError . catchError ( "LoadXML" , function ( a , b , c ) {
2011-08-03 14:09:14 +00:00
if ( c [ 0 ] . status != 0 ) {
alert ( c [ 0 ] . responseText ) ;
}
2011-04-07 16:41:06 +00:00
} ) ;
2011-08-03 14:09:14 +00:00
window . dhtmlXScheduler = window . scheduler = { version : 3.0 } ;
2011-04-07 16:41:06 +00:00
dhtmlxEventable ( scheduler ) ;
scheduler . init = function ( id , date , mode ) {
date = date || ( new Date ( ) ) ;
mode = mode || "week" ;
2011-08-03 14:09:14 +00:00
scheduler . date . init ( ) ;
2011-04-07 16:41:06 +00:00
this . _obj = ( typeof id == "string" ) ? document . getElementById ( id ) : id ;
this . _els = [ ] ;
this . _scroll = true ;
this . _quirks = ( _isIE && document . compatMode == "BackCompat" ) ;
this . _quirks7 = ( _isIE && navigator . appVersion . indexOf ( "MSIE 8" ) == - 1 ) ;
this . get _elements ( ) ;
this . init _templates ( ) ;
this . set _actions ( ) ;
dhtmlxEvent ( window , "resize" , function ( ) {
window . clearTimeout ( scheduler . _resize _timer ) ;
scheduler . _resize _timer = window . setTimeout ( function ( ) {
if ( scheduler . callEvent ( "onSchedulerResize" , [ ] ) )
scheduler . update _view ( ) ;
} , 100 ) ;
2011-08-03 14:09:14 +00:00
} ) ;
2011-04-07 16:41:06 +00:00
this . set _sizes ( ) ;
2011-08-03 14:09:14 +00:00
scheduler . callEvent ( 'onSchedulerReady' , [ ] ) ;
2011-04-07 16:41:06 +00:00
this . setCurrentView ( date , mode ) ;
} ;
scheduler . xy = {
nav _height : 22 ,
min _event _height : 40 ,
scale _width : 50 ,
bar _height : 20 ,
scroll _width : 18 ,
scale _height : 20 ,
month _scale _height : 20 ,
menu _width : 25 ,
margin _top : 0 ,
margin _left : 0 ,
editor _width : 140
} ;
scheduler . keys = {
edit _save : 13 ,
edit _cancel : 27
} ;
scheduler . set _sizes = function ( ) {
var w = this . _x = this . _obj . clientWidth - this . xy . margin _left ;
var h = this . _y = this . _obj . clientHeight - this . xy . margin _top ;
//not-table mode always has scroll - need to be fixed in future
var scale _x = this . _table _view ? 0 : ( this . xy . scale _width + this . xy . scroll _width ) ;
var scale _s = this . _table _view ? - 1 : this . xy . scale _width ;
this . set _xy ( this . _els [ "dhx_cal_navline" ] [ 0 ] , w , this . xy . nav _height , 0 , 0 ) ;
this . set _xy ( this . _els [ "dhx_cal_header" ] [ 0 ] , w - scale _x , this . xy . scale _height , scale _s , this . xy . nav _height + ( this . _quirks ? - 1 : 1 ) ) ;
//to support alter-skin, we need a way to alter height directly from css
var actual _height = this . _els [ "dhx_cal_navline" ] [ 0 ] . offsetHeight ;
if ( actual _height > 0 ) this . xy . nav _height = actual _height ;
var data _y = this . xy . scale _height + this . xy . nav _height + ( this . _quirks ? - 2 : 0 ) ;
this . set _xy ( this . _els [ "dhx_cal_data" ] [ 0 ] , w , h - ( data _y + 2 ) , 0 , data _y + 2 ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . set _xy = function ( node , w , h , x , y ) {
node . style . width = Math . max ( 0 , w ) + "px" ;
node . style . height = Math . max ( 0 , h ) + "px" ;
if ( arguments . length > 3 ) {
node . style . left = x + "px" ;
node . style . top = y + "px" ;
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . get _elements = function ( ) {
//get all child elements as named hash
var els = this . _obj . getElementsByTagName ( "DIV" ) ;
for ( var i = 0 ; i < els . length ; i ++ ) {
var name = els [ i ] . className ;
if ( ! this . _els [ name ] ) this . _els [ name ] = [ ] ;
this . _els [ name ] . push ( els [ i ] ) ;
//check if name need to be changed
var t = scheduler . locale . labels [ els [ i ] . getAttribute ( "name" ) || name ] ;
if ( t ) els [ i ] . innerHTML = t ;
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . set _actions = function ( ) {
for ( var a in this . _els )
if ( this . _click [ a ] )
for ( var i = 0 ; i < this . _els [ a ] . length ; i ++ )
this . _els [ a ] [ i ] . onclick = scheduler . _click [ a ] ;
2011-08-03 14:09:14 +00:00
this . _obj . onselectstart = function ( e ) { return false ; } ;
2011-04-07 16:41:06 +00:00
this . _obj . onmousemove = function ( e ) {
scheduler . _on _mouse _move ( e || event ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
this . _obj . onmousedown = function ( e ) {
scheduler . _on _mouse _down ( e || event ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
this . _obj . onmouseup = function ( e ) {
scheduler . _on _mouse _up ( e || event ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
this . _obj . ondblclick = function ( e ) {
scheduler . _on _dbl _click ( e || event ) ;
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . select = function ( id ) {
if ( this . _table _view || ! this . getEvent ( id ) . _timed ) return ; //temporary block
if ( this . _select _id == id ) return ;
this . editStop ( false ) ;
this . unselect ( ) ;
this . _select _id = id ;
this . updateEvent ( id ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . unselect = function ( id ) {
if ( id && id != this . _select _id ) return ;
var t = this . _select _id ;
this . _select _id = null ;
if ( t ) this . updateEvent ( t ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . getState = function ( ) {
return {
mode : this . _mode ,
date : this . _date ,
min _date : this . _min _date ,
max _date : this . _max _date ,
editor _id : this . _edit _id ,
2011-08-03 14:09:14 +00:00
lightbox _id : this . _lightbox _id ,
new _event : this . _new _event
2011-04-07 16:41:06 +00:00
} ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _click = {
dhx _cal _data : function ( e ) {
2011-08-03 14:09:14 +00:00
//debugger;
2011-04-07 16:41:06 +00:00
var trg = e ? e . target : event . srcElement ;
var id = scheduler . _locate _event ( trg ) ;
e = e || event ;
if ( ( id && ! scheduler . callEvent ( "onClick" , [ id , e ] ) ) || scheduler . config . readonly ) return ;
if ( id ) {
scheduler . select ( id ) ;
var mask = trg . className ;
if ( mask . indexOf ( "_icon" ) != - 1 )
scheduler . _click . buttons [ mask . split ( " " ) [ 1 ] . replace ( "icon_" , "" ) ] ( id ) ;
} else
scheduler . _close _not _saved ( ) ;
} ,
dhx _cal _prev _button : function ( ) {
scheduler . _click . dhx _cal _next _button ( 0 , - 1 ) ;
} ,
dhx _cal _next _button : function ( dummy , step ) {
scheduler . setCurrentView ( scheduler . date . add ( //next line changes scheduler._date , but seems it has not side-effects
scheduler . date [ scheduler . _mode + "_start" ] ( scheduler . _date ) , ( step || 1 ) , scheduler . _mode ) ) ;
} ,
dhx _cal _today _button : function ( ) {
scheduler . setCurrentView ( new Date ( ) ) ;
} ,
dhx _cal _tab : function ( ) {
2011-08-03 14:09:14 +00:00
var name = this . getAttribute ( "name" ) ;
var mode = name . substring ( 0 , name . search ( "_tab" ) ) ;
2011-04-07 16:41:06 +00:00
scheduler . setCurrentView ( scheduler . _date , mode ) ;
} ,
buttons : {
"delete" : function ( id ) { var c = scheduler . locale . labels . confirm _deleting ; if ( ! c || confirm ( c ) ) scheduler . deleteEvent ( id ) ; } ,
edit : function ( id ) { scheduler . edit ( id ) ; } ,
save : function ( id ) { scheduler . editStop ( true ) ; } ,
details : function ( id ) { scheduler . showLightbox ( id ) ; } ,
cancel : function ( id ) { scheduler . editStop ( false ) ; }
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . addEventNow = function ( start , end , e ) {
var base = { } ;
2011-08-03 14:09:14 +00:00
if ( start && start . constructor . toString ( ) . match ( /object/i ) !== null ) {
2011-04-07 16:41:06 +00:00
base = start ;
start = null ;
}
var d = ( this . config . event _duration || this . config . time _step ) * 60000 ;
if ( ! start ) start = Math . round ( ( new Date ( ) ) . valueOf ( ) / d ) * d ;
var start _date = new Date ( start ) ;
if ( ! end ) {
var start _hour = this . config . first _hour ;
if ( start _hour > start _date . getHours ( ) ) {
start _date . setHours ( start _hour ) ;
start = start _date . valueOf ( ) ;
}
end = start + d ;
}
2011-08-03 14:09:14 +00:00
var end _date = new Date ( end ) ;
// scheduler.addEventNow(new Date(), new Date()) + collision though get_visible events defect (such event was not retrieved)
if ( start _date . valueOf ( ) == end _date . valueOf ( ) )
end _date . setTime ( end _date . valueOf ( ) + d ) ;
2011-04-07 16:41:06 +00:00
base . start _date = base . start _date || start _date ;
2011-08-03 14:09:14 +00:00
base . end _date = base . end _date || end _date ;
2011-04-07 16:41:06 +00:00
base . text = base . text || this . locale . labels . new _event ;
base . id = this . _drag _id = this . uid ( ) ;
this . _drag _mode = "new-size" ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
this . _loading = true ;
this . addEvent ( base ) ;
this . callEvent ( "onEventCreated" , [ this . _drag _id , e ] ) ;
this . _loading = false ;
this . _drag _event = { } ; //dummy , to trigger correct event updating logic
this . _on _mouse _up ( e ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _on _dbl _click = function ( e , src ) {
src = src || ( e . target || e . srcElement ) ;
if ( this . config . readonly ) return ;
var name = src . className . split ( " " ) [ 0 ] ;
switch ( name ) {
case "dhx_scale_holder" :
case "dhx_scale_holder_now" :
case "dhx_month_body" :
2011-08-03 14:09:14 +00:00
case "dhx_wa_day_data" :
2011-04-07 16:41:06 +00:00
if ( ! scheduler . config . dblclick _create ) break ;
var pos = this . _mouse _coords ( e ) ;
var start = this . _min _date . valueOf ( ) + ( pos . y * this . config . time _step + ( this . _table _view ? 0 : pos . x ) * 24 * 60 ) * 60000 ;
start = this . _correct _shift ( start ) ;
this . addEventNow ( start , null , e ) ;
break ;
case "dhx_body" :
2011-08-03 14:09:14 +00:00
case "dhx_wa_ev_body" :
2011-04-07 16:41:06 +00:00
case "dhx_cal_event_line" :
case "dhx_cal_event_clear" :
var id = this . _locate _event ( src ) ;
if ( ! this . callEvent ( "onDblClick" , [ id , e ] ) ) return ;
if ( this . config . details _on _dblclick || this . _table _view || ! this . getEvent ( id ) . _timed )
this . showLightbox ( id ) ;
else
this . edit ( id ) ;
break ;
case "" :
if ( src . parentNode )
return scheduler . _on _dbl _click ( e , src . parentNode ) ;
default :
var t = this [ "dblclick_" + name ] ;
if ( t ) t . call ( this , e ) ;
break ;
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _mouse _coords = function ( ev ) {
var pos ;
var b = document . body ;
var d = document . documentElement ;
if ( ev . pageX || ev . pageY )
pos = { x : ev . pageX , y : ev . pageY } ;
else pos = {
x : ev . clientX + ( b . scrollLeft || d . scrollLeft || 0 ) - b . clientLeft ,
y : ev . clientY + ( b . scrollTop || d . scrollTop || 0 ) - b . clientTop
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
//apply layout
pos . x -= getAbsoluteLeft ( this . _obj ) + ( this . _table _view ? 0 : this . xy . scale _width ) ;
pos . y -= getAbsoluteTop ( this . _obj ) + this . xy . nav _height + ( this . _dy _shift || 0 ) + this . xy . scale _height - this . _els [ "dhx_cal_data" ] [ 0 ] . scrollTop ;
pos . ev = ev ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
var handler = this [ "mouse_" + this . _mode ] ;
if ( handler )
return handler . call ( this , pos ) ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
//transform to date
if ( ! this . _table _view ) {
pos . x = Math . max ( 0 , Math . ceil ( pos . x / this . _cols [ 0 ] ) - 1 ) ;
pos . y = Math . max ( 0 , Math . ceil ( pos . y * 60 / ( this . config . time _step * this . config . hour _size _px ) ) - 1 ) + this . config . first _hour * ( 60 / this . config . time _step ) ;
} else {
var dy = 0 ;
for ( dy = 1 ; dy < this . _colsS . heights . length ; dy ++ )
if ( this . _colsS . heights [ dy ] > pos . y ) break ;
2011-08-03 14:09:14 +00:00
pos . y = ( Math . max ( 0 , Math . ceil ( pos . x / this . _cols [ 0 ] ) - 1 ) + Math . max ( 0 , dy - 1 ) * 7 ) * 24 * 60 / this . config . time _step ;
2011-04-07 16:41:06 +00:00
pos . x = 0 ;
}
return pos ;
}
scheduler . _close _not _saved = function ( ) {
if ( new Date ( ) . valueOf ( ) - ( scheduler . _new _event || 0 ) > 500 && scheduler . _edit _id ) {
var c = scheduler . locale . labels . confirm _closing ;
if ( ! c || confirm ( c ) )
scheduler . editStop ( scheduler . config . positive _closing ) ;
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _correct _shift = function ( start , back ) {
return start -= ( ( new Date ( scheduler . _min _date ) ) . getTimezoneOffset ( ) - ( new Date ( start ) ) . getTimezoneOffset ( ) ) * 60000 * ( back ? - 1 : 1 ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _on _mouse _move = function ( e ) {
if ( this . _drag _mode ) {
var pos = this . _mouse _coords ( e ) ;
2011-08-03 14:09:14 +00:00
if ( ! this . _drag _pos || pos . custom || this . _drag _pos . x != pos . x || this . _drag _pos . y != pos . y ) {
2011-04-07 16:41:06 +00:00
if ( this . _edit _id != this . _drag _id )
this . _close _not _saved ( ) ;
this . _drag _pos = pos ;
if ( this . _drag _mode == "create" ) {
this . _close _not _saved ( ) ;
this . _loading = true ; //will be ignored by dataprocessor
var start = this . _min _date . valueOf ( ) + ( pos . y * this . config . time _step + ( this . _table _view ? 0 : pos . x ) * 24 * 60 ) * 60000 ;
//if (this._mode != "week" && this._mode != "day")
start = this . _correct _shift ( start ) ;
if ( ! this . _drag _start ) {
this . _drag _start = start ; return ;
}
var end = start ;
if ( end == this . _drag _start ) return ;
this . _drag _id = this . uid ( ) ;
this . addEvent ( new Date ( this . _drag _start ) , new Date ( end ) , this . locale . labels . new _event , this . _drag _id , pos . fields ) ;
this . callEvent ( "onEventCreated" , [ this . _drag _id , e ] ) ;
this . _loading = false ;
this . _drag _mode = "new-size" ;
}
var ev = this . getEvent ( this . _drag _id ) ;
var start , end ;
if ( this . _drag _mode == "move" ) {
start = this . _min _date . valueOf ( ) + ( pos . y * this . config . time _step + pos . x * 24 * 60 ) * 60000 ;
if ( ! pos . custom && this . _table _view ) start += this . date . time _part ( ev . start _date ) * 1000 ;
start = this . _correct _shift ( start ) ;
end = ev . end _date . valueOf ( ) - ( ev . start _date . valueOf ( ) - start ) ;
} else {
start = ev . start _date . valueOf ( ) ;
2011-08-03 14:09:14 +00:00
if ( this . _table _view ) {
2011-04-07 16:41:06 +00:00
end = this . _min _date . valueOf ( ) + pos . y * this . config . time _step * 60000 + ( pos . custom ? 0 : 24 * 60 * 60000 ) ;
2011-08-03 14:09:14 +00:00
if ( this . _mode == "month" )
end = this . _correct _shift ( end , false ) ;
}
2011-04-07 16:41:06 +00:00
else {
end = this . date . date _part ( new Date ( ev . end _date ) ) . valueOf ( ) + pos . y * this . config . time _step * 60000 ;
this . _els [ "dhx_cal_data" ] [ 0 ] . style . cursor = "s-resize" ;
if ( this . _mode == "week" || this . _mode == "day" )
end = this . _correct _shift ( end ) ;
}
if ( this . _drag _mode == "new-size" ) {
if ( end <= this . _drag _start ) {
var shift = pos . shift || ( ( this . _table _view && ! pos . custom ) ? 24 * 60 * 60000 : 0 ) ;
2011-08-03 14:09:14 +00:00
start = end - ( pos . shift ? 0 : shift ) ;
2011-04-07 16:41:06 +00:00
end = this . _drag _start + ( shift || ( this . config . time _step * 60000 ) ) ;
} else {
start = this . _drag _start ;
}
} else if ( end <= start )
end = start + this . config . time _step * 60000 ;
}
var new _end = new Date ( end - 1 ) ;
var new _start = new Date ( start ) ;
//prevent out-of-borders situation for day|week view
2011-08-03 14:09:14 +00:00
if ( this . _table _view || ( new _end . getDate ( ) == new _start . getDate ( ) && new _end . getHours ( ) < this . config . last _hour ) || ( scheduler . _wa && scheduler . _wa . _dnd ) ) {
2011-04-07 16:41:06 +00:00
ev . start _date = new _start ;
ev . end _date = new Date ( end ) ;
if ( this . config . update _render )
this . update _view ( ) ;
else
this . updateEvent ( this . _drag _id ) ;
}
if ( this . _table _view )
this . for _rendered ( this . _drag _id , function ( r ) {
r . className += " dhx_in_move" ;
} )
}
} else {
if ( scheduler . checkEvent ( "onMouseMove" ) ) {
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
var id = this . _locate _event ( e . target || e . srcElement ) ;
this . callEvent ( "onMouseMove" , [ id , e ] ) ;
}
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _on _mouse _context = function ( e , src ) {
return this . callEvent ( "onContextMenu" , [ this . _locate _event ( src ) , e ] ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _on _mouse _down = function ( e , src ) {
if ( this . config . readonly || this . _drag _mode ) return ;
src = src || ( e . target || e . srcElement ) ;
if ( e . button == 2 || e . ctrlKey ) return this . _on _mouse _context ( e , src ) ;
switch ( src . className . split ( " " ) [ 0 ] ) {
case "dhx_cal_event_line" :
case "dhx_cal_event_clear" :
if ( this . _table _view )
this . _drag _mode = "move" ; //item in table mode
break ;
case "dhx_header" :
case "dhx_title" :
2011-08-03 14:09:14 +00:00
case "dhx_wa_ev_body" :
2011-04-07 16:41:06 +00:00
this . _drag _mode = "move" ; //item in table mode
break ;
case "dhx_footer" :
this . _drag _mode = "resize" ; //item in table mode
break ;
case "dhx_scale_holder" :
case "dhx_scale_holder_now" :
case "dhx_month_body" :
case "dhx_matrix_cell" :
this . _drag _mode = "create" ;
break ;
case "" :
if ( src . parentNode )
return scheduler . _on _mouse _down ( e , src . parentNode ) ;
default :
this . _drag _mode = null ;
this . _drag _id = null ;
}
if ( this . _drag _mode ) {
var id = this . _locate _event ( src ) ;
if ( ! this . config [ "drag_" + this . _drag _mode ] || ! this . callEvent ( "onBeforeDrag" , [ id , this . _drag _mode , e ] ) )
this . _drag _mode = this . _drag _id = 0 ;
else {
this . _drag _id = id ;
2011-08-03 14:09:14 +00:00
this . _drag _event = scheduler . _lame _copy ( { } , this . _copy _event ( this . getEvent ( this . _drag _id ) || { } ) ) ;
2011-04-07 16:41:06 +00:00
}
}
this . _drag _start = null ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _on _mouse _up = function ( e ) {
if ( this . _drag _mode && this . _drag _id ) {
this . _els [ "dhx_cal_data" ] [ 0 ] . style . cursor = "default" ;
//drop
var ev = this . getEvent ( this . _drag _id ) ;
if ( this . _drag _event . _dhx _changed || ! this . _drag _event . start _date || ev . start _date . valueOf ( ) != this . _drag _event . start _date . valueOf ( ) || ev . end _date . valueOf ( ) != this . _drag _event . end _date . valueOf ( ) ) {
var is _new = ( this . _drag _mode == "new-size" ) ;
if ( ! this . callEvent ( "onBeforeEventChanged" , [ ev , e , is _new ] ) ) {
if ( is _new )
this . deleteEvent ( ev . id , true ) ;
else {
2011-08-03 14:09:14 +00:00
this . _drag _event . _dhx _changed = false ;
scheduler . _lame _copy ( ev , this . _drag _event ) ;
2011-04-07 16:41:06 +00:00
this . updateEvent ( ev . id ) ;
}
} else {
if ( is _new && this . config . edit _on _create ) {
this . unselect ( ) ;
this . _new _event = new Date ( ) ; //timestamp of creation
if ( this . _table _view || this . config . details _on _create ) {
this . _drag _mode = null ;
return this . showLightbox ( this . _drag _id ) ;
}
this . _drag _pos = true ; //set flag to trigger full redraw
this . _select _id = this . _edit _id = this . _drag _id ;
} else if ( ! this . _new _event )
this . callEvent ( is _new ? "onEventAdded" : "onEventChanged" , [ this . _drag _id , this . getEvent ( this . _drag _id ) ] ) ;
}
}
if ( this . _drag _pos ) this . render _view _data ( ) ; //redraw even if there is no real changes - necessary for correct positioning item after drag
}
this . _drag _mode = null ;
this . _drag _pos = null ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . update _view = function ( ) {
this . _reset _scale ( ) ;
if ( this . _load _mode && this . _load ( ) ) return this . _render _wait = true ;
this . render _view _data ( ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . setCurrentView = function ( date , mode ) {
2011-08-03 14:09:14 +00:00
date = date || this . _date ;
mode = mode || this . _mode ;
2011-04-07 16:41:06 +00:00
if ( ! this . callEvent ( "onBeforeViewChange" , [ this . _mode , this . _date , mode , date ] ) ) return ;
2011-08-03 14:09:14 +00:00
var dhx _cal _data = 'dhx_cal_data' ;
var prev _scroll = ( this . _mode == mode && this . config . preserve _scroll ) ? this . _els [ dhx _cal _data ] [ 0 ] . scrollTop : false ; // saving current scroll
2011-04-07 16:41:06 +00:00
//hide old custom view
if ( this [ this . _mode + "_view" ] && mode && this . _mode != mode )
this [ this . _mode + "_view" ] ( false ) ;
this . _close _not _saved ( ) ;
2011-08-03 14:09:14 +00:00
var dhx _multi _day = 'dhx_multi_day' ;
if ( this . _els [ dhx _multi _day ] ) {
this . _els [ dhx _multi _day ] [ 0 ] . parentNode . removeChild ( this . _els [ dhx _multi _day ] [ 0 ] ) ;
this . _els [ dhx _multi _day ] = null ;
}
2011-04-07 16:41:06 +00:00
2011-08-03 14:09:14 +00:00
this . _mode = mode ;
2011-04-07 16:41:06 +00:00
this . _date = date ;
this . _table _view = ( this . _mode == "month" ) ;
var tabs = this . _els [ "dhx_cal_tab" ] ;
for ( var i = 0 ; i < tabs . length ; i ++ ) {
tabs [ i ] . className = "dhx_cal_tab" + ( ( tabs [ i ] . getAttribute ( "name" ) == this . _mode + "_tab" ) ? " active" : "" ) ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
//show new view
var view = this [ this . _mode + "_view" ] ;
view ? view ( true ) : this . update _view ( ) ;
2011-08-03 14:09:14 +00:00
if ( typeof prev _scroll == "number" ) // if we are updating or working with the same view scrollTop should be saved
this . _els [ dhx _cal _data ] [ 0 ] . scrollTop = prev _scroll ; // restoring original scroll
2011-04-07 16:41:06 +00:00
this . callEvent ( "onViewChange" , [ this . _mode , this . _date ] ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _render _x _header = function ( i , left , d , h ) {
//header scale
var head = document . createElement ( "DIV" ) ; head . className = "dhx_scale_bar" ;
this . set _xy ( head , this . _cols [ i ] - 1 , this . xy . scale _height - 2 , left , 0 ) ; //-1 for border
head . innerHTML = this . templates [ this . _mode + "_scale_date" ] ( d , this . _mode ) ; //TODO - move in separate method
h . appendChild ( head ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _reset _scale = function ( ) {
//current mode doesn't support scales
//we mustn't call reset_scale for such modes, so it just to be sure
if ( ! this . templates [ this . _mode + "_date" ] ) return ;
var h = this . _els [ "dhx_cal_header" ] [ 0 ] ;
var b = this . _els [ "dhx_cal_data" ] [ 0 ] ;
var c = this . config ;
h . innerHTML = "" ;
b . scrollTop = 0 ; //fix flickering in FF
b . innerHTML = "" ;
var str = ( ( c . readonly || ( ! c . drag _resize ) ) ? " dhx_resize_denied" : "" ) + ( ( c . readonly || ( ! c . drag _move ) ) ? " dhx_move_denied" : "" ) ;
if ( str ) b . className = "dhx_cal_data" + str ;
this . _cols = [ ] ; //store for data section
this . _colsS = { height : 0 } ;
this . _dy _shift = 0 ;
this . set _sizes ( ) ;
var summ = parseInt ( h . style . width ) ; //border delta
var left = 0 ;
var d , dd , sd , today ;
dd = this . date [ this . _mode + "_start" ] ( new Date ( this . _date . valueOf ( ) ) ) ;
d = sd = this . _table _view ? scheduler . date . week _start ( dd ) : dd ;
today = this . date . date _part ( new Date ( ) ) ;
//reset date in header
var ed = scheduler . date . add ( dd , 1 , this . _mode ) ;
var count = 7 ;
if ( ! this . _table _view ) {
var count _n = this . date [ "get_" + this . _mode + "_end" ] ;
if ( count _n ) ed = count _n ( dd ) ;
count = Math . round ( ( ed . valueOf ( ) - dd . valueOf ( ) ) / ( 1000 * 60 * 60 * 24 ) ) ;
}
this . _min _date = d ;
this . _els [ "dhx_cal_date" ] [ 0 ] . innerHTML = this . templates [ this . _mode + "_date" ] ( dd , ed , this . _mode ) ;
2011-08-03 14:09:14 +00:00
for ( var i = 0 ; i < count ; i ++ ) {
2011-04-07 16:41:06 +00:00
this . _cols [ i ] = Math . floor ( summ / ( count - i ) ) ;
this . _render _x _header ( i , left , d , h ) ;
if ( ! this . _table _view ) {
var scales = document . createElement ( "DIV" ) ;
var cls = "dhx_scale_holder"
if ( d . valueOf ( ) == today . valueOf ( ) ) cls = "dhx_scale_holder_now" ;
scales . className = cls + " " + this . templates . week _date _class ( d , today ) ;
this . set _xy ( scales , this . _cols [ i ] - 1 , c . hour _size _px * ( c . last _hour - c . first _hour ) , left + this . xy . scale _width + 1 , 0 ) ; //-1 for border
b . appendChild ( scales ) ;
2011-08-03 14:09:14 +00:00
this . callEvent ( "onScaleAdd" , [ scales , d ] ) ;
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
d = this . date . add ( d , 1 , "day" ) ;
2011-04-07 16:41:06 +00:00
summ -= this . _cols [ i ] ;
left += this . _cols [ i ] ;
this . _colsS [ i ] = ( this . _cols [ i - 1 ] || 0 ) + ( this . _colsS [ i - 1 ] || ( this . _table _view ? 0 : this . xy . scale _width + 2 ) ) ;
2011-08-03 14:09:14 +00:00
this . _colsS [ 'col_length' ] = count + 1 ;
2011-04-07 16:41:06 +00:00
}
this . _max _date = d ;
this . _colsS [ count ] = this . _cols [ count - 1 ] + this . _colsS [ count - 1 ] ;
2011-08-03 14:09:14 +00:00
if ( this . _table _view ) // month view
2011-04-07 16:41:06 +00:00
this . _reset _month _scale ( b , dd , sd ) ;
else {
this . _reset _hours _scale ( b , dd , sd ) ;
if ( c . multi _day ) {
2011-08-03 14:09:14 +00:00
var dhx _multi _day = 'dhx_multi_day' ;
if ( this . _els [ dhx _multi _day ] ) {
this . _els [ dhx _multi _day ] [ 0 ] . parentNode . removeChild ( this . _els [ dhx _multi _day ] [ 0 ] ) ;
this . _els [ dhx _multi _day ] = null ;
}
var navline = this . _els [ "dhx_cal_navline" ] [ 0 ] ;
var top = navline . offsetHeight + this . _els [ "dhx_cal_header" ] [ 0 ] . offsetHeight + 1 ;
2011-04-07 16:41:06 +00:00
var c1 = document . createElement ( "DIV" ) ;
2011-08-03 14:09:14 +00:00
c1 . className = dhx _multi _day ;
2011-04-07 16:41:06 +00:00
c1 . style . visibility = "hidden" ;
2011-08-03 14:09:14 +00:00
this . set _xy ( c1 , this . _colsS [ this . _colsS . col _length - 1 ] + this . xy . scroll _width , 0 , 0 , top ) ; // 2 extra borders, dhx_header has -1 bottom margin
b . parentNode . insertBefore ( c1 , b ) ;
2011-04-07 16:41:06 +00:00
var c2 = c1 . cloneNode ( true ) ;
2011-08-03 14:09:14 +00:00
c2 . className = dhx _multi _day + "_icon" ;
2011-04-07 16:41:06 +00:00
c2 . style . visibility = "hidden" ;
2011-08-03 14:09:14 +00:00
this . set _xy ( c2 , this . xy . scale _width , 0 , 0 , top ) ; // dhx_header has -1 bottom margin
2011-04-07 16:41:06 +00:00
2011-08-03 14:09:14 +00:00
c1 . appendChild ( c2 ) ;
this . _els [ dhx _multi _day ] = [ c1 , c2 ] ;
this . _els [ dhx _multi _day ] [ 0 ] . onclick = this . _click . dhx _cal _data ;
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
if ( this . config . mark _now ) {
var now = new Date ( ) ;
if ( now < this . _max _date && now > this . _min _date && now . getHours ( ) >= this . config . first _hour && now . getHours ( ) < this . config . last _hour ) {
var day = this . locate _holder _day ( now ) ;
var sm = now . getHours ( ) * 60 + now . getMinutes ( ) ;
var now _time = document . createElement ( "DIV" ) ;
now _time . className = "dhx_now_time" ;
now _time . style . top = ( Math . round ( ( sm * 60 * 1000 - this . config . first _hour * 60 * 60 * 1000 ) * this . config . hour _size _px / ( 60 * 60 * 1000 ) ) ) % ( this . config . hour _size _px * 24 ) + 1 + "px" ;
b . childNodes [ day ] . appendChild ( now _time ) ;
}
}
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _reset _hours _scale = function ( b , dd , sd ) {
var c = document . createElement ( "DIV" ) ;
c . className = "dhx_scale_holder" ;
var date = new Date ( 1980 , 1 , 1 , this . config . first _hour , 0 , 0 ) ;
for ( var i = this . config . first _hour * 1 ; i < this . config . last _hour ; i ++ ) {
var cc = document . createElement ( "DIV" ) ;
cc . className = "dhx_scale_hour" ;
cc . style . height = this . config . hour _size _px - ( this . _quirks ? 0 : 1 ) + "px" ;
cc . style . width = this . xy . scale _width + "px" ;
cc . innerHTML = scheduler . templates . hour _scale ( date ) ;
c . appendChild ( cc ) ;
date = this . date . add ( date , 1 , "hour" ) ;
} ;
b . appendChild ( c ) ;
if ( this . config . scroll _hour )
b . scrollTop = this . config . hour _size _px * ( this . config . scroll _hour - this . config . first _hour ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _reset _month _scale = function ( b , dd , sd ) {
var ed = scheduler . date . add ( dd , 1 , "month" ) ;
//trim time part for comparation reasons
var cd = new Date ( ) ;
this . date . date _part ( cd ) ;
this . date . date _part ( sd ) ;
2011-08-03 14:09:14 +00:00
var rows = Math . ceil ( Math . round ( ( ed . valueOf ( ) - sd . valueOf ( ) ) / ( 60 * 60 * 24 * 1000 ) ) / 7 ) ;
2011-04-07 16:41:06 +00:00
var tdcss = [ ] ;
var height = ( Math . floor ( b . clientHeight / rows ) - 22 ) ;
this . _colsS . height = height + 22 ;
var h = this . _colsS . heights = [ ] ;
for ( var i = 0 ; i <= 7 ; i ++ )
tdcss [ i ] = " style='height:" + height + "px; width:" + ( ( this . _cols [ i ] || 0 ) - 1 ) + "px;' "
var cellheight = 0 ;
this . _min _date = sd ;
var html = "<table cellpadding='0' cellspacing='0'>" ;
for ( var i = 0 ; i < rows ; i ++ ) {
html += "<tr>" ;
for ( var j = 0 ; j < 7 ; j ++ ) {
html += "<td" ;
var cls = "" ;
if ( sd < dd )
cls = 'dhx_before' ;
else if ( sd >= ed )
cls = 'dhx_after' ;
else if ( sd . valueOf ( ) == cd . valueOf ( ) )
cls = 'dhx_now' ;
html += " class='" + cls + " " + this . templates . month _date _class ( sd , cd ) + "' " ;
2011-08-03 14:09:14 +00:00
html += "><div class='dhx_month_head'>" + this . templates . month _day ( sd ) + "</div><div class='dhx_month_body' " + tdcss [ j ] + "></div></td>" ;
2011-04-07 16:41:06 +00:00
sd = this . date . add ( sd , 1 , "day" ) ;
}
html += "</tr>" ;
h [ i ] = cellheight ;
cellheight += this . _colsS . height ;
}
html += "</table>" ;
this . _max _date = sd ;
b . innerHTML = html ;
return sd ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . getLabel = function ( property , key ) {
var sections = this . config . lightbox . sections ;
for ( var i = 0 ; i < sections . length ; i ++ ) {
if ( sections [ i ] . map _to == property ) {
var options = sections [ i ] . options ;
for ( var j = 0 ; j < options . length ; j ++ ) {
if ( options [ j ] . key == key ) {
return options [ j ] . label ;
}
}
}
}
return "" ;
2011-06-20 10:05:57 +00:00
} ;
2011-08-03 14:09:14 +00:00
scheduler . updateCollection = function ( list _name , collection ) {
var list = scheduler . serverList ( list _name ) ;
if ( ! list ) return false ;
list . splice ( 0 , list . length ) ;
list . push . apply ( list , collection || [ ] ) ;
scheduler . callEvent ( "onOptionsLoad" , [ ] ) ;
scheduler . resetLightbox ( ) ;
return true ;
} ;
scheduler . _lame _copy = function ( target , source ) {
for ( var key in source )
target [ key ] = source [ key ] ;
return target ;
} ;
2011-04-07 16:41:06 +00:00
scheduler . date = {
2011-08-03 14:09:14 +00:00
init : function ( ) {
var s = scheduler . locale . date . month _short ;
var t = scheduler . locale . date . month _short _hash = { } ;
for ( var i = 0 ; i < s . length ; i ++ )
t [ s [ i ] ] = i ;
var s = scheduler . locale . date . month _full ;
var t = scheduler . locale . date . month _full _hash = { } ;
for ( var i = 0 ; i < s . length ; i ++ )
t [ s [ i ] ] = i ;
} ,
2011-04-07 16:41:06 +00:00
date _part : function ( date ) {
date . setHours ( 0 ) ;
date . setMinutes ( 0 ) ;
date . setSeconds ( 0 ) ;
date . setMilliseconds ( 0 ) ;
return date ;
} ,
time _part : function ( date ) {
return ( date . valueOf ( ) / 1000 - date . getTimezoneOffset ( ) * 60 ) % 86400 ;
} ,
week _start : function ( date ) {
var shift = date . getDay ( ) ;
if ( scheduler . config . start _on _monday ) {
2011-08-03 14:09:14 +00:00
if ( shift === 0 ) shift = 6 ;
2011-04-07 16:41:06 +00:00
else shift -- ;
}
return this . date _part ( this . add ( date , - 1 * shift , "day" ) ) ;
} ,
month _start : function ( date ) {
date . setDate ( 1 ) ;
return this . date _part ( date ) ;
} ,
year _start : function ( date ) {
date . setMonth ( 0 ) ;
return this . month _start ( date ) ;
} ,
day _start : function ( date ) {
return this . date _part ( date ) ;
} ,
add : function ( date , inc , mode ) {
var ndate = new Date ( date . valueOf ( ) ) ;
switch ( mode ) {
2011-08-03 14:09:14 +00:00
case "day" :
ndate . setDate ( ndate . getDate ( ) + inc ) ;
if ( date . getDate ( ) == ndate . getDate ( ) && ! ! inc ) {
do {
ndate . setTime ( ndate . getTime ( ) + 60 * 60 * 1000 ) ;
} while ( date . getDate ( ) == ndate . getDate ( ) )
}
break ;
2011-04-07 16:41:06 +00:00
case "week" : ndate . setDate ( ndate . getDate ( ) + 7 * inc ) ; break ;
case "month" : ndate . setMonth ( ndate . getMonth ( ) + inc ) ; break ;
case "year" : ndate . setYear ( ndate . getFullYear ( ) + inc ) ; break ;
case "hour" : ndate . setHours ( ndate . getHours ( ) + inc ) ; break ;
case "minute" : ndate . setMinutes ( ndate . getMinutes ( ) + inc ) ; break ;
default :
return scheduler . date [ "add_" + mode ] ( date , inc , mode ) ;
}
return ndate ;
} ,
to _fixed : function ( num ) {
if ( num < 10 ) return "0" + num ;
return num ;
} ,
copy : function ( date ) {
return new Date ( date . valueOf ( ) ) ;
} ,
date _to _str : function ( format , utc ) {
format = format . replace ( /%[a-zA-Z]/g , function ( a ) {
switch ( a ) {
case "%d" : return "\"+scheduler.date.to_fixed(date.getDate())+\"" ;
case "%m" : return "\"+scheduler.date.to_fixed((date.getMonth()+1))+\"" ;
case "%j" : return "\"+date.getDate()+\"" ;
case "%n" : return "\"+(date.getMonth()+1)+\"" ;
case "%y" : return "\"+scheduler.date.to_fixed(date.getFullYear()%100)+\"" ;
case "%Y" : return "\"+date.getFullYear()+\"" ;
case "%D" : return "\"+scheduler.locale.date.day_short[date.getDay()]+\"" ;
case "%l" : return "\"+scheduler.locale.date.day_full[date.getDay()]+\"" ;
case "%M" : return "\"+scheduler.locale.date.month_short[date.getMonth()]+\"" ;
case "%F" : return "\"+scheduler.locale.date.month_full[date.getMonth()]+\"" ;
case "%h" : return "\"+scheduler.date.to_fixed((date.getHours()+11)%12+1)+\"" ;
case "%g" : return "\"+((date.getHours()+11)%12+1)+\"" ;
case "%G" : return "\"+date.getHours()+\"" ;
case "%H" : return "\"+scheduler.date.to_fixed(date.getHours())+\"" ;
case "%i" : return "\"+scheduler.date.to_fixed(date.getMinutes())+\"" ;
case "%a" : return "\"+(date.getHours()>11?\"pm\":\"am\")+\"" ;
case "%A" : return "\"+(date.getHours()>11?\"PM\":\"AM\")+\"" ;
case "%s" : return "\"+scheduler.date.to_fixed(date.getSeconds())+\"" ;
case "%W" : return "\"+scheduler.date.to_fixed(scheduler.date.getISOWeek(date))+\"" ;
default : return a ;
}
2011-08-03 14:09:14 +00:00
} ) ;
2011-04-07 16:41:06 +00:00
if ( utc ) format = format . replace ( /date\.get/g , "date.getUTC" ) ;
return new Function ( "date" , "return \"" + format + "\";" ) ;
} ,
str _to _date : function ( format , utc ) {
var splt = "var temp=date.split(/[^0-9a-zA-Z]+/g);" ;
var mask = format . match ( /%[a-zA-Z]/g ) ;
for ( var i = 0 ; i < mask . length ; i ++ ) {
switch ( mask [ i ] ) {
case "%j" :
case "%d" : splt += "set[2]=temp[" + i + "]||1;" ;
break ;
case "%n" :
case "%m" : splt += "set[1]=(temp[" + i + "]||1)-1;" ;
break ;
case "%y" : splt += "set[0]=temp[" + i + "]*1+(temp[" + i + "]>50?1900:2000);" ;
break ;
case "%g" :
case "%G" :
case "%h" :
case "%H" :
splt += "set[3]=temp[" + i + "]||0;" ;
break ;
case "%i" :
splt += "set[4]=temp[" + i + "]||0;" ;
break ;
case "%Y" : splt += "set[0]=temp[" + i + "]||0;" ;
break ;
case "%a" :
case "%A" : splt += "set[3]=set[3]%12+((temp[" + i + "]||'').toLowerCase()=='am'?0:12);" ;
break ;
case "%s" : splt += "set[5]=temp[" + i + "]||0;" ;
break ;
2011-08-03 14:09:14 +00:00
case "%M" : splt += "set[1]=scheduler.locale.date.month_short_hash[temp[" + i + "]]||0;" ;
break ;
case "%F" : splt += "set[1]=scheduler.locale.date.month_full_hash[temp[" + i + "]]||0;" ;
break ;
default :
break ;
2011-04-07 16:41:06 +00:00
}
}
var code = "set[0],set[1],set[2],set[3],set[4],set[5]" ;
if ( utc ) code = " Date.UTC(" + code + ")" ;
return new Function ( "date" , "var set=[0,0,1,0,0,0]; " + splt + " return new Date(" + code + ");" ) ;
} ,
getISOWeek : function ( ndate ) {
if ( ! ndate ) return false ;
var nday = ndate . getDay ( ) ;
2011-08-03 14:09:14 +00:00
if ( nday === 0 ) {
2011-04-07 16:41:06 +00:00
nday = 7 ;
}
var first _thursday = new Date ( ndate . valueOf ( ) ) ;
first _thursday . setDate ( ndate . getDate ( ) + ( 4 - nday ) ) ;
var year _number = first _thursday . getFullYear ( ) ; // year of the first Thursday
2011-08-03 14:09:14 +00:00
var ordinal _date = Math . round ( ( first _thursday . getTime ( ) - new Date ( year _number , 0 , 1 ) . getTime ( ) ) / 86400000 ) ; //ordinal date of the first Thursday - 1 (so not really ordinal date)
2011-04-07 16:41:06 +00:00
var week _number = 1 + Math . floor ( ordinal _date / 7 ) ;
return week _number ;
} ,
getUTCISOWeek : function ( ndate ) {
2011-08-03 14:09:14 +00:00
return this . getISOWeek ( ndate ) ;
}
} ;
2011-04-07 16:41:06 +00:00
scheduler . locale = {
date : {
month _full : [ "January" , "February" , "March" , "April" , "May" , "June" , "July" , "August" , "September" , "October" , "November" , "December" ] ,
month _short : [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ] ,
day _full : [ "Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" ] ,
day _short : [ "Sun" , "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ]
} ,
labels : {
dhx _cal _today _button : "Today" ,
day _tab : "Day" ,
week _tab : "Week" ,
month _tab : "Month" ,
new _event : "New event" ,
icon _save : "Save" ,
icon _cancel : "Cancel" ,
icon _details : "Details" ,
icon _edit : "Edit" ,
icon _delete : "Delete" ,
confirm _closing : "" , //Your changes will be lost, are your sure ?
confirm _deleting : "Event will be deleted permanently, are you sure?" ,
section _description : "Description" ,
section _time : "Time period" ,
full _day : "Full day" ,
/*recurring events*/
confirm _recurring : "Do you want to edit the whole set of repeated events?" ,
section _recurring : "Repeat event" ,
button _recurring : "Disabled" ,
button _recurring _open : "Enabled" ,
/*agenda view extension*/
agenda _tab : "Agenda" ,
date : "Date" ,
description : "Description" ,
/*year view extension*/
2011-08-03 14:09:14 +00:00
year _tab : "Year" ,
2011-04-07 16:41:06 +00:00
2011-08-03 14:09:14 +00:00
/* week agenda extension */
week _agenda _tab : "Agenda"
}
} ;
2011-06-20 10:05:57 +00:00
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
/ *
% e Day of the month without leading zeros ( 01. . 31 )
% d Day of the month , 2 digits with leading zeros ( 01. . 31 )
% j Day of the year , 3 digits with leading zeros ( 001. . 366 )
% a A textual representation of a day , two letters
% W A full textual representation of the day of the week
% c Numeric representation of a month , without leading zeros ( 0. . 12 )
% m Numeric representation of a month , with leading zeros ( 00. . 12 )
% b A short textual representation of a month , three letters ( Jan . . Dec )
% M A full textual representation of a month , such as January or March ( January . . December )
% y A two digit representation of a year ( 93. . 03 )
% Y A full numeric representation of a year , 4 digits ( 1993. . 03 )
* /
scheduler . config = {
default _date : "%j %M %Y" ,
month _date : "%F %Y" ,
load _date : "%Y-%m-%d" ,
week _date : "%l" ,
day _date : "%D, %F %j" ,
hour _date : "%H:%i" ,
month _day : "%d" ,
xml _date : "%m/%d/%Y %H:%i" ,
api _date : "%d-%m-%Y %H:%i" ,
hour _size _px : 42 ,
time _step : 5 ,
start _on _monday : 1 ,
first _hour : 0 ,
last _hour : 24 ,
readonly : false ,
drag _resize : 1 ,
drag _move : 1 ,
drag _create : 1 ,
dblclick _create : 1 ,
edit _on _create : 1 ,
details _on _create : 0 ,
click _form _details : 0 ,
2011-08-03 14:09:14 +00:00
cascade _event _display : false ,
cascade _event _count : 4 ,
cascade _event _margin : 30 ,
drag _lightbox : true ,
preserve _scroll : true ,
2011-04-07 16:41:06 +00:00
server _utc : false ,
positive _closing : false ,
icons _edit : [ "icon_save" , "icon_cancel" ] ,
icons _select : [ "icon_details" , "icon_edit" , "icon_delete" ] ,
2011-08-03 14:09:14 +00:00
buttons _left : [ "dhx_save_btn" , "dhx_cancel_btn" ] ,
buttons _right : [ "dhx_delete_btn" ] ,
2011-04-07 16:41:06 +00:00
lightbox : {
sections : [ { name : "description" , height : 200 , map _to : "text" , type : "textarea" , focus : true } ,
{ name : "time" , height : 72 , type : "time" , map _to : "auto" } ]
2011-08-03 14:09:14 +00:00
} ,
repeat _date _of _end : "01.01.2010"
2011-04-07 16:41:06 +00:00
} ;
2011-08-03 14:09:14 +00:00
scheduler . templates = { } ;
2011-04-07 16:41:06 +00:00
scheduler . init _templates = function ( ) {
var d = scheduler . date . date _to _str ;
var c = scheduler . config ;
var f = function ( a , b ) {
for ( var c in b )
if ( ! a [ c ] ) a [ c ] = b [ c ] ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
f ( scheduler . templates , {
day _date : d ( c . default _date ) ,
month _date : d ( c . month _date ) ,
week _date : function ( d1 , d2 ) {
return scheduler . templates . day _date ( d1 ) + " – " + scheduler . templates . day _date ( scheduler . date . add ( d2 , - 1 , "day" ) ) ;
} ,
day _scale _date : d ( c . default _date ) ,
month _scale _date : d ( c . week _date ) ,
week _scale _date : d ( c . day _date ) ,
hour _scale : d ( c . hour _date ) ,
time _picker : d ( c . hour _date ) ,
event _date : d ( c . hour _date ) ,
month _day : d ( c . month _day ) ,
xml _date : scheduler . date . str _to _date ( c . xml _date , c . server _utc ) ,
load _format : d ( c . load _date , c . server _utc ) ,
xml _format : d ( c . xml _date , c . server _utc ) ,
api _date : scheduler . date . str _to _date ( c . api _date ) ,
event _header : function ( start , end , ev ) {
return scheduler . templates . event _date ( start ) + " - " + scheduler . templates . event _date ( end ) ;
} ,
event _text : function ( start , end , ev ) {
return ev . text ;
} ,
event _class : function ( start , end , ev ) {
return "" ;
} ,
month _date _class : function ( d ) {
return "" ;
} ,
week _date _class : function ( d ) {
return "" ;
} ,
event _bar _date : function ( start , end , ev ) {
return scheduler . templates . event _date ( start ) + " " ;
} ,
event _bar _text : function ( start , end , ev ) {
return ev . text ;
}
} ) ;
2011-08-03 14:09:14 +00:00
this . callEvent ( "onTemplatesReady" , [ ] ) ;
} ;
2011-04-07 16:41:06 +00:00
2011-06-20 10:05:57 +00:00
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
scheduler . uid = function ( ) {
if ( ! this . _seed ) this . _seed = ( new Date ) . valueOf ( ) ;
return this . _seed ++ ;
} ;
scheduler . _events = { } ;
scheduler . clearAll = function ( ) {
this . _events = { } ;
this . _loaded = { } ;
this . clear _view ( ) ;
} ;
scheduler . addEvent = function ( start _date , end _date , text , id , extra _data ) {
2011-08-03 14:09:14 +00:00
if ( ! arguments . length )
return this . addEventNow ( ) ;
2011-04-07 16:41:06 +00:00
var ev = start _date ;
if ( arguments . length != 1 ) {
ev = extra _data || { } ;
ev . start _date = start _date ;
ev . end _date = end _date ;
ev . text = text ;
ev . id = id ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
ev . id = ev . id || scheduler . uid ( ) ;
ev . text = ev . text || "" ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
if ( typeof ev . start _date == "string" ) ev . start _date = this . templates . api _date ( ev . start _date ) ;
if ( typeof ev . end _date == "string" ) ev . end _date = this . templates . api _date ( ev . end _date ) ;
2011-08-03 14:09:14 +00:00
var d = ( this . config . event _duration || this . config . time _step ) * 60000 ;
if ( ev . start _date . valueOf ( ) == ev . end _date . valueOf ( ) )
ev . end _date . setTime ( ev . end _date . valueOf ( ) + d ) ;
2011-04-07 16:41:06 +00:00
ev . _timed = this . is _one _day _event ( ev ) ;
var is _new = ! this . _events [ ev . id ] ;
this . _events [ ev . id ] = ev ;
this . event _updated ( ev ) ;
if ( ! this . _loading )
this . callEvent ( is _new ? "onEventAdded" : "onEventChanged" , [ ev . id , ev ] ) ;
} ;
2011-08-03 14:09:14 +00:00
scheduler . deleteEvent = function ( id , silent ) {
2011-04-07 16:41:06 +00:00
var ev = this . _events [ id ] ;
2011-08-03 14:09:14 +00:00
if ( ! silent && ( ! this . callEvent ( "onBeforeEventDelete" , [ id , ev ] ) || ! this . callEvent ( "onConfirmedBeforeEventDelete" , [ id , ev ] ) ) )
return ;
2011-04-07 16:41:06 +00:00
if ( ev ) {
delete this . _events [ id ] ;
this . unselect ( id ) ;
this . event _updated ( ev ) ;
}
2011-08-03 14:09:14 +00:00
this . callEvent ( "onEventDeleted" , [ id ] ) ;
2011-04-07 16:41:06 +00:00
} ;
scheduler . getEvent = function ( id ) {
return this . _events [ id ] ;
} ;
scheduler . setEvent = function ( id , hash ) {
this . _events [ id ] = hash ;
} ;
scheduler . for _rendered = function ( id , method ) {
for ( var i = this . _rendered . length - 1 ; i >= 0 ; i -- )
if ( this . _rendered [ i ] . getAttribute ( "event_id" ) == id )
method ( this . _rendered [ i ] , i ) ;
} ;
scheduler . changeEventId = function ( id , new _id ) {
if ( id == new _id ) return ;
var ev = this . _events [ id ] ;
if ( ev ) {
ev . id = new _id ;
this . _events [ new _id ] = ev ;
delete this . _events [ id ] ;
}
this . for _rendered ( id , function ( r ) {
r . setAttribute ( "event_id" , new _id ) ;
} ) ;
if ( this . _select _id == id ) this . _select _id = new _id ;
if ( this . _edit _id == id ) this . _edit _id = new _id ;
2011-08-03 14:09:14 +00:00
//if (this._drag_id==id) this._drag_id=new_id;
2011-04-07 16:41:06 +00:00
this . callEvent ( "onEventIdChange" , [ id , new _id ] ) ;
} ;
( function ( ) {
var attrs = [ "text" , "Text" , "start_date" , "StartDate" , "end_date" , "EndDate" ] ;
var create _getter = function ( name ) {
return function ( id ) { return ( scheduler . getEvent ( id ) ) [ name ] ; } ;
} ;
var create _setter = function ( name ) {
return function ( id , value ) {
var ev = scheduler . getEvent ( id ) ; ev [ name ] = value ;
ev . _changed = true ;
ev . _timed = this . is _one _day _event ( ev ) ;
scheduler . event _updated ( ev , true ) ;
} ;
} ;
for ( var i = 0 ; i < attrs . length ; i += 2 ) {
scheduler [ "getEvent" + attrs [ i + 1 ] ] = create _getter ( attrs [ i ] ) ;
scheduler [ "setEvent" + attrs [ i + 1 ] ] = create _setter ( attrs [ i ] ) ;
}
} ) ( ) ;
scheduler . event _updated = function ( ev , force ) {
if ( this . is _visible _events ( ev ) )
this . render _view _data ( ) ;
else this . clear _event ( ev . id ) ;
} ;
scheduler . is _visible _events = function ( ev ) {
2011-08-03 14:09:14 +00:00
return ( ev . start _date < this . _max _date && this . _min _date < ev . end _date ) ;
2011-04-07 16:41:06 +00:00
} ;
scheduler . is _one _day _event = function ( ev ) {
var delta = ev . end _date . getDate ( ) - ev . start _date . getDate ( ) ;
if ( ! delta )
return ev . start _date . getMonth ( ) == ev . end _date . getMonth ( ) && ev . start _date . getFullYear ( ) == ev . end _date . getFullYear ( ) ;
else {
if ( delta < 0 ) delta = Math . ceil ( ( ev . end _date . valueOf ( ) - ev . start _date . valueOf ( ) ) / ( 24 * 60 * 60 * 1000 ) ) ;
return ( delta == 1 && ! ev . end _date . getHours ( ) && ! ev . end _date . getMinutes ( ) && ( ev . start _date . getHours ( ) || ev . start _date . getMinutes ( ) ) ) ;
}
} ;
scheduler . get _visible _events = function ( ) {
//not the best strategy for sure
var stack = [ ] ;
var filter = this [ "filter_" + this . _mode ] ;
for ( var id in this . _events )
if ( this . is _visible _events ( this . _events [ id ] ) )
if ( this . _table _view || this . config . multi _day || this . _events [ id ] . _timed )
if ( ! filter || filter ( id , this . _events [ id ] ) )
stack . push ( this . _events [ id ] ) ;
return stack ;
} ;
2011-08-03 14:09:14 +00:00
scheduler . render _view _data = function ( evs , hold ) {
if ( ! evs ) {
if ( this . _not _render ) {
this . _render _wait = true ;
return ;
}
this . _render _wait = false ;
this . clear _view ( ) ;
evs = this . get _visible _events ( ) ;
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
if ( this . config . multi _day && ! this . _table _view ) {
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
var tvs = [ ] ;
var tvd = [ ] ;
for ( var i = 0 ; i < evs . length ; i ++ ) {
if ( evs [ i ] . _timed )
tvs . push ( evs [ i ] ) ;
else
tvd . push ( evs [ i ] ) ;
2011-08-03 14:09:14 +00:00
}
// multiday events
this . _rendered _location = this . _els [ 'dhx_multi_day' ] [ 0 ] ;
2011-04-07 16:41:06 +00:00
this . _table _view = true ;
2011-08-03 14:09:14 +00:00
this . render _data ( tvd , hold ) ;
this . _table _view = false ;
// normal events
this . _rendered _location = this . _els [ 'dhx_cal_data' ] [ 0 ] ;
this . _table _view = false ;
this . render _data ( tvs , hold ) ;
} else {
this . _rendered _location = this . _els [ 'dhx_cal_data' ] [ 0 ] ;
this . render _data ( evs , hold ) ;
}
2011-04-07 16:41:06 +00:00
} ;
scheduler . render _data = function ( evs , hold ) {
evs = this . _pre _render _events ( evs , hold ) ;
2011-08-03 14:09:14 +00:00
for ( var i = 0 ; i < evs . length ; i ++ )
2011-04-07 16:41:06 +00:00
if ( this . _table _view )
this . render _event _bar ( evs [ i ] ) ;
else
this . render _event ( evs [ i ] ) ;
} ;
scheduler . _pre _render _events = function ( evs , hold ) {
var hb = this . xy . bar _height ;
2011-08-03 14:09:14 +00:00
var h _old = this . _colsS . heights ;
2011-04-07 16:41:06 +00:00
var h = this . _colsS . heights = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
2011-08-03 14:09:14 +00:00
var data = this . _els [ "dhx_cal_data" ] [ 0 ] ;
2011-04-07 16:41:06 +00:00
if ( ! this . _table _view ) evs = this . _pre _render _events _line ( evs , hold ) ; //ignore long events for now
else evs = this . _pre _render _events _table ( evs , hold ) ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
if ( this . _table _view ) {
if ( hold )
this . _colsS . heights = h _old ;
else {
2011-08-03 14:09:14 +00:00
var evl = data . firstChild ;
2011-04-07 16:41:06 +00:00
if ( evl . rows ) {
for ( var i = 0 ; i < evl . rows . length ; i ++ ) {
h [ i ] ++ ;
if ( ( h [ i ] ) * hb > this . _colsS . height - 22 ) { // 22 - height of cell's header
//we have overflow, update heights
var cells = evl . rows [ i ] . cells ;
for ( var j = 0 ; j < cells . length ; j ++ ) {
cells [ j ] . childNodes [ 1 ] . style . height = h [ i ] * hb + "px" ;
}
h [ i ] = ( h [ i - 1 ] || 0 ) + cells [ 0 ] . offsetHeight ;
}
h [ i ] = ( h [ i - 1 ] || 0 ) + evl . rows [ i ] . cells [ 0 ] . offsetHeight ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
h . unshift ( 0 ) ;
if ( evl . parentNode . offsetHeight < evl . parentNode . scrollHeight && ! evl . _h _fix ) {
//we have v-scroll, decrease last day cell
for ( var i = 0 ; i < evl . rows . length ; i ++ ) {
var cell = evl . rows [ i ] . cells [ 6 ] . childNodes [ 0 ] ;
var w = cell . offsetWidth - scheduler . xy . scroll _width + "px" ;
cell . style . width = w ;
cell . nextSibling . style . width = w ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
evl . _h _fix = true ;
}
} else {
if ( ! evs . length && this . _els [ "dhx_multi_day" ] [ 0 ] . style . visibility == "visible" )
h [ 0 ] = - 1 ;
if ( evs . length || h [ 0 ] == - 1 ) {
//shift days to have space for multiday events
var childs = evl . parentNode . childNodes ;
2011-08-03 14:09:14 +00:00
var dh = ( ( h [ 0 ] + 1 ) * hb + 1 ) + "px" ; // +1 so multiday events would have 2px from top and 2px from bottom by default
data . style . top = ( this . _els [ "dhx_cal_navline" ] [ 0 ] . offsetHeight + this . _els [ "dhx_cal_header" ] [ 0 ] . offsetHeight + parseInt ( dh ) ) + 'px' ;
data . style . height = ( this . _obj . offsetHeight - parseInt ( data . style . top ) - ( this . xy . margin _top || 0 ) ) + 'px' ;
2011-04-07 16:41:06 +00:00
var last = this . _els [ "dhx_multi_day" ] [ 0 ] ;
last . style . height = dh ;
last . style . visibility = ( h [ 0 ] == - 1 ? "hidden" : "visible" ) ;
last = this . _els [ "dhx_multi_day" ] [ 1 ] ;
last . style . height = dh ;
last . style . visibility = ( h [ 0 ] == - 1 ? "hidden" : "visible" ) ;
last . className = h [ 0 ] ? "dhx_multi_day_icon" : "dhx_multi_day_icon_small" ;
this . _dy _shift = ( h [ 0 ] + 1 ) * hb ;
h [ 0 ] = 0 ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
}
}
}
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
return evs ;
} ;
scheduler . _get _event _sday = function ( ev ) {
return Math . floor ( ( ev . start _date . valueOf ( ) - this . _min _date . valueOf ( ) ) / ( 24 * 60 * 60 * 1000 ) ) ;
} ;
scheduler . _pre _render _events _line = function ( evs , hold ) {
2011-08-03 14:09:14 +00:00
evs . sort ( function ( a , b ) {
if ( a . start _date . valueOf ( ) == b . start _date . valueOf ( ) )
return a . id > b . id ? 1 : - 1 ;
return a . start _date > b . start _date ? 1 : - 1 ;
} ) ;
2011-04-07 16:41:06 +00:00
var days = [ ] ; //events by weeks
var evs _originals = [ ] ;
for ( var i = 0 ; i < evs . length ; i ++ ) {
var ev = evs [ i ] ;
//check scale overflow
var sh = ev . start _date . getHours ( ) ;
var eh = ev . end _date . getHours ( ) ;
ev . _sday = this . _get _event _sday ( ev ) ;
if ( ! days [ ev . _sday ] ) days [ ev . _sday ] = [ ] ;
if ( ! hold ) {
ev . _inner = false ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
var stack = days [ ev . _sday ] ;
while ( stack . length && stack [ stack . length - 1 ] . end _date <= ev . start _date )
stack . splice ( stack . length - 1 , 1 ) ;
2011-08-03 14:09:14 +00:00
var sorderSet = false ;
for ( var j = 0 ; j < stack . length ; j ++ ) {
if ( stack [ j ] . end _date . valueOf ( ) < ev . start _date . valueOf ( ) ) {
sorderSet = true ;
ev . _sorder = stack [ j ] . _sorder ;
stack . splice ( j , 1 ) ;
ev . _inner = true ;
break ;
}
}
if ( stack . length )
stack [ stack . length - 1 ] . _inner = true ;
if ( ! sorderSet ) {
if ( stack . length ) {
if ( stack . length <= stack [ stack . length - 1 ] . _sorder ) {
if ( ! stack [ stack . length - 1 ] . _sorder )
ev . _sorder = 0 ;
else
for ( j = 0 ; j < stack . length ; j ++ ) {
var _is _sorder = false ;
for ( k = 0 ; k < stack . length ; k ++ ) {
if ( stack [ k ] . _sorder == j ) {
_is _sorder = true ;
break ;
}
}
if ( ! _is _sorder ) {
ev . _sorder = j ;
break ;
}
}
ev . _inner = true ;
}
else {
var _max _sorder = stack [ 0 ] . _sorder ;
for ( j = 1 ; j < stack . length ; j ++ )
if ( stack [ j ] . _sorder > _max _sorder )
_max _sorder = stack [ j ] . _sorder ;
ev . _sorder = _max _sorder + 1 ;
ev . _inner = false ;
}
}
else
ev . _sorder = 0 ;
}
stack . push ( ev ) ;
if ( stack . length > ( stack . max _count || 0 ) ) {
stack . max _count = stack . length ;
ev . _count = stack . length ;
}
else {
ev . _count = ( ev . _count ) ? ev . _count : 1 ;
}
2011-04-07 16:41:06 +00:00
}
if ( sh < this . config . first _hour || eh >= this . config . last _hour ) {
evs _originals . push ( ev ) ;
evs [ i ] = ev = this . _copy _event ( ev ) ;
if ( sh < this . config . first _hour ) {
ev . start _date . setHours ( this . config . first _hour ) ;
ev . start _date . setMinutes ( 0 ) ;
}
if ( eh >= this . config . last _hour ) {
ev . end _date . setMinutes ( 0 ) ;
ev . end _date . setHours ( this . config . last _hour ) ;
}
if ( ev . start _date > ev . end _date || sh == this . config . last _hour ) {
evs . splice ( i , 1 ) ; i -- ; continue ;
}
}
}
if ( ! hold ) {
2011-08-03 14:09:14 +00:00
for ( var i = 0 ; i < evs . length ; i ++ ) {
evs [ i ] . _count = days [ evs [ i ] . _sday ] . max _count ;
}
for ( var i = 0 ; i < evs _originals . length ; i ++ )
2011-04-07 16:41:06 +00:00
evs _originals [ i ] . _count = days [ evs _originals [ i ] . _sday ] . max _count ;
}
return evs ;
} ;
scheduler . _time _order = function ( evs ) {
2011-08-03 14:09:14 +00:00
evs . sort ( function ( a , b ) {
2011-04-07 16:41:06 +00:00
if ( a . start _date . valueOf ( ) == b . start _date . valueOf ( ) ) {
if ( a . _timed && ! b . _timed ) return 1 ;
if ( ! a . _timed && b . _timed ) return - 1 ;
2011-08-03 14:09:14 +00:00
return a . id > b . id ? 1 : - 1 ;
2011-04-07 16:41:06 +00:00
}
return a . start _date > b . start _date ? 1 : - 1 ;
} ) ;
} ;
scheduler . _pre _render _events _table = function ( evs , hold ) { // max - max height of week slot
this . _time _order ( evs ) ;
var out = [ ] ;
var weeks = [ [ ] , [ ] , [ ] , [ ] , [ ] , [ ] , [ ] ] ; //events by weeks
var max = this . _colsS . heights ;
var start _date ;
var cols = this . _cols . length ;
for ( var i = 0 ; i < evs . length ; i ++ ) {
var ev = evs [ i ] ;
var sd = ( start _date || ev . start _date ) ;
var ed = ev . end _date ;
//trim events which are crossing through current view
if ( sd < this . _min _date ) sd = this . _min _date ;
if ( ed > this . _max _date ) ed = this . _max _date ;
var locate _s = this . locate _holder _day ( sd , false , ev ) ;
ev . _sday = locate _s % cols ;
var locate _e = this . locate _holder _day ( ed , true , ev ) || cols ;
ev . _eday = ( locate _e % cols ) || cols ; //cols used to fill full week, when event end on monday
ev . _length = locate _e - locate _s ;
//3600000 - compensate 1 hour during winter|summer time shift
ev . _sweek = Math . floor ( ( this . _correct _shift ( sd . valueOf ( ) , 1 ) - this . _min _date . valueOf ( ) ) / ( 60 * 60 * 1000 * 24 * cols ) ) ;
//current slot
var stack = weeks [ ev . _sweek ] ;
//check order position
var stack _line ;
for ( stack _line = 0 ; stack _line < stack . length ; stack _line ++ )
if ( stack [ stack _line ] . _eday <= ev . _sday )
break ;
2011-08-03 14:09:14 +00:00
if ( ! ev . _sorder || ! hold ) {
ev . _sorder = stack _line ;
}
2011-04-07 16:41:06 +00:00
if ( ev . _sday + ev . _length <= cols ) {
start _date = null ;
out . push ( ev ) ;
stack [ stack _line ] = ev ;
//get max height of slot
max [ ev . _sweek ] = stack . length - 1 ;
} else { // split long event in chunks
var copy = this . _copy _event ( ev ) ;
copy . _length = cols - ev . _sday ;
copy . _eday = cols ; copy . _sday = ev . _sday ;
copy . _sweek = ev . _sweek ; copy . _sorder = ev . _sorder ;
copy . end _date = this . date . add ( sd , copy . _length , "day" ) ;
out . push ( copy ) ;
stack [ stack _line ] = copy ;
start _date = copy . end _date ;
//get max height of slot
max [ ev . _sweek ] = stack . length - 1 ;
i -- ; continue ; //repeat same step
}
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
return out ;
} ;
scheduler . _copy _dummy = function ( ) {
this . start _date = new Date ( this . start _date ) ;
this . end _date = new Date ( this . end _date ) ;
} ;
scheduler . _copy _event = function ( ev ) {
this . _copy _dummy . prototype = ev ;
return new this . _copy _dummy ( ) ;
//return {start_date:ev.start_date, end_date:ev.end_date, text:ev.text, id:ev.id}
} ;
scheduler . _rendered = [ ] ;
scheduler . clear _view = function ( ) {
for ( var i = 0 ; i < this . _rendered . length ; i ++ ) {
var obj = this . _rendered [ i ] ;
if ( obj . parentNode ) obj . parentNode . removeChild ( obj ) ;
}
this . _rendered = [ ] ;
} ;
scheduler . updateEvent = function ( id ) {
var ev = this . getEvent ( id ) ;
this . clear _event ( id ) ;
2011-08-03 14:09:14 +00:00
if ( ev && this . is _visible _events ( ev ) )
this . render _view _data ( [ ev ] , true ) ;
2011-04-07 16:41:06 +00:00
} ;
scheduler . clear _event = function ( id ) {
this . for _rendered ( id , function ( node , i ) {
if ( node . parentNode )
node . parentNode . removeChild ( node ) ;
scheduler . _rendered . splice ( i , 1 ) ;
} ) ;
} ;
scheduler . render _event = function ( ev ) {
var menu = scheduler . xy . menu _width ;
if ( ev . _sday < 0 ) return ; //can occur in case of recurring event during time shift
var parent = scheduler . locate _holder ( ev . _sday ) ;
if ( ! parent ) return ; //attempt to render non-visible event
var sm = ev . start _date . getHours ( ) * 60 + ev . start _date . getMinutes ( ) ;
var em = ( ev . end _date . getHours ( ) * 60 + ev . end _date . getMinutes ( ) ) || ( scheduler . config . last _hour * 60 ) ;
var top = ( Math . round ( ( sm * 60 * 1000 - this . config . first _hour * 60 * 60 * 1000 ) * this . config . hour _size _px / ( 60 * 60 * 1000 ) ) ) % ( this . config . hour _size _px * 24 ) + 1 ; //42px/hour
var height = Math . max ( scheduler . xy . min _event _height , ( em - sm ) * this . config . hour _size _px / 60 ) + 1 ; //42px/hour
//var height = Math.max(25,Math.round((ev.end_date.valueOf()-ev.start_date.valueOf())*(this.config.hour_size_px+(this._quirks?1:0))/(60*60*1000))); //42px/hour
var width = Math . floor ( ( parent . clientWidth - menu ) / ev . _count ) ;
var left = ev . _sorder * width + 1 ;
if ( ! ev . _inner ) width = width * ( ev . _count - ev . _sorder ) ;
2011-08-03 14:09:14 +00:00
if ( this . config . cascade _event _display ) {
var limit = this . config . cascade _event _count ;
var margin = this . config . cascade _event _margin ;
left = ev . _sorder % limit * margin ;
var right = ( ev . _inner ) ? ( ev . _count - ev . _sorder - 1 ) % limit * margin / 2 : 0 ;
width = Math . floor ( parent . clientWidth - menu - left - right ) ;
}
2011-04-07 16:41:06 +00:00
var d = this . _render _v _bar ( ev . id , menu + left , top , width , height , ev . _text _style , scheduler . templates . event _header ( ev . start _date , ev . end _date , ev ) , scheduler . templates . event _text ( ev . start _date , ev . end _date , ev ) ) ;
this . _rendered . push ( d ) ;
parent . appendChild ( d ) ;
left = left + parseInt ( parent . style . left , 10 ) + menu ;
if ( this . _edit _id == ev . id ) {
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
d . style . zIndex = 1 ; //fix overlapping issue
width = Math . max ( width - 4 , scheduler . xy . editor _width ) ;
2011-08-03 14:09:14 +00:00
d = document . createElement ( "DIV" ) ;
2011-04-07 16:41:06 +00:00
d . setAttribute ( "event_id" , ev . id ) ;
this . set _xy ( d , width , height - 20 , left , top + 14 ) ;
d . className = "dhx_cal_editor" ;
var d2 = document . createElement ( "DIV" ) ;
this . set _xy ( d2 , width - 6 , height - 26 ) ;
d2 . style . cssText += ";margin:2px 2px 2px 2px;overflow:hidden;" ;
d . appendChild ( d2 ) ;
this . _els [ "dhx_cal_data" ] [ 0 ] . appendChild ( d ) ;
this . _rendered . push ( d ) ;
d2 . innerHTML = "<textarea class='dhx_cal_editor'>" + ev . text + "</textarea>" ;
if ( this . _quirks7 ) d2 . firstChild . style . height = height - 12 + "px" ; //IEFIX
this . _editor = d2 . firstChild ;
this . _editor . onkeypress = function ( e ) {
if ( ( e || event ) . shiftKey ) return true ;
var code = ( e || event ) . keyCode ;
if ( code == scheduler . keys . edit _save ) scheduler . editStop ( true ) ;
if ( code == scheduler . keys . edit _cancel ) scheduler . editStop ( false ) ;
} ;
this . _editor . onselectstart = function ( e ) { return ( e || event ) . cancelBubble = true ; } ;
d2 . firstChild . focus ( ) ;
//IE and opera can add x-scroll during focusing
this . _els [ "dhx_cal_data" ] [ 0 ] . scrollLeft = 0 ;
d2 . firstChild . select ( ) ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
}
if ( this . _select _id == ev . id ) {
2011-08-03 14:09:14 +00:00
if ( this . config . cascade _event _display && this . _drag _mode )
d . style . zIndex = 1 ; //fix overlapping issue for cascade view in case of dnd of selected event
2011-04-07 16:41:06 +00:00
var icons = this . config [ "icons_" + ( ( this . _edit _id == ev . id ) ? "edit" : "select" ) ] ;
var icons _str = "" ;
2011-08-03 14:09:14 +00:00
var bg _color = ( ev . color ? ( "background-color:" + ev . color + ";" ) : "" ) ;
var color = ( ev . textColor ? ( "color:" + ev . textColor + ";" ) : "" ) ;
2011-04-07 16:41:06 +00:00
for ( var i = 0 ; i < icons . length ; i ++ )
2011-08-03 14:09:14 +00:00
icons _str += "<div class='dhx_menu_icon " + icons [ i ] + "' style='" + bg _color + "" + color + "' title='" + this . locale . labels [ icons [ i ] ] + "'></div>" ;
var obj = this . _render _v _bar ( ev . id , left - menu + 1 , top , menu , icons . length * 20 + 26 , "" , "<div style='" + bg _color + "" + color + "' class='dhx_menu_head'></div>" , icons _str , true ) ;
2011-04-07 16:41:06 +00:00
obj . style . left = left - menu + 1 ;
this . _els [ "dhx_cal_data" ] [ 0 ] . appendChild ( obj ) ;
this . _rendered . push ( obj ) ;
}
} ;
scheduler . _render _v _bar = function ( id , x , y , w , h , style , contentA , contentB , bottom ) {
var d = document . createElement ( "DIV" ) ;
var ev = this . getEvent ( id ) ;
var cs = "dhx_cal_event" ;
var cse = scheduler . templates . event _class ( ev . start _date , ev . end _date , ev ) ;
if ( cse ) cs = cs + " " + cse ;
2011-08-03 14:09:14 +00:00
var bg _color = ( ev . color ? ( "background-color:" + ev . color + ";" ) : "" ) ;
var color = ( ev . textColor ? ( "color:" + ev . textColor + ";" ) : "" ) ;
2011-04-07 16:41:06 +00:00
var html = '<div event_id="' + id + '" class="' + cs + '" style="position:absolute; top:' + y + 'px; left:' + x + 'px; width:' + ( w - 4 ) + 'px; height:' + h + 'px;' + ( style || "" ) + '">' ;
2011-08-03 14:09:14 +00:00
html += '<div class="dhx_header" style=" width:' + ( w - 6 ) + 'px;' + bg _color + '" > </div>' ;
html += '<div class="dhx_title" style="' + bg _color + '' + color + '">' + contentA + '</div>' ;
html += '<div class="dhx_body" style=" width:' + ( w - ( this . _quirks ? 4 : 14 ) ) + 'px; height:' + ( h - ( this . _quirks ? 20 : 30 ) ) + 'px;' + bg _color + '' + color + '">' + contentB + '</div>' ;
html += '<div class="dhx_footer" style=" width:' + ( w - 8 ) + 'px;' + ( bottom ? ' margin-top:-1px;' : '' ) + '' + bg _color + '' + color + '" ></div></div>' ;
2011-04-07 16:41:06 +00:00
d . innerHTML = html ;
return d . firstChild ;
} ;
scheduler . locate _holder = function ( day ) {
if ( this . _mode == "day" ) return this . _els [ "dhx_cal_data" ] [ 0 ] . firstChild ; //dirty
return this . _els [ "dhx_cal_data" ] [ 0 ] . childNodes [ day ] ;
} ;
scheduler . locate _holder _day = function ( date , past ) {
var day = Math . floor ( ( this . _correct _shift ( date , 1 ) - this . _min _date ) / ( 60 * 60 * 24 * 1000 ) ) ;
//when locating end data of event , we need to use next day if time part was defined
if ( past && this . date . time _part ( date ) ) day ++ ;
return day ;
} ;
scheduler . render _event _bar = function ( ev ) {
2011-08-03 14:09:14 +00:00
var parent = this . _rendered _location ;
2011-04-07 16:41:06 +00:00
var x = this . _colsS [ ev . _sday ] ;
var x2 = this . _colsS [ ev . _eday ] ;
if ( x2 == x ) x2 = this . _colsS [ ev . _eday + 1 ] ;
var hb = this . xy . bar _height ;
2011-08-03 14:09:14 +00:00
var y = this . _colsS . heights [ ev . _sweek ] + ( this . _colsS . height ? ( this . xy . month _scale _height + 2 ) : 2 ) + ( ev . _sorder * hb ) ;
2011-04-07 16:41:06 +00:00
var d = document . createElement ( "DIV" ) ;
var cs = ev . _timed ? "dhx_cal_event_clear" : "dhx_cal_event_line" ;
var cse = scheduler . templates . event _class ( ev . start _date , ev . end _date , ev ) ;
2011-08-03 14:09:14 +00:00
if ( cse ) cs = cs + " " + cse ;
var bg _color = ( ev . color ? ( "background-color:" + ev . color + ";" ) : "" ) ;
var color = ( ev . textColor ? ( "color:" + ev . textColor + ";" ) : "" ) ;
var html = '<div event_id="' + ev . id + '" class="' + cs + '" style="position:absolute; top:' + y + 'px; left:' + x + 'px; width:' + ( x2 - x - 15 ) + 'px;' + color + '' + bg _color + '' + ( ev . _text _style || "" ) + '">' ;
2011-04-07 16:41:06 +00:00
if ( ev . _timed )
html += scheduler . templates . event _bar _date ( ev . start _date , ev . end _date , ev ) ;
html += scheduler . templates . event _bar _text ( ev . start _date , ev . end _date , ev ) + '</div>' ;
html += '</div>' ;
d . innerHTML = html ;
this . _rendered . push ( d . firstChild ) ;
parent . appendChild ( d . firstChild ) ;
} ;
scheduler . _locate _event = function ( node ) {
var id = null ;
while ( node && ! id && node . getAttribute ) {
id = node . getAttribute ( "event_id" ) ;
node = node . parentNode ;
}
return id ;
} ;
scheduler . edit = function ( id ) {
if ( this . _edit _id == id ) return ;
this . editStop ( false , id ) ;
this . _edit _id = id ;
this . updateEvent ( id ) ;
} ;
scheduler . editStop = function ( mode , id ) {
if ( id && this . _edit _id == id ) return ;
var ev = this . getEvent ( this . _edit _id ) ;
if ( ev ) {
if ( mode ) ev . text = this . _editor . value ;
this . _edit _id = null ;
this . _editor = null ;
this . updateEvent ( ev . id ) ;
this . _edit _stop _event ( ev , mode ) ;
}
} ;
scheduler . _edit _stop _event = function ( ev , mode ) {
if ( this . _new _event ) {
if ( ! mode ) this . deleteEvent ( ev . id , true ) ;
else this . callEvent ( "onEventAdded" , [ ev . id , ev ] ) ;
this . _new _event = null ;
} else
if ( mode ) this . callEvent ( "onEventChanged" , [ ev . id , ev ] ) ;
} ;
scheduler . getEvents = function ( from , to ) {
var result = [ ] ;
for ( var a in this . _events ) {
var ev = this . _events [ a ] ;
if ( ev && ev . start _date < to && ev . end _date > from )
result . push ( ev ) ;
}
return result ;
2011-06-20 10:05:57 +00:00
} ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
scheduler . _loaded = { } ;
scheduler . _load = function ( url , from ) {
url = url || this . _load _url ;
url += ( url . indexOf ( "?" ) == - 1 ? "?" : "&" ) + "timeshift=" + ( new Date ( ) ) . getTimezoneOffset ( ) ;
if ( this . config . prevent _cache ) url += "&uid=" + this . uid ( ) ;
var to ;
from = from || this . _date ;
if ( this . _load _mode ) {
var lf = this . templates . load _format ;
from = this . date [ this . _load _mode + "_start" ] ( new Date ( from . valueOf ( ) ) ) ;
while ( from > this . _min _date ) from = this . date . add ( from , - 1 , this . _load _mode ) ;
to = from ;
var cache _line = true ;
while ( to < this . _max _date ) {
to = this . date . add ( to , 1 , this . _load _mode ) ;
if ( this . _loaded [ lf ( from ) ] && cache _line )
from = this . date . add ( from , 1 , this . _load _mode ) ;
else cache _line = false ;
}
var temp _to = to ;
do {
to = temp _to ;
temp _to = this . date . add ( to , - 1 , this . _load _mode ) ;
} while ( temp _to > from && this . _loaded [ lf ( temp _to ) ] ) ;
if ( to <= from )
return false ; //already loaded
dhtmlxAjax . get ( url + "&from=" + lf ( from ) + "&to=" + lf ( to ) , function ( l ) { scheduler . on _load ( l ) ; } ) ;
while ( from < to ) {
this . _loaded [ lf ( from ) ] = true ;
from = this . date . add ( from , 1 , this . _load _mode ) ;
}
} else
dhtmlxAjax . get ( url , function ( l ) { scheduler . on _load ( l ) ; } ) ;
this . callEvent ( "onXLS" , [ ] ) ;
return true ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . on _load = function ( loader ) {
this . _loading = true ;
2011-08-03 14:09:14 +00:00
var evs ;
2011-04-07 16:41:06 +00:00
if ( this . _process )
2011-08-03 14:09:14 +00:00
evs = this [ this . _process ] . parse ( loader . xmlDoc . responseText ) ;
2011-04-07 16:41:06 +00:00
else
2011-08-03 14:09:14 +00:00
evs = this . _magic _parser ( loader ) ;
2011-04-07 16:41:06 +00:00
this . _not _render = true ;
for ( var i = 0 ; i < evs . length ; i ++ ) {
if ( ! this . callEvent ( "onEventLoading" , [ evs [ i ] ] ) ) continue ;
this . addEvent ( evs [ i ] ) ;
}
this . _not _render = false ;
if ( this . _render _wait ) this . render _view _data ( ) ;
2011-08-03 14:09:14 +00:00
this . _loading = false ;
2011-04-07 16:41:06 +00:00
if ( this . _after _call ) this . _after _call ( ) ;
this . _after _call = null ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
this . callEvent ( "onXLE" , [ ] ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . json = { } ;
scheduler . json . parse = function ( data ) {
if ( typeof data == "string" ) {
eval ( "scheduler._temp = " + data + ";" ) ;
data = scheduler . _temp ;
}
var evs = [ ] ;
for ( var i = 0 ; i < data . length ; i ++ ) {
data [ i ] . start _date = scheduler . templates . xml _date ( data [ i ] . start _date ) ;
data [ i ] . end _date = scheduler . templates . xml _date ( data [ i ] . end _date ) ;
evs . push ( data [ i ] ) ;
}
return evs ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . parse = function ( data , type ) {
this . _process = type ;
this . on _load ( { xmlDoc : { responseText : data } } ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . load = function ( url , call ) {
if ( typeof call == "string" ) {
this . _process = call ;
call = arguments [ 2 ] ;
}
this . _load _url = url ;
this . _after _call = call ;
this . _load ( url , this . _date ) ;
} ;
//possible values - day,week,month,year,all
scheduler . setLoadMode = function ( mode ) {
if ( mode == "all" ) mode = "" ;
this . _load _mode = mode ;
} ;
//current view by default, or all data if "true" as parameter provided
scheduler . refresh = function ( refresh _all ) {
alert ( "not implemented" ) ;
/ *
this . _loaded = { } ;
this . _load ( ) ;
* /
2011-08-03 14:09:14 +00:00
} ;
scheduler . serverList = function ( name , array ) {
if ( array ) {
return this . serverList [ name ] = array . slice ( 0 ) ;
}
2011-04-07 16:41:06 +00:00
return this . serverList [ name ] = ( this . serverList [ name ] || [ ] ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _userdata = { } ;
scheduler . _magic _parser = function ( loader ) {
2011-08-03 14:09:14 +00:00
var xml ;
2011-04-07 16:41:06 +00:00
if ( ! loader . getXMLTopNode ) { //from a string
var xml _string = loader . xmlDoc . responseText ;
loader = new dtmlXMLLoaderObject ( function ( ) { } ) ;
loader . loadXMLString ( xml _string ) ;
}
2011-08-03 14:09:14 +00:00
xml = loader . getXMLTopNode ( "data" ) ;
2011-04-07 16:41:06 +00:00
if ( xml . tagName != "data" ) return [ ] ; //not an xml
var opts = loader . doXPath ( "//coll_options" ) ;
for ( var i = 0 ; i < opts . length ; i ++ ) {
var bind = opts [ i ] . getAttribute ( "for" ) ;
var arr = this . serverList [ bind ] ;
if ( ! arr ) continue ;
arr . splice ( 0 , arr . length ) ; //clear old options
var itms = loader . doXPath ( ".//item" , opts [ i ] ) ;
2011-08-03 14:09:14 +00:00
for ( var j = 0 ; j < itms . length ; j ++ ) {
var itm = itms [ j ] ;
var attrs = itm . attributes ;
var obj = { key : itms [ j ] . getAttribute ( "value" ) , label : itms [ j ] . getAttribute ( "label" ) } ;
for ( var k = 0 ; k < attrs . length ; k ++ ) {
var attr = attrs [ k ] ;
if ( attr . nodeName == "value" || attr . nodeName == "label" )
continue ;
obj [ attr . nodeName ] = attr . nodeValue ;
}
arr . push ( obj ) ;
}
2011-04-07 16:41:06 +00:00
}
if ( opts . length )
scheduler . callEvent ( "onOptionsLoad" , [ ] ) ;
var ud = loader . doXPath ( "//userdata" ) ;
for ( var i = 0 ; i < ud . length ; i ++ ) {
var udx = this . xmlNodeToJSON ( ud [ i ] ) ;
this . _userdata [ udx . name ] = udx . text ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
var evs = [ ] ;
2011-08-03 14:09:14 +00:00
xml = loader . doXPath ( "//event" ) ;
2011-04-07 16:41:06 +00:00
for ( var i = 0 ; i < xml . length ; i ++ ) {
2011-08-03 14:09:14 +00:00
evs [ i ] = this . xmlNodeToJSON ( xml [ i ] ) ;
2011-04-07 16:41:06 +00:00
evs [ i ] . text = evs [ i ] . text || evs [ i ] . _tagvalue ;
evs [ i ] . start _date = this . templates . xml _date ( evs [ i ] . start _date ) ;
evs [ i ] . end _date = this . templates . xml _date ( evs [ i ] . end _date ) ;
}
return evs ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . xmlNodeToJSON = function ( node ) {
var t = { } ;
for ( var i = 0 ; i < node . attributes . length ; i ++ )
t [ node . attributes [ i ] . name ] = node . attributes [ i ] . value ;
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
var child = node . childNodes [ i ] ;
if ( child . nodeType == 1 )
t [ child . tagName ] = child . firstChild ? child . firstChild . nodeValue : "" ;
}
if ( ! t . text ) t . text = node . firstChild ? node . firstChild . nodeValue : "" ;
return t ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . attachEvent ( "onXLS" , function ( ) {
if ( this . config . show _loading === true ) {
var t ;
t = this . config . show _loading = document . createElement ( "DIV" ) ;
t . className = 'dhx_loading' ;
t . style . left = Math . round ( ( this . _x - 128 ) / 2 ) + "px" ;
t . style . top = Math . round ( ( this . _y - 15 ) / 2 ) + "px" ;
this . _obj . appendChild ( t ) ;
}
} ) ;
scheduler . attachEvent ( "onXLE" , function ( ) {
var t ;
if ( t = this . config . show _loading )
if ( typeof t == "object" ) {
this . _obj . removeChild ( t ) ;
this . config . show _loading = true ;
}
} ) ;
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
scheduler . ical = {
parse : function ( str ) {
var data = str . match ( RegExp ( this . c _start + "[^\f]*" + this . c _end , "" ) ) ;
if ( ! data . length ) return ;
//unfolding
data [ 0 ] = data [ 0 ] . replace ( /[\r\n]+(?=[a-z \t])/g , " " ) ;
//drop property
data [ 0 ] = data [ 0 ] . replace ( /\;[^:\r\n]*/g , "" ) ;
var incoming = [ ] ;
var match ;
var event _r = RegExp ( "(?:" + this . e _start + ")([^\f]*?)(?:" + this . e _end + ")" , "g" ) ;
while ( match = event _r . exec ( data ) ) {
var e = { } ;
var param ;
var param _r = /[^\r\n]+[\r\n]+/g ;
while ( param = param _r . exec ( match [ 1 ] ) )
this . parse _param ( param . toString ( ) , e ) ;
if ( e . uid && ! e . id ) e . id = e . uid ; //fallback to UID, when ID is not defined
incoming . push ( e ) ;
}
return incoming ;
} ,
parse _param : function ( str , obj ) {
var d = str . indexOf ( ":" ) ;
if ( d == - 1 ) return ;
var name = str . substr ( 0 , d ) . toLowerCase ( ) ;
var value = str . substr ( d + 1 ) . replace ( /\\\,/g , "," ) . replace ( /[\r\n]+$/ , "" ) ;
if ( name == "summary" )
name = "text" ;
else if ( name == "dtstart" ) {
name = "start_date" ;
value = this . parse _date ( value , 0 , 0 ) ;
}
else if ( name == "dtend" ) {
name = "end_date" ;
if ( obj . start _date && obj . start _date . getHours ( ) == 0 )
value = this . parse _date ( value , 24 , 00 ) ;
else
value = this . parse _date ( value , 23 , 59 ) ;
}
obj [ name ] = value ;
} ,
parse _date : function ( value , dh , dm ) {
var t = value . split ( "T" ) ;
if ( t [ 1 ] ) {
dh = t [ 1 ] . substr ( 0 , 2 ) ;
dm = t [ 1 ] . substr ( 2 , 2 ) ;
}
var dy = t [ 0 ] . substr ( 0 , 4 ) ;
var dn = parseInt ( t [ 0 ] . substr ( 4 , 2 ) , 10 ) - 1 ;
var dd = t [ 0 ] . substr ( 6 , 2 ) ;
if ( scheduler . config . server _utc && ! t [ 1 ] ) { // if no hours/minutes were specified == full day event
return new Date ( Date . UTC ( dy , dn , dd , dh , dm ) ) ;
}
return new Date ( dy , dn , dd , dh , dm ) ;
} ,
c _start : "BEGIN:VCALENDAR" ,
e _start : "BEGIN:VEVENT" ,
e _end : "END:VEVENT" ,
c _end : "END:VCALENDAR"
2011-08-03 14:09:14 +00:00
} ;
scheduler . formSection = function ( name ) {
var config = this . config . lightbox . sections ;
var i = 0 ;
for ( i ; i < config . length ; i ++ )
if ( config [ i ] . name == name )
break ;
var section = config [ i ] ;
var node = document . getElementById ( section . id ) . nextSibling ;
return {
getValue : function ( ev ) {
return scheduler . form _blocks [ section . type ] . get _value ( node , ( ev || { } ) , section ) ;
} ,
setValue : function ( value , ev ) {
return scheduler . form _blocks [ section . type ] . set _value ( node , value , ( ev || { } ) , section ) ;
}
} ;
2011-06-20 10:05:57 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . form _blocks = {
2011-08-03 14:09:14 +00:00
template : {
render : function ( sns ) {
var height = ( sns . height || "30" ) + "px" ;
return "<div class='dhx_cal_ltext dhx_cal_template' style='height:" + height + ";'></div>" ;
} ,
set _value : function ( node , value , ev , config ) {
node . innerHTML = value || "" ;
} ,
get _value : function ( node , ev , config ) {
return node . innerHTML || "" ;
} ,
focus : function ( node ) {
}
} ,
2011-04-07 16:41:06 +00:00
textarea : {
render : function ( sns ) {
var height = ( sns . height || "130" ) + "px" ;
return "<div class='dhx_cal_ltext' style='height:" + height + ";'><textarea></textarea></div>" ;
} ,
set _value : function ( node , value , ev ) {
node . firstChild . value = value || "" ;
} ,
get _value : function ( node , ev ) {
return node . firstChild . value ;
} ,
focus : function ( node ) {
var a = node . firstChild ; a . select ( ) ; a . focus ( ) ;
}
} ,
select : {
render : function ( sns ) {
var height = ( sns . height || "23" ) + "px" ;
2011-08-03 14:09:14 +00:00
var html = "<div class='dhx_cal_ltext' style='height:" + height + ";'><select style='width:100%;'>" ;
2011-04-07 16:41:06 +00:00
for ( var i = 0 ; i < sns . options . length ; i ++ )
html += "<option value='" + sns . options [ i ] . key + "'>" + sns . options [ i ] . label + "</option>" ;
html += "</select></div>" ;
return html ;
} ,
set _value : function ( node , value , ev ) {
if ( typeof value == "undefined" )
value = ( node . firstChild . options [ 0 ] || { } ) . value ;
node . firstChild . value = value || "" ;
} ,
get _value : function ( node , ev ) {
return node . firstChild . value ;
} ,
focus : function ( node ) {
var a = node . firstChild ; if ( a . select ) a . select ( ) ; a . focus ( ) ;
}
} ,
time : {
render : function ( ) {
//hours
var cfg = scheduler . config ;
var dt = this . date . date _part ( new Date ( ) ) ;
var last = 24 * 60 , first = 0 ;
if ( scheduler . config . limit _time _select ) {
last = 60 * cfg . last _hour + 1 ;
first = 60 * cfg . first _hour ;
dt . setHours ( cfg . first _hour ) ;
}
var html = "<select>" ;
2011-08-03 14:09:14 +00:00
var i = first ;
var tdate = dt . getDate ( ) ;
while ( i < last ) {
2011-04-07 16:41:06 +00:00
var time = this . templates . time _picker ( dt ) ;
html += "<option value='" + i + "'>" + time + "</option>" ;
2011-08-03 14:09:14 +00:00
dt . setTime ( dt . valueOf ( ) + this . config . time _step * 60 * 1000 ) ;
var diff = ( dt . getDate ( ) != tdate ) ? 1 : 0 ; // moved or not to the next day
i = diff * 24 * 60 + dt . getHours ( ) * 60 + dt . getMinutes ( ) ;
2011-04-07 16:41:06 +00:00
}
//days
html += "</select> <select>" ;
for ( var i = 1 ; i < 32 ; i ++ )
html += "<option value='" + i + "'>" + i + "</option>" ;
//month
html += "</select> <select>" ;
for ( var i = 0 ; i < 12 ; i ++ )
html += "<option value='" + i + "'>" + this . locale . date . month _full [ i ] + "</option>" ;
//year
html += "</select> <select>" ;
dt = dt . getFullYear ( ) - 5 ; //maybe take from config?
for ( var i = 0 ; i < 10 ; i ++ )
html += "<option value='" + ( dt + i ) + "'>" + ( dt + i ) + "</option>" ;
html += "</select> " ;
2011-08-03 14:09:14 +00:00
return "<div style='height:30px;padding-top:0px;font-size:inherit;' class='dhx_section_time'>" + html + "<span style='font-weight:normal; font-size:10pt;'> – </span>" + html + "</div>" ;
2011-04-07 16:41:06 +00:00
} ,
set _value : function ( node , value , ev ) {
2011-08-03 14:09:14 +00:00
2011-04-07 16:41:06 +00:00
var s = node . getElementsByTagName ( "select" ) ;
if ( scheduler . config . full _day ) {
if ( ! node . _full _day ) {
2011-08-03 14:09:14 +00:00
var html = "<label class='dhx_fullday'><input type='checkbox' name='full_day' value='true'> " + scheduler . locale . labels . full _day + " </label></input>" ;
if ( ! scheduler . config . wide _form )
html = node . previousSibling . innerHTML + html ;
node . previousSibling . innerHTML = html ;
2011-04-07 16:41:06 +00:00
node . _full _day = true ;
}
var input = node . previousSibling . getElementsByTagName ( "input" ) [ 0 ] ;
2011-08-03 14:09:14 +00:00
var isFulldayEvent = ( scheduler . date . time _part ( ev . start _date ) === 0 && scheduler . date . time _part ( ev . end _date ) === 0 && ev . end _date . valueOf ( ) - ev . start _date . valueOf ( ) < 2 * 24 * 60 * 60 * 1000 ) ;
2011-04-07 16:41:06 +00:00
input . checked = isFulldayEvent ;
for ( var k in s )
s [ k ] . disabled = input . checked ;
input . onclick = function ( ) {
if ( input . checked ) {
var start _date = new Date ( ev . start _date ) ;
var end _date = new Date ( ev . end _date ) ;
scheduler . date . date _part ( start _date ) ;
2011-08-03 14:09:14 +00:00
end _date = scheduler . date . add ( start _date , 1 , "day" ) ;
2011-04-07 16:41:06 +00:00
}
for ( var i in s )
s [ i ] . disabled = input . checked ;
_fill _lightbox _select ( s , 0 , start _date || ev . start _date ) ;
_fill _lightbox _select ( s , 4 , end _date || ev . end _date ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
}
if ( scheduler . config . auto _end _date && scheduler . config . event _duration ) {
function _update _lightbox _select ( ) {
ev . start _date = new Date ( s [ 3 ] . value , s [ 2 ] . value , s [ 1 ] . value , 0 , s [ 0 ] . value ) ;
ev . end _date . setTime ( ev . start _date . getTime ( ) + ( scheduler . config . event _duration * 60 * 1000 ) ) ;
_fill _lightbox _select ( s , 4 , ev . end _date ) ;
}
for ( var i = 0 ; i < 4 ; i ++ ) {
s [ i ] . onchange = _update _lightbox _select ;
}
}
function _fill _lightbox _select ( s , i , d ) {
s [ i + 0 ] . value = Math . round ( ( d . getHours ( ) * 60 + d . getMinutes ( ) ) / scheduler . config . time _step ) * scheduler . config . time _step ;
s [ i + 1 ] . value = d . getDate ( ) ;
s [ i + 2 ] . value = d . getMonth ( ) ;
s [ i + 3 ] . value = d . getFullYear ( ) ;
}
_fill _lightbox _select ( s , 0 , ev . start _date ) ;
_fill _lightbox _select ( s , 4 , ev . end _date ) ;
} ,
get _value : function ( node , ev ) {
s = node . getElementsByTagName ( "select" ) ;
ev . start _date = new Date ( s [ 3 ] . value , s [ 2 ] . value , s [ 1 ] . value , 0 , s [ 0 ] . value ) ;
ev . end _date = new Date ( s [ 7 ] . value , s [ 6 ] . value , s [ 5 ] . value , 0 , s [ 4 ] . value ) ;
if ( ev . end _date <= ev . start _date )
ev . end _date = scheduler . date . add ( ev . start _date , scheduler . config . time _step , "minute" ) ;
} ,
focus : function ( node ) {
node . getElementsByTagName ( "select" ) [ 0 ] . focus ( ) ;
}
}
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . showCover = function ( box ) {
if ( box ) {
box . style . display = "block" ;
2011-08-03 14:09:14 +00:00
var scroll _top = window . pageYOffset || document . body . scrollTop || document . documentElement . scrollTop ;
var scroll _left = window . pageXOffset || document . body . scrollLeft || document . documentElement . scrollLeft ;
var view _height = window . innerHeight || document . documentElement . clientHeight ;
if ( scroll _top ) // if vertical scroll on window
box . style . top = Math . round ( scroll _top + Math . max ( ( view _height - box . offsetHeight ) / 2 , 0 ) ) + "px" ;
else // vertical scroll on body
box . style . top = Math . round ( Math . max ( ( ( view _height - box . offsetHeight ) / 2 ) , 0 ) + 9 ) + "px" ; // +9 for compatibility with auto tests
// not quite accurate but used for compatibility reasons
if ( document . documentElement . scrollWidth > document . body . offsetWidth ) // if horizontal scroll on the window
box . style . left = Math . round ( scroll _left + ( document . body . offsetWidth - box . offsetWidth ) / 2 ) + "px" ;
else // horizontal scroll on the body
box . style . left = Math . round ( ( document . body . offsetWidth - box . offsetWidth ) / 2 ) + "px" ;
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
this . show _cover ( ) ;
} ;
2011-04-07 16:41:06 +00:00
scheduler . showLightbox = function ( id ) {
if ( ! id ) return ;
if ( ! this . callEvent ( "onBeforeLightbox" , [ id ] ) ) return ;
var box = this . _get _lightbox ( ) ;
this . showCover ( box ) ;
this . _fill _lightbox ( id , box ) ;
this . callEvent ( "onLightbox" , [ id ] ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _fill _lightbox = function ( id , box ) {
var ev = this . getEvent ( id ) ;
var s = box . getElementsByTagName ( "span" ) ;
if ( scheduler . templates . lightbox _header ) {
s [ 1 ] . innerHTML = "" ;
s [ 2 ] . innerHTML = scheduler . templates . lightbox _header ( ev . start _date , ev . end _date , ev ) ;
} else {
s [ 1 ] . innerHTML = this . templates . event _header ( ev . start _date , ev . end _date , ev ) ;
s [ 2 ] . innerHTML = ( this . templates . event _bar _text ( ev . start _date , ev . end _date , ev ) || "" ) . substr ( 0 , 70 ) ; //IE6 fix
}
var sns = this . config . lightbox . sections ;
for ( var i = 0 ; i < sns . length ; i ++ ) {
var node = document . getElementById ( sns [ i ] . id ) . nextSibling ;
var block = this . form _blocks [ sns [ i ] . type ] ;
2011-08-03 14:09:14 +00:00
block . set _value . call ( this , node , ev [ sns [ i ] . map _to ] , ev , sns [ i ] ) ;
2011-04-07 16:41:06 +00:00
if ( sns [ i ] . focus )
block . focus . call ( this , node ) ;
2011-08-03 14:09:14 +00:00
}
2011-04-07 16:41:06 +00:00
scheduler . _lightbox _id = id ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _lightbox _out = function ( ev ) {
var sns = this . config . lightbox . sections ;
for ( var i = 0 ; i < sns . length ; i ++ ) {
2011-08-03 14:09:14 +00:00
var node = document . getElementById ( sns [ i ] . id ) ;
node = ( node ? node . nextSibling : node ) ;
2011-04-07 16:41:06 +00:00
var block = this . form _blocks [ sns [ i ] . type ] ;
var res = block . get _value . call ( this , node , ev , sns [ i ] ) ;
if ( sns [ i ] . map _to != "auto" )
ev [ sns [ i ] . map _to ] = res ;
}
return ev ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . _empty _lightbox = function ( ) {
var id = scheduler . _lightbox _id ;
var ev = this . getEvent ( id ) ;
var box = this . _get _lightbox ( ) ;
this . _lightbox _out ( ev ) ;
ev . _timed = this . is _one _day _event ( ev ) ;
this . setEvent ( ev . id , ev ) ;
2011-08-03 14:09:14 +00:00
this . _edit _stop _event ( ev , true ) ;
2011-04-07 16:41:06 +00:00
this . render _view _data ( ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . hide _lightbox = function ( id ) {
this . hideCover ( this . _get _lightbox ( ) ) ;
this . _lightbox _id = null ;
this . callEvent ( "onAfterLightbox" , [ ] ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . hideCover = function ( box ) {
if ( box ) box . style . display = "none" ;
this . hide _cover ( ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . hide _cover = function ( ) {
if ( this . _cover )
this . _cover . parentNode . removeChild ( this . _cover ) ;
this . _cover = null ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . show _cover = function ( ) {
this . _cover = document . createElement ( "DIV" ) ;
this . _cover . className = "dhx_cal_cover" ;
2011-08-03 14:09:14 +00:00
var _document _height = ( ( document . height !== undefined ) ? document . height : document . body . offsetHeight ) ;
var _scroll _height = ( ( document . documentElement ) ? document . documentElement . scrollHeight : 0 ) ;
this . _cover . style . height = Math . max ( _document _height , _scroll _height ) + 'px' ;
2011-04-07 16:41:06 +00:00
document . body . appendChild ( this . _cover ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . save _lightbox = function ( ) {
2011-08-03 14:09:14 +00:00
if ( this . checkEvent ( "onEventSave" ) && ! this . callEvent ( "onEventSave" , [ this . _lightbox _id , this . _lightbox _out ( { id : this . _lightbox _id } ) , this . _new _event ] ) )
2011-04-07 16:41:06 +00:00
return ;
2011-08-03 14:09:14 +00:00
this . _empty _lightbox ( ) ;
2011-04-07 16:41:06 +00:00
this . hide _lightbox ( ) ;
} ;
scheduler . startLightbox = function ( id , box ) {
this . _lightbox _id = id ;
this . showCover ( box ) ;
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
scheduler . endLightbox = function ( mode , box ) {
this . _edit _stop _event ( scheduler . getEvent ( this . _lightbox _id ) , mode ) ;
if ( mode )
scheduler . render _view _data ( ) ;
this . hideCover ( box ) ;
} ;
scheduler . resetLightbox = function ( ) {
2011-08-03 14:09:14 +00:00
if ( scheduler . _lightbox )
scheduler . _lightbox . parentNode . removeChild ( scheduler . _lightbox ) ;
2011-04-07 16:41:06 +00:00
scheduler . _lightbox = null ;
} ;
scheduler . cancel _lightbox = function ( ) {
this . callEvent ( "onEventCancel" , [ this . _lightbox _id , this . _new _event ] ) ;
this . endLightbox ( false ) ;
this . hide _lightbox ( ) ;
} ;
scheduler . _init _lightbox _events = function ( ) {
this . _get _lightbox ( ) . onclick = function ( e ) {
var src = e ? e . target : event . srcElement ;
if ( ! src . className ) src = src . previousSibling ;
if ( src && src . className )
switch ( src . className ) {
case "dhx_save_btn" :
scheduler . save _lightbox ( ) ;
break ;
case "dhx_delete_btn" :
var c = scheduler . locale . labels . confirm _deleting ;
if ( ! c || confirm ( c ) ) {
scheduler . deleteEvent ( scheduler . _lightbox _id ) ;
scheduler . _new _event = null ; //clear flag, if it was unsaved event
scheduler . hide _lightbox ( ) ;
}
break ;
case "dhx_cancel_btn" :
scheduler . cancel _lightbox ( ) ;
break ;
default :
2011-08-03 14:09:14 +00:00
if ( src . getAttribute ( "dhx_button" ) ) {
scheduler . callEvent ( "onLightboxButton" , [ src . className , src , e ] ) ;
} else if ( src . className . indexOf ( "dhx_custom_button_" ) != - 1 ) {
2011-04-07 16:41:06 +00:00
var index = src . parentNode . getAttribute ( "index" ) ;
var block = scheduler . form _blocks [ scheduler . config . lightbox . sections [ index ] . type ] ;
var sec = src . parentNode . parentNode ;
block . button _click ( index , src , sec , sec . nextSibling ) ;
}
2011-08-03 14:09:14 +00:00
break ;
2011-04-07 16:41:06 +00:00
}
} ;
2011-08-03 14:09:14 +00:00
this . _get _lightbox ( ) . onkeydown = function ( e ) {
2011-04-07 16:41:06 +00:00
switch ( ( e || event ) . keyCode ) {
case scheduler . keys . edit _save :
if ( ( e || event ) . shiftKey ) return ;
scheduler . save _lightbox ( ) ;
break ;
case scheduler . keys . edit _cancel :
scheduler . cancel _lightbox ( ) ;
break ;
2011-08-03 14:09:14 +00:00
default :
break ;
2011-04-07 16:41:06 +00:00
}
2011-08-03 14:09:14 +00:00
} ;
} ;
2011-04-07 16:41:06 +00:00
scheduler . setLightboxSize = function ( ) {
var d = this . _lightbox ;
if ( ! d ) return ;
var con = d . childNodes [ 1 ] ;
con . style . height = "0px" ;
con . style . height = con . scrollHeight + "px" ;
d . style . height = con . scrollHeight + 50 + "px" ;
con . style . height = con . scrollHeight + "px" ; //it is incredible , how ugly IE can be
2011-08-03 14:09:14 +00:00
} ;
2011-04-07 16:41:06 +00:00
2011-08-03 14:09:14 +00:00
scheduler . _init _dnd _events = function ( ) {
dhtmlxEvent ( document . body , "mousemove" , scheduler . _move _while _dnd ) ;
dhtmlxEvent ( document . body , "mouseup" , scheduler . _finish _dnd ) ;
scheduler . _init _dnd _events = function ( ) { } ;
} ;
scheduler . _move _while _dnd = function ( e ) {
if ( scheduler . _dnd _start _lb ) {
if ( ! document . dhx _unselectable ) {
document . body . className += " dhx_unselectable" ;
document . dhx _unselectable = true ;
}
var lb = scheduler . _get _lightbox ( ) ;
var now = ( e && e . target ) ? [ e . pageX , e . pageY ] : [ event . clientX , event . clientY ] ;
lb . style . top = scheduler . _lb _start [ 1 ] + now [ 1 ] - scheduler . _dnd _start _lb [ 1 ] + "px" ;
lb . style . left = scheduler . _lb _start [ 0 ] + now [ 0 ] - scheduler . _dnd _start _lb [ 0 ] + "px" ;
}
} ;
scheduler . _ready _to _dnd = function ( e ) {
var lb = scheduler . _get _lightbox ( ) ;
scheduler . _lb _start = [ parseInt ( lb . style . left , 10 ) , parseInt ( lb . style . top , 10 ) ] ;
scheduler . _dnd _start _lb = ( e && e . target ) ? [ e . pageX , e . pageY ] : [ event . clientX , event . clientY ] ;
} ;
scheduler . _finish _dnd = function ( ) {
if ( scheduler . _lb _start ) {
scheduler . _lb _start = scheduler . _dnd _start _lb = false ;
document . body . className = document . body . className . replace ( " dhx_unselectable" , "" ) ;
document . dhx _unselectable = false ;
}
} ;
scheduler . _get _lightbox = function ( ) { //scheduler.config.wide_form=true;
2011-04-07 16:41:06 +00:00
if ( ! this . _lightbox ) {
var d = document . createElement ( "DIV" ) ;
d . className = "dhx_cal_light" ;
2011-08-03 14:09:14 +00:00
if ( scheduler . config . wide _form )
d . className += " dhx_cal_light_wide" ;
if ( scheduler . form _blocks . recurring )
d . className += " dhx_cal_light_rec" ;
2011-04-07 16:41:06 +00:00
if ( /msie|MSIE 6/ . test ( navigator . userAgent ) )
d . className += " dhx_ie6" ;
d . style . visibility = "hidden" ;
2011-08-03 14:09:14 +00:00
var html = this . _lightbox _template
var buttons = this . config . buttons _left ;
scheduler . locale . labels [ "dhx_save_btn" ] = scheduler . locale . labels . icon _save ;
scheduler . locale . labels [ "dhx_cancel_btn" ] = scheduler . locale . labels . icon _cancel ;
scheduler . locale . labels [ "dhx_delete_btn" ] = scheduler . locale . labels . icon _delete ;
for ( var i = 0 ; i < buttons . length ; i ++ )
html += "<div class='dhx_btn_set'><div dhx_button='1' class='" + buttons [ i ] + "'></div><div>" + scheduler . locale . labels [ buttons [ i ] ] + "</div></div>" ;
buttons = this . config . buttons _right ;
for ( var i = 0 ; i < buttons . length ; i ++ )
html += "<div class='dhx_btn_set' style='float:right;'><div dhx_button='1' class='" + buttons [ i ] + "'></div><div>" + scheduler . locale . labels [ buttons [ i ] ] + "</div></div>" ;
html += "</div>" ;
d . innerHTML = html ;
if ( scheduler . config . drag _lightbox ) {
d . firstChild . onmousedown = scheduler . _ready _to _dnd ;
d . firstChild . onselectstart = function ( ) { return false ; } ;
d . firstChild . style . cursor = "pointer" ;
scheduler . _init _dnd _events ( ) ;
}
2011-04-07 16:41:06 +00:00
document . body . insertBefore ( d , document . body . firstChild ) ;
this . _lightbox = d ;
var sns = this . config . lightbox . sections ;
2011-08-03 14:09:14 +00:00
html = "" ;
2011-04-07 16:41:06 +00:00
for ( var i = 0 ; i < sns . length ; i ++ ) {
var block = this . form _blocks [ sns [ i ] . type ] ;
if ( ! block ) continue ; //ignore incorrect blocks
sns [ i ] . id = "area_" + this . uid ( ) ;
var button = "" ;
2011-08-03 14:09:14 +00:00
if ( sns [ i ] . button ) {
button = "<div class='dhx_custom_button' index='" + i + "'><div class='dhx_custom_button_" + sns [ i ] . button + "'></div><div>" + this . locale . labels [ "button_" + sns [ i ] . button ] + "</div></div>" ;
}
if ( this . config . wide _form ) {
html += "<div class='dhx_wrap_section'>" ;
}
2011-04-07 16:41:06 +00:00
html += "<div id='" + sns [ i ] . id + "' class='dhx_cal_lsection'>" + button + this . locale . labels [ "section_" + sns [ i ] . name ] + "</div>" + block . render . call ( this , sns [ i ] ) ;
2011-08-03 14:09:14 +00:00
html += "</div>"
}
2011-04-07 16:41:06 +00:00
//localization
var ds = d . getElementsByTagName ( "div" ) ;
//sections
ds [ 1 ] . innerHTML = html ;
//sizes
this . setLightboxSize ( ) ;
this . _init _lightbox _events ( this ) ;
d . style . display = "none" ;
d . style . visibility = "visible" ;
}
return this . _lightbox ;
2011-08-03 14:09:14 +00:00
} ;
scheduler . _lightbox _template = "<div class='dhx_cal_ltitle'><span class='dhx_mark'> </span><span class='dhx_time'></span><span class='dhx_title'></span></div><div class='dhx_cal_larea'></div>" ;
2011-04-07 16:41:06 +00:00
scheduler . _dp _init = function ( dp ) {
dp . _methods = [ "setEventTextStyle" , "" , "changeEventId" , "deleteEvent" ] ;
this . attachEvent ( "onEventAdded" , function ( id ) {
if ( ! this . _loading && this . validId ( id ) )
dp . setUpdated ( id , true , "inserted" ) ;
} ) ;
2011-08-03 14:09:14 +00:00
this . attachEvent ( "onConfirmedBeforeEventDelete" , function ( id ) {
2011-04-07 16:41:06 +00:00
if ( ! this . validId ( id ) ) return ;
var z = dp . getState ( id ) ;
if ( z == "inserted" || this . _new _event ) { dp . setUpdated ( id , false ) ; return true ; }
if ( z == "deleted" ) return false ;
if ( z == "true_deleted" ) return true ;
dp . setUpdated ( id , true , "deleted" ) ;
return false ;
} ) ;
this . attachEvent ( "onEventChanged" , function ( id ) {
if ( ! this . _loading && this . validId ( id ) )
dp . setUpdated ( id , true , "updated" ) ;
} ) ;
dp . _getRowData = function ( id , pref ) {
var ev = this . obj . getEvent ( id ) ;
var data = { } ;
for ( var a in ev ) {
if ( a . indexOf ( "_" ) == 0 ) continue ;
if ( ev [ a ] && ev [ a ] . getUTCFullYear ) //not very good, but will work
data [ a ] = this . obj . templates . xml _format ( ev [ a ] ) ;
else
data [ a ] = ev [ a ] ;
}
return data ;
} ;
dp . _clearUpdateFlag = function ( ) { } ;
dp . attachEvent ( "insertCallback" , scheduler . _update _callback ) ;
dp . attachEvent ( "updateCallback" , scheduler . _update _callback ) ;
dp . attachEvent ( "deleteCallback" , function ( upd , id ) {
this . obj . setUserData ( id , this . action _param , "true_deleted" ) ;
this . obj . deleteEvent ( id ) ;
} ) ;
} ;
scheduler . setUserData = function ( id , name , value ) {
if ( id )
this . getEvent ( id ) [ name ] = value ;
else
this . _userdata [ name ] = value ;
} ;
scheduler . getUserData = function ( id , name ) {
return id ? this . getEvent ( id ) [ name ] : this . _userdata [ name ] ;
} ;
scheduler . setEventTextStyle = function ( id , style ) {
this . for _rendered ( id , function ( r ) {
r . style . cssText += ";" + style ;
} ) ;
var ev = this . getEvent ( id ) ;
ev [ "_text_style" ] = style ;
this . event _updated ( ev ) ;
} ;
scheduler . validId = function ( id ) {
return true ;
} ;
scheduler . _update _callback = function ( upd , id ) {
var data = scheduler . xmlNodeToJSON ( upd . firstChild ) ;
data . text = data . text || data . _tagvalue ;
data . start _date = scheduler . templates . xml _date ( data . start _date ) ;
data . end _date = scheduler . templates . xml _date ( data . end _date ) ;
scheduler . addEvent ( data ) ;
2011-08-03 14:09:14 +00:00
} ;