[MERGE] Merge with trunk
Replace dHtmlXScheduler calendar by FullCalendar from Jquery Manage filter by coworker/favorite Employee Manage avatar in event / in sidebar filter bzr revid: jke@openerp.com-20140114160325-1e4dgbe3f8fo38na
|
@ -4261,6 +4261,7 @@ var lazy_build_o2m_kanban_view = function() {
|
||||||
|
|
||||||
instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, instance.web.form.ReinitializeFieldMixin, {
|
instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, instance.web.form.ReinitializeFieldMixin, {
|
||||||
template: "FieldMany2ManyTags",
|
template: "FieldMany2ManyTags",
|
||||||
|
tag_template: "FieldMany2ManyTag",
|
||||||
init: function() {
|
init: function() {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
instance.web.form.CompletionFieldMixin.init.call(this);
|
instance.web.form.CompletionFieldMixin.init.call(this);
|
||||||
|
@ -4268,13 +4269,9 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
|
||||||
this._display_orderer = new instance.web.DropMisordered();
|
this._display_orderer = new instance.web.DropMisordered();
|
||||||
this._drop_shown = false;
|
this._drop_shown = false;
|
||||||
},
|
},
|
||||||
initialize_content: function() {
|
initialize_texttext: function(){
|
||||||
if (this.get("effective_readonly"))
|
|
||||||
return;
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var ignore_blur = false;
|
return {
|
||||||
self.$text = this.$("textarea");
|
|
||||||
self.$text.textext({
|
|
||||||
plugins : 'tags arrow autocomplete',
|
plugins : 'tags arrow autocomplete',
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
render: function(suggestion) {
|
render: function(suggestion) {
|
||||||
|
@ -4325,7 +4322,15 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}).bind('getSuggestions', function(e, data) {
|
}
|
||||||
|
},
|
||||||
|
initialize_content: function() {
|
||||||
|
if (this.get("effective_readonly"))
|
||||||
|
return;
|
||||||
|
var self = this;
|
||||||
|
var ignore_blur = false;
|
||||||
|
self.$text = this.$("textarea");
|
||||||
|
self.$text.textext(self.initialize_texttext()).bind('getSuggestions', function(e, data) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
var str = !!data ? data.query || '' : '';
|
var str = !!data ? data.query || '' : '';
|
||||||
self.get_search_result(str).done(function(result) {
|
self.get_search_result(str).done(function(result) {
|
||||||
|
@ -4373,6 +4378,24 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
|
||||||
get_search_blacklist: function() {
|
get_search_blacklist: function() {
|
||||||
return this.get("value");
|
return this.get("value");
|
||||||
},
|
},
|
||||||
|
map_tag: function(data){
|
||||||
|
return _.map(data, function(el) {return {name: el[1], id:el[0]};})
|
||||||
|
},
|
||||||
|
get_render_data: function(ids){
|
||||||
|
var self = this;
|
||||||
|
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
|
||||||
|
return dataset.name_get(ids);
|
||||||
|
},
|
||||||
|
render_tag: function(data) {
|
||||||
|
var self = this;
|
||||||
|
if (! self.get("effective_readonly")) {
|
||||||
|
self.tags.containerElement().children().remove();
|
||||||
|
self.$('textarea').css("padding-left", "3px");
|
||||||
|
self.tags.addTags(self.map_tag(data));
|
||||||
|
} else {
|
||||||
|
self.$el.html(QWeb.render(self.tag_template, {elements: data}));
|
||||||
|
}
|
||||||
|
},
|
||||||
render_value: function() {
|
render_value: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
|
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
|
||||||
|
@ -4385,17 +4408,12 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
|
||||||
indexed[el[0]] = el;
|
indexed[el[0]] = el;
|
||||||
});
|
});
|
||||||
data = _.map(values, function(el) { return indexed[el]; });
|
data = _.map(values, function(el) { return indexed[el]; });
|
||||||
if (! self.get("effective_readonly")) {
|
self.render_tag(data);
|
||||||
self.tags.containerElement().children().remove();
|
}
|
||||||
self.$('textarea').css("padding-left", "3px");
|
|
||||||
self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};}));
|
|
||||||
} else {
|
|
||||||
self.$el.html(QWeb.render("FieldMany2ManyTag", {elements: data}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (! values || values.length > 0) {
|
if (! values || values.length > 0) {
|
||||||
this._display_orderer.add(dataset.name_get(values)).done(handle_names);
|
this._display_orderer.add(self.get_render_data(values)).done(handle_names);
|
||||||
} else {
|
}
|
||||||
|
else{
|
||||||
handle_names([]);
|
handle_names([]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -331,6 +331,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
|
||||||
action_menu_id: null,
|
action_menu_id: null,
|
||||||
additional_context: {},
|
additional_context: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (action === false) {
|
if (action === false) {
|
||||||
action = { type: 'ir.actions.act_window_close' };
|
action = { type: 'ir.actions.act_window_close' };
|
||||||
} else if (_.isString(action) && instance.web.client_actions.contains(action)) {
|
} else if (_.isString(action) && instance.web.client_actions.contains(action)) {
|
||||||
|
|
|
@ -8,18 +8,16 @@ OpenERP Web Calendar view.
|
||||||
""",
|
""",
|
||||||
'version': '2.0',
|
'version': '2.0',
|
||||||
'depends': ['web'],
|
'depends': ['web'],
|
||||||
|
'data' : [],
|
||||||
'js': [
|
'js': [
|
||||||
'static/lib/dhtmlxScheduler/sources/dhtmlxscheduler.js',
|
'static/lib/fullcalendar/js/fullcalendar.js',
|
||||||
'static/lib/dhtmlxScheduler/sources/ext/dhtmlxscheduler_minical.js',
|
'static/src/js/*.js'
|
||||||
'static/src/js/calendar.js'
|
|
||||||
],
|
],
|
||||||
'css': [
|
'css': [
|
||||||
#'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css',
|
'static/lib/fullcalendar/css/*.css',
|
||||||
#'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler_dhx_terrace.css',
|
'static/src/css/*.css'
|
||||||
'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler_glossy.css',
|
|
||||||
'static/src/css/web_calendar.css'
|
|
||||||
],
|
],
|
||||||
'qweb' : [
|
'qweb': [
|
||||||
'static/src/xml/*.xml',
|
'static/src/xml/*.xml',
|
||||||
],
|
],
|
||||||
'auto_install': True
|
'auto_install': True
|
||||||
|
|
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 159 B |
Before Width: | Height: | Size: 622 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 388 B |
Before Width: | Height: | Size: 452 B |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 97 B |
Before Width: | Height: | Size: 97 B |
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 899 B |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 81 B |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 168 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1018 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 141 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 706 B |
Before Width: | Height: | Size: 82 B |
Before Width: | Height: | Size: 82 B |
Before Width: | Height: | Size: 78 B |
Before Width: | Height: | Size: 78 B |
Before Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 616 B |
Before Width: | Height: | Size: 622 B |
Before Width: | Height: | Size: 998 B |
Before Width: | Height: | Size: 401 B |
Before Width: | Height: | Size: 452 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 89 B |
Before Width: | Height: | Size: 89 B |
Before Width: | Height: | Size: 127 B |
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 190 B |
Before Width: | Height: | Size: 119 B |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 123 B |
Before Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 117 B |
Before Width: | Height: | Size: 154 B |
Before Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 241 B |
Before Width: | Height: | Size: 266 B |
|
@ -1,228 +0,0 @@
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains a
|
|
||||||
notice placed by the copyright holder saying it may be distributed under
|
|
||||||
the terms of this General Public License. The "Program", below, refers
|
|
||||||
to any such program or work, and a "work based on the Program" means
|
|
||||||
either the Program or any derivative work under copyright law: that is
|
|
||||||
to say, a work containing the Program or a portion of it, either
|
|
||||||
verbatim or with modifications and/or translated into another language.
|
|
||||||
(Hereinafter, translation is included without limitation in the term
|
|
||||||
"modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of running
|
|
||||||
the Program is not restricted, and the output from the Program is
|
|
||||||
covered only if its contents constitute a work based on the Program
|
|
||||||
(independent of having been made by running the Program). Whether that
|
|
||||||
is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's source
|
|
||||||
code as you receive it, in any medium, provided that you conspicuously
|
|
||||||
and appropriately publish on each copy an appropriate copyright notice
|
|
||||||
and disclaimer of warranty; keep intact all the notices that refer to
|
|
||||||
this License and to the absence of any warranty; and give any other
|
|
||||||
recipients of the Program a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion of
|
|
||||||
it, thus forming a work based on the Program, and copy and distribute
|
|
||||||
such modifications or work under the terms of Section 1 above, provided
|
|
||||||
that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices stating
|
|
||||||
that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in whole
|
|
||||||
or in part contains or is derived from the Program or any part thereof,
|
|
||||||
to be licensed as a whole at no charge to all third parties under the
|
|
||||||
terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively when
|
|
||||||
run, you must cause it, when started running for such interactive use in
|
|
||||||
the most ordinary way, to print or display an announcement including an
|
|
||||||
appropriate copyright notice and a notice that there is no warranty (or
|
|
||||||
else, saying that you provide a warranty) and that users may
|
|
||||||
redistribute the program under these conditions, and telling the user
|
|
||||||
how to view a copy of this License. (Exception: if the Program itself is
|
|
||||||
interactive but does not normally print such an announcement, your work
|
|
||||||
based on the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program, and
|
|
||||||
can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based on
|
|
||||||
the Program, the distribution of the whole must be on the terms of this
|
|
||||||
License, whose permissions for other licensees extend to the entire
|
|
||||||
whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of a
|
|
||||||
storage or distribution medium does not bring the other work under the
|
|
||||||
scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it, under
|
|
||||||
Section 2) in object code or executable form under the terms of Sections
|
|
||||||
1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable source
|
|
||||||
code, which must be distributed under the terms of Sections 1 and 2
|
|
||||||
above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three years, to
|
|
||||||
give any third party, for a charge no more than your cost of physically
|
|
||||||
performing source distribution, a complete machine-readable copy of the
|
|
||||||
corresponding source code, to be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer to
|
|
||||||
distribute corresponding source code. (This alternative is allowed only
|
|
||||||
for noncommercial distribution and only if you received the program in
|
|
||||||
object code or executable form with such an offer, in accord with
|
|
||||||
Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source code
|
|
||||||
means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to control
|
|
||||||
compilation and installation of the executable. However, as a special
|
|
||||||
exception, the source code distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies the
|
|
||||||
executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering access
|
|
||||||
to copy from a designated place, then offering equivalent access to copy
|
|
||||||
the source code from the same place counts as distribution of the source
|
|
||||||
code, even though third parties are not compelled to copy the source
|
|
||||||
along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt otherwise
|
|
||||||
to copy, modify, sublicense or distribute the Program is void, and will
|
|
||||||
automatically terminate your rights under this License. However, parties
|
|
||||||
who have received copies, or rights, from you under this License will
|
|
||||||
not have their licenses terminated so long as such parties remain in
|
|
||||||
full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and all
|
|
||||||
its terms and conditions for copying, distributing or modifying the
|
|
||||||
Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further restrictions
|
|
||||||
on the recipients' exercise of the rights granted herein. You are not
|
|
||||||
responsible for enforcing compliance by third parties to this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot distribute
|
|
||||||
so as to satisfy simultaneously your obligations under this License and
|
|
||||||
any other pertinent obligations, then as a consequence you may not
|
|
||||||
distribute the Program at all. For example, if a patent license would
|
|
||||||
not permit royalty-free redistribution of the Program by all those who
|
|
||||||
receive copies directly or indirectly through you, then the only way you
|
|
||||||
could satisfy both it and this License would be to refrain entirely from
|
|
||||||
distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is implemented
|
|
||||||
by public license practices. Many people have made generous
|
|
||||||
contributions to the wide range of software distributed through that
|
|
||||||
system in reliance on consistent application of that system; it is up to
|
|
||||||
the author/donor to decide if he or she is willing to distribute
|
|
||||||
software through any other system and a licensee cannot impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to be
|
|
||||||
a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License may
|
|
||||||
add an explicit geographical distribution limitation excluding those
|
|
||||||
countries, so that distribution is permitted only in or among countries
|
|
||||||
not thus excluded. In such case, this License incorporates the
|
|
||||||
limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Program does not specify a version
|
|
||||||
number of this License, you may choose any version ever published by the
|
|
||||||
Free Software Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the
|
|
||||||
author to ask for permission. For software which is copyrighted by the
|
|
||||||
Free Software Foundation, write to the Free Software Foundation; we
|
|
||||||
sometimes make exceptions for this. Our decision will be guided by the
|
|
||||||
two goals of preserving the free status of all derivatives of our free
|
|
||||||
software and of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
||||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
|
||||||
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
|
|
||||||
YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
|
||||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
|
||||||
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
|
||||||
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
|
|
||||||
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
|
||||||
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
|
||||||
THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
|
|
||||||
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
dhtmlxScheduler v.3.5 build 120823
|
|
||||||
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
|
|
||||||
(c) DHTMLX Ltd.
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.config.active_link_view = "day";
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function() {
|
|
||||||
var s_d = scheduler.date.str_to_date(scheduler.config.api_date);
|
|
||||||
var d_s = scheduler.date.date_to_str(scheduler.config.api_date);
|
|
||||||
|
|
||||||
var month_x = scheduler.templates.month_day;
|
|
||||||
scheduler.templates.month_day = function(date) {
|
|
||||||
return "<a jump_to='" + d_s(date) + "' href='#'>" + month_x(date) + "</a>";
|
|
||||||
};
|
|
||||||
var week_x = scheduler.templates.week_scale_date;
|
|
||||||
scheduler.templates.week_scale_date = function(date) {
|
|
||||||
return "<a jump_to='" + d_s(date) + "' href='#'>" + week_x(date) + "</a>";
|
|
||||||
};
|
|
||||||
dhtmlxEvent(this._obj, "click", function(e) {
|
|
||||||
var start = e.target || event.srcElement;
|
|
||||||
var to = start.getAttribute("jump_to");
|
|
||||||
if (to) {
|
|
||||||
scheduler.setCurrentView(s_d(to), scheduler.config.active_link_view);
|
|
||||||
if (e && e.preventDefault)
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
|
@ -1,120 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.date.add_agenda = function(date){
|
|
||||||
return scheduler.date.add(date, 1, "year");
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.templates.agenda_time = function(start,end,ev){
|
|
||||||
if (ev._timed)
|
|
||||||
return this.day_date(ev.start_date, ev.end_date, ev)+" "+this.event_date(start);
|
|
||||||
else
|
|
||||||
return scheduler.templates.day_date(start)+" – "+scheduler.templates.day_date(end);
|
|
||||||
};
|
|
||||||
scheduler.templates.agenda_text = function(start,end,event){
|
|
||||||
return event.text;
|
|
||||||
};
|
|
||||||
scheduler.templates.agenda_date = function(){ return ""; };
|
|
||||||
|
|
||||||
scheduler.date.agenda_start=function(){ return scheduler.date.date_part(new Date()); };
|
|
||||||
|
|
||||||
scheduler.attachEvent("onTemplatesReady",function() {
|
|
||||||
var old_dblclick_dhx_cal_data = scheduler.dblclick_dhx_cal_data;
|
|
||||||
scheduler.dblclick_dhx_cal_data = function() {
|
|
||||||
if (this._mode == "agenda") {
|
|
||||||
if (!this.config.readonly && this.config.dblclick_create)
|
|
||||||
this.addEventNow();
|
|
||||||
} else {
|
|
||||||
if (old_dblclick_dhx_cal_data)
|
|
||||||
return old_dblclick_dhx_cal_data.apply(this, arguments);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onSchedulerResize",function(){
|
|
||||||
if (this._mode == "agenda"){
|
|
||||||
this.agenda_view(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var old = scheduler.render_data;
|
|
||||||
scheduler.render_data=function(evs){
|
|
||||||
if (this._mode == "agenda")
|
|
||||||
fill_agenda_tab();
|
|
||||||
else
|
|
||||||
return old.apply(this,arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
var old_render_view_data = scheduler.render_view_data;
|
|
||||||
scheduler.render_view_data = function(){
|
|
||||||
if(this._mode == "agenda") {
|
|
||||||
scheduler._agendaScrollTop = scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop;
|
|
||||||
scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop = 0;
|
|
||||||
}
|
|
||||||
return old_render_view_data.apply(this,arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function set_full_view(mode){
|
|
||||||
if (mode){
|
|
||||||
var l = scheduler.locale.labels;
|
|
||||||
scheduler._els["dhx_cal_header"][0].innerHTML="<div class='dhx_agenda_line'><div>"+l.date+"</div><span style='padding-left:25px'>"+l.description+"</span></div>";
|
|
||||||
scheduler._table_view=true;
|
|
||||||
scheduler.set_sizes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fill_agenda_tab(){
|
|
||||||
//get current date
|
|
||||||
var date = scheduler._date;
|
|
||||||
//select events for which data need to be printed
|
|
||||||
|
|
||||||
var events = scheduler.get_visible_events();
|
|
||||||
events.sort(function(a,b){ return a.start_date>b.start_date?1:-1});
|
|
||||||
|
|
||||||
//generate html for the view
|
|
||||||
var html="<div class='dhx_agenda_area'>";
|
|
||||||
for (var i=0; i<events.length; i++){
|
|
||||||
var ev = events[i];
|
|
||||||
var bg_color = (ev.color?("background:"+ev.color+";"):"");
|
|
||||||
var color = (ev.textColor?("color:"+ev.textColor+";"):"");
|
|
||||||
var ev_class = scheduler.templates.event_class(ev.start_date, ev.end_date, ev);
|
|
||||||
html+="<div class='dhx_agenda_line"+(ev_class?' '+ev_class:'')+"' event_id='"+ev.id+"' style='"+color+""+bg_color+""+(ev._text_style||"")+"'><div class='dhx_agenda_event_time'>"+scheduler.templates.agenda_time(ev.start_date, ev.end_date,ev)+"</div>";
|
|
||||||
html+="<div class='dhx_event_icon icon_details'> </div>";
|
|
||||||
html+="<span>"+scheduler.templates.agenda_text(ev.start_date, ev.end_date, ev)+"</span></div>";
|
|
||||||
}
|
|
||||||
html+="<div class='dhx_v_border'></div></div>";
|
|
||||||
|
|
||||||
//render html
|
|
||||||
scheduler._els["dhx_cal_data"][0].innerHTML = html;
|
|
||||||
scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop = scheduler._agendaScrollTop||0;
|
|
||||||
|
|
||||||
// setting up dhx_v_border size
|
|
||||||
var agenda_area = scheduler._els["dhx_cal_data"][0].childNodes[0];
|
|
||||||
var v_border = agenda_area.childNodes[agenda_area.childNodes.length-1];
|
|
||||||
v_border.style.height = (agenda_area.offsetHeight < scheduler._els["dhx_cal_data"][0].offsetHeight) ? "100%" : (agenda_area.offsetHeight+"px");
|
|
||||||
|
|
||||||
var t=scheduler._els["dhx_cal_data"][0].firstChild.childNodes;
|
|
||||||
scheduler._els["dhx_cal_date"][0].innerHTML=scheduler.templates.agenda_date(scheduler._min_date, scheduler._max_date, scheduler._mode);
|
|
||||||
|
|
||||||
scheduler._rendered=[];
|
|
||||||
for (var i=0; i < t.length-1; i++)
|
|
||||||
scheduler._rendered[i]=t[i]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.agenda_view=function(mode){
|
|
||||||
scheduler._min_date = scheduler.config.agenda_start||scheduler.date.agenda_start(scheduler._date);
|
|
||||||
scheduler._max_date = scheduler.config.agenda_end||scheduler.date.add_agenda(scheduler._min_date, 1);
|
|
||||||
scheduler._table_view = true;
|
|
||||||
set_full_view(mode);
|
|
||||||
if (mode){
|
|
||||||
//agenda tab activated
|
|
||||||
fill_agenda_tab();
|
|
||||||
} else {
|
|
||||||
//agenda tab de-activated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,133 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
scheduler.config.all_timed = "short";
|
|
||||||
scheduler.config.update_render = true;
|
|
||||||
|
|
||||||
var is_event_short = function (ev) {
|
|
||||||
return !((ev.end_date - ev.start_date)/(1000*60*60) >= 24);
|
|
||||||
};
|
|
||||||
|
|
||||||
var old_prerender_events_line = scheduler._pre_render_events_line;
|
|
||||||
scheduler._pre_render_events_line = function(evs, hold){
|
|
||||||
if (!this.config.all_timed)
|
|
||||||
return old_prerender_events_line.call(this, evs, hold);
|
|
||||||
|
|
||||||
for (var i=0; i < evs.length; i++) {
|
|
||||||
var ev=evs[i];
|
|
||||||
|
|
||||||
if (!ev._timed) {
|
|
||||||
|
|
||||||
if (this.config.all_timed == "short") {
|
|
||||||
if (!is_event_short(ev)) {
|
|
||||||
evs.splice(i--,1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var ce = this._lame_copy({}, ev); // current event (event for one specific day) is copy of original with modified dates
|
|
||||||
|
|
||||||
ce.start_date = new Date(ce.start_date); // as lame copy doesn't copy date objects
|
|
||||||
|
|
||||||
var next_day = scheduler.date.add(ev.start_date, 1, "day");
|
|
||||||
next_day = scheduler.date.date_part(next_day);
|
|
||||||
|
|
||||||
if (ev.end_date < next_day) {
|
|
||||||
ce.end_date = new Date(ev.end_date);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ce.end_date = next_day;
|
|
||||||
if (this.config.last_hour != 24) { // if specific last_hour was set (e.g. 20)
|
|
||||||
ce.end_date = scheduler.date.date_part(new Date(ce.start_date));
|
|
||||||
ce.end_date.setHours(this.config.last_hour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var event_changed = false;
|
|
||||||
if (ce.start_date < this._max_date && ce.end_date > this._min_date && ce.start_date < ce.end_date) {
|
|
||||||
evs[i] = ce; // adding another event in collection
|
|
||||||
event_changed = true;
|
|
||||||
}
|
|
||||||
if (ce.start_date > ce.end_date) {
|
|
||||||
evs.splice(i--,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var re = this._lame_copy({}, ev); // remaining event, copy of original with modified start_date (making range more narrow)
|
|
||||||
re.end_date = new Date(re.end_date);
|
|
||||||
if (re.start_date < this._min_date)
|
|
||||||
re.start_date = new Date(this._min_date);
|
|
||||||
else
|
|
||||||
re.start_date = this.date.add(ev.start_date, 1, "day");
|
|
||||||
|
|
||||||
re.start_date.setHours(this.config.first_hour);
|
|
||||||
re.start_date.setMinutes(0); // as we are starting only with whole hours
|
|
||||||
if (re.start_date < this._max_date && re.start_date < re.end_date) {
|
|
||||||
if (event_changed)
|
|
||||||
evs.splice(i+1,0,re);
|
|
||||||
else {
|
|
||||||
evs[i--] = re;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// in case of all_timed pre_render is not applied to the original event
|
|
||||||
// so we need to force redraw in case of dnd
|
|
||||||
var redraw = (this._drag_mode == 'move')?false:hold;
|
|
||||||
return old_prerender_events_line.call(this, evs, redraw);
|
|
||||||
};
|
|
||||||
var old_get_visible_events = scheduler.get_visible_events;
|
|
||||||
scheduler.get_visible_events = function(only_timed){
|
|
||||||
if (!this.config.all_timed)
|
|
||||||
return old_get_visible_events.call(this, only_timed);
|
|
||||||
return old_get_visible_events.call(this, false); // only timed = false
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onBeforeViewChange", function (old_mode, old_date, mode, date) {
|
|
||||||
scheduler._allow_dnd = (mode == "day" || mode == "week");
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
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( !(this._table_view || this.config.multi_day) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.config.multi_day && !this._table_view){
|
|
||||||
|
|
||||||
var tvs = [];
|
|
||||||
var tvd = [];
|
|
||||||
for (var i=0; i < evs.length; i++){
|
|
||||||
if (evs[i]._timed || this.config.all_timed === true || (this.config.all_timed == "short" && is_event_short(evs[i])) )
|
|
||||||
tvs.push(evs[i]);
|
|
||||||
else
|
|
||||||
tvd.push(evs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// normal events
|
|
||||||
this._rendered_location = this._els['dhx_cal_data'][0];
|
|
||||||
this._table_view=false;
|
|
||||||
this.render_data(tvs, hold);
|
|
||||||
|
|
||||||
// multiday events
|
|
||||||
this._rendered_location = this._els['dhx_multi_day'][0];
|
|
||||||
this._table_view = true;
|
|
||||||
this.render_data(tvd, hold);
|
|
||||||
this._table_view=false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this._rendered_location = this._els['dhx_cal_data'][0];
|
|
||||||
this.render_data(evs, hold);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
var temp_section;
|
|
||||||
var before;
|
|
||||||
|
|
||||||
scheduler.config.collision_limit = 1;
|
|
||||||
|
|
||||||
function _setTempSection(event_id) { // for custom views (matrix, timeline, units)
|
|
||||||
var pr = scheduler._props?scheduler._props[scheduler._mode]:null;
|
|
||||||
var matrix = scheduler.matrix?scheduler.matrix[scheduler._mode]:null;
|
|
||||||
var checked_mode = pr||matrix; // units or matrix mode
|
|
||||||
if(pr)
|
|
||||||
var map_to = checked_mode.map_to;
|
|
||||||
if(matrix)
|
|
||||||
var map_to = checked_mode.y_property;
|
|
||||||
if ((checked_mode) && event_id){
|
|
||||||
temp_section = scheduler.getEvent(event_id)[map_to];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeDrag",function(id){
|
|
||||||
_setTempSection(id);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeLightbox",function(id){
|
|
||||||
var ev = scheduler.getEvent(id);
|
|
||||||
before = [ev.start_date, ev.end_date];
|
|
||||||
_setTempSection(id);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventChanged",function(id){
|
|
||||||
if (!id) return true;
|
|
||||||
var ev = scheduler.getEvent(id);
|
|
||||||
if (!collision_check(ev)){
|
|
||||||
if (!before) return false;
|
|
||||||
ev.start_date = before[0];
|
|
||||||
ev.end_date = before[1];
|
|
||||||
ev._timed=this.is_one_day_event(ev);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeEventChanged",function(ev,e,is_new){
|
|
||||||
return collision_check(ev);
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventSave",function(id, edited_ev, is_new){
|
|
||||||
edited_ev = scheduler._lame_clone(edited_ev);
|
|
||||||
edited_ev.id = id;
|
|
||||||
|
|
||||||
if(edited_ev.rec_type){
|
|
||||||
scheduler._roll_back_dates(data_copy);
|
|
||||||
}
|
|
||||||
return collision_check(edited_ev); // in case user creates event on one date but then edited it another
|
|
||||||
});
|
|
||||||
|
|
||||||
function collision_check(ev){
|
|
||||||
var evs = [];
|
|
||||||
var collision_limit = scheduler.config.collision_limit;
|
|
||||||
if (ev.rec_type) {
|
|
||||||
var evs_dates = scheduler.getRecDates(ev);
|
|
||||||
for(var k=0; k<evs_dates.length; k++) {
|
|
||||||
var tevs = scheduler.getEvents(evs_dates[k].start_date, evs_dates[k].end_date);
|
|
||||||
for(var j=0; j<tevs.length; j++) {
|
|
||||||
if ((tevs[j].event_pid || tevs[j].id) != ev.id )
|
|
||||||
evs.push(tevs[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
evs = scheduler.getEvents(ev.start_date, ev.end_date);
|
|
||||||
for (var i=0; i<evs.length; i++) {
|
|
||||||
if (evs[i].id == ev.id) {
|
|
||||||
evs.splice(i,1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pr = scheduler._props?scheduler._props[scheduler._mode]:null;
|
|
||||||
var matrix = scheduler.matrix?scheduler.matrix[scheduler._mode]:null;
|
|
||||||
|
|
||||||
var checked_mode = pr||matrix;
|
|
||||||
if(pr)
|
|
||||||
var map_to = checked_mode.map_to;
|
|
||||||
if(matrix)
|
|
||||||
var map_to = checked_mode.y_property;
|
|
||||||
|
|
||||||
var single = true;
|
|
||||||
if (checked_mode) { // custom view
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < evs.length; i++)
|
|
||||||
|
|
||||||
if (evs[i][map_to] == ev[map_to] && evs[i].id != ev.id)
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (count >= collision_limit) {
|
|
||||||
|
|
||||||
single = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( evs.length >= collision_limit )
|
|
||||||
single = false;
|
|
||||||
}
|
|
||||||
if (!single) {
|
|
||||||
var res = !scheduler.callEvent("onEventCollision",[ev,evs]);
|
|
||||||
if (!res) {
|
|
||||||
ev[map_to] = temp_section||ev[map_to]; // from _setTempSection for custom views
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return single;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
function setCookie(name,cookie_param,value) {
|
|
||||||
var str = name + "=" + value + (cookie_param?("; "+cookie_param):"");
|
|
||||||
document.cookie = str;
|
|
||||||
}
|
|
||||||
function getCookie(name) {
|
|
||||||
var search = name + "=";
|
|
||||||
if (document.cookie.length > 0) {
|
|
||||||
var offset = document.cookie.indexOf(search);
|
|
||||||
if (offset != -1) {
|
|
||||||
offset += search.length;
|
|
||||||
var end = document.cookie.indexOf(";", offset);
|
|
||||||
if (end == -1)
|
|
||||||
end = document.cookie.length;
|
|
||||||
return document.cookie.substring(offset, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
var first = true;
|
|
||||||
scheduler.attachEvent("onBeforeViewChange",function(om,od,m,d){
|
|
||||||
if (first){
|
|
||||||
first = false;
|
|
||||||
var data=getCookie("scheduler_settings");
|
|
||||||
if (data){
|
|
||||||
data = unescape(data).split("@");
|
|
||||||
data[0] = this.templates.xml_date(data[0]);
|
|
||||||
window.setTimeout(function(){
|
|
||||||
scheduler.setCurrentView(data[0],data[1]);
|
|
||||||
},1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var text = escape(this.templates.xml_format(d||od)+"@"+(m||om));
|
|
||||||
setCookie("scheduler_settings","expires=Sun, 31 Jan 9999 22:00:00 GMT",text);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
scheduler.config.fix_tab_position = true;
|
|
||||||
scheduler.config.use_select_menu_space = true;
|
|
||||||
scheduler.config.hour_size_px = 44;
|
|
||||||
scheduler.xy.nav_height = 59;
|
|
||||||
scheduler.xy.bar_height = 24;
|
|
||||||
scheduler.config.wide_form = true;
|
|
||||||
scheduler.xy.lightbox_additional_height = 90;
|
|
||||||
|
|
||||||
scheduler.config.displayed_event_color = "#ff4a4a";
|
|
||||||
scheduler.config.displayed_event_text_color = "#ffef80";
|
|
||||||
|
|
||||||
scheduler.templates.event_bar_date = function(start,end,ev) {
|
|
||||||
return "• <b>"+scheduler.templates.event_date(start)+"</b> ";
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onLightbox", function(){
|
|
||||||
var lightbox = scheduler.getLightbox();
|
|
||||||
var divs = lightbox.getElementsByTagName('div');
|
|
||||||
for (var i=0; i<divs.length; i++) {
|
|
||||||
var div = divs[i];
|
|
||||||
if (div.className == "dhx_close_icon") {
|
|
||||||
div.onclick = function() {
|
|
||||||
scheduler.endLightbox(false, lightbox);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler._lightbox_template="<div class='dhx_cal_ltitle'><span class='dhx_mark'> </span><span class='dhx_time'></span><span class='dhx_title'></span><div class='dhx_close_icon'></div></div><div class='dhx_cal_larea'></div>";
|
|
||||||
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function() {
|
|
||||||
|
|
||||||
var date_to_str = scheduler.date.date_to_str("%d");
|
|
||||||
var old_month_day = scheduler.templates.month_day;
|
|
||||||
scheduler.templates.month_day = function(date) {
|
|
||||||
if (this._mode == "month") {
|
|
||||||
var label = date_to_str(date);
|
|
||||||
if (date.getDate() == 1) {
|
|
||||||
label = scheduler.locale.date.month_full[date.getMonth()] + " " + label;
|
|
||||||
}
|
|
||||||
if (+date == +scheduler.date.date_part(new Date)) {
|
|
||||||
label = scheduler.locale.labels.dhx_cal_today_button + " " + label;
|
|
||||||
}
|
|
||||||
return label;
|
|
||||||
} else {
|
|
||||||
return old_month_day.call(this, date);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scheduler.config.fix_tab_position){
|
|
||||||
var navline_divs = scheduler._els["dhx_cal_navline"][0].getElementsByTagName('div');
|
|
||||||
var tabs = [];
|
|
||||||
var last = 211;
|
|
||||||
for (var i=0; i<navline_divs.length; i++) {
|
|
||||||
var div = navline_divs[i];
|
|
||||||
var name = div.getAttribute("name");
|
|
||||||
if (name) { // mode tab
|
|
||||||
div.style.right = "auto";
|
|
||||||
switch (name) {
|
|
||||||
case "day_tab":
|
|
||||||
div.style.left = "14px";
|
|
||||||
div.className += " dhx_cal_tab_first";
|
|
||||||
break;
|
|
||||||
case "week_tab":
|
|
||||||
div.style.left = "75px";
|
|
||||||
break;
|
|
||||||
case "month_tab":
|
|
||||||
div.style.left = "136px";
|
|
||||||
div.className += " dhx_cal_tab_last";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
div.style.left = last+"px";
|
|
||||||
div.className += " dhx_cal_tab_standalone";
|
|
||||||
last = last + 14 + div.offsetWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.form_blocks['combo']={
|
|
||||||
render:function(sns) {
|
|
||||||
if (!sns.cached_options)
|
|
||||||
sns.cached_options = {};
|
|
||||||
var res = '';
|
|
||||||
res += "<div class='"+sns.type+"' style='height:"+(sns.height||20)+"px;' ></div>";
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
set_value:function(node,value,ev,config){
|
|
||||||
if(node._combo) {
|
|
||||||
node._combo.destructor();
|
|
||||||
}
|
|
||||||
window.dhx_globalImgPath = config.image_path||'/';
|
|
||||||
node._combo = new dhtmlXCombo(node, config.name, node.offsetWidth-8);
|
|
||||||
if (config.options_height)
|
|
||||||
node._combo.setOptionHeight(config.options_height);
|
|
||||||
var combo = node._combo;
|
|
||||||
combo.enableFilteringMode(!!config.filtering, config.script_path||null, !!config.cache);
|
|
||||||
|
|
||||||
if (!config.script_path) { // script-side filtration is used
|
|
||||||
var all_options = [];
|
|
||||||
for (var i = 0; i < config.options.length; i++) {
|
|
||||||
var single_option = [];
|
|
||||||
single_option.push(config.options[i].key);
|
|
||||||
single_option.push(config.options[i].label);
|
|
||||||
all_options.push(single_option);
|
|
||||||
}
|
|
||||||
combo.addOption(all_options);
|
|
||||||
if (ev[config.map_to]) {
|
|
||||||
var index = combo.getIndexByValue(ev[config.map_to]);
|
|
||||||
combo.selectOption(index);
|
|
||||||
}
|
|
||||||
} else { // server-side filtration is used
|
|
||||||
var selected_id = ev[config.map_to];
|
|
||||||
if (selected_id) {
|
|
||||||
if (config.cached_options[selected_id]) {
|
|
||||||
combo.addOption(selected_id, config.cached_options[selected_id]);
|
|
||||||
combo.disable(1);
|
|
||||||
combo.selectOption(0);
|
|
||||||
combo.disable(0);
|
|
||||||
} else {
|
|
||||||
dhtmlxAjax.get(config.script_path+"?id="+selected_id+"&uid="+scheduler.uid(), function(result){
|
|
||||||
var option = result.doXPath("//option")[0];
|
|
||||||
var label = option.childNodes[0].nodeValue;
|
|
||||||
config.cached_options[selected_id] = label;
|
|
||||||
combo.addOption(selected_id, label);
|
|
||||||
combo.disable(1);
|
|
||||||
combo.selectOption(0);
|
|
||||||
combo.disable(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
combo.setComboValue(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get_value:function(node,ev,config) {
|
|
||||||
var selected_id = node._combo.getSelectedValue(); // value = key
|
|
||||||
if (config.script_path) {
|
|
||||||
config.cached_options[selected_id] = node._combo.getSelectedText();
|
|
||||||
}
|
|
||||||
return selected_id;
|
|
||||||
},
|
|
||||||
focus:function(node){
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.form_blocks['radio']={
|
|
||||||
render:function(sns) {
|
|
||||||
var res = '';
|
|
||||||
res += "<div class='dhx_cal_ltext dhx_cal_radio' style='height:"+sns.height+"px;' >";
|
|
||||||
for (var i=0; i<sns.options.length; i++) {
|
|
||||||
var id = scheduler.uid();
|
|
||||||
res += "<input id='"+id+"' type='radio' name='"+sns.name+"' value='"+sns.options[i].key+"'><label for='"+id+"'>"+" "+sns.options[i].label+"</label>";
|
|
||||||
if(sns.vertical)
|
|
||||||
res += "<br/>";
|
|
||||||
}
|
|
||||||
res += "</div>";
|
|
||||||
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
set_value:function(node,value,ev,config){
|
|
||||||
var radiobuttons = node.getElementsByTagName('input');
|
|
||||||
for (var i = 0; i < radiobuttons.length; i++) {
|
|
||||||
radiobuttons[i].checked = false;
|
|
||||||
var checked_value = ev[config.map_to]||value;
|
|
||||||
if (radiobuttons[i].value == checked_value) {
|
|
||||||
radiobuttons[i].checked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get_value:function(node,ev,config){
|
|
||||||
var radiobuttons = node.getElementsByTagName('input');
|
|
||||||
for(var i=0; i<radiobuttons.length; i++) {
|
|
||||||
if(radiobuttons[i].checked) {
|
|
||||||
return radiobuttons[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
focus:function(node){
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.form_blocks['checkbox']={
|
|
||||||
render:function(sns) {
|
|
||||||
if (scheduler.config.wide_form)
|
|
||||||
return '<div class="dhx_cal_wide_checkbox"></div>';
|
|
||||||
else
|
|
||||||
return '';
|
|
||||||
},
|
|
||||||
set_value:function(node,value,ev,config){
|
|
||||||
node=document.getElementById(config.id);
|
|
||||||
var id = scheduler.uid();
|
|
||||||
var isChecked = (typeof config.checked_value != "undefined") ? ev[config.map_to] == config.checked_value : !!value;
|
|
||||||
node.className += " dhx_cal_checkbox";
|
|
||||||
var check_html = "<input id='"+id+"' type='checkbox' value='true' name='"+config.name+"'"+((isChecked)?"checked='true'":'')+"'>";
|
|
||||||
var label_html = "<label for='"+id+"'>"+(scheduler.locale.labels["section_"+config.name]||config.name)+"</label>";
|
|
||||||
if (scheduler.config.wide_form){
|
|
||||||
node.innerHTML = label_html;
|
|
||||||
node.nextSibling.innerHTML=check_html;
|
|
||||||
} else
|
|
||||||
node.innerHTML=check_html+label_html;
|
|
||||||
|
|
||||||
if (config.handler) {
|
|
||||||
var checkbox = node.getElementsByTagName('input')[0];
|
|
||||||
checkbox.onclick = config.handler;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get_value:function(node,ev,config){
|
|
||||||
node=document.getElementById(config.id);
|
|
||||||
var checkbox = node.getElementsByTagName('input')[0]; // moved to the header
|
|
||||||
if (!checkbox)
|
|
||||||
checkbox = node.nextSibling.getElementsByTagName('input')[0];
|
|
||||||
return (checkbox.checked)?(config.checked_value||true):(config.unchecked_value||false);
|
|
||||||
},
|
|
||||||
focus:function(node){
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.expand = function(){
|
|
||||||
var t = scheduler._obj;
|
|
||||||
do {
|
|
||||||
t._position = t.style.position||"";
|
|
||||||
t.style.position = "static";
|
|
||||||
} while ((t = t.parentNode) && t.style );
|
|
||||||
t = scheduler._obj;
|
|
||||||
t.style.position="absolute";
|
|
||||||
t._width = t.style.width;
|
|
||||||
t._height = t.style.height;
|
|
||||||
t.style.width = t.style.height = "100%";
|
|
||||||
t.style.top = t.style.left = "0px";
|
|
||||||
|
|
||||||
var top = document.body;
|
|
||||||
top.scrollTop = 0;
|
|
||||||
|
|
||||||
top = top.parentNode;
|
|
||||||
if (top)
|
|
||||||
top.scrollTop = 0;
|
|
||||||
document.body._overflow=document.body.style.overflow||"";
|
|
||||||
document.body.style.overflow = "hidden";
|
|
||||||
scheduler._maximize();
|
|
||||||
};
|
|
||||||
scheduler.collapse = function(){
|
|
||||||
var t = scheduler._obj;
|
|
||||||
do {
|
|
||||||
t.style.position = t._position;
|
|
||||||
} while ((t = t.parentNode) && t.style );
|
|
||||||
t = scheduler._obj;
|
|
||||||
t.style.width = t._width;
|
|
||||||
t.style.height = t._height;
|
|
||||||
document.body.style.overflow=document.body._overflow;
|
|
||||||
scheduler._maximize();
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onTemplatesReady",function(){
|
|
||||||
var t = document.createElement("DIV");
|
|
||||||
t.className="dhx_expand_icon";
|
|
||||||
scheduler.toggleIcon = t;
|
|
||||||
scheduler._obj.appendChild(t);
|
|
||||||
t.onclick = function(){
|
|
||||||
if (!scheduler.expanded)
|
|
||||||
scheduler.expand();
|
|
||||||
else
|
|
||||||
scheduler.collapse();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler._maximize = function(){
|
|
||||||
this.expanded = !this.expanded;
|
|
||||||
this.toggleIcon.style.backgroundPosition="0px "+(this.expanded?"0":"18")+"px";
|
|
||||||
|
|
||||||
var directions = ['left', 'top'];
|
|
||||||
for(var i=0; i<directions.length; i++) {
|
|
||||||
var margin = scheduler.xy['margin_'+directions[i]];
|
|
||||||
var prev_margin = scheduler['_prev_margin_'+directions[i]];
|
|
||||||
if(scheduler.xy['margin_'+directions[i]]){
|
|
||||||
scheduler['_prev_margin_'+directions[i]] = scheduler.xy['margin_'+directions[i]];
|
|
||||||
scheduler.xy['margin_'+directions[i]] = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(prev_margin){
|
|
||||||
scheduler.xy['margin_'+directions[i]] = scheduler['_prev_margin_'+directions[i]];
|
|
||||||
delete scheduler['_prev_margin_'+directions[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scheduler.callEvent("onSchedulerResize",[]))
|
|
||||||
scheduler.update_view();
|
|
||||||
};
|
|
|
@ -1,470 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
scheduler.grid = {
|
|
||||||
sort_rules:{
|
|
||||||
"int":function(a,b, getVal){ return getVal(a)*1 < getVal(b)*1?1:-1},
|
|
||||||
"str":function(a,b, getVal){ return getVal(a) < getVal(b)?1:-1},
|
|
||||||
"date":function(a,b, getVal){ return new Date(getVal(a))< new Date(getVal(b))?1:-1}
|
|
||||||
},
|
|
||||||
_getObjName:function(name){
|
|
||||||
return "grid_"+name;
|
|
||||||
},
|
|
||||||
_getViewName:function(objName){
|
|
||||||
return objName.replace(/^grid_/,'');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)();
|
|
||||||
/*
|
|
||||||
obj={
|
|
||||||
name:'grid_name'
|
|
||||||
fields:[
|
|
||||||
{ id:"id", label:"Id", width:80, sort:"int/date/str", template:function(start_date, end_date, ev){ return ""}, align:"right/left/center" },
|
|
||||||
{ id:"text", label:"Text", width:'*', css:"class_name", sort:function(a,b){ return 1 or -1}, valign:'top/bottom/middle' }
|
|
||||||
...
|
|
||||||
],
|
|
||||||
from:new Date(0),
|
|
||||||
to:Date:new Date(9999,1,1),
|
|
||||||
rowHeight:int,
|
|
||||||
paging:true/false,
|
|
||||||
select:true/false
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.createGridView=function(obj){
|
|
||||||
|
|
||||||
var name = obj.name || 'grid';
|
|
||||||
var objName = scheduler.grid._getObjName(name);
|
|
||||||
|
|
||||||
scheduler.config[name + '_start'] = obj.from ||(new Date(0));
|
|
||||||
scheduler.config[name + '_end'] = obj.to || (new Date(9999,1,1));
|
|
||||||
|
|
||||||
scheduler[objName] = obj;
|
|
||||||
scheduler[objName].defPadding = 8;
|
|
||||||
scheduler[objName].columns = scheduler[objName].fields;
|
|
||||||
delete scheduler[objName].fields;
|
|
||||||
function isValidSize(size){
|
|
||||||
return !(size !== undefined && (size*1 != size || size < 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
var cols = scheduler[objName].columns;
|
|
||||||
for(var i=0; i < cols.length; i++){
|
|
||||||
if(isValidSize(cols[i].width))
|
|
||||||
cols[i].initialWidth = cols[i].width;
|
|
||||||
if(!isValidSize(cols[i].paddingLeft))
|
|
||||||
delete cols[i].paddingLeft;
|
|
||||||
if(!isValidSize(cols[i].paddingRight))
|
|
||||||
delete cols[i].paddingRight;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler[objName].select = obj.select === undefined ? true : obj.select;
|
|
||||||
if(scheduler.locale.labels[name +'_tab'] === undefined)
|
|
||||||
scheduler.locale.labels[name +'_tab'] = scheduler[objName].label || scheduler.locale.labels.grid_tab;
|
|
||||||
|
|
||||||
scheduler[objName]._selected_divs = [];
|
|
||||||
|
|
||||||
scheduler.date[name+'_start']=function(d){ return d; };
|
|
||||||
scheduler.date['add_' + name] = function(date, inc){
|
|
||||||
var ndate = new Date(date);
|
|
||||||
ndate.setMonth(ndate.getMonth()+inc);
|
|
||||||
return ndate;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.templates[name+"_date"] = function(start, end){
|
|
||||||
return scheduler.templates.day_date(start)+" - "+scheduler.templates.day_date(end)
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.attachEvent("onTemplatesReady",function(){
|
|
||||||
|
|
||||||
scheduler.templates[name + '_full_date'] = function(start,end,ev){
|
|
||||||
if (ev._timed)
|
|
||||||
return this.day_date(ev.start_date, ev.end_date, ev)+" "+this.event_date(start);
|
|
||||||
else
|
|
||||||
return scheduler.templates.day_date(start)+" – "+scheduler.templates.day_date(end);
|
|
||||||
};
|
|
||||||
scheduler.templates[name + '_single_date'] = function(date){
|
|
||||||
return scheduler.templates.day_date(date)+" "+this.event_date(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.attachEvent("onDblClick",function(event_id, native_event_object){
|
|
||||||
if(this._mode == name){
|
|
||||||
scheduler._click.buttons['details'](event_id)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onClick",function(event_id, native_event_object){
|
|
||||||
if(this._mode == name && scheduler[objName].select ){
|
|
||||||
scheduler.grid.unselectEvent('', name);
|
|
||||||
scheduler.grid.selectEvent(event_id, name, native_event_object);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.templates[name + '_field'] = function(field_name, event){
|
|
||||||
return event[field_name];
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerResize", function() {
|
|
||||||
if (this._mode == name) {
|
|
||||||
this[name + '_view'](true);
|
|
||||||
// timeout used to run code after all onSchedulerResize handlers are finished
|
|
||||||
window.setTimeout(function(){
|
|
||||||
// we need to call event manually because handler return false, and blocks default logic
|
|
||||||
scheduler.callEvent("onAfterSchedulerResize", []);
|
|
||||||
},1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var old = scheduler.render_data;
|
|
||||||
scheduler.render_data=function(evs){
|
|
||||||
if (this._mode == name)
|
|
||||||
scheduler.grid._fill_grid_tab(objName);
|
|
||||||
else
|
|
||||||
return old.apply(this,arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
var old_render_view_data = scheduler.render_view_data;
|
|
||||||
scheduler.render_view_data=function(){
|
|
||||||
if(this._mode == name) {
|
|
||||||
scheduler.grid._gridScrollTop = scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop;
|
|
||||||
scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop = 0;
|
|
||||||
scheduler._els["dhx_cal_data"][0].style.overflowY = 'auto';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
scheduler._els["dhx_cal_data"][0].style.overflowY = 'auto';
|
|
||||||
}
|
|
||||||
return old_render_view_data.apply(this,arguments);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
scheduler[name+'_view']=function(mode){
|
|
||||||
if (mode){
|
|
||||||
scheduler._min_date = scheduler[objName].paging ? scheduler.date[name+'_start'](new Date(scheduler._date)) : scheduler.config[name + '_start'];
|
|
||||||
scheduler._max_date = scheduler[objName].paging ? scheduler.date.add(scheduler._min_date, 1, name) : scheduler.config[name + '_end'];
|
|
||||||
|
|
||||||
scheduler.grid.set_full_view(objName);
|
|
||||||
if(scheduler._min_date > new Date(0) && scheduler._max_date < (new Date(9999,1,1)))
|
|
||||||
scheduler._els["dhx_cal_date"][0].innerHTML=scheduler.templates[name+"_date"](scheduler._min_date,scheduler._max_date);
|
|
||||||
else
|
|
||||||
scheduler._els["dhx_cal_date"][0].innerHTML="";
|
|
||||||
|
|
||||||
//grid tab activated
|
|
||||||
scheduler.grid._fill_grid_tab(objName);
|
|
||||||
scheduler._gridView = objName;
|
|
||||||
} else {
|
|
||||||
scheduler.grid._sort_marker = null;
|
|
||||||
delete scheduler._gridView;
|
|
||||||
scheduler._rendered=[];
|
|
||||||
scheduler[objName]._selected_divs = [];
|
|
||||||
//grid tab de-activated
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.dblclick_dhx_grid_area=function(){
|
|
||||||
if (!this.config.readonly && this.config.dblclick_create)
|
|
||||||
this.addEventNow();
|
|
||||||
};
|
|
||||||
|
|
||||||
if(scheduler._click.dhx_cal_header){
|
|
||||||
scheduler._old_header_click = scheduler._click.dhx_cal_header;
|
|
||||||
}
|
|
||||||
scheduler._click.dhx_cal_header=function(e){
|
|
||||||
if(scheduler._gridView){
|
|
||||||
var event = e||window.event;
|
|
||||||
var params = scheduler.grid.get_sort_params(event, scheduler._gridView);
|
|
||||||
|
|
||||||
scheduler.grid.draw_sort_marker(event.originalTarget || event.srcElement, params.dir);
|
|
||||||
|
|
||||||
scheduler.clear_view();
|
|
||||||
scheduler.grid._fill_grid_tab(scheduler._gridView, params);
|
|
||||||
}
|
|
||||||
else if(scheduler._old_header_click)
|
|
||||||
return scheduler._old_header_click.apply(this,arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid.selectEvent = function(id, view_name, native_event_object){
|
|
||||||
if(scheduler.callEvent("onBeforeRowSelect",[id,native_event_object])){
|
|
||||||
var objName = scheduler.grid._getObjName(view_name);
|
|
||||||
|
|
||||||
scheduler.for_rendered(id, function(event_div){
|
|
||||||
event_div.className += " dhx_grid_event_selected";
|
|
||||||
scheduler[objName]._selected_divs.push(event_div);
|
|
||||||
});
|
|
||||||
scheduler._select_id = id;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid._unselectDiv= function(div){
|
|
||||||
div.className = div.className.replace(/ dhx_grid_event_selected/,'');
|
|
||||||
}
|
|
||||||
scheduler.grid.unselectEvent = function(id, view_name){
|
|
||||||
var objName = scheduler.grid._getObjName(view_name);
|
|
||||||
if(!objName || !scheduler[objName]._selected_divs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!id){
|
|
||||||
for(var i=0; i<scheduler[objName]._selected_divs.length; i++)
|
|
||||||
scheduler.grid._unselectDiv(scheduler[objName]._selected_divs[i]);
|
|
||||||
|
|
||||||
scheduler[objName]._selected_divs = [];
|
|
||||||
|
|
||||||
}else{
|
|
||||||
for(var i=0; i<scheduler[objName]._selected_divs.length; i++)
|
|
||||||
if(scheduler[objName]._selected_divs[i].getAttribute('event_id') == id){
|
|
||||||
scheduler.grid._unselectDiv(scheduler[objName]._selected_divs[i]);
|
|
||||||
scheduler[objName]._selected_divs.slice(i,1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid.get_sort_params = function(event, objName){
|
|
||||||
var targ = event.originalTarget || event.srcElement;
|
|
||||||
if(targ.className == 'dhx_grid_view_sort')
|
|
||||||
targ = targ.parentNode;
|
|
||||||
if(!targ.className || targ.className.indexOf("dhx_grid_sort_asc") == -1)
|
|
||||||
var direction = 'asc';
|
|
||||||
else
|
|
||||||
var direction = 'desc';
|
|
||||||
|
|
||||||
var index = 0;
|
|
||||||
for(var i =0; i < targ.parentNode.childNodes.length; i++){
|
|
||||||
if(targ.parentNode.childNodes[i] == targ){
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var value = null;
|
|
||||||
if(scheduler[objName].columns[index].template){
|
|
||||||
var template = scheduler[objName].columns[index].template
|
|
||||||
value = function(ev){
|
|
||||||
return template(ev.start_date, ev.end_date, ev);
|
|
||||||
};
|
|
||||||
}else{
|
|
||||||
var field = scheduler[objName].columns[index].id;
|
|
||||||
if(field == "date")
|
|
||||||
field = "start_date";
|
|
||||||
value = function(ev){ return ev[field];}
|
|
||||||
}
|
|
||||||
|
|
||||||
var rule = scheduler[objName].columns[index].sort;
|
|
||||||
|
|
||||||
if(typeof rule != 'function'){
|
|
||||||
rule = scheduler.grid.sort_rules[rule] || scheduler.grid.sort_rules['str'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {dir:direction, value:value, rule:rule};
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid.draw_sort_marker = function(node, direction){
|
|
||||||
if(node.className == 'dhx_grid_view_sort')
|
|
||||||
node = node.parentNode;
|
|
||||||
|
|
||||||
if(scheduler.grid._sort_marker){
|
|
||||||
scheduler.grid._sort_marker.className = scheduler.grid._sort_marker.className.replace(/( )?dhx_grid_sort_(asc|desc)/, '');
|
|
||||||
scheduler.grid._sort_marker.removeChild(scheduler.grid._sort_marker.lastChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
node.className += " dhx_grid_sort_"+direction;
|
|
||||||
scheduler.grid._sort_marker = node;
|
|
||||||
var html = "<div class='dhx_grid_view_sort' style='left:"+(+node.style.width.replace('px','') -15+node.offsetLeft)+"px'> </div>";
|
|
||||||
node.innerHTML += html;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid.sort_grid=function(sort){
|
|
||||||
|
|
||||||
var sort = sort || {dir:'desc', value:function(ev){return ev.start_date;}, rule:scheduler.grid.sort_rules['date']};
|
|
||||||
|
|
||||||
var events = scheduler.get_visible_events();
|
|
||||||
|
|
||||||
if(sort.dir == 'desc')
|
|
||||||
events.sort(function(a,b){return sort.rule(a,b,sort.value)});
|
|
||||||
else
|
|
||||||
events.sort(function(a,b){return -sort.rule(a,b, sort.value)});
|
|
||||||
return events;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.grid.set_full_view = function(mode){
|
|
||||||
if (mode){
|
|
||||||
var l = scheduler.locale.labels;
|
|
||||||
var html =scheduler.grid._print_grid_header(mode);
|
|
||||||
|
|
||||||
scheduler._els["dhx_cal_header"][0].innerHTML= html;
|
|
||||||
scheduler._table_view=true;
|
|
||||||
scheduler.set_sizes();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.grid._calcPadding = function(column, parent){
|
|
||||||
var padding = (column.paddingLeft !== undefined ? 1*column.paddingLeft : scheduler[parent].defPadding)
|
|
||||||
+ (column.paddingRight !== undefined ? 1*column.paddingRight : scheduler[parent].defPadding);
|
|
||||||
return padding;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid._getStyles = function(column, items){
|
|
||||||
var cell_style = [], style = "";
|
|
||||||
for(var i=0; items[i]; i++ ){
|
|
||||||
style = items[i] + ":";
|
|
||||||
switch (items[i]){
|
|
||||||
case "text-align":
|
|
||||||
if(column.align)
|
|
||||||
cell_style.push(style+column.align);
|
|
||||||
break;
|
|
||||||
case "vertical-align":
|
|
||||||
if(column.valign)
|
|
||||||
cell_style.push(style+column.valign);
|
|
||||||
break;
|
|
||||||
case "padding-left":
|
|
||||||
if(column.paddingLeft != undefined)
|
|
||||||
cell_style.push(style+(column.paddingLeft||'0') + "px");
|
|
||||||
break;
|
|
||||||
case "padding-left":
|
|
||||||
if(column.paddingRight != undefined)
|
|
||||||
cell_style.push(style+(column.paddingRight||'0') + "px");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cell_style;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid._fill_grid_tab = function(objName, sort){
|
|
||||||
//get current date
|
|
||||||
var date = scheduler._date;
|
|
||||||
//select events for which data need to be printed
|
|
||||||
var events = scheduler.grid.sort_grid(sort)
|
|
||||||
|
|
||||||
//generate html for the view
|
|
||||||
var columns = scheduler[objName].columns;
|
|
||||||
|
|
||||||
var html = "<div>";
|
|
||||||
var left = -2;//column borders at the same pos as header borders...
|
|
||||||
for(var i=0; i < columns.length; i++){
|
|
||||||
var padding = scheduler.grid._calcPadding(columns[i], objName);
|
|
||||||
left +=columns[i].width + padding ;//
|
|
||||||
if(i < columns.length - 1)
|
|
||||||
html += "<div class='dhx_grid_v_border' style='left:"+(left)+"px'></div>";
|
|
||||||
}
|
|
||||||
html += "</div>"
|
|
||||||
html +="<div class='dhx_grid_area'><table>";
|
|
||||||
|
|
||||||
for (var i=0; i<events.length; i++){
|
|
||||||
html += scheduler.grid._print_event_row(events[i], objName);
|
|
||||||
}
|
|
||||||
|
|
||||||
html +="</table></div>";
|
|
||||||
//render html
|
|
||||||
scheduler._els["dhx_cal_data"][0].innerHTML = html;
|
|
||||||
scheduler._els["dhx_cal_data"][0].scrollTop = scheduler.grid._gridScrollTop||0;
|
|
||||||
|
|
||||||
var t=scheduler._els["dhx_cal_data"][0].getElementsByTagName("tr");
|
|
||||||
|
|
||||||
scheduler._rendered=[];
|
|
||||||
for (var i=0; i < t.length; i++){
|
|
||||||
scheduler._rendered[i]=t[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
scheduler.grid._print_event_row = function(ev, objName){
|
|
||||||
|
|
||||||
var styles = [];
|
|
||||||
if(ev.color)
|
|
||||||
styles.push("background:"+ev.color);
|
|
||||||
if(ev.textColor)
|
|
||||||
styles.push("color:"+ev.textColor);
|
|
||||||
if(ev._text_style)
|
|
||||||
styles.push(ev._text_style);
|
|
||||||
if(scheduler[objName]['rowHeight'])
|
|
||||||
styles.push('height:'+scheduler[objName]['rowHeight'] + 'px');
|
|
||||||
|
|
||||||
var style = "";
|
|
||||||
if(styles.length){
|
|
||||||
style = "style='"+styles.join(";")+"'";
|
|
||||||
}
|
|
||||||
|
|
||||||
var columns = scheduler[objName].columns;
|
|
||||||
var ev_class = scheduler.templates.event_class(ev.start_date, ev.end_date, ev);
|
|
||||||
|
|
||||||
var html ="<tr class='dhx_grid_event"+(ev_class? ' '+ev_class:'')+"' event_id='"+ev.id+"' " + style + ">";
|
|
||||||
|
|
||||||
var name = scheduler.grid._getViewName(objName);
|
|
||||||
var availStyles = ["text-align", "vertical-align", "padding-left","padding-right"];
|
|
||||||
for(var i =0; i < columns.length; i++){
|
|
||||||
var value;
|
|
||||||
if(columns[i].template){
|
|
||||||
value = columns[i].template(ev.start_date, ev.end_date, ev);
|
|
||||||
}else if(columns[i].id == 'date') {
|
|
||||||
value = scheduler.templates[name + '_full_date'](ev.start_date, ev.end_date, ev);
|
|
||||||
}else if(columns[i].id == 'start_date' || columns[i].id == 'end_date' ){
|
|
||||||
value = scheduler.templates[name + '_single_date'](ev[columns[i].id]);
|
|
||||||
}else{
|
|
||||||
value = scheduler.templates[name + '_field'](columns[i].id, ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
var cell_style = scheduler.grid._getStyles(columns[i], availStyles);
|
|
||||||
|
|
||||||
var className = columns[i].css ? (" class=\""+columns[i].css+"\"") : "";
|
|
||||||
|
|
||||||
html+= "<td style='width:"+ (columns[i].width )+"px;"+cell_style.join(";")+"' "+className+">"+value+"</td>";
|
|
||||||
|
|
||||||
}
|
|
||||||
html+="<td class='dhx_grid_dummy'></td></tr>";
|
|
||||||
|
|
||||||
return html;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.grid._print_grid_header = function(objName){
|
|
||||||
var head = "<div class='dhx_grid_line'>";
|
|
||||||
|
|
||||||
var columns = scheduler[objName].columns;
|
|
||||||
var widths = [];
|
|
||||||
|
|
||||||
var unsized_columns = columns.length;
|
|
||||||
var avail_width = scheduler._obj.clientWidth - 2*columns.length -20;//-20 for possible scrollbar, -length for borders
|
|
||||||
for(var ind=0; ind < columns.length; ind++){
|
|
||||||
|
|
||||||
var val = columns[ind].initialWidth*1;
|
|
||||||
if(!isNaN(val) && columns[ind].initialWidth != '' && columns[ind].initialWidth != null && typeof columns[ind].initialWidth != 'boolean'){
|
|
||||||
|
|
||||||
unsized_columns--;
|
|
||||||
avail_width -= val;
|
|
||||||
widths[ind] = val;
|
|
||||||
}else {
|
|
||||||
widths[ind] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var unsized_width = Math.floor(avail_width / unsized_columns);
|
|
||||||
var availStyles = ["text-align", "padding-left","padding-right"];
|
|
||||||
for(var i=0; i < columns.length; i++){
|
|
||||||
var column_width = !widths[i] ? unsized_width : widths[i];
|
|
||||||
columns[i].width = column_width - scheduler.grid._calcPadding(columns[i], objName);
|
|
||||||
var cell_style = scheduler.grid._getStyles(columns[i], availStyles);
|
|
||||||
head += "<div style='width:"+(columns[i].width -1)+"px;"+cell_style.join(";")+"'>" + (columns[i].label === undefined ? columns[i].id : columns[i].label) + "</div>";
|
|
||||||
}
|
|
||||||
head +="</div>";
|
|
||||||
|
|
||||||
return head;
|
|
||||||
};
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.attachEvent("onTemplatesReady",function(){
|
|
||||||
var els = document.body.getElementsByTagName("DIV");
|
|
||||||
for (var i=0; i < els.length; i++) {
|
|
||||||
var cs = els[i].className||"";
|
|
||||||
cs = cs.split(":");
|
|
||||||
if (cs.length == 2 && cs[0] == "template"){
|
|
||||||
var code = "return \""+(els[i].innerHTML||"").replace(/\"/g,"\\\"").replace(/[\n\r]+/g,"")+"\";";
|
|
||||||
code = unescape(code).replace(/\{event\.([a-z]+)\}/g,function(all,mask){
|
|
||||||
return '"+ev.'+mask+'+"';
|
|
||||||
});
|
|
||||||
scheduler.templates[cs[1]]=Function("start","end","ev",code);
|
|
||||||
els[i].style.display='none';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
//Initial idea and implementation by Steve MC
|
|
||||||
(function (){
|
|
||||||
|
|
||||||
var isLightboxOpen = false;
|
|
||||||
var date; // used for copy and paste operations
|
|
||||||
var isCopy = null;
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeLightbox",function(){ isLightboxOpen = true; return true; });
|
|
||||||
scheduler.attachEvent("onAfterLightbox",function(){ isLightboxOpen = false; return true; });
|
|
||||||
|
|
||||||
scheduler.attachEvent("onMouseMove", function(id,e){
|
|
||||||
date = scheduler.getActionData(e).date;
|
|
||||||
});
|
|
||||||
|
|
||||||
dhtmlxEvent(document,(_isOpera?"keypress":"keydown"),function(e){
|
|
||||||
e=e||event;
|
|
||||||
if (!isLightboxOpen){
|
|
||||||
|
|
||||||
var scheduler = window.scheduler;
|
|
||||||
|
|
||||||
if (e.keyCode == 37 || e.keyCode == 39) { // Left, Right arrows
|
|
||||||
e.cancelBubble = true;
|
|
||||||
|
|
||||||
var next = scheduler.date.add(scheduler._date,(e.keyCode == 37 ? -1 : 1 ),scheduler._mode);
|
|
||||||
scheduler.setCurrentView(next);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var select_id = scheduler._select_id;
|
|
||||||
if (e.ctrlKey && e.keyCode == 67) { // CTRL+C
|
|
||||||
if (select_id) {
|
|
||||||
scheduler._buffer_id = select_id;
|
|
||||||
isCopy = true;
|
|
||||||
scheduler.callEvent("onEventCopied", [scheduler.getEvent(select_id)]);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (e.ctrlKey && e.keyCode == 88) { // CTRL+X
|
|
||||||
if (select_id) {
|
|
||||||
isCopy = false;
|
|
||||||
scheduler._buffer_id = select_id;
|
|
||||||
var ev = scheduler.getEvent(select_id);
|
|
||||||
scheduler.updateEvent(ev.id);
|
|
||||||
scheduler.callEvent("onEventCut", [ev]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.ctrlKey && e.keyCode == 86) { // CTRL+V
|
|
||||||
var ev = scheduler.getEvent(scheduler._buffer_id);
|
|
||||||
if (ev) {
|
|
||||||
var event_duration = ev.end_date-ev.start_date;
|
|
||||||
if (isCopy) {
|
|
||||||
var new_ev = scheduler._lame_clone(ev);
|
|
||||||
new_ev.id = scheduler.uid();
|
|
||||||
new_ev.start_date = new Date(date);
|
|
||||||
new_ev.end_date = new Date(new_ev.start_date.valueOf() + event_duration);
|
|
||||||
scheduler.addEvent(new_ev);
|
|
||||||
scheduler.callEvent("onEventPasted", [isCopy, new_ev, ev]);
|
|
||||||
}
|
|
||||||
else { // cut operation
|
|
||||||
var copy = scheduler._lame_copy({}, ev);
|
|
||||||
ev.start_date = new Date(date);
|
|
||||||
ev.end_date = new Date(ev.start_date.valueOf() + event_duration);
|
|
||||||
scheduler.render_view_data(); // need to redraw all events
|
|
||||||
|
|
||||||
scheduler.callEvent("onEventPasted", [isCopy, ev, copy]);
|
|
||||||
isCopy = true; // switch to copy after first paste operation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,831 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.config.limit_start = null;
|
|
||||||
scheduler.config.limit_end = null;
|
|
||||||
scheduler.config.limit_view = false;
|
|
||||||
scheduler.config.check_limits = true;
|
|
||||||
scheduler.config.mark_now = true;
|
|
||||||
scheduler.config.display_marked_timespans = true;
|
|
||||||
|
|
||||||
(function(){
|
|
||||||
var before = null;
|
|
||||||
var dhx_time_block = "dhx_time_block";
|
|
||||||
|
|
||||||
var fix_options = function(options, days, zones) {
|
|
||||||
if (days instanceof Date && zones instanceof Date) {
|
|
||||||
options.start_date = days;
|
|
||||||
options.end_date = zones
|
|
||||||
} else {
|
|
||||||
options.days = days;
|
|
||||||
options.zones = zones;
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
var get_resulting_options = function(days, zones, sections) {
|
|
||||||
var options = (typeof days == "object") ? days : { days: days };
|
|
||||||
options.type = dhx_time_block;
|
|
||||||
options.css = "";
|
|
||||||
if (zones) {
|
|
||||||
if (sections)
|
|
||||||
options.sections = sections;
|
|
||||||
options = fix_options(options, days, zones);
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
scheduler.blockTime = function(days, zones, sections){
|
|
||||||
var options = get_resulting_options(days, zones, sections);
|
|
||||||
return scheduler.addMarkedTimespan(options);
|
|
||||||
};
|
|
||||||
scheduler.unblockTime = function(days, zones, sections) {
|
|
||||||
zones = zones || "fullday";
|
|
||||||
var options = get_resulting_options(days, zones, sections);
|
|
||||||
return scheduler.deleteMarkedTimespan(options);
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onBeforeViewChange",function(om,od,nm,nd){
|
|
||||||
nd = nd||od; nm = nm||om;
|
|
||||||
if (scheduler.config.limit_view){
|
|
||||||
if (nd.valueOf()>scheduler.config.limit_end.valueOf() || this.date.add(nd,1,nm)<=scheduler.config.limit_start.valueOf()){
|
|
||||||
setTimeout(function(){
|
|
||||||
scheduler.setCurrentView(scheduler._date, nm);
|
|
||||||
},1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
var get_relevant_blocked_zones = function(day_index, day_value, zones) {
|
|
||||||
var relevant_zones = (zones[day_value] && zones[day_value][dhx_time_block]) ? zones[day_value][dhx_time_block] :
|
|
||||||
(zones[day_index] && zones[day_index][dhx_time_block]) ? zones[day_index][dhx_time_block] : [];
|
|
||||||
return relevant_zones;
|
|
||||||
};
|
|
||||||
var blocker = function(event){
|
|
||||||
if(!event)
|
|
||||||
return true;
|
|
||||||
if (!scheduler.config.check_limits)
|
|
||||||
return true;
|
|
||||||
var s = scheduler;
|
|
||||||
var mode = s._mode;
|
|
||||||
var timespans = scheduler._marked_timespans;
|
|
||||||
var c = s.config;
|
|
||||||
var evs = [];
|
|
||||||
if (event.rec_type) {
|
|
||||||
evs = scheduler.getRecDates(event);
|
|
||||||
} else {
|
|
||||||
evs = [event];
|
|
||||||
}
|
|
||||||
|
|
||||||
var res = true;
|
|
||||||
for (var p=0; p<evs.length; p++) {
|
|
||||||
var ev = evs[p];
|
|
||||||
|
|
||||||
res = (c.limit_start && c.limit_end) ? (ev.start_date.valueOf() >= c.limit_start.valueOf() && ev.end_date.valueOf() <= c.limit_end.valueOf()) : true;
|
|
||||||
if (res){
|
|
||||||
var temp_start_date = new Date(ev.start_date.valueOf());
|
|
||||||
var temp_end_date = scheduler.date.add(temp_start_date, 1, "day");
|
|
||||||
|
|
||||||
for (; temp_start_date < ev.end_date; temp_start_date = scheduler.date.date_part(temp_end_date), temp_end_date = s.date.add(temp_start_date, 1, "day") ) {
|
|
||||||
var day_value = +scheduler.date.date_part( new Date(temp_start_date) ); // the first part of event not necessarily contains only date part
|
|
||||||
var day_index = temp_start_date.getDay();
|
|
||||||
|
|
||||||
var zones = [];
|
|
||||||
if(s._props && s._props[mode]){
|
|
||||||
var view = s._props[mode];
|
|
||||||
var block_units = timespans[mode];
|
|
||||||
if(block_units && block_units[ev[view.map_to]]) {
|
|
||||||
var unit_zones = block_units[ev[view.map_to]];
|
|
||||||
var blocked_unit_zones = get_relevant_blocked_zones(day_index, day_value, unit_zones);
|
|
||||||
for (var i=0; i<blocked_unit_zones.length; i++) {
|
|
||||||
zones = scheduler._add_timespan_zones(zones, blocked_unit_zones[i].zones);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s.matrix && s.matrix[mode]) {
|
|
||||||
var timeline_options = s.matrix[mode];
|
|
||||||
var timeline_units = timespans[mode];
|
|
||||||
if (timeline_units && timeline_units[ev[timeline_options.y_property]]) {
|
|
||||||
var timeline_zones = timeline_units[ev[timeline_options.y_property]];
|
|
||||||
var blocked_timeline_zones = get_relevant_blocked_zones(day_index, day_value, timeline_zones);
|
|
||||||
for (var i=0; i<blocked_timeline_zones.length; i++) {
|
|
||||||
zones = scheduler._add_timespan_zones(zones, blocked_timeline_zones[i].zones);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now need to add day blocks
|
|
||||||
var block_days = timespans.global;
|
|
||||||
var blocked_day_zones = get_relevant_blocked_zones(day_index, day_value, block_days)
|
|
||||||
for (var i=0; i<blocked_day_zones.length; i++) {
|
|
||||||
zones = scheduler._add_timespan_zones(zones, blocked_day_zones[i].zones);
|
|
||||||
}
|
|
||||||
|
|
||||||
var sm = scheduler._get_zone_minutes(temp_start_date);
|
|
||||||
var em = ( ev.end_date>temp_end_date || ev.end_date.getDate() != temp_start_date.getDate() ) ? 1440 : scheduler._get_zone_minutes(ev.end_date);
|
|
||||||
|
|
||||||
if (zones){
|
|
||||||
for (var i = 0; i < zones.length; i+=2){
|
|
||||||
var sz = zones[i];
|
|
||||||
var ez = zones[i+1];
|
|
||||||
if (sz<em && ez>sm) {
|
|
||||||
if (sm<=ez && sm >=sz){
|
|
||||||
if (ez == 24*60 || em<ez){
|
|
||||||
res = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(ev._timed && s._drag_id && s._drag_mode == "new-size"){
|
|
||||||
ev.start_date.setHours(0);
|
|
||||||
ev.start_date.setMinutes(ez);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((em>=sz && em<ez) || (sm < sz && em > ez)){
|
|
||||||
if(ev._timed && s._drag_id && s._drag_mode == "new-size"){
|
|
||||||
ev.end_date.setHours(0);
|
|
||||||
ev.end_date.setMinutes(sz);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!res) {
|
|
||||||
s._drag_id = null;
|
|
||||||
s._drag_mode = null;
|
|
||||||
res = (s.checkEvent("onLimitViolation")) ? s.callEvent("onLimitViolation",[ev.id, ev]) : res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onMouseDown", function(classname) {
|
|
||||||
return !(classname = dhx_time_block);
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeDrag",function(id){
|
|
||||||
if (!id) return true;
|
|
||||||
return blocker(scheduler.getEvent(id));
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onClick", function (event_id, native_event_object){
|
|
||||||
return blocker(scheduler.getEvent(event_id));
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeLightbox",function(id){
|
|
||||||
|
|
||||||
var ev = scheduler.getEvent(id);
|
|
||||||
before = [ev.start_date, ev.end_date];
|
|
||||||
return blocker(ev);
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventSave", function(id, data, is_new_event) {
|
|
||||||
if(data.rec_type){
|
|
||||||
var data_copy = scheduler._lame_clone(data);
|
|
||||||
scheduler._roll_back_dates(data_copy);
|
|
||||||
return blocker(data);
|
|
||||||
}
|
|
||||||
return blocker(data);
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventAdded",function(id){
|
|
||||||
if (!id) return true;
|
|
||||||
var ev = scheduler.getEvent(id);
|
|
||||||
if (!blocker(ev) && scheduler.config.limit_start && scheduler.config.limit_end) {
|
|
||||||
if (ev.start_date < scheduler.config.limit_start) {
|
|
||||||
ev.start_date = new Date(scheduler.config.limit_start);
|
|
||||||
}
|
|
||||||
if (ev.start_date.valueOf() >= scheduler.config.limit_end.valueOf()) {
|
|
||||||
ev.start_date = this.date.add(scheduler.config.limit_end, -1, "day");
|
|
||||||
}
|
|
||||||
if (ev.end_date < scheduler.config.limit_start) {
|
|
||||||
ev.end_date = new Date(scheduler.config.limit_start);
|
|
||||||
}
|
|
||||||
if (ev.end_date.valueOf() >= scheduler.config.limit_end.valueOf()) {
|
|
||||||
ev.end_date = this.date.add(scheduler.config.limit_end, -1, "day");
|
|
||||||
}
|
|
||||||
if (ev.start_date.valueOf() >= ev.end_date.valueOf()) {
|
|
||||||
ev.end_date = this.date.add(ev.start_date, (this.config.event_duration||this.config.time_step), "minute");
|
|
||||||
}
|
|
||||||
ev._timed=this.is_one_day_event(ev);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventChanged",function(id){
|
|
||||||
if (!id) return true;
|
|
||||||
var ev = scheduler.getEvent(id);
|
|
||||||
if (!blocker(ev)){
|
|
||||||
if (!before) return false;
|
|
||||||
ev.start_date = before[0];
|
|
||||||
ev.end_date = before[1];
|
|
||||||
ev._timed=this.is_one_day_event(ev);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeEventChanged",function(ev, native_object, is_new){
|
|
||||||
return blocker(ev);
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeEventCreated", function(ev) { // native event
|
|
||||||
var start_date = scheduler.getActionData(ev).date;
|
|
||||||
var event = {
|
|
||||||
_timed: true,
|
|
||||||
start_date: start_date,
|
|
||||||
end_date: scheduler.date.add(start_date, scheduler.config.time_step, "minute")
|
|
||||||
};
|
|
||||||
return blocker(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onViewChange", function(){
|
|
||||||
scheduler.markNow();
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onSchedulerResize", function(){
|
|
||||||
window.setTimeout(function(){ scheduler.markNow(); }, 1);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function() {
|
|
||||||
scheduler._mark_now_timer = window.setInterval(function() {
|
|
||||||
scheduler.markNow();
|
|
||||||
}, 60000);
|
|
||||||
});
|
|
||||||
scheduler.markNow = function(hide) {
|
|
||||||
// day, week, units views
|
|
||||||
var dhx_now_time = 'dhx_now_time';
|
|
||||||
if (!this._els[dhx_now_time]) {
|
|
||||||
this._els[dhx_now_time] = [];
|
|
||||||
}
|
|
||||||
var now = scheduler.config.now_date || new Date();
|
|
||||||
var cfg = this.config;
|
|
||||||
scheduler._remove_mark_now(); // delete previous marks if they exist
|
|
||||||
if (!hide && cfg.mark_now && now < this._max_date && now > this._min_date && now.getHours() >= cfg.first_hour && now.getHours()<cfg.last_hour) {
|
|
||||||
var day_index = this.locate_holder_day(now);
|
|
||||||
this._els[dhx_now_time] = scheduler._append_mark_now(day_index, now);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler._append_mark_now = function(day_index, now) {
|
|
||||||
var dhx_now_time = 'dhx_now_time';
|
|
||||||
var zone_start= scheduler._get_zone_minutes(now);
|
|
||||||
var options = {
|
|
||||||
zones: [zone_start, zone_start+1],
|
|
||||||
css: dhx_now_time,
|
|
||||||
type: dhx_now_time
|
|
||||||
};
|
|
||||||
if (!this._table_view) {
|
|
||||||
if (this._props && this._props[this._mode]) { // units view
|
|
||||||
var day_divs = this._els["dhx_cal_data"][0].childNodes;
|
|
||||||
var r_divs = [];
|
|
||||||
|
|
||||||
for (var i=0; i<day_divs.length-1; i++) {
|
|
||||||
var t_day = day_index+i; // as each unit is actually considered +1 day
|
|
||||||
options.days = t_day;
|
|
||||||
var t_div = scheduler._render_marked_timespan(options, null, t_day)[0];
|
|
||||||
r_divs.push(t_div)
|
|
||||||
}
|
|
||||||
return r_divs;
|
|
||||||
} else { // day/week views
|
|
||||||
options.days = day_index;
|
|
||||||
return scheduler._render_marked_timespan(options, null, day_index);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this._mode == "month") {
|
|
||||||
options.days = +scheduler.date.date_part(now);
|
|
||||||
return scheduler._render_marked_timespan(options, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler._remove_mark_now = function() {
|
|
||||||
var dhx_now_time = 'dhx_now_time';
|
|
||||||
var els = this._els[dhx_now_time];
|
|
||||||
for (var i=0; i<els.length; i++) {
|
|
||||||
var div = els[i];
|
|
||||||
var parent = div.parentNode;
|
|
||||||
if (parent) {
|
|
||||||
parent.removeChild(div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._els[dhx_now_time] = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
scheduler._marked_timespans = {
|
|
||||||
"global": {
|
|
||||||
"0": {
|
|
||||||
"default": [
|
|
||||||
{ // sunday
|
|
||||||
zones: [0, 100, 500, 600],
|
|
||||||
css: "yellow_box",
|
|
||||||
type: "default",
|
|
||||||
view: "global",
|
|
||||||
day: 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
"112121312": {
|
|
||||||
"my_special_type": [
|
|
||||||
{
|
|
||||||
zones: [600, 900],
|
|
||||||
type: "block",
|
|
||||||
css: "some_class",
|
|
||||||
view: "global",
|
|
||||||
day: 112121312
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"units": {
|
|
||||||
"5_id": {
|
|
||||||
"3": {
|
|
||||||
"special_type": [ {}, {}, {} ],
|
|
||||||
"another_type": [ {} ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"6_id": {
|
|
||||||
"11212127": {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
scheduler._marked_timespans = { global: {} };
|
|
||||||
|
|
||||||
scheduler._get_zone_minutes = function(date) {
|
|
||||||
return date.getHours()*60 + date.getMinutes();
|
|
||||||
};
|
|
||||||
scheduler._prepare_timespan_options = function(config) { // receives 1 option, returns array of options
|
|
||||||
var r_configs = []; // resulting configs
|
|
||||||
var temp_configs = [];
|
|
||||||
|
|
||||||
if (config.days == "fullweek")
|
|
||||||
config.days = [0,1,2,3,4,5,6];
|
|
||||||
|
|
||||||
if (config.days instanceof Array) {
|
|
||||||
var t_days = config.days.slice();
|
|
||||||
for (var i=0; i<t_days.length; i++) {
|
|
||||||
var cloned_config = scheduler._lame_clone(config);
|
|
||||||
cloned_config.days = t_days[i];
|
|
||||||
r_configs.push.apply(r_configs, scheduler._prepare_timespan_options(cloned_config));
|
|
||||||
}
|
|
||||||
return r_configs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !config || !((config.start_date && config.end_date && config.end_date > config.start_date) || (config.days !== undefined && config.zones)) )
|
|
||||||
return r_configs; // incorrect config was provided
|
|
||||||
|
|
||||||
var min = 0;
|
|
||||||
var max = 24*60;
|
|
||||||
if (config.zones == "fullday")
|
|
||||||
config.zones = [min, max];
|
|
||||||
if (config.zones && config.invert_zones) {
|
|
||||||
config.zones = scheduler.invertZones(config.zones);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.id = scheduler.uid();
|
|
||||||
config.css = config.css||"";
|
|
||||||
config.type = config.type||"default";
|
|
||||||
|
|
||||||
var sections = config.sections;
|
|
||||||
if (sections) {
|
|
||||||
for (var view_key in sections) {
|
|
||||||
if (sections.hasOwnProperty(view_key)) {
|
|
||||||
var ids = sections[view_key];
|
|
||||||
if (!(ids instanceof Array))
|
|
||||||
ids = [ids];
|
|
||||||
for (var i=0; i<ids.length; i++) {
|
|
||||||
var t_config = scheduler._lame_copy({}, config);
|
|
||||||
t_config.sections = {};
|
|
||||||
t_config.sections[view_key] = ids[i];
|
|
||||||
temp_configs.push(t_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
temp_configs.push(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var k=0; k<temp_configs.length; k++) {
|
|
||||||
var c_config = temp_configs[k]; // config to be checked
|
|
||||||
|
|
||||||
var start_date = c_config.start_date;
|
|
||||||
var end_date = c_config.end_date;
|
|
||||||
|
|
||||||
if (start_date && end_date) {
|
|
||||||
var t_sd = scheduler.date.date_part(new Date(start_date)); // e.g. 05 october
|
|
||||||
var t_ed= scheduler.date.add(t_sd, 1, "day"); // 06 october, will both be incremented in the loop
|
|
||||||
|
|
||||||
while (t_sd < end_date) {
|
|
||||||
var t_config = scheduler._lame_copy({}, c_config);
|
|
||||||
delete t_config.start_date;
|
|
||||||
delete t_config.end_date;
|
|
||||||
t_config.days = t_sd.valueOf();
|
|
||||||
var zone_start = (start_date > t_sd) ? scheduler._get_zone_minutes(start_date) : min;
|
|
||||||
var zone_end = ( end_date>t_ed || end_date.getDate() != t_sd.getDate() ) ? max : scheduler._get_zone_minutes(end_date);
|
|
||||||
t_config.zones = [zone_start, zone_end];
|
|
||||||
r_configs.push(t_config);
|
|
||||||
|
|
||||||
t_sd = t_ed;
|
|
||||||
t_ed = scheduler.date.add(t_ed, 1, "day");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (c_config.days instanceof Date)
|
|
||||||
c_config.days = (scheduler.date.date_part(c_config.days)).valueOf();
|
|
||||||
c_config.zones = config.zones.slice();
|
|
||||||
r_configs.push(c_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r_configs;
|
|
||||||
};
|
|
||||||
scheduler._get_dates_by_index = function(index, start, end) {
|
|
||||||
var dates = [];
|
|
||||||
start = start||scheduler._min_date;
|
|
||||||
end = end||scheduler._max_date;
|
|
||||||
var start_day = start.getDay();
|
|
||||||
var delta = (index-start_day >= 0) ? (index-start_day) : (7-start.getDay()+index);
|
|
||||||
var t_date = scheduler.date.add(start, delta, "day");
|
|
||||||
for (; t_date < end; t_date = scheduler.date.add(t_date, 1, "week")) {
|
|
||||||
dates.push(t_date);
|
|
||||||
}
|
|
||||||
return dates;
|
|
||||||
};
|
|
||||||
scheduler._get_css_classes_by_config = function(config) {
|
|
||||||
var css_classes = [];
|
|
||||||
if (config.type == dhx_time_block) {
|
|
||||||
css_classes.push(dhx_time_block);
|
|
||||||
if (config.css)
|
|
||||||
css_classes.push(dhx_time_block+"_reset");
|
|
||||||
}
|
|
||||||
css_classes.push("dhx_marked_timespan", config.css);
|
|
||||||
return css_classes.join(" ");
|
|
||||||
};
|
|
||||||
scheduler._get_block_by_config = function(config) {
|
|
||||||
var block = document.createElement("DIV");
|
|
||||||
if (config.html) {
|
|
||||||
if (typeof config.html == "string")
|
|
||||||
block.innerHTML = config.html;
|
|
||||||
else
|
|
||||||
block.appendChild(config.html);
|
|
||||||
}
|
|
||||||
return block;
|
|
||||||
};
|
|
||||||
scheduler._render_marked_timespan = function(options, area, day) {
|
|
||||||
var blocks = []; // resulting block which will be rendered and returned
|
|
||||||
var c = scheduler.config;
|
|
||||||
var min_date = this._min_date;
|
|
||||||
var max_date = this._max_date;
|
|
||||||
var day_value = false; // if timespan for specific date should be displayed
|
|
||||||
|
|
||||||
if (!c.display_marked_timespans)
|
|
||||||
return blocks;
|
|
||||||
|
|
||||||
if (!day && day !== 0) { // in case of markTimespan
|
|
||||||
if (options.days < 7)
|
|
||||||
day = options.days;
|
|
||||||
else {
|
|
||||||
var date_to_display = new Date(options.days);
|
|
||||||
day_value = +date_to_display;
|
|
||||||
|
|
||||||
// in case of markTimespan date could be not in the viewing range, need to return
|
|
||||||
if ( !(+max_date >= +date_to_display && +min_date <= +date_to_display) )
|
|
||||||
return blocks;
|
|
||||||
|
|
||||||
var day_index = date_to_display.getDay();
|
|
||||||
if (scheduler.config.start_on_monday) {
|
|
||||||
day = (day_index == 0) ? 6 : day_index-1;
|
|
||||||
} else
|
|
||||||
day = day_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var zones = options.zones;
|
|
||||||
var css_classes = scheduler._get_css_classes_by_config(options);
|
|
||||||
|
|
||||||
if (scheduler._table_view && scheduler._mode == "month") {
|
|
||||||
var areas = [];
|
|
||||||
var days = [];
|
|
||||||
|
|
||||||
|
|
||||||
if (!area) {
|
|
||||||
days = (day_value) ? [day_value] : scheduler._get_dates_by_index(day);
|
|
||||||
for (var i=0; i < days.length; i++) {
|
|
||||||
areas.push( this._scales[days[i]] );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
areas.push(area);
|
|
||||||
days.push(day);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i=0; i < areas.length; i++) {
|
|
||||||
area = areas[i];
|
|
||||||
day = days[i];
|
|
||||||
|
|
||||||
for (var k=0; k < zones.length; k+=2) {
|
|
||||||
var start = zones[i];
|
|
||||||
var end = zones[i+1];
|
|
||||||
if (end <= start)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
var block = scheduler._get_block_by_config(options);
|
|
||||||
block.className = css_classes;
|
|
||||||
|
|
||||||
var height = area.offsetHeight - 1; // 1 for bottom border
|
|
||||||
var width = area.offsetWidth - 1; // 1 for left border
|
|
||||||
|
|
||||||
var sweek = Math.floor((this._correct_shift(day,1)-min_date.valueOf())/(60*60*1000*24*this._cols.length));
|
|
||||||
var sday = this.locate_holder_day(day, false) % this._cols.length;
|
|
||||||
|
|
||||||
var left = this._colsS[sday];
|
|
||||||
var top = this._colsS.heights[sweek]+(this._colsS.height?(this.xy.month_scale_height+2):2)-1;
|
|
||||||
|
|
||||||
block.style.top = top + "px";
|
|
||||||
block.style.lineHeight = block.style.height = height + "px";
|
|
||||||
|
|
||||||
block.style.left = (left + Math.round( (start)/(24*60) * width)) + "px";
|
|
||||||
block.style.width = Math.round( (end-start)/(24*60) * width) + "px";
|
|
||||||
|
|
||||||
area.appendChild(block);
|
|
||||||
blocks.push(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
area = area ? area : scheduler.locate_holder(day);
|
|
||||||
|
|
||||||
for (var i = 0; i < zones.length; i+=2){
|
|
||||||
var start = Math.max(zones[i], c.first_hour*60);
|
|
||||||
var end = Math.min(zones[i+1], c.last_hour*60);
|
|
||||||
if (end <= start)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
var block = scheduler._get_block_by_config(options);
|
|
||||||
block.className = css_classes;
|
|
||||||
|
|
||||||
block.style.top = (Math.round((start*60*1000-this.config.first_hour*60*60*1000)*this.config.hour_size_px/(60*60*1000)))%(this.config.hour_size_px*24)+"px";
|
|
||||||
block.style.lineHeight = block.style.height = Math.max((Math.round(((end-start-1)*60*1000)*this.config.hour_size_px/(60*60*1000)))%(this.config.hour_size_px*24), 1)+"px";
|
|
||||||
|
|
||||||
area.appendChild(block);
|
|
||||||
blocks.push(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return blocks;
|
|
||||||
};
|
|
||||||
// just marks timespan, will be cleaned after refresh
|
|
||||||
scheduler.markTimespan = function(configuration) {
|
|
||||||
var configs = scheduler._prepare_timespan_options(configuration);
|
|
||||||
if (!configs.length)
|
|
||||||
return;
|
|
||||||
var divs = [];
|
|
||||||
for (var i=0; i<configs.length; i++) {
|
|
||||||
var config = configs[i];
|
|
||||||
var blocks = scheduler._render_marked_timespan(config, null, null);
|
|
||||||
if(blocks.length)
|
|
||||||
divs.push.apply(divs, blocks);
|
|
||||||
}
|
|
||||||
return divs;
|
|
||||||
};
|
|
||||||
scheduler.unmarkTimespan = function(divs) {
|
|
||||||
if (!divs)
|
|
||||||
return;
|
|
||||||
for (var i=0; i<divs.length; i++) {
|
|
||||||
var div = divs[i];
|
|
||||||
div.parentNode.removeChild(div);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler._marked_timespans_ids = {};
|
|
||||||
// adds marked timespan to collections, persistent
|
|
||||||
scheduler.addMarkedTimespan = function(configuration) {
|
|
||||||
var configs = scheduler._prepare_timespan_options(configuration);
|
|
||||||
var global = "global";
|
|
||||||
|
|
||||||
if (!configs.length)
|
|
||||||
return; // options are incorrect, nothing to mark
|
|
||||||
|
|
||||||
var id = configs[0].id;
|
|
||||||
var timespans = scheduler._marked_timespans;
|
|
||||||
var ids = scheduler._marked_timespans_ids;
|
|
||||||
if (!ids[id])
|
|
||||||
ids[id] = [];
|
|
||||||
|
|
||||||
for (var i=0; i<configs.length; i++) {
|
|
||||||
var config = configs[i];
|
|
||||||
var day = config.days;
|
|
||||||
var zones = config.zones;
|
|
||||||
var css = config.css;
|
|
||||||
var sections = config.sections;
|
|
||||||
var type = config.type; // default or specified
|
|
||||||
|
|
||||||
if (sections) {
|
|
||||||
for (var view_key in sections) {
|
|
||||||
if (sections.hasOwnProperty(view_key)) {
|
|
||||||
if (!timespans[view_key])
|
|
||||||
timespans[view_key] = {};
|
|
||||||
var unit_id = sections[view_key];
|
|
||||||
var timespans_view = timespans[view_key];
|
|
||||||
if (!timespans_view[unit_id])
|
|
||||||
timespans_view[unit_id] = {};
|
|
||||||
if (!timespans_view[unit_id][day])
|
|
||||||
timespans_view[unit_id][day] = {};
|
|
||||||
if (!timespans_view[unit_id][day][type])
|
|
||||||
timespans_view[unit_id][day][type] = [];
|
|
||||||
var day_configs = timespans_view[unit_id][day][type];
|
|
||||||
config._array = day_configs;
|
|
||||||
day_configs.push(config);
|
|
||||||
ids[id].push(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!timespans[global][day])
|
|
||||||
timespans[global][day] = {};
|
|
||||||
if (!timespans[global][day][type])
|
|
||||||
timespans[global][day][type] = [];
|
|
||||||
var day_configs = timespans[global][day][type];
|
|
||||||
config._array = day_configs;
|
|
||||||
day_configs.push(config);
|
|
||||||
ids[id].push(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
};
|
|
||||||
// not used for now
|
|
||||||
scheduler._add_timespan_zones = function(current_zones, zones) {
|
|
||||||
var resulting_zones = current_zones.slice();
|
|
||||||
zones = zones.slice();
|
|
||||||
|
|
||||||
if (!resulting_zones.length)
|
|
||||||
return zones;
|
|
||||||
|
|
||||||
for (var i=0; i<resulting_zones.length; i+=2) {
|
|
||||||
var c_zone_start = resulting_zones[i];
|
|
||||||
var c_zone_end = resulting_zones[i+1];
|
|
||||||
var isLast = (i+2 == resulting_zones.length);
|
|
||||||
|
|
||||||
for (var k=0; k<zones.length; k+=2) {
|
|
||||||
var zone_start = zones[k];
|
|
||||||
var zone_end = zones[k+1];
|
|
||||||
if ((zone_end > c_zone_end && zone_start <= c_zone_end) || (zone_start < c_zone_start && zone_end >= c_zone_start)) {
|
|
||||||
resulting_zones[i] = Math.min(c_zone_start, zone_start);
|
|
||||||
resulting_zones[i+1] = Math.max(c_zone_end, zone_end);
|
|
||||||
i -= 2;
|
|
||||||
} else {
|
|
||||||
if (!isLast) // do nothing, maybe next current zone will match or will be last
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var offset = (c_zone_start > zone_start)?0:2;
|
|
||||||
resulting_zones.splice(i+offset, 0, zone_start, zone_end); // last current zone, need to add another
|
|
||||||
}
|
|
||||||
zones.splice(k--,2); // zone was merged or added, need to exclude it
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resulting_zones;
|
|
||||||
};
|
|
||||||
scheduler._subtract_timespan_zones = function(current_zones, zones) {
|
|
||||||
var resulting_zones = current_zones.slice();
|
|
||||||
for (var i=0; i<resulting_zones.length; i+=2 ) {
|
|
||||||
var c_zone_start = resulting_zones[i];// current_zone_start
|
|
||||||
var c_zone_end = resulting_zones[i+1];
|
|
||||||
for (var k=0; k<zones.length; k+=2) {
|
|
||||||
var zone_start = zones[k];
|
|
||||||
var zone_end = zones[k+1];
|
|
||||||
if (zone_end > c_zone_start && zone_start < c_zone_end) {
|
|
||||||
var is_modified = false;
|
|
||||||
if (c_zone_start >= zone_start && c_zone_end <= zone_end) {
|
|
||||||
resulting_zones.splice(i, 2);
|
|
||||||
}
|
|
||||||
if (c_zone_start < zone_start) {
|
|
||||||
resulting_zones.splice(i, 2, c_zone_start, zone_start);
|
|
||||||
is_modified = true;
|
|
||||||
}
|
|
||||||
if (c_zone_end > zone_end) {
|
|
||||||
resulting_zones.splice( (is_modified)?(i+2):i, (is_modified)?0:2, zone_end, c_zone_end);
|
|
||||||
}
|
|
||||||
i -= 2;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resulting_zones;
|
|
||||||
};
|
|
||||||
scheduler.invertZones = function(zones) {
|
|
||||||
return scheduler._subtract_timespan_zones([0, 1440], zones.slice());
|
|
||||||
};
|
|
||||||
scheduler._delete_marked_timespan_by_id = function(id) {
|
|
||||||
var configs = scheduler._marked_timespans_ids[id];
|
|
||||||
if (configs) {
|
|
||||||
for (var i=0; i<configs.length; i++) {
|
|
||||||
var config = configs[i];
|
|
||||||
var parent_array = config._array;
|
|
||||||
for (var k=0; k<parent_array.length; k++) {
|
|
||||||
if (parent_array[k] == config) {
|
|
||||||
parent_array.splice(k, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler._delete_marked_timespan_by_config = function(config) {
|
|
||||||
var timespans = scheduler._marked_timespans;
|
|
||||||
var sections = config.sections;
|
|
||||||
var day = config.days;
|
|
||||||
var type = config.type||"default";
|
|
||||||
var day_timespans = []; // array of timespans to subtract our config
|
|
||||||
if (sections) {
|
|
||||||
for (var view_key in sections) {
|
|
||||||
if (sections.hasOwnProperty(view_key) && timespans[view_key]) {
|
|
||||||
var unit_id = sections[view_key];
|
|
||||||
if (timespans[view_key][unit_id] && timespans[view_key][unit_id][day] && timespans[view_key][unit_id][day][type])
|
|
||||||
day_timespans = timespans[view_key][unit_id][day][type];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (timespans.global[day] && timespans.global[day][type])
|
|
||||||
day_timespans = timespans.global[day][type];
|
|
||||||
}
|
|
||||||
for (var i=0; i<day_timespans.length; i++) {
|
|
||||||
var d_t = day_timespans[i];
|
|
||||||
var zones = scheduler._subtract_timespan_zones(d_t.zones, config.zones);
|
|
||||||
if (zones.length)
|
|
||||||
d_t.zones = zones;
|
|
||||||
else {
|
|
||||||
day_timespans.splice(i,1);
|
|
||||||
i--;
|
|
||||||
// need to update ids collection
|
|
||||||
var related_zones = scheduler._marked_timespans_ids[d_t.id];
|
|
||||||
for (var k=0; k<related_zones.length; k++) {
|
|
||||||
if (related_zones[k] == d_t) {
|
|
||||||
related_zones.splice(k, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.deleteMarkedTimespan = function(configuration) {
|
|
||||||
if (!arguments.length) // delete everything
|
|
||||||
scheduler._marked_timespans = { global: {} };
|
|
||||||
if (typeof configuration != "object") { // id was passed
|
|
||||||
scheduler._delete_marked_timespan_by_id(configuration);
|
|
||||||
} else { // normal configuration was passed
|
|
||||||
var configs = scheduler._prepare_timespan_options(configuration);
|
|
||||||
for (var i=0; i<configs.length; i++) {
|
|
||||||
var config = configs[i];
|
|
||||||
scheduler._delete_marked_timespan_by_config(configs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler._get_types_to_render = function(common, specific) {
|
|
||||||
var types_to_render = (common) ? common : {};
|
|
||||||
for (var type in specific||{} ) {
|
|
||||||
if (specific.hasOwnProperty(type)) {
|
|
||||||
types_to_render[type] = specific[type];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return types_to_render;
|
|
||||||
};
|
|
||||||
scheduler._get_configs_to_render = function(types) {
|
|
||||||
var configs = [];
|
|
||||||
for (var type in types) {
|
|
||||||
if (types.hasOwnProperty(type)) {
|
|
||||||
configs.push.apply(configs, types[type]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return configs;
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onScaleAdd", function(area, day) {
|
|
||||||
if (scheduler._table_view && scheduler._mode != "month")
|
|
||||||
return;
|
|
||||||
|
|
||||||
var day_index = day.getDay();
|
|
||||||
var day_value = day.valueOf();
|
|
||||||
var mode = this._mode;
|
|
||||||
var timespans = scheduler._marked_timespans;
|
|
||||||
var r_configs = [];
|
|
||||||
|
|
||||||
if (this._props && this._props[mode]) { // we are in the units view and need to draw it's sections as well
|
|
||||||
var view = this._props[mode]; // units view object
|
|
||||||
var units = view.options;
|
|
||||||
var index = (view.position||0)+Math.floor((this._correct_shift(day.valueOf(),1)-this._min_date.valueOf())/(60*60*24*1000)); // user index
|
|
||||||
var unit = units[index]; // key, label
|
|
||||||
day = scheduler.date.date_part(new Date(this._date)); // for units view actually only 1 day is displayed yet the day variable will change, need to use this._date for all calls
|
|
||||||
day_index = day.getDay();
|
|
||||||
day_value = day.valueOf();
|
|
||||||
|
|
||||||
if (timespans[mode] && timespans[mode][unit.key]) {
|
|
||||||
var unit_zones = timespans[mode][unit.key];
|
|
||||||
var unit_types = scheduler._get_types_to_render(unit_zones[day_index], unit_zones[day_value]);
|
|
||||||
r_configs.push.apply(r_configs, scheduler._get_configs_to_render(unit_types));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var global_data = timespans["global"];
|
|
||||||
var day_types = global_data[day_value]||global_data[day_index];
|
|
||||||
r_configs.push.apply(r_configs, scheduler._get_configs_to_render(day_types));
|
|
||||||
|
|
||||||
for (var i=0; i<r_configs.length; i++) {
|
|
||||||
scheduler._render_marked_timespan(r_configs[i], area, day);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,490 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.xy.map_date_width = 188; // date column width
|
|
||||||
scheduler.xy.map_description_width = 400; // description column width
|
|
||||||
|
|
||||||
scheduler.config.map_resolve_event_location = true; // if events in database doesn't have lat and lng values there will be an attempt to resolve them on event loading, useful for migration
|
|
||||||
scheduler.config.map_resolve_user_location = true; // if user will be promted to share his location to display it on the map
|
|
||||||
|
|
||||||
scheduler.config.map_initial_position = new google.maps.LatLng(48.724, 8.215); // inital position of the map
|
|
||||||
scheduler.config.map_error_position = new google.maps.LatLng(15, 15); // this position will be displayed in case if event doesn't have corresponding coordinates
|
|
||||||
|
|
||||||
scheduler.config.map_infowindow_max_width = 300;
|
|
||||||
|
|
||||||
scheduler.config.map_type = google.maps.MapTypeId.ROADMAP;
|
|
||||||
|
|
||||||
scheduler.config.map_zoom_after_resolve = 15;
|
|
||||||
|
|
||||||
scheduler.locale.labels.marker_geo_success = "It seems you are here.";
|
|
||||||
scheduler.locale.labels.marker_geo_fail = "Sorry, could not get your current position using geolocation.";
|
|
||||||
|
|
||||||
scheduler.templates.marker_date = scheduler.date.date_to_str("%Y-%m-%d %H:%i"); // date for map's infowindow will be formated following way
|
|
||||||
|
|
||||||
scheduler.templates.marker_text = function(start, end, ev) {
|
|
||||||
return "<div><b>" + ev.text + "</b><br/><br/>" + (ev.event_location || '') + "<br/><br/>" + scheduler.templates.marker_date(start) + " - " + scheduler.templates.marker_date(end) + "</div>";
|
|
||||||
};
|
|
||||||
scheduler.dblclick_dhx_map_area = function() {
|
|
||||||
if (!this.config.readonly && this.config.dblclick_create)
|
|
||||||
this.addEventNow({
|
|
||||||
start_date: scheduler._date,
|
|
||||||
end_date: scheduler.date.add(scheduler._date, scheduler.config.time_step, "minute")
|
|
||||||
});
|
|
||||||
};
|
|
||||||
scheduler.templates.map_time = function(start, end, ev) {
|
|
||||||
if (ev._timed)
|
|
||||||
return this.day_date(ev.start_date, ev.end_date, ev) + " " + this.event_date(start);
|
|
||||||
else
|
|
||||||
return scheduler.templates.day_date(start) + " – " + scheduler.templates.day_date(end);
|
|
||||||
};
|
|
||||||
scheduler.templates.map_text = function(start, end, ev) {
|
|
||||||
return ev.text;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.date.map_start = function(d) {
|
|
||||||
return d;
|
|
||||||
};
|
|
||||||
scheduler.date.add_map = function(date, inc, mode) {
|
|
||||||
return (new Date(date.valueOf()));
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.templates.map_date = function(dd, ed, mode) {
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler._latLngUpdate = false; // flag for not displaying event second time in case of coordinates update
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerReady", function() {
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
scheduler._isMapPositionSet = false; // if user actual (geolocation) position was set on the map
|
|
||||||
|
|
||||||
var gmap = document.createElement('div');
|
|
||||||
gmap.className = 'dhx_map';
|
|
||||||
gmap.id = 'dhx_gmap';
|
|
||||||
gmap.style.dispay = "none";
|
|
||||||
|
|
||||||
var node = scheduler._obj;
|
|
||||||
|
|
||||||
node.appendChild(gmap);
|
|
||||||
|
|
||||||
scheduler._els.dhx_gmap = [];
|
|
||||||
scheduler._els.dhx_gmap.push(gmap);
|
|
||||||
|
|
||||||
_setMapSize('dhx_gmap');
|
|
||||||
|
|
||||||
var mapOptions = {
|
|
||||||
zoom: scheduler.config.map_inital_zoom || 10,
|
|
||||||
center: scheduler.config.map_initial_position,
|
|
||||||
mapTypeId: scheduler.config.map_type || google.maps.MapTypeId.ROADMAP
|
|
||||||
};
|
|
||||||
var map = new google.maps.Map(document.getElementById('dhx_gmap'), mapOptions);
|
|
||||||
map.disableDefaultUI = false;
|
|
||||||
map.disableDoubleClickZoom = !scheduler.config.readonly;
|
|
||||||
|
|
||||||
google.maps.event.addListener(map, "dblclick", function(event) {
|
|
||||||
if (!scheduler.config.readonly && scheduler.config.dblclick_create) {
|
|
||||||
var point = event.latLng;
|
|
||||||
geocoder.geocode(
|
|
||||||
{ 'latLng': point },
|
|
||||||
function(results, status) {
|
|
||||||
if (status == google.maps.GeocoderStatus.OK) {
|
|
||||||
point = results[0].geometry.location;
|
|
||||||
scheduler.addEventNow({
|
|
||||||
lat: point.lat(),
|
|
||||||
lng: point.lng(),
|
|
||||||
event_location: results[0].formatted_address,
|
|
||||||
start_date: scheduler._date,
|
|
||||||
end_date: scheduler.date.add(scheduler._date, scheduler.config.time_step, "minute")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var infoWindowOptions = {
|
|
||||||
content: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scheduler.config.map_infowindow_max_width) {
|
|
||||||
infoWindowOptions.maxWidth = scheduler.config.map_infowindow_max_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.map = {
|
|
||||||
_points: [],
|
|
||||||
_markers: [],
|
|
||||||
_infowindow: new google.maps.InfoWindow(infoWindowOptions),
|
|
||||||
_infowindows_content: [],
|
|
||||||
_initialization_count: -1,
|
|
||||||
_obj: map
|
|
||||||
};
|
|
||||||
|
|
||||||
geocoder = new google.maps.Geocoder();
|
|
||||||
|
|
||||||
if (scheduler.config.map_resolve_user_location) {
|
|
||||||
if (navigator.geolocation) {
|
|
||||||
if (!scheduler._isMapPositionSet) {
|
|
||||||
navigator.geolocation.getCurrentPosition(function(position) {
|
|
||||||
var _userLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
|
|
||||||
map.setCenter(_userLocation);
|
|
||||||
map.setZoom(scheduler.config.map_zoom_after_resolve || 10);
|
|
||||||
scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_success);
|
|
||||||
scheduler.map._infowindow.position = map.getCenter();
|
|
||||||
scheduler.map._infowindow.open(map);
|
|
||||||
|
|
||||||
scheduler._isMapPositionSet = true;
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_fail);
|
|
||||||
scheduler.map._infowindow.setPosition(map.getCenter());
|
|
||||||
scheduler.map._infowindow.open(map);
|
|
||||||
scheduler._isMapPositionSet = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
google.maps.event.addListener(map, "resize", function(event) {
|
|
||||||
gmap.style.zIndex = '5';
|
|
||||||
map.setZoom(map.getZoom());
|
|
||||||
|
|
||||||
});
|
|
||||||
google.maps.event.addListener(map, "tilesloaded", function(event) {
|
|
||||||
gmap.style.zIndex = '5';
|
|
||||||
});
|
|
||||||
|
|
||||||
gmap.style.display = 'none'; // property was changed after attaching map
|
|
||||||
})();
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerResize", function() {
|
|
||||||
if (this._mode == "map") {
|
|
||||||
this.map_view(true);
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
var old = scheduler.render_data;
|
|
||||||
scheduler.render_data = function(evs, hold) {
|
|
||||||
if (this._mode == "map") {
|
|
||||||
fill_map_tab();
|
|
||||||
var events = scheduler.get_visible_events();
|
|
||||||
for (var i = 0; i < events.length; i++) {
|
|
||||||
if (!scheduler.map._markers[events[i].id]) {
|
|
||||||
showAddress(events[i], false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
return old.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
function set_full_view(mode) {
|
|
||||||
if (mode) {
|
|
||||||
var l = scheduler.locale.labels;
|
|
||||||
scheduler._els["dhx_cal_header"][0].innerHTML = "<div class='dhx_map_line' style='width: " + (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 2) + "px;' ><div class='headline_date' style='width: " + scheduler.xy.map_date_width + "px;'>" + l.date + "</div><div class='headline_description' style='width: " + scheduler.xy.map_description_width + "px;'>" + l.description + "</div></div>";
|
|
||||||
scheduler._table_view = true;
|
|
||||||
scheduler.set_sizes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear_map_tab() {
|
|
||||||
scheduler._selected_event_id = null;
|
|
||||||
scheduler.map._infowindow.close();
|
|
||||||
var markers = scheduler.map._markers;
|
|
||||||
for (var key in markers) {
|
|
||||||
if (markers.hasOwnProperty(key)) {
|
|
||||||
markers[key].setMap(null);
|
|
||||||
delete scheduler.map._markers[key];
|
|
||||||
if (scheduler.map._infowindows_content[key])
|
|
||||||
delete scheduler.map._infowindows_content[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fill_map_tab() {
|
|
||||||
//select events for which data need to be printed
|
|
||||||
var events = scheduler.get_visible_events();
|
|
||||||
events.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;
|
|
||||||
});
|
|
||||||
|
|
||||||
//generate html for the view
|
|
||||||
var html = "<div class='dhx_map_area'>";
|
|
||||||
for (var i = 0; i < events.length; i++) {
|
|
||||||
var ev = events[i];
|
|
||||||
var event_class = (ev.id == scheduler._selected_event_id) ? 'dhx_map_line highlight' : 'dhx_map_line';
|
|
||||||
var bg_color = (ev.color ? ("background:" + ev.color + ";") : "");
|
|
||||||
var color = (ev.textColor ? ("color:" + ev.textColor + ";") : "");
|
|
||||||
html += "<div class='" + event_class + "' event_id='" + ev.id + "' style='" + bg_color + "" + color + "" + (ev._text_style || "") + " width: " + (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 2) + "px;'><div style='width: " + scheduler.xy.map_date_width + "px;' >" + scheduler.templates.map_time(ev.start_date, ev.end_date, ev) + "</div>";
|
|
||||||
html += "<div class='dhx_event_icon icon_details'> </div>";
|
|
||||||
html += "<div class='line_description' style='width:" + (scheduler.xy.map_description_width - 25) + "px;'>" + scheduler.templates.map_text(ev.start_date, ev.end_date, ev) + "</div></div>"; // -25 = icon size 20 and padding 5
|
|
||||||
}
|
|
||||||
html += "<div class='dhx_v_border' style='left: " + (scheduler.xy.map_date_width - 2) + "px;'></div><div class='dhx_v_border_description'></div></div>";
|
|
||||||
|
|
||||||
//render html
|
|
||||||
scheduler._els["dhx_cal_data"][0].scrollTop = 0; //fix flickering in FF
|
|
||||||
scheduler._els["dhx_cal_data"][0].innerHTML = html;
|
|
||||||
scheduler._els["dhx_cal_data"][0].style.width = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px';
|
|
||||||
|
|
||||||
var t = scheduler._els["dhx_cal_data"][0].firstChild.childNodes;
|
|
||||||
scheduler._els["dhx_cal_date"][0].innerHTML = scheduler.templates[scheduler._mode + "_date"](scheduler._min_date, scheduler._max_date, scheduler._mode);
|
|
||||||
|
|
||||||
scheduler._rendered = [];
|
|
||||||
for (var i = 0; i < t.length - 2; i++) {
|
|
||||||
scheduler._rendered[i] = t[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _setMapSize(elem_id) { //input - map's div id
|
|
||||||
var map = document.getElementById(elem_id);
|
|
||||||
var height = scheduler._y - scheduler.xy.nav_height;
|
|
||||||
if (height < 0)
|
|
||||||
height = 0;
|
|
||||||
var width = scheduler._x - scheduler.xy.map_date_width - scheduler.xy.map_description_width - 1;
|
|
||||||
if (width < 0)
|
|
||||||
width = 0;
|
|
||||||
map.style.height = height + 'px';
|
|
||||||
map.style.width = width + 'px';
|
|
||||||
map.style.marginLeft = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px';
|
|
||||||
map.style.marginTop = (scheduler.xy.nav_height + 2) + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.map_view = function(mode) {
|
|
||||||
scheduler.map._initialization_count++;
|
|
||||||
var gmap = scheduler._els.dhx_gmap[0];
|
|
||||||
scheduler._els.dhx_cal_data[0].style.width = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px';
|
|
||||||
|
|
||||||
scheduler._min_date = scheduler.config.map_start || (new Date());
|
|
||||||
scheduler._max_date = scheduler.config.map_end || scheduler.date.add(new Date(), 1, "year");
|
|
||||||
|
|
||||||
scheduler._table_view = true;
|
|
||||||
set_full_view(mode);
|
|
||||||
|
|
||||||
if (mode) { //map tab activated
|
|
||||||
clear_map_tab();
|
|
||||||
fill_map_tab();
|
|
||||||
gmap.style.display = 'block';
|
|
||||||
|
|
||||||
// need to resize block everytime window is resized
|
|
||||||
_setMapSize('dhx_gmap');
|
|
||||||
var temp_center = scheduler.map._obj.getCenter();
|
|
||||||
|
|
||||||
var events = scheduler.get_visible_events();
|
|
||||||
for (var i = 0; i < events.length; i++) {
|
|
||||||
if (!scheduler.map._markers[events[i].id]) {
|
|
||||||
showAddress(events[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { //map tab de-activated
|
|
||||||
gmap.style.display = 'none';
|
|
||||||
}
|
|
||||||
google.maps.event.trigger(scheduler.map._obj, 'resize');
|
|
||||||
|
|
||||||
if (scheduler.map._initialization_count === 0 && temp_center) { // if tab is activated for the first time need to fix position
|
|
||||||
scheduler.map._obj.setCenter(temp_center);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scheduler._selected_event_id) {
|
|
||||||
selectEvent(scheduler._selected_event_id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var selectEvent = function(event_id) {
|
|
||||||
scheduler.map._obj.setCenter(scheduler.map._points[event_id]);
|
|
||||||
scheduler.callEvent("onClick", [event_id]);
|
|
||||||
};
|
|
||||||
|
|
||||||
var showAddress = function(event, setCenter, performClick) { // what if event have incorrect position from the start?
|
|
||||||
var point = scheduler.config.map_error_position;
|
|
||||||
if (event.lat && event.lng) {
|
|
||||||
point = new google.maps.LatLng(event.lat, event.lng);
|
|
||||||
}
|
|
||||||
var message = scheduler.templates.marker_text(event.start_date, event.end_date, event);
|
|
||||||
if (!scheduler._new_event) {
|
|
||||||
|
|
||||||
scheduler.map._infowindows_content[event.id] = message;
|
|
||||||
|
|
||||||
if (scheduler.map._markers[event.id])
|
|
||||||
scheduler.map._markers[event.id].setMap(null);
|
|
||||||
|
|
||||||
scheduler.map._markers[event.id] = new google.maps.Marker({
|
|
||||||
position: point,
|
|
||||||
map: scheduler.map._obj
|
|
||||||
});
|
|
||||||
|
|
||||||
google.maps.event.addListener(scheduler.map._markers[event.id], 'click', function() {
|
|
||||||
scheduler.map._infowindow.setContent(scheduler.map._infowindows_content[event.id]);
|
|
||||||
scheduler.map._infowindow.open(scheduler.map._obj, scheduler.map._markers[event.id]);
|
|
||||||
scheduler._selected_event_id = event.id;
|
|
||||||
scheduler.render_data();
|
|
||||||
});
|
|
||||||
scheduler.map._points[event.id] = point;
|
|
||||||
|
|
||||||
if (setCenter) scheduler.map._obj.setCenter(scheduler.map._points[event.id]);
|
|
||||||
if (performClick) scheduler.callEvent("onClick", [event.id]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onClick", function(event_id, native_event_object) {
|
|
||||||
if (this._mode == "map") {
|
|
||||||
scheduler._selected_event_id = event_id;
|
|
||||||
for (var i = 0; i < scheduler._rendered.length; i++) {
|
|
||||||
scheduler._rendered[i].className = 'dhx_map_line';
|
|
||||||
if (scheduler._rendered[i].getAttribute("event_id") == event_id) {
|
|
||||||
scheduler._rendered[i].className += " highlight";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (scheduler.map._points[event_id] && scheduler.map._markers[event_id]) {
|
|
||||||
scheduler.map._obj.setCenter(scheduler.map._points[event_id]); // was panTo
|
|
||||||
google.maps.event.trigger(scheduler.map._markers[event_id], 'click');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
var _displayEventOnMap = function(event) {
|
|
||||||
if (event.event_location && geocoder) {
|
|
||||||
geocoder.geocode(
|
|
||||||
{
|
|
||||||
'address': event.event_location,
|
|
||||||
'language': scheduler.uid().toString()
|
|
||||||
},
|
|
||||||
function(results, status) {
|
|
||||||
var point = {};
|
|
||||||
if (status != google.maps.GeocoderStatus.OK) {
|
|
||||||
point = scheduler.callEvent("onLocationError", [event.id]);
|
|
||||||
if (!point || point === true)
|
|
||||||
point = scheduler.config.map_error_position;
|
|
||||||
} else {
|
|
||||||
point = results[0].geometry.location;
|
|
||||||
}
|
|
||||||
event.lat = point.lat();
|
|
||||||
event.lng = point.lng();
|
|
||||||
|
|
||||||
scheduler._selected_event_id = event.id;
|
|
||||||
|
|
||||||
scheduler._latLngUpdate = true;
|
|
||||||
scheduler.callEvent("onEventChanged", [event.id, event]);
|
|
||||||
showAddress(event, true, true);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
showAddress(event, true, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var _updateEventLocation = function(event) { // update lat and lng in database
|
|
||||||
if (event.event_location && geocoder) {
|
|
||||||
geocoder.geocode(
|
|
||||||
{
|
|
||||||
'address': event.event_location,
|
|
||||||
'language': scheduler.uid().toString()
|
|
||||||
},
|
|
||||||
function(results, status) {
|
|
||||||
var point = {};
|
|
||||||
if (status != google.maps.GeocoderStatus.OK) {
|
|
||||||
point = scheduler.callEvent("onLocationError", [event.id]);
|
|
||||||
if (!point || point === true)
|
|
||||||
point = scheduler.config.map_error_position;
|
|
||||||
} else {
|
|
||||||
point = results[0].geometry.location;
|
|
||||||
}
|
|
||||||
event.lat = point.lat();
|
|
||||||
event.lng = point.lng();
|
|
||||||
scheduler._latLngUpdate = true;
|
|
||||||
scheduler.callEvent("onEventChanged", [event.id, event]);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var _delay = function(method, object, params, delay) {
|
|
||||||
setTimeout(function() {
|
|
||||||
var ret = method.apply(object, params);
|
|
||||||
method = object = params = null;
|
|
||||||
return ret;
|
|
||||||
}, delay || 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventChanged", function(event_id, event_object) {
|
|
||||||
if (!this._latLngUpdate) {
|
|
||||||
var event = scheduler.getEvent(event_id);
|
|
||||||
if ((event.start_date < scheduler._min_date && event.end_date > scheduler._min_date) || (event.start_date < scheduler._max_date && event.end_date > scheduler._max_date) || (event.start_date.valueOf() >= scheduler._min_date && event.end_date.valueOf() <= scheduler._max_date)) {
|
|
||||||
if (scheduler.map._markers[event_id])
|
|
||||||
scheduler.map._markers[event_id].setMap(null);
|
|
||||||
_displayEventOnMap(event);
|
|
||||||
} else { // event no longer should be displayed on the map view
|
|
||||||
scheduler._selected_event_id = null;
|
|
||||||
scheduler.map._infowindow.close();
|
|
||||||
if (scheduler.map._markers[event_id])
|
|
||||||
scheduler.map._markers[event_id].setMap(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this._latLngUpdate = false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventIdChange", function(old_event_id, new_event_id) {
|
|
||||||
var event = scheduler.getEvent(new_event_id);
|
|
||||||
if ((event.start_date < scheduler._min_date && event.end_date > scheduler._min_date) || (event.start_date < scheduler._max_date && event.end_date > scheduler._max_date) || (event.start_date.valueOf() >= scheduler._min_date && event.end_date.valueOf() <= scheduler._max_date)) {
|
|
||||||
if (scheduler.map._markers[old_event_id]) {
|
|
||||||
scheduler.map._markers[old_event_id].setMap(null);
|
|
||||||
delete scheduler.map._markers[old_event_id];
|
|
||||||
}
|
|
||||||
if (scheduler.map._infowindows_content[old_event_id])
|
|
||||||
delete scheduler.map._infowindows_content[old_event_id];
|
|
||||||
_displayEventOnMap(event);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventAdded", function(event_id, event_object) {
|
|
||||||
if (!scheduler._dataprocessor) {
|
|
||||||
if ((event_object.start_date < scheduler._min_date && event_object.end_date > scheduler._min_date) || (event_object.start_date < scheduler._max_date && event_object.end_date > scheduler._max_date) || (event_object.start_date.valueOf() >= scheduler._min_date && event_object.end_date.valueOf() <= scheduler._max_date)) {
|
|
||||||
if (scheduler.map._markers[event_id])
|
|
||||||
scheduler.map._markers[event_id].setMap(null);
|
|
||||||
_displayEventOnMap(event_object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Test/example
|
|
||||||
scheduler.attachEvent("onLocationError", function(event_id,event_object){
|
|
||||||
return new google.maps.LatLng(8, 8);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeEventDelete", function(event_id, event_object) {
|
|
||||||
if (scheduler.map._markers[event_id]) {
|
|
||||||
scheduler.map._markers[event_id].setMap(null); // if new event is deleted tab != map then it doesn't have marker yet
|
|
||||||
}
|
|
||||||
scheduler._selected_event_id = null;
|
|
||||||
scheduler.map._infowindow.close();
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler._event_resolve_delay = 1500;
|
|
||||||
scheduler.attachEvent("onEventLoading", function(event) {
|
|
||||||
if (scheduler.config.map_resolve_event_location && event.event_location && !event.lat && !event.lng) { // don't delete !event.lat && !event.lng as location could change
|
|
||||||
scheduler._event_resolve_delay += 1500;
|
|
||||||
_delay(_updateEventLocation, this, [event], scheduler._event_resolve_delay);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventCancel", function(event_id, is_new) {
|
|
||||||
if (is_new) {
|
|
||||||
if (scheduler.map._markers[event_id])
|
|
||||||
scheduler.map._markers[event_id].setMap(null);
|
|
||||||
scheduler.map._infowindow.close();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,435 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.templates.calendar_month = scheduler.date.date_to_str("%F %Y");
|
|
||||||
scheduler.templates.calendar_scale_date = scheduler.date.date_to_str("%D");
|
|
||||||
scheduler.templates.calendar_date = scheduler.date.date_to_str("%d");
|
|
||||||
scheduler.config.minicalendar = {
|
|
||||||
mark_events: true
|
|
||||||
};
|
|
||||||
scheduler._synced_minicalendars = [];
|
|
||||||
scheduler.renderCalendar = function(obj, _prev, is_refresh) {
|
|
||||||
var cal = null;
|
|
||||||
var date = obj.date || (new Date());
|
|
||||||
if (typeof date == "string")
|
|
||||||
date = this.templates.api_date(date);
|
|
||||||
|
|
||||||
if (!_prev) {
|
|
||||||
var cont = obj.container;
|
|
||||||
var pos = obj.position;
|
|
||||||
|
|
||||||
if (typeof cont == "string")
|
|
||||||
cont = document.getElementById(cont);
|
|
||||||
|
|
||||||
if (typeof pos == "string")
|
|
||||||
pos = document.getElementById(pos);
|
|
||||||
if (pos && (typeof pos.left == "undefined")) {
|
|
||||||
var tpos = getOffset(pos);
|
|
||||||
pos = {
|
|
||||||
top: tpos.top + pos.offsetHeight,
|
|
||||||
left: tpos.left
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!cont)
|
|
||||||
cont = scheduler._get_def_cont(pos);
|
|
||||||
|
|
||||||
cal = this._render_calendar(cont, date, obj);
|
|
||||||
cal.onclick = function(e) {
|
|
||||||
e = e || event;
|
|
||||||
var src = e.target || e.srcElement;
|
|
||||||
|
|
||||||
if (src.className.indexOf("dhx_month_head") != -1) {
|
|
||||||
var pname = src.parentNode.className;
|
|
||||||
if (pname.indexOf("dhx_after") == -1 && pname.indexOf("dhx_before") == -1) {
|
|
||||||
var newdate = scheduler.templates.xml_date(this.getAttribute("date"));
|
|
||||||
newdate.setDate(parseInt(src.innerHTML, 10));
|
|
||||||
scheduler.unmarkCalendar(this);
|
|
||||||
scheduler.markCalendar(this, newdate, "dhx_calendar_click");
|
|
||||||
this._last_date = newdate;
|
|
||||||
if (this.conf.handler) this.conf.handler.call(scheduler, newdate, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
cal = this._render_calendar(_prev.parentNode, date, obj, _prev);
|
|
||||||
scheduler.unmarkCalendar(cal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scheduler.config.minicalendar.mark_events) {
|
|
||||||
var start = scheduler.date.month_start(date);
|
|
||||||
var end = scheduler.date.add(start, 1, "month");
|
|
||||||
var evs = this.getEvents(start, end);
|
|
||||||
var filter = this["filter_" + this._mode];
|
|
||||||
for (var i = 0; i < evs.length; i++) {
|
|
||||||
var ev = evs[i];
|
|
||||||
if (filter && !filter(ev.id, ev))
|
|
||||||
continue;
|
|
||||||
var d = ev.start_date;
|
|
||||||
if (d.valueOf() < start.valueOf())
|
|
||||||
d = start;
|
|
||||||
d = scheduler.date.date_part(new Date(d.valueOf()));
|
|
||||||
while (d < ev.end_date) {
|
|
||||||
this.markCalendar(cal, d, "dhx_year_event");
|
|
||||||
d = this.date.add(d, 1, "day");
|
|
||||||
if (d.valueOf() >= end.valueOf())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._markCalendarCurrentDate(cal);
|
|
||||||
|
|
||||||
cal.conf = obj;
|
|
||||||
if (obj.sync && !is_refresh)
|
|
||||||
this._synced_minicalendars.push(cal);
|
|
||||||
|
|
||||||
return cal;
|
|
||||||
};
|
|
||||||
scheduler._get_def_cont = function(pos) {
|
|
||||||
if (!this._def_count) {
|
|
||||||
this._def_count = document.createElement("DIV");
|
|
||||||
this._def_count.className = "dhx_minical_popup";
|
|
||||||
this._def_count.onclick = function(e) { (e || event).cancelBubble = true; };
|
|
||||||
document.body.appendChild(this._def_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._def_count.style.left = pos.left + "px";
|
|
||||||
this._def_count.style.top = pos.top + "px";
|
|
||||||
this._def_count._created = new Date();
|
|
||||||
|
|
||||||
return this._def_count;
|
|
||||||
};
|
|
||||||
scheduler._locateCalendar = function(cal, date) {
|
|
||||||
var table = cal.childNodes[2].childNodes[0];
|
|
||||||
if (typeof date == "string")
|
|
||||||
date = scheduler.templates.api_date(date);
|
|
||||||
|
|
||||||
var d = cal.week_start + date.getDate() - 1;
|
|
||||||
return table.rows[Math.floor(d / 7)].cells[d % 7].firstChild;
|
|
||||||
};
|
|
||||||
scheduler.markCalendar = function(cal, date, css) {
|
|
||||||
this._locateCalendar(cal, date).className += " " + css;
|
|
||||||
};
|
|
||||||
scheduler.unmarkCalendar = function(cal, date, css) {
|
|
||||||
date = date || cal._last_date;
|
|
||||||
css = css || "dhx_calendar_click";
|
|
||||||
if (!date) return;
|
|
||||||
var el = this._locateCalendar(cal, date);
|
|
||||||
el.className = (el.className || "").replace(RegExp(css, "g"));
|
|
||||||
};
|
|
||||||
scheduler._week_template = function(width) {
|
|
||||||
var summ = (width || 250);
|
|
||||||
var left = 0;
|
|
||||||
|
|
||||||
var week_template = document.createElement("div");
|
|
||||||
var dummy_date = this.date.week_start(new Date());
|
|
||||||
for (var i = 0; i < 7; i++) {
|
|
||||||
this._cols[i] = Math.floor(summ / (7 - i));
|
|
||||||
this._render_x_header(i, left, dummy_date, week_template);
|
|
||||||
dummy_date = this.date.add(dummy_date, 1, "day");
|
|
||||||
summ -= this._cols[i];
|
|
||||||
left += this._cols[i];
|
|
||||||
}
|
|
||||||
week_template.lastChild.className += " dhx_scale_bar_last";
|
|
||||||
return week_template;
|
|
||||||
};
|
|
||||||
scheduler.updateCalendar = function(obj, sd) {
|
|
||||||
obj.conf.date = sd;
|
|
||||||
this.renderCalendar(obj.conf, obj, true);
|
|
||||||
};
|
|
||||||
scheduler._mini_cal_arrows = [" ", " "];
|
|
||||||
scheduler._render_calendar = function(obj, sd, conf, previous) {
|
|
||||||
/*store*/
|
|
||||||
var ts = scheduler.templates;
|
|
||||||
var temp = this._cols;
|
|
||||||
this._cols = [];
|
|
||||||
var temp2 = this._mode;
|
|
||||||
this._mode = "calendar";
|
|
||||||
var temp3 = this._colsS;
|
|
||||||
this._colsS = {height: 0};
|
|
||||||
var temp4 = new Date(this._min_date);
|
|
||||||
var temp5 = new Date(this._max_date);
|
|
||||||
var temp6 = new Date(scheduler._date);
|
|
||||||
var temp7 = ts.month_day;
|
|
||||||
ts.month_day = ts.calendar_date;
|
|
||||||
|
|
||||||
sd = this.date.month_start(sd);
|
|
||||||
var week_template = this._week_template(obj.offsetWidth - 1);
|
|
||||||
|
|
||||||
var d;
|
|
||||||
if (previous)
|
|
||||||
d = previous; else {
|
|
||||||
d = document.createElement("DIV");
|
|
||||||
d.className = "dhx_cal_container dhx_mini_calendar";
|
|
||||||
}
|
|
||||||
d.setAttribute("date", this.templates.xml_format(sd));
|
|
||||||
d.innerHTML = "<div class='dhx_year_month'></div><div class='dhx_year_week'>" + week_template.innerHTML + "</div><div class='dhx_year_body'></div>";
|
|
||||||
|
|
||||||
d.childNodes[0].innerHTML = this.templates.calendar_month(sd);
|
|
||||||
if (conf.navigation) {
|
|
||||||
var move_minicalendar_date = function(calendar, diff) {
|
|
||||||
var date = scheduler.date.add(calendar._date, diff, "month");
|
|
||||||
scheduler.updateCalendar(calendar, date);
|
|
||||||
if (scheduler._date.getMonth() == calendar._date.getMonth() && scheduler._date.getFullYear() == calendar._date.getFullYear()) {
|
|
||||||
scheduler._markCalendarCurrentDate(calendar);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var css_classnames = ["dhx_cal_prev_button", "dhx_cal_next_button"];
|
|
||||||
var css_texts = ["left:1px;top:2px;position:absolute;", "left:auto; right:1px;top:2px;position:absolute;"];
|
|
||||||
var diffs = [-1, 1];
|
|
||||||
var handler = function(diff) {
|
|
||||||
return function() {
|
|
||||||
if (conf.sync) {
|
|
||||||
var calendars = scheduler._synced_minicalendars;
|
|
||||||
for (var k = 0; k < calendars.length; k++) {
|
|
||||||
move_minicalendar_date(calendars[k], diff);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
move_minicalendar_date(d, diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for (var j = 0; j < 2; j++) {
|
|
||||||
var arrow = document.createElement("DIV");
|
|
||||||
//var diff = diffs[j];
|
|
||||||
arrow.className = css_classnames[j];
|
|
||||||
arrow.style.cssText = css_texts[j];
|
|
||||||
arrow.innerHTML = this._mini_cal_arrows[j];
|
|
||||||
d.firstChild.appendChild(arrow);
|
|
||||||
arrow.onclick = handler(diffs[j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d._date = new Date(sd);
|
|
||||||
|
|
||||||
d.week_start = (sd.getDay() - (this.config.start_on_monday ? 1 : 0) + 7) % 7;
|
|
||||||
|
|
||||||
var dd = this.date.week_start(sd);
|
|
||||||
this._reset_month_scale(d.childNodes[2], sd, dd);
|
|
||||||
|
|
||||||
var r = d.childNodes[2].firstChild.rows;
|
|
||||||
for (var k = r.length; k < 6; k++) {
|
|
||||||
var last_row = r[r.length - 1];
|
|
||||||
r[0].parentNode.appendChild(last_row.cloneNode(true));
|
|
||||||
var last_day_number = parseInt(last_row.childNodes[last_row.childNodes.length - 1].childNodes[0].innerHTML);
|
|
||||||
last_day_number = (last_day_number < 10) ? last_day_number : 0; // previous week could end on 28-31, so we should start with 0
|
|
||||||
for (var ri = 0; ri < r[k].childNodes.length; ri++) {
|
|
||||||
r[k].childNodes[ri].className = "dhx_after";
|
|
||||||
r[k].childNodes[ri].childNodes[0].innerHTML = scheduler.date.to_fixed(++last_day_number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!previous)
|
|
||||||
obj.appendChild(d);
|
|
||||||
|
|
||||||
d.childNodes[1].style.height = (d.childNodes[1].childNodes[0].offsetHeight - 1) + "px"; // dhx_year_week should have height property so that day dates would get correct position. dhx_year_week height = height of it's child (with the day name)
|
|
||||||
|
|
||||||
/*restore*/
|
|
||||||
this._cols = temp;
|
|
||||||
this._mode = temp2;
|
|
||||||
this._colsS = temp3;
|
|
||||||
this._min_date = temp4;
|
|
||||||
this._max_date = temp5;
|
|
||||||
scheduler._date = temp6;
|
|
||||||
ts.month_day = temp7;
|
|
||||||
return d;
|
|
||||||
};
|
|
||||||
scheduler.destroyCalendar = function(cal, force) {
|
|
||||||
if (!cal && this._def_count && this._def_count.firstChild) {
|
|
||||||
if (force || (new Date()).valueOf() - this._def_count._created.valueOf() > 500)
|
|
||||||
cal = this._def_count.firstChild;
|
|
||||||
}
|
|
||||||
if (!cal) return;
|
|
||||||
cal.onclick = null;
|
|
||||||
cal.innerHTML = "";
|
|
||||||
if (cal.parentNode)
|
|
||||||
cal.parentNode.removeChild(cal);
|
|
||||||
if (this._def_count)
|
|
||||||
this._def_count.style.top = "-1000px";
|
|
||||||
};
|
|
||||||
scheduler.isCalendarVisible = function() {
|
|
||||||
if (this._def_count && parseInt(this._def_count.style.top, 10) > 0)
|
|
||||||
return this._def_count;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function() {
|
|
||||||
dhtmlxEvent(document.body, "click", function() { scheduler.destroyCalendar(); });
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.templates.calendar_time = scheduler.date.date_to_str("%d-%m-%Y");
|
|
||||||
|
|
||||||
scheduler.form_blocks.calendar_time = {
|
|
||||||
render: function() {
|
|
||||||
var html = "<input class='dhx_readonly' type='text' readonly='true'>";
|
|
||||||
|
|
||||||
var cfg = scheduler.config;
|
|
||||||
var dt = this.date.date_part(new Date());
|
|
||||||
|
|
||||||
var last = 24 * 60, first = 0;
|
|
||||||
if (cfg.limit_time_select) {
|
|
||||||
first = 60 * cfg.first_hour;
|
|
||||||
last = 60 * cfg.last_hour + 1; // to include "17:00" option if time select is limited
|
|
||||||
}
|
|
||||||
dt.setHours(first / 60);
|
|
||||||
|
|
||||||
html += " <select>";
|
|
||||||
for (var i = first; i < last; i += this.config.time_step * 1) { // `<` to exclude last "00:00" option
|
|
||||||
var time = this.templates.time_picker(dt);
|
|
||||||
html += "<option value='" + i + "'>" + time + "</option>";
|
|
||||||
dt = this.date.add(dt, this.config.time_step, "minute");
|
|
||||||
}
|
|
||||||
html += "</select>";
|
|
||||||
|
|
||||||
var full_day = scheduler.config.full_day;
|
|
||||||
|
|
||||||
return "<div style='height:30px;padding-top:0; font-size:inherit;' class='dhx_section_time'>" + html + "<span style='font-weight:normal; font-size:10pt;'> – </span>" + html + "</div>";
|
|
||||||
},
|
|
||||||
set_value: function(node, value, ev) {
|
|
||||||
|
|
||||||
var inputs = node.getElementsByTagName("input");
|
|
||||||
var selects = node.getElementsByTagName("select");
|
|
||||||
|
|
||||||
var _init_once = function(inp, date, number) {
|
|
||||||
inp.onclick = function() {
|
|
||||||
scheduler.destroyCalendar(null, true);
|
|
||||||
scheduler.renderCalendar({
|
|
||||||
position: inp,
|
|
||||||
date: new Date(this._date),
|
|
||||||
navigation: true,
|
|
||||||
handler: function(new_date) {
|
|
||||||
inp.value = scheduler.templates.calendar_time(new_date);
|
|
||||||
inp._date = new Date(new_date);
|
|
||||||
scheduler.destroyCalendar();
|
|
||||||
if (scheduler.config.event_duration && scheduler.config.auto_end_date && number == 0) { //first element = start date
|
|
||||||
_update_minical_select();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scheduler.config.full_day) {
|
|
||||||
if (!node._full_day) {
|
|
||||||
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;
|
|
||||||
node._full_day = true;
|
|
||||||
}
|
|
||||||
var input = node.previousSibling.getElementsByTagName("input")[0];
|
|
||||||
|
|
||||||
var isFulldayEvent = (scheduler.date.time_part(ev.start_date) == 0 && scheduler.date.time_part(ev.end_date) == 0);
|
|
||||||
input.checked = isFulldayEvent;
|
|
||||||
|
|
||||||
selects[0].disabled = input.checked;
|
|
||||||
selects[1].disabled = input.checked;
|
|
||||||
|
|
||||||
input.onclick = function() {
|
|
||||||
if (input.checked == true) {
|
|
||||||
var obj = {};
|
|
||||||
scheduler.form_blocks.calendar_time.get_value(node, obj);
|
|
||||||
|
|
||||||
var start_date = scheduler.date.date_part(obj.start_date);
|
|
||||||
var end_date = scheduler.date.date_part(obj.end_date);
|
|
||||||
|
|
||||||
if (+end_date == +start_date || (+end_date >= +start_date && (ev.end_date.getHours() != 0 || ev.end_date.getMinutes() != 0)))
|
|
||||||
end_date = scheduler.date.add(end_date, 1, "day");
|
|
||||||
}
|
|
||||||
|
|
||||||
var start = start_date || ev.start_date;
|
|
||||||
var end = end_date || ev.end_date;
|
|
||||||
_attach_action(inputs[0], start);
|
|
||||||
_attach_action(inputs[1], end);
|
|
||||||
selects[0].value = start.getHours() * 60 + start.getMinutes();
|
|
||||||
selects[1].value = end.getHours() * 60 + end.getMinutes();
|
|
||||||
|
|
||||||
selects[0].disabled = input.checked;
|
|
||||||
selects[1].disabled = input.checked;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scheduler.config.event_duration && scheduler.config.auto_end_date) {
|
|
||||||
|
|
||||||
function _update_minical_select() {
|
|
||||||
start_date = scheduler.date.add(inputs[0]._date, selects[0].value, "minute");
|
|
||||||
end_date = new Date(start_date.getTime() + (scheduler.config.event_duration * 60 * 1000));
|
|
||||||
|
|
||||||
inputs[1].value = scheduler.templates.calendar_time(end_date);
|
|
||||||
inputs[1]._date = scheduler.date.date_part(new Date(end_date));
|
|
||||||
|
|
||||||
selects[1].value = end_date.getHours() * 60 + end_date.getMinutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
selects[0].onchange = _update_minical_select; // only update on first select should trigger update so user could define other end date if he wishes too
|
|
||||||
}
|
|
||||||
|
|
||||||
function _attach_action(inp, date, number) {
|
|
||||||
_init_once(inp, date, number);
|
|
||||||
inp.value = scheduler.templates.calendar_time(date);
|
|
||||||
inp._date = scheduler.date.date_part(new Date(date));
|
|
||||||
}
|
|
||||||
|
|
||||||
_attach_action(inputs[0], ev.start_date, 0);
|
|
||||||
_attach_action(inputs[1], ev.end_date, 1);
|
|
||||||
_init_once = function() {};
|
|
||||||
|
|
||||||
selects[0].value = ev.start_date.getHours() * 60 + ev.start_date.getMinutes();
|
|
||||||
selects[1].value = ev.end_date.getHours() * 60 + ev.end_date.getMinutes();
|
|
||||||
|
|
||||||
},
|
|
||||||
get_value: function(node, ev) {
|
|
||||||
var inputs = node.getElementsByTagName("input");
|
|
||||||
var selects = node.getElementsByTagName("select");
|
|
||||||
|
|
||||||
ev.start_date = scheduler.date.add(inputs[0]._date, selects[0].value, "minute");
|
|
||||||
ev.end_date = scheduler.date.add(inputs[1]._date, selects[1].value, "minute");
|
|
||||||
|
|
||||||
if (ev.end_date <= ev.start_date)
|
|
||||||
ev.end_date = scheduler.date.add(ev.start_date, scheduler.config.time_step, "minute");
|
|
||||||
},
|
|
||||||
focus: function(node) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.linkCalendar = function(calendar, datediff) {
|
|
||||||
var action = function() {
|
|
||||||
var date = scheduler._date;
|
|
||||||
var dateNew = new Date(date.valueOf());
|
|
||||||
if (datediff) dateNew = datediff(dateNew);
|
|
||||||
dateNew.setDate(1);
|
|
||||||
scheduler.updateCalendar(calendar, dateNew);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onViewChange", action);
|
|
||||||
scheduler.attachEvent("onXLE", action);
|
|
||||||
scheduler.attachEvent("onEventAdded", action);
|
|
||||||
scheduler.attachEvent("onEventChanged", action);
|
|
||||||
scheduler.attachEvent("onAfterEventDelete", action);
|
|
||||||
action();
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler._markCalendarCurrentDate = function(calendar) {
|
|
||||||
var date = scheduler._date;
|
|
||||||
var mode = scheduler._mode;
|
|
||||||
var month_start = scheduler.date.month_start(new Date(calendar._date));
|
|
||||||
var month_end = scheduler.date.add(month_start, 1, "month");
|
|
||||||
|
|
||||||
if (mode == 'day' || (this._props && !!this._props[mode])) { // if day or units view
|
|
||||||
if (month_start.valueOf() <= date.valueOf() && month_end > date) {
|
|
||||||
scheduler.markCalendar(calendar, date, "dhx_calendar_click");
|
|
||||||
}
|
|
||||||
} else if (mode == 'week') {
|
|
||||||
var dateNew = scheduler.date.week_start(new Date(date.valueOf()));
|
|
||||||
for (var i = 0; i < 7; i++) {
|
|
||||||
if (month_start.valueOf() <= dateNew.valueOf() && month_end > dateNew) // >= would mean mark first day of the next month
|
|
||||||
scheduler.markCalendar(calendar, dateNew, "dhx_calendar_click");
|
|
||||||
dateNew = scheduler.date.add(dateNew, 1, "day");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventCancel", function(){
|
|
||||||
scheduler.destroyCalendar(null, true);
|
|
||||||
});
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.form_blocks["multiselect"]={
|
|
||||||
render:function(sns) {
|
|
||||||
var _result = "<div class='dhx_multi_select_"+sns.name+"' style='overflow: auto; height: "+sns.height+"px; position: relative;' >";
|
|
||||||
for (var i=0; i<sns.options.length; i++) {
|
|
||||||
_result += "<label><input type='checkbox' value='"+sns.options[i].key+"'/>"+sns.options[i].label+"</label>";
|
|
||||||
if(convertStringToBoolean(sns.vertical)) _result += '<br/>';
|
|
||||||
}
|
|
||||||
_result += "</div>";
|
|
||||||
return _result;
|
|
||||||
},
|
|
||||||
set_value:function(node,value,ev,config){
|
|
||||||
|
|
||||||
var _children = node.getElementsByTagName('input');
|
|
||||||
for(var i=0;i<_children.length;i++) {
|
|
||||||
_children[i].checked = false; //unchecking all inputs on the form
|
|
||||||
}
|
|
||||||
|
|
||||||
function _mark_inputs(ids) { // ids = [ 0: undefined, 1: undefined, 2: true ... ]
|
|
||||||
var _children = node.getElementsByTagName('input');
|
|
||||||
for(var i=0;i<_children.length; i++) {
|
|
||||||
_children[i].checked = !! ids[_children[i].value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ids = [];
|
|
||||||
if (ev[config.map_to]) {
|
|
||||||
var results = ev[config.map_to].split(',');
|
|
||||||
for (var i = 0; i < results.length; i++) {
|
|
||||||
_ids[results[i]] = true;
|
|
||||||
}
|
|
||||||
_mark_inputs(_ids);
|
|
||||||
} else {
|
|
||||||
if (scheduler._new_event || !config.script_url)
|
|
||||||
return;
|
|
||||||
var divLoading = document.createElement('div');
|
|
||||||
divLoading.className = 'dhx_loading';
|
|
||||||
divLoading.style.cssText = "position: absolute; top: 40%; left: 40%;";
|
|
||||||
node.appendChild(divLoading);
|
|
||||||
dhtmlxAjax.get(config.script_url + '?dhx_crosslink_' + config.map_to + '=' + ev.id + '&uid=' + scheduler.uid(), function(loader) {
|
|
||||||
var _result = loader.doXPath("//data/item");
|
|
||||||
var _ids = [];
|
|
||||||
for (var i = 0; i < _result.length; i++) {
|
|
||||||
_ids[_result[i].getAttribute(config.map_to)] = true;
|
|
||||||
}
|
|
||||||
_mark_inputs(_ids);
|
|
||||||
node.removeChild(divLoading);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get_value:function(node,ev,config){
|
|
||||||
var _result = [];
|
|
||||||
var _children = node.getElementsByTagName("input");
|
|
||||||
for(var i=0;i<_children.length;i++) {
|
|
||||||
if(_children[i].checked)
|
|
||||||
_result.push(_children[i].value);
|
|
||||||
}
|
|
||||||
return _result.join(',');
|
|
||||||
},
|
|
||||||
|
|
||||||
focus:function(node){
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
function backup(obj){
|
|
||||||
var t = function(){};
|
|
||||||
t.prototype = obj;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
var old = scheduler._load;
|
|
||||||
scheduler._load=function(url,from){
|
|
||||||
url=url||this._load_url;
|
|
||||||
if (typeof url == "object"){
|
|
||||||
var t = backup(this._loaded);
|
|
||||||
for (var i=0; i < url.length; i++) {
|
|
||||||
this._loaded=new t();
|
|
||||||
old.call(this,url[i],from);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
old.apply(this,arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.load=function(url,call){
|
|
||||||
if (typeof call == "string"){
|
|
||||||
this._process=call;
|
|
||||||
var type = call;
|
|
||||||
call = arguments[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
this._load_url=url;
|
|
||||||
this._after_call=call;
|
|
||||||
if (url.$proxy) {
|
|
||||||
url.load(this, typeof type == "string" ? type : null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._load(url,this._date);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler._dp_init_backup = scheduler._dp_init;
|
|
||||||
scheduler._dp_init = function(dp) {
|
|
||||||
dp._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();
|
|
||||||
if (this.serverProcessor.$proxy) {
|
|
||||||
var mode = this._tMode!="POST" ? 'get' : 'post';
|
|
||||||
var to_send = [];
|
|
||||||
for (var i in a1)
|
|
||||||
to_send.push({ id: i, data: a1[i], operation: this.getState(i)});
|
|
||||||
this.serverProcessor._send(to_send, mode, this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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++;
|
|
||||||
};
|
|
||||||
|
|
||||||
dp._updatesToParams = function(items) {
|
|
||||||
var stack = {};
|
|
||||||
for (var i = 0; i < items.length; i++)
|
|
||||||
stack[items[i].id] = items[i].data;
|
|
||||||
return this.serialize(stack);
|
|
||||||
};
|
|
||||||
|
|
||||||
dp._processResult = function(text, xml, loader) {
|
|
||||||
if (loader.status != 200) {
|
|
||||||
for (var i in this._in_progress) {
|
|
||||||
var state = this.getState(i);
|
|
||||||
this.afterUpdateCallback(i, i, state, null);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xml = new dtmlXMLLoaderObject(function() {},this,true);
|
|
||||||
xml.loadXMLString(text);
|
|
||||||
xml.xmlDoc = loader;
|
|
||||||
|
|
||||||
this.afterUpdate(this, null, null, null, xml);
|
|
||||||
};
|
|
||||||
this._dp_init_backup(dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.dataProcessor)
|
|
||||||
dataProcessor.prototype.init=function(obj){
|
|
||||||
this.init_original(obj);
|
|
||||||
obj._dataprocessor=this;
|
|
||||||
|
|
||||||
this.setTransactionMode("POST",true);
|
|
||||||
if (!this.serverProcessor.$proxy)
|
|
||||||
this.serverProcessor+=(this.serverProcessor.indexOf("?")!=-1?"&":"?")+"editing=true";
|
|
||||||
};
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
//lame old code doesn't provide raw event object
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function(){
|
|
||||||
|
|
||||||
var dragger = (new dhtmlDragAndDropObject());
|
|
||||||
var old = dragger.stopDrag;
|
|
||||||
var last_event;
|
|
||||||
dragger.stopDrag = function(e){
|
|
||||||
last_event = e||event;
|
|
||||||
return old.apply(this, arguments);
|
|
||||||
};
|
|
||||||
dragger.addDragLanding(scheduler._els["dhx_cal_data"][0],{
|
|
||||||
_drag:function(sourceHtmlObject,dhtmlObject,targetHtmlObject,targetHtml){
|
|
||||||
|
|
||||||
if (scheduler.checkEvent("onBeforeExternalDragIn") && !scheduler.callEvent("onBeforeExternalDragIn", [sourceHtmlObject,dhtmlObject,targetHtmlObject,targetHtml,last_event]))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var temp = scheduler.attachEvent("onEventCreated", function(id,e){
|
|
||||||
if (!scheduler.callEvent("onExternalDragIn", [id, sourceHtmlObject, e])){
|
|
||||||
this._drag_mode = this._drag_id = null;
|
|
||||||
this.deleteEvent(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode])
|
|
||||||
scheduler.dblclick_dhx_matrix_cell(last_event);
|
|
||||||
else {
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
|
||||||
div.className = 'dhx_month_body';
|
|
||||||
var eventCopy = {};
|
|
||||||
for (var i in last_event) eventCopy[i] = last_event[i];
|
|
||||||
eventCopy.target = eventCopy.srcElement = div;
|
|
||||||
|
|
||||||
scheduler._on_dbl_click(eventCopy);
|
|
||||||
}
|
|
||||||
scheduler.detachEvent(temp);
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
_dragIn:function(htmlObject,shtmlObject){
|
|
||||||
return htmlObject;
|
|
||||||
},
|
|
||||||
_dragOut:function(htmlObject){
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,276 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.toPDF=function(url,mode,header,footer){
|
|
||||||
var dx = 0;
|
|
||||||
var dy = 0;
|
|
||||||
var colors = false;
|
|
||||||
if (mode == "fullcolor"){
|
|
||||||
colors = true;
|
|
||||||
mode = "color";
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = mode||"color";
|
|
||||||
html_regexp = new RegExp("<[^>]*>","g");
|
|
||||||
newline_regexp = new RegExp("<br[^>]*>","g");
|
|
||||||
function clean_html(val){
|
|
||||||
return val.replace(newline_regexp, "\n").replace(html_regexp,"");
|
|
||||||
}
|
|
||||||
function x_norm(x) {
|
|
||||||
x = parseFloat(x);
|
|
||||||
if (isNaN(x)) return "auto";
|
|
||||||
return 100 * x / (dx + 1);
|
|
||||||
}
|
|
||||||
function y_norm(y) {
|
|
||||||
y = parseFloat(y);
|
|
||||||
if (isNaN(y)) return "auto";
|
|
||||||
return 100 * y / dy;
|
|
||||||
}
|
|
||||||
function xml_month_scale(xh){
|
|
||||||
var xml="";
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode]) {
|
|
||||||
if (scheduler.matrix[scheduler._mode].second_scale)
|
|
||||||
var xhs = xh[1].childNodes;
|
|
||||||
|
|
||||||
xh = xh[0].childNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < xh.length; i++)
|
|
||||||
xml += "\n<column><![CDATA[" + clean_html(xh[i].innerHTML) + "]]></column>";
|
|
||||||
dx = xh[0].offsetWidth;
|
|
||||||
|
|
||||||
if (xhs) {
|
|
||||||
var width = 0;
|
|
||||||
var top_width = xh[0].offsetWidth;
|
|
||||||
var top_col = 1;
|
|
||||||
for (var i = 0; i < xhs.length; i++) {
|
|
||||||
xml += "\n<column second_scale='"+top_col+"'><![CDATA[" + clean_html(xhs[i].innerHTML) + "]]></column>";
|
|
||||||
width+=xhs[i].offsetWidth;
|
|
||||||
if (width>=top_width){
|
|
||||||
top_width+=(xh[top_col] ? xh[top_col].offsetWidth: 0);
|
|
||||||
top_col++;
|
|
||||||
}
|
|
||||||
dx = xhs[0].offsetWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
function de_day(node,n){
|
|
||||||
var x = parseInt(node.style.left,10);
|
|
||||||
|
|
||||||
for (var dx=0; dx < scheduler._cols.length; dx++){
|
|
||||||
x-=scheduler._cols[dx];
|
|
||||||
if (x<0) return dx;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
function de_week(node,n){
|
|
||||||
var y = parseInt(node.style.top,10);
|
|
||||||
for (var dy=0; dy < scheduler._colsS.heights.length; dy++)
|
|
||||||
if (scheduler._colsS.heights[dy]>y) return dy;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
function xml_month(yh){
|
|
||||||
var xml="";
|
|
||||||
var r = yh.firstChild.rows;
|
|
||||||
for (var i = 0; i < r.length; i++) {
|
|
||||||
var days = [];
|
|
||||||
for (var j = 0; j < r[i].cells.length; j++){
|
|
||||||
/* var dd = r[i].cells[j];
|
|
||||||
var css = dd.className;
|
|
||||||
|
|
||||||
if (css!=" " && css!="dhx_now ")
|
|
||||||
days.push("");
|
|
||||||
else*/
|
|
||||||
days.push(r[i].cells[j].firstChild.innerHTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
xml += "\n<row height='"+yh.firstChild.rows[i].cells[0].offsetHeight+"'><![CDATA[" + clean_html(days.join("|")) + "]]></row>";
|
|
||||||
dy = yh.firstChild.rows[0].cells[0].offsetHeight;
|
|
||||||
}
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
function xml_top(profile) {
|
|
||||||
var xml = "<data profile='"+profile+"'";
|
|
||||||
if (header)
|
|
||||||
xml+=" header='"+header+"'";
|
|
||||||
if (footer)
|
|
||||||
xml+=" footer='"+footer+"'";
|
|
||||||
xml+=">";
|
|
||||||
// detects if current mode is timeline
|
|
||||||
var mode = scheduler._mode;
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode])
|
|
||||||
mode = (scheduler.matrix[scheduler._mode].render == "cell") ? "matrix" : "timeline";
|
|
||||||
xml += "<scale mode='" + mode + "' today='" + scheduler._els.dhx_cal_date[0].innerHTML + "'>";
|
|
||||||
|
|
||||||
if (scheduler._mode == "week_agenda"){
|
|
||||||
var xh = scheduler._els.dhx_cal_data[0].getElementsByTagName("DIV");
|
|
||||||
for (var i=0; i<xh.length; i++)
|
|
||||||
if (xh[i].className == "dhx_wa_scale_bar")
|
|
||||||
xml+="<column>"+clean_html(xh[i].innerHTML)+"</column>";
|
|
||||||
} else if (scheduler._mode == "agenda" || scheduler._mode == "map"){
|
|
||||||
var xh = scheduler._els.dhx_cal_header[0].childNodes[0].childNodes;
|
|
||||||
|
|
||||||
xml+="<column>"+clean_html(xh[0].innerHTML)+"</column><column>"+clean_html(xh[1].innerHTML)+"</column>";
|
|
||||||
} else if (scheduler._mode == "year"){
|
|
||||||
var xh = scheduler._els.dhx_cal_data[0].childNodes;
|
|
||||||
for (var i=0; i < xh.length; i++) {
|
|
||||||
xml+="<month label='"+clean_html(xh[i].childNodes[0].innerHTML)+"'>";
|
|
||||||
xml+=xml_month_scale(xh[i].childNodes[1].childNodes);
|
|
||||||
xml+=xml_month(xh[i].childNodes[2]);
|
|
||||||
xml+="</month>";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
xml += "<x>";
|
|
||||||
var xh = scheduler._els.dhx_cal_header[0].childNodes;
|
|
||||||
xml+=xml_month_scale(xh);
|
|
||||||
xml += "</x>";
|
|
||||||
|
|
||||||
var yh = scheduler._els.dhx_cal_data[0];
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode]) {
|
|
||||||
xml += "<y>";
|
|
||||||
for (var i=0; i < yh.firstChild.rows.length; i++) {
|
|
||||||
var el = yh.firstChild.rows[i];
|
|
||||||
xml+="<row><![CDATA["+clean_html(el.cells[0].innerHTML)+"]]></row>";
|
|
||||||
}
|
|
||||||
xml+="</y>";
|
|
||||||
dy = yh.firstChild.rows[0].cells[0].offsetHeight;
|
|
||||||
} else if (yh.firstChild.tagName == "TABLE") {
|
|
||||||
xml += xml_month(yh);
|
|
||||||
} else {
|
|
||||||
yh = yh.childNodes[yh.childNodes.length - 1];
|
|
||||||
while (yh.className.indexOf("dhx_scale_holder") == -1)
|
|
||||||
yh = yh.previousSibling;
|
|
||||||
yh = yh.childNodes;
|
|
||||||
|
|
||||||
xml += "<y>";
|
|
||||||
for (var i = 0; i < yh.length; i++)
|
|
||||||
xml += "\n<row><![CDATA[" + clean_html(yh[i].innerHTML) + "]]></row>";
|
|
||||||
xml += "</y>";
|
|
||||||
dy = yh[0].offsetHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xml += "</scale>";
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
function get_style(node, style){
|
|
||||||
return (window.getComputedStyle?(window.getComputedStyle(node, null)[style]):(node.currentStyle?node.currentStyle[style]:null))||"";
|
|
||||||
}
|
|
||||||
function xml_body() {
|
|
||||||
var xml = "";
|
|
||||||
var evs = scheduler._rendered;
|
|
||||||
if (scheduler._mode == "agenda" || scheduler._mode == "map"){
|
|
||||||
for (var i=0; i < evs.length; i++)
|
|
||||||
xml+="<event><head>"+clean_html(evs[i].childNodes[0].innerHTML)+"</head><body>"+clean_html(evs[i].childNodes[2].innerHTML)+"</body></event>";
|
|
||||||
} else if (scheduler._mode == "week_agenda"){
|
|
||||||
for (var i=0; i < evs.length; i++)
|
|
||||||
xml+="<event day='"+evs[i].parentNode.getAttribute("day")+"'><body>"+clean_html(evs[i].innerHTML)+"</body></event>";
|
|
||||||
} else if (scheduler._mode == "year"){
|
|
||||||
var evs = scheduler.get_visible_events();
|
|
||||||
for (var i=0; i < evs.length; i++) {
|
|
||||||
var d = evs[i].start_date;
|
|
||||||
if (d.valueOf()<scheduler._min_date.valueOf())
|
|
||||||
d = scheduler._min_date;
|
|
||||||
while (d<evs[i].end_date){
|
|
||||||
var m = d.getMonth()+12*(d.getFullYear()-scheduler._min_date.getFullYear())-scheduler.week_starts._month;
|
|
||||||
var day = scheduler.week_starts[m]+d.getDate()-1;
|
|
||||||
var text_color = colors?get_style(scheduler._get_year_cell(d),"color"):"";
|
|
||||||
var bg_color = colors?get_style(scheduler._get_year_cell(d),"backgroundColor"):"";
|
|
||||||
|
|
||||||
xml+="<event day='"+(day%7)+"' week='"+Math.floor(day/7)+"' month='"+m+"' backgroundColor='"+bg_color+"' color='" + text_color + "'></event>";
|
|
||||||
d = scheduler.date.add(d,1,"day");
|
|
||||||
if (d.valueOf()>=scheduler._max_date.valueOf())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var matrix = scheduler.matrix && scheduler.matrix[scheduler._mode];
|
|
||||||
if (matrix && matrix.render == "cell"){
|
|
||||||
var evs = scheduler._els.dhx_cal_data[0].getElementsByTagName("TD");
|
|
||||||
for (var i = 0; i < evs.length; i++){
|
|
||||||
var text_color = colors?get_style(evs[i],"color"):"";
|
|
||||||
var bg_color = colors?get_style(evs[i],"backgroundColor"):"";
|
|
||||||
xml += "\n<event><body backgroundColor='"+bg_color+"' color='" + text_color + "'><![CDATA[" + clean_html(evs[i].innerHTML) + "]]></body></event>";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < evs.length; i++) {
|
|
||||||
var zx = x_norm(evs[i].style.left);
|
|
||||||
var zdx = x_norm(evs[i].style.width);
|
|
||||||
if (isNaN(zdx*1)) continue;
|
|
||||||
var zy = y_norm(evs[i].style.top);
|
|
||||||
var zdy = y_norm(evs[i].style.height);
|
|
||||||
var e_type = evs[i].className.split(" ")[0].replace("dhx_cal_", "");
|
|
||||||
if (e_type === 'dhx_tooltip_line') continue;
|
|
||||||
var dets = scheduler.getEvent(evs[i].getAttribute("event_id"));
|
|
||||||
// if (evs[i].parentNode == scheduler._els.dhx_cal_data[0]) continue;
|
|
||||||
var day = dets._sday;
|
|
||||||
var week = dets._sweek;
|
|
||||||
var length = dets._length || 0;
|
|
||||||
if (scheduler._mode != "month") {
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode]){
|
|
||||||
day = 0;
|
|
||||||
var el = evs[i].parentNode.parentNode.parentNode;
|
|
||||||
week = el.rowIndex;
|
|
||||||
zdx += x_norm(10);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (scheduler.xy.menu_width){
|
|
||||||
zdx+=x_norm(zdx*20/100);
|
|
||||||
zx-=x_norm(15-zx*20/100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evs[i].parentNode == scheduler._els.dhx_cal_data[0]) continue;
|
|
||||||
zx += x_norm(evs[i].parentNode.style.left);
|
|
||||||
zx -= x_norm(51);
|
|
||||||
}
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode]) {
|
|
||||||
var dy_copy = dy;
|
|
||||||
dy = evs[i].parentNode.offsetHeight;
|
|
||||||
zy = y_norm(evs[i].style.top);
|
|
||||||
zy -= zy*0.2;
|
|
||||||
dy = dy_copy;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
zdy = parseInt(evs[i].offsetHeight,10);
|
|
||||||
zy = parseInt(evs[i].style.top,10) - 22;
|
|
||||||
|
|
||||||
day = de_day(evs[i],day);
|
|
||||||
week = de_week(evs[i],week);
|
|
||||||
}
|
|
||||||
|
|
||||||
xml += "\n<event week='"+week+"' day='"+day+"' type='" + e_type + "' x='" + zx + "' y='" + zy + "' width='" + zdx + "' height='" + zdy + "' len='" + length + "'>";
|
|
||||||
|
|
||||||
|
|
||||||
if (e_type == "event") {
|
|
||||||
xml += "<header><![CDATA[" + clean_html(evs[i].childNodes[1].innerHTML) + "]]></header>";
|
|
||||||
var text_color = colors?get_style(evs[i].childNodes[2],"color"):"";
|
|
||||||
var bg_color = colors?get_style(evs[i].childNodes[2],"backgroundColor"):"";
|
|
||||||
xml += "<body backgroundColor='"+bg_color+"' color='" + text_color + "'><![CDATA[" + clean_html(evs[i].childNodes[2].innerHTML) + "]]></body>";
|
|
||||||
} else {
|
|
||||||
var text_color = colors?get_style(evs[i],"color"):"";
|
|
||||||
var bg_color = colors?get_style(evs[i],"backgroundColor"):"";
|
|
||||||
xml += "<body backgroundColor='"+bg_color+"' color='" + text_color + "'><![CDATA[" + clean_html(evs[i].innerHTML) + "]]></body>";
|
|
||||||
}
|
|
||||||
xml += "</event>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
function xml_end(){
|
|
||||||
var xml = "</data>";
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
var uid = (new Date()).valueOf();
|
|
||||||
var d=document.createElement("div");
|
|
||||||
d.style.display="none";
|
|
||||||
document.body.appendChild(d);
|
|
||||||
|
|
||||||
d.innerHTML = '<form id="'+uid+'" method="post" target="_blank" action="'+url+'" accept-charset="utf-8" enctype="application/x-www-form-urlencoded"><input type="hidden" name="mycoolxmlbody"/> </form>';
|
|
||||||
document.getElementById(uid).firstChild.value = encodeURIComponent(xml_top(mode).replace("\u2013", "-") + xml_body() + xml_end());
|
|
||||||
document.getElementById(uid).submit();
|
|
||||||
d.parentNode.removeChild(d);grid = null;
|
|
||||||
};
|
|
|
@ -1,144 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function() {
|
|
||||||
var original_sns = scheduler.config.lightbox.sections;
|
|
||||||
var recurring_section = null;
|
|
||||||
var original_left_buttons = scheduler.config.buttons_left.slice();
|
|
||||||
var original_right_buttons = scheduler.config.buttons_right.slice();
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeLightbox", function(id) {
|
|
||||||
if (this.config.readonly_form || this.getEvent(id).readonly) {
|
|
||||||
this.config.readonly_active = true;
|
|
||||||
|
|
||||||
for (var i = 0; i < this.config.lightbox.sections.length; i++) {
|
|
||||||
this.config.lightbox.sections[i].focus = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.config.readonly_active = false;
|
|
||||||
scheduler.config.buttons_left = original_left_buttons.slice();
|
|
||||||
scheduler.config.buttons_right = original_right_buttons.slice();
|
|
||||||
}
|
|
||||||
|
|
||||||
var sns = this.config.lightbox.sections;
|
|
||||||
if (this.config.readonly_active) {
|
|
||||||
var is_rec_found = false;
|
|
||||||
for (var i = 0; i < sns.length; i++) {
|
|
||||||
if (sns[i].type == 'recurring') {
|
|
||||||
recurring_section = sns[i];
|
|
||||||
if (this.config.readonly_active) {
|
|
||||||
sns.splice(i, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_rec_found && !this.config.readonly_active && recurring_section) {
|
|
||||||
// need to restore restore section
|
|
||||||
sns.splice(sns.length-2,0,recurring_section);
|
|
||||||
}
|
|
||||||
|
|
||||||
var forbidden_buttons = ["dhx_delete_btn", "dhx_save_btn"];
|
|
||||||
var button_arrays = [scheduler.config.buttons_left, scheduler.config.buttons_right];
|
|
||||||
for (var i = 0; i < forbidden_buttons.length; i++) {
|
|
||||||
var forbidden_button = forbidden_buttons[i];
|
|
||||||
for (var k = 0; k < button_arrays.length; k++) {
|
|
||||||
var button_array = button_arrays[k];
|
|
||||||
var index = -1;
|
|
||||||
for (var p = 0; p < button_array.length; p++) {
|
|
||||||
if (button_array[p] == forbidden_button) {
|
|
||||||
index = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index != -1) {
|
|
||||||
button_array.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resetLightbox();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
function txt_replace(tag, d, n, text) {
|
|
||||||
var txts = d.getElementsByTagName(tag);
|
|
||||||
var txtt = n.getElementsByTagName(tag);
|
|
||||||
for (var i = txtt.length - 1; i >= 0; i--) {
|
|
||||||
var n = txtt[i];
|
|
||||||
if (!text)
|
|
||||||
n.disabled = true;
|
|
||||||
else {
|
|
||||||
var t = document.createElement("SPAN");
|
|
||||||
t.className = "dhx_text_disabled";
|
|
||||||
t.innerHTML = text(txts[i]);
|
|
||||||
n.parentNode.insertBefore(t, n);
|
|
||||||
n.parentNode.removeChild(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var old = scheduler._fill_lightbox;
|
|
||||||
scheduler._fill_lightbox = function() {
|
|
||||||
var res = old.apply(this, arguments);
|
|
||||||
|
|
||||||
if (this.config.readonly_active) {
|
|
||||||
|
|
||||||
var d = this.getLightbox();
|
|
||||||
var n = this._lightbox_r = d.cloneNode(true);
|
|
||||||
n.id = scheduler.uid();
|
|
||||||
|
|
||||||
txt_replace("textarea", d, n, function(a) {
|
|
||||||
return a.value;
|
|
||||||
});
|
|
||||||
txt_replace("input", d, n, false);
|
|
||||||
txt_replace("select", d, n, function(a) {
|
|
||||||
return a.options[Math.max((a.selectedIndex || 0), 0)].text;
|
|
||||||
});
|
|
||||||
|
|
||||||
d.parentNode.insertBefore(n, d);
|
|
||||||
|
|
||||||
olds.call(this, n);
|
|
||||||
if (scheduler._lightbox)
|
|
||||||
scheduler._lightbox.parentNode.removeChild(scheduler._lightbox);
|
|
||||||
this._lightbox = n;
|
|
||||||
this.setLightboxSize();
|
|
||||||
this._lightbox = null;
|
|
||||||
n.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_cancel_btn":
|
|
||||||
scheduler.callEvent("onEventCancel", [scheduler._lightbox_id]);
|
|
||||||
scheduler._edit_stop_event(scheduler.getEvent(scheduler._lightbox_id), false);
|
|
||||||
scheduler.hide_lightbox();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
var olds = scheduler.showCover;
|
|
||||||
scheduler.showCover = function() {
|
|
||||||
if (!this.config.readonly_active)
|
|
||||||
olds.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
var hold = scheduler.hide_lightbox;
|
|
||||||
scheduler.hide_lightbox = function() {
|
|
||||||
if (this._lightbox_r) {
|
|
||||||
this._lightbox_r.parentNode.removeChild(this._lightbox_r);
|
|
||||||
this._lightbox_r = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hold.apply(this, arguments);
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -1,750 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
|
|
||||||
scheduler.config.occurrence_timestamp_in_utc = false;
|
|
||||||
scheduler.form_blocks["recurring"] = {
|
|
||||||
render:function(sns) {
|
|
||||||
return scheduler.__recurring_template;
|
|
||||||
},
|
|
||||||
_ds: {},
|
|
||||||
_init_set_value:function(node, value, ev) {
|
|
||||||
scheduler.form_blocks["recurring"]._ds = {start:ev.start_date, end:ev._end_date};
|
|
||||||
|
|
||||||
var str_date_format = scheduler.date.str_to_date(scheduler.config.repeat_date);
|
|
||||||
var str_date = function(str_date) {
|
|
||||||
var date = str_date_format(str_date);
|
|
||||||
if (scheduler.config.include_end_by)
|
|
||||||
date = scheduler.date.add(date, 1, 'day');
|
|
||||||
return date;
|
|
||||||
};
|
|
||||||
|
|
||||||
var date_str = scheduler.date.date_to_str(scheduler.config.repeat_date);
|
|
||||||
|
|
||||||
var top = node.getElementsByTagName("FORM")[0];
|
|
||||||
var els = [];
|
|
||||||
|
|
||||||
function register_els(inps) {
|
|
||||||
for (var i = 0; i < inps.length; i++) {
|
|
||||||
var inp = inps[i];
|
|
||||||
if (inp.type == "checkbox" || inp.type == "radio") {
|
|
||||||
if (!els[inp.name])
|
|
||||||
els[inp.name] = [];
|
|
||||||
els[inp.name].push(inp);
|
|
||||||
} else
|
|
||||||
els[inp.name] = inp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register_els(top.getElementsByTagName("INPUT"));
|
|
||||||
register_els(top.getElementsByTagName("SELECT"));
|
|
||||||
|
|
||||||
if (!scheduler.config.repeat_date_of_end) {
|
|
||||||
var formatter = scheduler.date.date_to_str(scheduler.config.repeat_date);
|
|
||||||
scheduler.config.repeat_date_of_end = formatter(scheduler.date.add(new Date(), 30, "day"));
|
|
||||||
}
|
|
||||||
els["date_of_end"].value = scheduler.config.repeat_date_of_end;
|
|
||||||
|
|
||||||
var $ = function(a) {
|
|
||||||
return document.getElementById(a);
|
|
||||||
};
|
|
||||||
|
|
||||||
function get_radio_value(name) {
|
|
||||||
var col = els[name];
|
|
||||||
for (var i = 0; i < col.length; i++)
|
|
||||||
if (col[i].checked) return col[i].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function change_current_view() {
|
|
||||||
$("dhx_repeat_day").style.display = "none";
|
|
||||||
$("dhx_repeat_week").style.display = "none";
|
|
||||||
$("dhx_repeat_month").style.display = "none";
|
|
||||||
$("dhx_repeat_year").style.display = "none";
|
|
||||||
$("dhx_repeat_" + this.value).style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_repeat_code(dates) {
|
|
||||||
var code = [get_radio_value("repeat")];
|
|
||||||
get_rcode[code[0]](code, dates);
|
|
||||||
|
|
||||||
while (code.length < 5) code.push("");
|
|
||||||
var repeat = "";
|
|
||||||
if (els["end"][0].checked) {
|
|
||||||
dates.end = new Date(9999, 1, 1);
|
|
||||||
repeat = "no";
|
|
||||||
}
|
|
||||||
else if (els["end"][2].checked) {
|
|
||||||
dates.end = str_date(els["date_of_end"].value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
scheduler.transpose_type(code.join("_"));
|
|
||||||
repeat = Math.max(1, els["occurences_count"].value);
|
|
||||||
var transp = ((code[0] == "week" && code[4] && code[4].toString().indexOf(scheduler.config.start_on_monday ? 1 : 0) == -1) ? 1 : 0);
|
|
||||||
dates.end = scheduler.date.add(new Date(dates.start), repeat + transp, code.join("_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return code.join("_") + "#" + repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.form_blocks["recurring"]._get_repeat_code = get_repeat_code;
|
|
||||||
var get_rcode = {
|
|
||||||
month:function(code, dates) {
|
|
||||||
if (get_radio_value("month_type") == "d") {
|
|
||||||
code.push(Math.max(1, els["month_count"].value));
|
|
||||||
dates.start.setDate(els["month_day"].value);
|
|
||||||
} else {
|
|
||||||
code.push(Math.max(1, els["month_count2"].value));
|
|
||||||
code.push(els["month_day2"].value);
|
|
||||||
code.push(Math.max(1, els["month_week2"].value));
|
|
||||||
dates.start.setDate(1);
|
|
||||||
}
|
|
||||||
dates._start = true;
|
|
||||||
},
|
|
||||||
week:function(code, dates) {
|
|
||||||
code.push(Math.max(1, els["week_count"].value));
|
|
||||||
code.push("");
|
|
||||||
code.push("");
|
|
||||||
var t = [];
|
|
||||||
var col = els["week_day"];
|
|
||||||
for (var i = 0; i < col.length; i++) {
|
|
||||||
if (col[i].checked) t.push(col[i].value);
|
|
||||||
}
|
|
||||||
if (!t.length)
|
|
||||||
t.push(dates.start.getDay());
|
|
||||||
|
|
||||||
dates.start = scheduler.date.week_start(dates.start);
|
|
||||||
dates._start = true;
|
|
||||||
|
|
||||||
code.push(t.sort().join(","));
|
|
||||||
},
|
|
||||||
day:function(code) {
|
|
||||||
if (get_radio_value("day_type") == "d") {
|
|
||||||
code.push(Math.max(1, els["day_count"].value));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
code.push("week");
|
|
||||||
code.push(1);
|
|
||||||
code.push("");
|
|
||||||
code.push("");
|
|
||||||
code.push("1,2,3,4,5");
|
|
||||||
code.splice(0, 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
year:function(code, dates) {
|
|
||||||
if (get_radio_value("year_type") == "d") {
|
|
||||||
code.push("1");
|
|
||||||
dates.start.setMonth(0);
|
|
||||||
dates.start.setDate(els["year_day"].value);
|
|
||||||
dates.start.setMonth(els["year_month"].value);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
code.push("1");
|
|
||||||
code.push(els["year_day2"].value);
|
|
||||||
code.push(els["year_week2"].value);
|
|
||||||
dates.start.setDate(1);
|
|
||||||
dates.start.setMonth(els["year_month2"].value);
|
|
||||||
}
|
|
||||||
dates._start = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var set_rcode = {
|
|
||||||
week:function(code, dates) {
|
|
||||||
els["week_count"].value = code[1];
|
|
||||||
var col = els["week_day"];
|
|
||||||
var t = code[4].split(",");
|
|
||||||
var d = {};
|
|
||||||
for (var i = 0; i < t.length; i++) d[t[i]] = true;
|
|
||||||
for (var i = 0; i < col.length; i++)
|
|
||||||
col[i].checked = (!!d[col[i].value]);
|
|
||||||
},
|
|
||||||
month:function(code, dates) {
|
|
||||||
if (code[2] == "") {
|
|
||||||
els["month_type"][0].checked = true;
|
|
||||||
els["month_count"].value = code[1];
|
|
||||||
els["month_day"].value = dates.start.getDate();
|
|
||||||
} else {
|
|
||||||
els["month_type"][1].checked = true;
|
|
||||||
els["month_count2"].value = code[1];
|
|
||||||
els["month_week2"].value = code[3];
|
|
||||||
els["month_day2"].value = code[2];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
day:function(code, dates) {
|
|
||||||
els["day_type"][0].checked = true;
|
|
||||||
els["day_count"].value = code[1];
|
|
||||||
},
|
|
||||||
year:function(code, dates) {
|
|
||||||
if (code[2] == "") {
|
|
||||||
els["year_type"][0].checked = true;
|
|
||||||
els["year_day"].value = dates.start.getDate();
|
|
||||||
els["year_month"].value = dates.start.getMonth();
|
|
||||||
} else {
|
|
||||||
els["year_type"][1].checked = true;
|
|
||||||
els["year_week2"].value = code[3];
|
|
||||||
els["year_day2"].value = code[2];
|
|
||||||
els["year_month2"].value = dates.start.getMonth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function set_repeat_code(code, dates) {
|
|
||||||
var data = code.split("#");
|
|
||||||
code = data[0].split("_");
|
|
||||||
set_rcode[code[0]](code, dates);
|
|
||||||
var e = els["repeat"][({day:0, week:1, month:2, year:3})[code[0]]];
|
|
||||||
switch (data[1]) {
|
|
||||||
case "no":
|
|
||||||
els["end"][0].checked = true;
|
|
||||||
break;
|
|
||||||
case "":
|
|
||||||
els["end"][2].checked = true;
|
|
||||||
els["date_of_end"].value = date_str(dates.end);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
els["end"][1].checked = true;
|
|
||||||
els["occurences_count"].value = data[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.checked = true;
|
|
||||||
e.onclick();
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.form_blocks["recurring"]._set_repeat_code = set_repeat_code;
|
|
||||||
|
|
||||||
for (var i = 0; i < top.elements.length; i++) {
|
|
||||||
var el = top.elements[i];
|
|
||||||
switch (el.name) {
|
|
||||||
case "repeat":
|
|
||||||
el.onclick = change_current_view;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scheduler._lightbox._rec_init_done = true;
|
|
||||||
},
|
|
||||||
set_value:function(node, value, ev) {
|
|
||||||
var rf = scheduler.form_blocks["recurring"];
|
|
||||||
if (!scheduler._lightbox._rec_init_done)
|
|
||||||
rf._init_set_value(node, value, ev);
|
|
||||||
node.open = !ev.rec_type;
|
|
||||||
if (ev.event_pid && ev.event_pid != "0")
|
|
||||||
node.blocked = true;
|
|
||||||
else node.blocked = false;
|
|
||||||
|
|
||||||
var ds = rf._ds;
|
|
||||||
ds.start = ev.start_date;
|
|
||||||
ds.end = ev._end_date;
|
|
||||||
|
|
||||||
rf.button_click(0, node.previousSibling.firstChild.firstChild, node, node);
|
|
||||||
if (value)
|
|
||||||
rf._set_repeat_code(value, ds);
|
|
||||||
},
|
|
||||||
get_value:function(node, ev) {
|
|
||||||
if (node.open) {
|
|
||||||
var ds = scheduler.form_blocks["recurring"]._ds;
|
|
||||||
var actual_dates = {};
|
|
||||||
this.formSection('time').getValue(actual_dates);
|
|
||||||
ds.start = actual_dates.start_date;
|
|
||||||
ev.rec_type = scheduler.form_blocks["recurring"]._get_repeat_code(ds);
|
|
||||||
if (ds._start) {
|
|
||||||
ev.start_date = new Date(ds.start);
|
|
||||||
ev._start_date = new Date(ds.start);
|
|
||||||
ds._start = false;
|
|
||||||
} else
|
|
||||||
ev._start_date = null;
|
|
||||||
|
|
||||||
ev._end_date = ev.end_date = ds.end;
|
|
||||||
ev.rec_pattern = ev.rec_type.split("#")[0];
|
|
||||||
} else {
|
|
||||||
ev.rec_type = ev.rec_pattern = "";
|
|
||||||
ev._end_date = ev.end_date;
|
|
||||||
}
|
|
||||||
return ev.rec_type;
|
|
||||||
},
|
|
||||||
focus:function(node) {
|
|
||||||
},
|
|
||||||
button_click:function(index, el, section, cont) {
|
|
||||||
if (!cont.open && !cont.blocked) {
|
|
||||||
cont.style.height = "115px";
|
|
||||||
el.style.backgroundPosition = "-5px 0px";
|
|
||||||
el.nextSibling.innerHTML = scheduler.locale.labels.button_recurring_open;
|
|
||||||
} else {
|
|
||||||
cont.style.height = "0px";
|
|
||||||
el.style.backgroundPosition = "-5px 20px";
|
|
||||||
el.nextSibling.innerHTML = scheduler.locale.labels.button_recurring;
|
|
||||||
}
|
|
||||||
cont.open = !cont.open;
|
|
||||||
|
|
||||||
scheduler.setLightboxSize();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//problem may occur if we will have two repeating events in the same moment of time
|
|
||||||
scheduler._rec_markers = {};
|
|
||||||
scheduler._rec_markers_pull = {};
|
|
||||||
scheduler._add_rec_marker = function(ev, time) {
|
|
||||||
ev._pid_time = time;
|
|
||||||
this._rec_markers[ev.id] = ev;
|
|
||||||
if (!this._rec_markers_pull[ev.event_pid]) this._rec_markers_pull[ev.event_pid] = {};
|
|
||||||
this._rec_markers_pull[ev.event_pid][time] = ev;
|
|
||||||
};
|
|
||||||
scheduler._get_rec_marker = function(time, id) {
|
|
||||||
var ch = this._rec_markers_pull[id];
|
|
||||||
if (ch) return ch[time];
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
scheduler._get_rec_markers = function(id) {
|
|
||||||
return (this._rec_markers_pull[id] || []);
|
|
||||||
};
|
|
||||||
scheduler._rec_temp = [];
|
|
||||||
(function() {
|
|
||||||
var old_add_event = scheduler.addEvent;
|
|
||||||
scheduler.addEvent = function(start_date, end_date, text, id, extra_data) {
|
|
||||||
var ev_id = old_add_event.apply(this, arguments);
|
|
||||||
|
|
||||||
if (ev_id) {
|
|
||||||
var ev = scheduler.getEvent(ev_id);
|
|
||||||
if (ev.event_pid != 0)
|
|
||||||
scheduler._add_rec_marker(ev, ev.event_length * 1000);
|
|
||||||
if (ev.rec_type)
|
|
||||||
ev.rec_pattern = ev.rec_type.split("#")[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
scheduler.attachEvent("onEventIdChange", function(id, new_id) {
|
|
||||||
if (this._ignore_call) return;
|
|
||||||
this._ignore_call = true;
|
|
||||||
|
|
||||||
for (var i = 0; i < this._rec_temp.length; i++) {
|
|
||||||
var tev = this._rec_temp[i];
|
|
||||||
if (tev.event_pid == id) {
|
|
||||||
tev.event_pid = new_id;
|
|
||||||
this.changeEventId(tev.id, new_id + "#" + tev.id.split("#")[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this._ignore_call;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeEventDelete", function(id) {
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
if (id.toString().indexOf("#") != -1 || (ev.event_pid && ev.event_pid != "0" && ev.rec_type && ev.rec_type != 'none')) {
|
|
||||||
id = id.split("#");
|
|
||||||
var nid = this.uid();
|
|
||||||
var tid = (id[1]) ? id[1] : (ev._pid_time / 1000);
|
|
||||||
|
|
||||||
var nev = this._copy_event(ev);
|
|
||||||
nev.id = nid;
|
|
||||||
nev.event_pid = ev.event_pid || id[0];
|
|
||||||
var timestamp = tid;
|
|
||||||
nev.event_length = timestamp;
|
|
||||||
nev.rec_type = nev.rec_pattern = "none";
|
|
||||||
this.addEvent(nev);
|
|
||||||
|
|
||||||
this._add_rec_marker(nev, timestamp * 1000);
|
|
||||||
} else {
|
|
||||||
if (ev.rec_type && this._lightbox_id)
|
|
||||||
this._roll_back_dates(ev);
|
|
||||||
var sub = this._get_rec_markers(id);
|
|
||||||
for (var i in sub) {
|
|
||||||
if (sub.hasOwnProperty(i)) {
|
|
||||||
id = sub[i].id;
|
|
||||||
if (this.getEvent(id))
|
|
||||||
this.deleteEvent(id, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventChanged", function(id) {
|
|
||||||
if (this._loading) return true;
|
|
||||||
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
if (id.toString().indexOf("#") != -1) {
|
|
||||||
var id = id.split("#");
|
|
||||||
var nid = this.uid();
|
|
||||||
this._not_render = true;
|
|
||||||
|
|
||||||
var nev = this._copy_event(ev);
|
|
||||||
nev.id = nid;
|
|
||||||
nev.event_pid = id[0];
|
|
||||||
var timestamp = id[1];
|
|
||||||
nev.event_length = timestamp;
|
|
||||||
nev.rec_type = nev.rec_pattern = "";
|
|
||||||
this.addEvent(nev);
|
|
||||||
|
|
||||||
this._not_render = false;
|
|
||||||
this._add_rec_marker(nev, timestamp * 1000);
|
|
||||||
} else {
|
|
||||||
if (ev.rec_type && this._lightbox_id)
|
|
||||||
this._roll_back_dates(ev);
|
|
||||||
var sub = this._get_rec_markers(id);
|
|
||||||
for (var i in sub) {
|
|
||||||
if (sub.hasOwnProperty(i)) {
|
|
||||||
delete this._rec_markers[sub[i].id];
|
|
||||||
this.deleteEvent(sub[i].id, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete this._rec_markers_pull[id];
|
|
||||||
|
|
||||||
// it's possible that after editing event is no longer exists, in such case we need to remove _select_id flag
|
|
||||||
var isEventFound = false;
|
|
||||||
for (var k = 0; k < this._rendered.length; k++) {
|
|
||||||
if (this._rendered[k].getAttribute('event_id') == id)
|
|
||||||
isEventFound = true;
|
|
||||||
}
|
|
||||||
if (!isEventFound)
|
|
||||||
this._select_id = null;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventAdded", function(id) {
|
|
||||||
if (!this._loading) {
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
if (ev.rec_type && !ev.event_length)
|
|
||||||
this._roll_back_dates(ev);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventSave", function(id, data, is_new_event) {
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
if (!ev.rec_type && data.rec_type && (id + '').indexOf('#') == -1)
|
|
||||||
this._select_id = null;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventCreated", function(id) {
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
if (!ev.rec_type)
|
|
||||||
ev.rec_type = ev.rec_pattern = ev.event_length = ev.event_pid = "";
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventCancel", function(id) {
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
if (ev.rec_type) {
|
|
||||||
this._roll_back_dates(ev);
|
|
||||||
// a bit expensive, but we need to be sure that event re-rendered, because view can be corrupted by resize , during edit process
|
|
||||||
this.render_view_data();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
scheduler._roll_back_dates = function(ev) {
|
|
||||||
ev.event_length = (ev.end_date.valueOf() - ev.start_date.valueOf()) / 1000;
|
|
||||||
ev.end_date = ev._end_date;
|
|
||||||
if (ev._start_date) {
|
|
||||||
ev.start_date.setMonth(0);
|
|
||||||
ev.start_date.setDate(ev._start_date.getDate());
|
|
||||||
ev.start_date.setMonth(ev._start_date.getMonth());
|
|
||||||
ev.start_date.setFullYear(ev._start_date.getFullYear());
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.validId = function(id) {
|
|
||||||
return id.toString().indexOf("#") == -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.showLightbox_rec = scheduler.showLightbox;
|
|
||||||
scheduler.showLightbox = function(id) {
|
|
||||||
var locale = this.locale;
|
|
||||||
var c = scheduler.config.lightbox_recurring;
|
|
||||||
var pid = this.getEvent(id).event_pid;
|
|
||||||
var isVirtual = (id.toString().indexOf("#") != -1);
|
|
||||||
if (isVirtual)
|
|
||||||
pid = id.split("#")[0];
|
|
||||||
if ( !pid || pid == 0 || ( (!locale.labels.confirm_recurring || c == 'instance') || (c == 'series' && !isVirtual)) ) {
|
|
||||||
return this.showLightbox_rec(id); // editing instance or non recurring event
|
|
||||||
}
|
|
||||||
// show series
|
|
||||||
var callback = function() {
|
|
||||||
pid = this.getEvent(pid);
|
|
||||||
pid._end_date = pid.end_date;
|
|
||||||
pid.end_date = new Date(pid.start_date.valueOf() + pid.event_length * 1000);
|
|
||||||
return this.showLightbox_rec(pid.id); // editing series
|
|
||||||
};
|
|
||||||
if (c == 'ask') {
|
|
||||||
var that = this;
|
|
||||||
dhtmlx.modalbox({
|
|
||||||
text: locale.labels.confirm_recurring,
|
|
||||||
title: locale.labels.title_confirm_recurring,
|
|
||||||
width: "500px",
|
|
||||||
position: "middle",
|
|
||||||
buttons:[locale.labels.button_edit_series, locale.labels.button_edit_occurrence, locale.labels.icon_cancel],
|
|
||||||
callback: function(index) {
|
|
||||||
switch(+index) {
|
|
||||||
case 0:
|
|
||||||
return callback.call(that);
|
|
||||||
case 1:
|
|
||||||
return that.showLightbox_rec(id);
|
|
||||||
case 2:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.get_visible_events_rec = scheduler.get_visible_events;
|
|
||||||
scheduler.get_visible_events = function(only_timed) {
|
|
||||||
for (var i = 0; i < this._rec_temp.length; i++)
|
|
||||||
delete this._events[this._rec_temp[i].id];
|
|
||||||
this._rec_temp = [];
|
|
||||||
|
|
||||||
var stack = this.get_visible_events_rec(only_timed);
|
|
||||||
var out = [];
|
|
||||||
for (var i = 0; i < stack.length; i++) {
|
|
||||||
if (stack[i].rec_type) {
|
|
||||||
//deleted element of serie
|
|
||||||
if (stack[i].rec_pattern != "none")
|
|
||||||
this.repeat_date(stack[i], out);
|
|
||||||
}
|
|
||||||
else out.push(stack[i]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var old = scheduler.is_one_day_event;
|
|
||||||
scheduler.is_one_day_event = function(ev) {
|
|
||||||
if (ev.rec_type) return true;
|
|
||||||
return old.call(this, ev);
|
|
||||||
};
|
|
||||||
var old_update_event = scheduler.updateEvent;
|
|
||||||
scheduler.updateEvent = function(id) {
|
|
||||||
var ev = scheduler.getEvent(id);
|
|
||||||
if (ev && ev.rec_type && id.toString().indexOf('#') === -1) {
|
|
||||||
scheduler.update_view();
|
|
||||||
} else {
|
|
||||||
old_update_event.call(this, id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
scheduler.transponse_size = {
|
|
||||||
day:1, week:7, month:1, year:12
|
|
||||||
};
|
|
||||||
scheduler.date.day_week = function(sd, day, week) {
|
|
||||||
sd.setDate(1);
|
|
||||||
week = (week - 1) * 7;
|
|
||||||
var cday = sd.getDay();
|
|
||||||
var nday = day * 1 + week - cday + 1;
|
|
||||||
sd.setDate(nday <= week ? (nday + 7) : nday);
|
|
||||||
};
|
|
||||||
scheduler.transpose_day_week = function(sd, list, cor, size, cor2) {
|
|
||||||
var cday = (sd.getDay() || (scheduler.config.start_on_monday ? 7 : 0)) - cor;
|
|
||||||
for (var i = 0; i < list.length; i++) {
|
|
||||||
if (list[i] > cday)
|
|
||||||
return sd.setDate(sd.getDate() + list[i] * 1 - cday - (size ? cor : cor2));
|
|
||||||
}
|
|
||||||
this.transpose_day_week(sd, list, cor + size, null, cor);
|
|
||||||
};
|
|
||||||
scheduler.transpose_type = function(type) {
|
|
||||||
var f = "transpose_" + type;
|
|
||||||
if (!this.date[f]) {
|
|
||||||
var str = type.split("_");
|
|
||||||
var day = 60 * 60 * 24 * 1000;
|
|
||||||
var gf = "add_" + type;
|
|
||||||
var step = this.transponse_size[str[0]] * str[1];
|
|
||||||
|
|
||||||
if (str[0] == "day" || str[0] == "week") {
|
|
||||||
var days = null;
|
|
||||||
if (str[4]) {
|
|
||||||
days = str[4].split(",");
|
|
||||||
if (scheduler.config.start_on_monday) {
|
|
||||||
for (var i = 0; i < days.length; i++)
|
|
||||||
days[i] = (days[i] * 1) || 7;
|
|
||||||
days.sort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.date[f] = function(nd, td) {
|
|
||||||
var delta = Math.floor((td.valueOf() - nd.valueOf()) / (day * step));
|
|
||||||
if (delta > 0)
|
|
||||||
nd.setDate(nd.getDate() + delta * step);
|
|
||||||
if (days)
|
|
||||||
scheduler.transpose_day_week(nd, days, 1, step);
|
|
||||||
};
|
|
||||||
this.date[gf] = function(sd, inc) {
|
|
||||||
var nd = new Date(sd.valueOf());
|
|
||||||
if (days) {
|
|
||||||
for (var count = 0; count < inc; count++)
|
|
||||||
scheduler.transpose_day_week(nd, days, 0, step);
|
|
||||||
} else
|
|
||||||
nd.setDate(nd.getDate() + inc * step);
|
|
||||||
|
|
||||||
return nd;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (str[0] == "month" || str[0] == "year") {
|
|
||||||
this.date[f] = function(nd, td) {
|
|
||||||
var delta = Math.ceil(((td.getFullYear() * 12 + td.getMonth() * 1) - (nd.getFullYear() * 12 + nd.getMonth() * 1)) / (step));
|
|
||||||
if (delta >= 0)
|
|
||||||
nd.setMonth(nd.getMonth() + delta * step);
|
|
||||||
if (str[3])
|
|
||||||
scheduler.date.day_week(nd, str[2], str[3]);
|
|
||||||
};
|
|
||||||
this.date[gf] = function(sd, inc) {
|
|
||||||
var nd = new Date(sd.valueOf());
|
|
||||||
nd.setMonth(nd.getMonth() + inc * step);
|
|
||||||
if (str[3])
|
|
||||||
scheduler.date.day_week(nd, str[2], str[3]);
|
|
||||||
return nd;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.repeat_date = function(ev, stack, non_render, from, to) {
|
|
||||||
|
|
||||||
from = from || this._min_date;
|
|
||||||
to = to || this._max_date;
|
|
||||||
|
|
||||||
var td = new Date(ev.start_date.valueOf());
|
|
||||||
|
|
||||||
if (!ev.rec_pattern && ev.rec_type)
|
|
||||||
ev.rec_pattern = ev.rec_type.split("#")[0];
|
|
||||||
|
|
||||||
this.transpose_type(ev.rec_pattern);
|
|
||||||
scheduler.date["transpose_" + ev.rec_pattern](td, from);
|
|
||||||
while (td < ev.start_date || scheduler._fix_daylight_saving_date(td,from,ev,td,new Date(td.valueOf() + ev.event_length * 1000)).valueOf() <= from.valueOf() || td.valueOf() + ev.event_length * 1000 <= from.valueOf())
|
|
||||||
td = this.date.add(td, 1, ev.rec_pattern);
|
|
||||||
while (td < to && td < ev.end_date) {
|
|
||||||
var timestamp = (scheduler.config.occurrence_timestamp_in_utc) ? Date.UTC(td.getFullYear(), td.getMonth(), td.getDate(), td.getHours(), td.getMinutes(), td.getSeconds()) : td.valueOf();
|
|
||||||
var ch = this._get_rec_marker(timestamp, ev.id);
|
|
||||||
if (!ch) { // unmodified element of series
|
|
||||||
var ted = new Date(td.valueOf() + ev.event_length * 1000);
|
|
||||||
var copy = this._copy_event(ev);
|
|
||||||
//copy._timed = ev._timed;
|
|
||||||
copy.text = ev.text;
|
|
||||||
copy.start_date = td;
|
|
||||||
copy.event_pid = ev.id;
|
|
||||||
copy.id = ev.id + "#" + Math.ceil(timestamp / 1000);
|
|
||||||
copy.end_date = ted;
|
|
||||||
|
|
||||||
copy.end_date = scheduler._fix_daylight_saving_date(copy.start_date, copy.end_date, ev, td, copy.end_date);
|
|
||||||
|
|
||||||
copy._timed = this.is_one_day_event(copy);
|
|
||||||
|
|
||||||
if (!copy._timed && !this._table_view && !this.config.multi_day) return;
|
|
||||||
stack.push(copy);
|
|
||||||
|
|
||||||
if (!non_render) {
|
|
||||||
this._events[copy.id] = copy;
|
|
||||||
this._rec_temp.push(copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
if (non_render) stack.push(ch);
|
|
||||||
|
|
||||||
td = this.date.add(td, 1, ev.rec_pattern);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler._fix_daylight_saving_date = function(start_date, end_date, ev, counter, default_date) {
|
|
||||||
var shift = start_date.getTimezoneOffset() - end_date.getTimezoneOffset();
|
|
||||||
if (shift) {
|
|
||||||
if (shift > 0) {
|
|
||||||
// e.g. 24h -> 23h
|
|
||||||
return new Date(counter.valueOf() + ev.event_length * 1000 - shift * 60 * 1000);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// e.g. 24h -> 25h
|
|
||||||
return new Date(end_date.valueOf() - shift * 60 * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Date(default_date.valueOf());
|
|
||||||
};
|
|
||||||
scheduler.getRecDates = function(id, max) {
|
|
||||||
var ev = typeof id == "object" ? id : scheduler.getEvent(id);
|
|
||||||
var count = 0;
|
|
||||||
var result = [];
|
|
||||||
max = max || 100;
|
|
||||||
|
|
||||||
var td = new Date(ev.start_date.valueOf());
|
|
||||||
var from = new Date(td.valueOf());
|
|
||||||
|
|
||||||
if (!ev.rec_type) {
|
|
||||||
return [
|
|
||||||
{ start_date: ev.start_date, end_date: ev.end_date }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (ev.rec_type == "none") {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
this.transpose_type(ev.rec_pattern);
|
|
||||||
scheduler.date["transpose_" + ev.rec_pattern](td, from);
|
|
||||||
|
|
||||||
while (td < ev.start_date || (td.valueOf() + ev.event_length * 1000) <= from.valueOf())
|
|
||||||
td = this.date.add(td, 1, ev.rec_pattern);
|
|
||||||
while (td < ev.end_date) {
|
|
||||||
var ch = this._get_rec_marker(td.valueOf(), ev.id);
|
|
||||||
var res = true;
|
|
||||||
if (!ch) { // unmodified element of series
|
|
||||||
var sed = new Date(td);
|
|
||||||
var ted = new Date(td.valueOf() + ev.event_length * 1000);
|
|
||||||
|
|
||||||
ted = scheduler._fix_daylight_saving_date(sed, ted, ev, td, ted);
|
|
||||||
|
|
||||||
result.push({start_date:sed, end_date:ted});
|
|
||||||
} else {
|
|
||||||
(ch.rec_type == "none") ?
|
|
||||||
(res = false) :
|
|
||||||
result.push({ start_date: ch.start_date, end_date: ch.end_date });
|
|
||||||
}
|
|
||||||
td = this.date.add(td, 1, ev.rec_pattern);
|
|
||||||
if (res) {
|
|
||||||
count++;
|
|
||||||
if (count == max)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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) {
|
|
||||||
if (ev.rec_pattern) {
|
|
||||||
if (ev.rec_pattern == "none") continue;
|
|
||||||
var sev = [];
|
|
||||||
this.repeat_date(ev, sev, true, from, to);
|
|
||||||
for (var i = 0; i < sev.length; i++) {
|
|
||||||
// if event is in rec_markers then it will be checked by himself, here need to skip it
|
|
||||||
if (!sev[i].rec_pattern && sev[i].start_date < to && sev[i].end_date > from && !this._rec_markers[sev[i].id]) {
|
|
||||||
result.push(sev[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ev.id.toString().indexOf("#") == -1) { // if it's virtual event we can skip it
|
|
||||||
result.push(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.config.repeat_date = "%m.%d.%Y";
|
|
||||||
scheduler.config.lightbox.sections = [
|
|
||||||
{name:"description", height:130, map_to:"text", type:"textarea" , focus:true},
|
|
||||||
{name:"recurring", type:"recurring", map_to:"rec_type", button:"recurring"},
|
|
||||||
{name:"time", height:72, type:"time", map_to:"auto"}
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
//drop secondary attributes
|
|
||||||
scheduler._copy_dummy = function(ev) {
|
|
||||||
var start_date = new Date(this.start_date);
|
|
||||||
var end_date = new Date(this.end_date);
|
|
||||||
this.start_date = start_date;
|
|
||||||
this.end_date = end_date;
|
|
||||||
this.event_length = this.event_pid = this.rec_pattern = this.rec_type = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.config.include_end_by = false;
|
|
||||||
scheduler.config.lightbox_recurring = 'ask'; // series, instance
|
|
||||||
scheduler.__recurring_template='<div class="dhx_form_repeat"> <form> <div class="dhx_repeat_left"> <label><input class="dhx_repeat_radio" type="radio" name="repeat" value="day" />Daily</label><br /> <label><input class="dhx_repeat_radio" type="radio" name="repeat" value="week"/>Weekly</label><br /> <label><input class="dhx_repeat_radio" type="radio" name="repeat" value="month" checked />Monthly</label><br /> <label><input class="dhx_repeat_radio" type="radio" name="repeat" value="year" />Yearly</label> </div> <div class="dhx_repeat_divider"></div> <div class="dhx_repeat_center"> <div style="display:none;" id="dhx_repeat_day"> <label><input class="dhx_repeat_radio" type="radio" name="day_type" value="d"/>Every</label><input class="dhx_repeat_text" type="text" name="day_count" value="1" />day<br /> <label><input class="dhx_repeat_radio" type="radio" name="day_type" checked value="w"/>Every workday</label> </div> <div style="display:none;" id="dhx_repeat_week"> Repeat every<input class="dhx_repeat_text" type="text" name="week_count" value="1" />week next days:<br /> <table class="dhx_repeat_days"> <tr> <td> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="1" />Monday</label><br /> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="4" />Thursday</label> </td> <td> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="2" />Tuesday</label><br /> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="5" />Friday</label> </td> <td> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="3" />Wednesday</label><br /> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="6" />Saturday</label> </td> <td> <label><input class="dhx_repeat_checkbox" type="checkbox" name="week_day" value="0" />Sunday</label><br /><br /> </td> </tr> </table> </div> <div id="dhx_repeat_month"> <label><input class="dhx_repeat_radio" type="radio" name="month_type" value="d"/>Repeat</label><input class="dhx_repeat_text" type="text" name="month_day" value="1" />day every<input class="dhx_repeat_text" type="text" name="month_count" value="1" />month<br /> <label><input class="dhx_repeat_radio" type="radio" name="month_type" checked value="w"/>On</label><input class="dhx_repeat_text" type="text" name="month_week2" value="1" /><select name="month_day2"><option value="1" selected >Monday<option value="2">Tuesday<option value="3">Wednesday<option value="4">Thursday<option value="5">Friday<option value="6">Saturday<option value="0">Sunday</select>every<input class="dhx_repeat_text" type="text" name="month_count2" value="1" />month<br /> </div> <div style="display:none;" id="dhx_repeat_year"> <label><input class="dhx_repeat_radio" type="radio" name="year_type" value="d"/>Every</label><input class="dhx_repeat_text" type="text" name="year_day" value="1" />day<select name="year_month"><option value="0" selected >January<option value="1">February<option value="2">March<option value="3">April<option value="4">May<option value="5">June<option value="6">July<option value="7">August<option value="8">September<option value="9">October<option value="10">November<option value="11">December</select>month<br /> <label><input class="dhx_repeat_radio" type="radio" name="year_type" checked value="w"/>On</label><input class="dhx_repeat_text" type="text" name="year_week2" value="1" /><select name="year_day2"><option value="1" selected >Monday<option value="2">Tuesday<option value="3">Wednesday<option value="4">Thursday<option value="5">Friday<option value="6">Saturday<option value="7">Sunday</select>of<select name="year_month2"><option value="0" selected >January<option value="1">February<option value="2">March<option value="3">April<option value="4">May<option value="5">June<option value="6">July<option value="7">August<option value="8">September<option value="9">October<option value="10">November<option value="11">December</select><br /> </div> </div> <div class="dhx_repeat_divider"></div> <div class="dhx_repeat_right"> <label><input class="dhx_repeat_radio" type="radio" name="end" checked/>No end date</label><br /> <label><input class="dhx_repeat_radio" type="radio" name="end" />After</label><input class="dhx_repeat_text" type="text" name="occurences_count" value="1" />occurrences<br /> <label><input class="dhx_repeat_radio" type="radio" name="end" />End by</label><input class="dhx_repeat_date" type="text" name="date_of_end" value="'+scheduler.config.repeat_date_of_end+'" /><br /> </div> </form> </div> <div style="clear:both"> </div>';
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
//redefine this method, if you want to provide a custom set of attributes for serialization
|
|
||||||
scheduler.data_attributes=function(){
|
|
||||||
var attrs = [];
|
|
||||||
var format = scheduler.templates.xml_format;
|
|
||||||
for (var a in this._events){
|
|
||||||
var ev = this._events[a];
|
|
||||||
for (var name in ev)
|
|
||||||
if (name.substr(0,1) !="_")
|
|
||||||
attrs.push([name,((name == "start_date" || name == "end_date")?format:null)]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return attrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.toXML = function(header){
|
|
||||||
var xml = [];
|
|
||||||
var attrs = this.data_attributes();
|
|
||||||
|
|
||||||
|
|
||||||
for (var a in this._events){
|
|
||||||
var ev = this._events[a];
|
|
||||||
if (ev.id.toString().indexOf("#")!=-1) continue;
|
|
||||||
xml.push("<event>");
|
|
||||||
for (var i=0; i < attrs.length; i++)
|
|
||||||
xml.push("<"+attrs[i][0]+"><![CDATA["+(attrs[i][1]?attrs[i][1](ev[attrs[i][0]]):ev[attrs[i][0]])+"]]></"+attrs[i][0]+">");
|
|
||||||
|
|
||||||
xml.push("</event>");
|
|
||||||
}
|
|
||||||
return (header||"")+"<data>"+xml.join("\n")+"</data>";
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.toJSON = function(){
|
|
||||||
var json = [];
|
|
||||||
var attrs = this.data_attributes();
|
|
||||||
for (var a in this._events){
|
|
||||||
var ev = this._events[a];
|
|
||||||
if (ev.id.toString().indexOf("#")!=-1) continue;
|
|
||||||
var ev = this._events[a];
|
|
||||||
var line =[];
|
|
||||||
for (var i=0; i < attrs.length; i++)
|
|
||||||
line.push(' "'+attrs[i][0]+'": "'+((attrs[i][1]?attrs[i][1](ev[attrs[i][0]]):ev[attrs[i][0]])||"").toString().replace(/\n/g,"")+'" ');
|
|
||||||
json.push("{"+line.join(",")+"}");
|
|
||||||
}
|
|
||||||
return "["+json.join(",\n")+"]";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.toICal = function(header){
|
|
||||||
var start = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//dhtmlXScheduler//NONSGML v2.2//EN\nDESCRIPTION:";
|
|
||||||
var end = "END:VCALENDAR";
|
|
||||||
var format = scheduler.date.date_to_str("%Y%m%dT%H%i%s");
|
|
||||||
var full_day_format = scheduler.date.date_to_str("%Y%m%d");
|
|
||||||
|
|
||||||
var ical = [];
|
|
||||||
for (var a in this._events){
|
|
||||||
var ev = this._events[a];
|
|
||||||
if (ev.id.toString().indexOf("#")!=-1) continue;
|
|
||||||
|
|
||||||
|
|
||||||
ical.push("BEGIN:VEVENT");
|
|
||||||
if (!ev._timed || (!ev.start_date.getHours() && !ev.start_date.getMinutes()))
|
|
||||||
ical.push("DTSTART:"+full_day_format(ev.start_date));
|
|
||||||
else
|
|
||||||
ical.push("DTSTART:"+format(ev.start_date));
|
|
||||||
if (!ev._timed || (!ev.end_date.getHours() && !ev.end_date.getMinutes()))
|
|
||||||
ical.push("DTEND:"+full_day_format(ev.end_date));
|
|
||||||
else
|
|
||||||
ical.push("DTEND:"+format(ev.end_date));
|
|
||||||
ical.push("SUMMARY:"+ev.text);
|
|
||||||
ical.push("END:VEVENT");
|
|
||||||
}
|
|
||||||
return start+(header||"")+"\n"+ical.join("\n")+"\n"+end;
|
|
||||||
};
|
|
|
@ -1,963 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
(function(){
|
|
||||||
scheduler.matrix = {};
|
|
||||||
scheduler._merge=function(a,b){
|
|
||||||
for (var c in b)
|
|
||||||
if (typeof a[c] == "undefined")
|
|
||||||
a[c]=b[c];
|
|
||||||
};
|
|
||||||
scheduler.createTimelineView=function(obj){
|
|
||||||
|
|
||||||
scheduler._merge(obj,{
|
|
||||||
section_autoheight: true,
|
|
||||||
name:"matrix",
|
|
||||||
x:"time",
|
|
||||||
y:"time",
|
|
||||||
x_step:1,
|
|
||||||
x_unit:"hour",
|
|
||||||
y_unit:"day",
|
|
||||||
y_step:1,
|
|
||||||
x_start:0,
|
|
||||||
x_size:24,
|
|
||||||
y_start:0,
|
|
||||||
y_size: 7,
|
|
||||||
render:"cell",
|
|
||||||
dx:200,
|
|
||||||
dy:50,
|
|
||||||
event_dy: scheduler.xy.bar_height-5,
|
|
||||||
event_min_dy: scheduler.xy.bar_height-5,
|
|
||||||
resize_events: true,
|
|
||||||
fit_events: true,
|
|
||||||
second_scale: false,
|
|
||||||
_logic: function(render_name, y_unit, timeline) {
|
|
||||||
var res = {};
|
|
||||||
if(scheduler.checkEvent("onBeforeViewRender")) {
|
|
||||||
res = scheduler.callEvent("onBeforeViewRender", [render_name, y_unit, timeline]);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (scheduler.checkEvent("onTimelineCreated")) {
|
|
||||||
scheduler.callEvent("onTimelineCreated", [obj]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var old = scheduler.render_data;
|
|
||||||
scheduler.render_data=function(evs, mode){
|
|
||||||
|
|
||||||
if (this._mode == obj.name){
|
|
||||||
if (mode) //repaint single event, precision is not necessary
|
|
||||||
for (var i=0; i < evs.length; i++) {
|
|
||||||
this.clear_event(evs[i]);
|
|
||||||
this.render_timeline_event.call(this.matrix[this._mode], evs[i], true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
scheduler.renderMatrix.call(obj, true, true);
|
|
||||||
} else
|
|
||||||
return old.apply(this,arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.matrix[obj.name]=obj;
|
|
||||||
scheduler.templates[obj.name+"_cell_value"] = function(ar){ return ar?ar.length:""; };
|
|
||||||
scheduler.templates[obj.name+"_cell_class"] = function(arr){ return ""; };
|
|
||||||
scheduler.templates[obj.name+"_scalex_class"] = function(date){ return ""; };
|
|
||||||
scheduler.templates[obj.name+"_second_scalex_class"] = function(date){ return ""; };
|
|
||||||
|
|
||||||
scheduler.templates[obj.name+"_scaley_class"] = function(section_id, section_label, section_options){ return ""; };
|
|
||||||
scheduler.templates[obj.name+"_scale_label"] = function(section_id, section_label, section_options){ return section_label; };
|
|
||||||
|
|
||||||
scheduler.templates[obj.name+"_tooltip"] = function(a,b,e){ return e.text; };
|
|
||||||
scheduler.templates[obj.name+"_date"] = function(datea, dateb){
|
|
||||||
if (datea.getDay()==dateb.getDay() && dateb-datea<(24*60*60*1000))
|
|
||||||
return scheduler.templates.day_date(datea);
|
|
||||||
return scheduler.templates.week_date(datea, dateb);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.templates[obj.name+"_scale_date"] = scheduler.date.date_to_str(obj.x_date||scheduler.config.hour_date);
|
|
||||||
scheduler.templates[obj.name+"_second_scale_date"] = scheduler.date.date_to_str((obj.second_scale && obj.second_scale.x_date)?obj.second_scale.x_date:scheduler.config.hour_date);
|
|
||||||
|
|
||||||
scheduler.date["add_"+obj.name]=function(a, b, c){
|
|
||||||
return scheduler.date.add(a, (obj.x_length||obj.x_size)*b*obj.x_step, obj.x_unit);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.date[obj.name+"_start"] = function(date) {
|
|
||||||
var func = scheduler.date[obj.x_unit+"_start"] || scheduler.date.day_start;
|
|
||||||
var start_date = func.call(scheduler.date, date);
|
|
||||||
start_date = scheduler.date.add(start_date, obj.x_step*obj.x_start, obj.x_unit);
|
|
||||||
return start_date;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerResize",function(){
|
|
||||||
if (this._mode == obj.name){
|
|
||||||
scheduler.renderMatrix.call(obj, true, true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onOptionsLoad",function(){
|
|
||||||
obj.order = {};
|
|
||||||
scheduler.callEvent('onOptionsLoadStart', []);
|
|
||||||
for(var i=0; i<obj.y_unit.length;i++)
|
|
||||||
obj.order[obj.y_unit[i].key]=i;
|
|
||||||
scheduler.callEvent('onOptionsLoadFinal', []);
|
|
||||||
if (scheduler._date && obj.name == scheduler._mode)
|
|
||||||
scheduler.setCurrentView(scheduler._date, scheduler._mode);
|
|
||||||
});
|
|
||||||
scheduler.callEvent("onOptionsLoad",[obj]);
|
|
||||||
|
|
||||||
//init custom wrappers
|
|
||||||
scheduler[obj.name+"_view"]=function(){
|
|
||||||
scheduler.renderMatrix.apply(obj, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
//enable drag for non-cell modes
|
|
||||||
var temp_date = new Date();
|
|
||||||
var step_diff = (scheduler.date.add(temp_date, obj.x_step, obj.x_unit).valueOf() - temp_date.valueOf()); // "minute" + step in ms
|
|
||||||
scheduler["mouse_"+obj.name]=function(pos){ //mouse_coord handler
|
|
||||||
//get event object
|
|
||||||
var ev = this._drag_event;
|
|
||||||
if (this._drag_id){
|
|
||||||
ev = this.getEvent(this._drag_id);
|
|
||||||
this._drag_event._dhx_changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.x-=obj.dx;
|
|
||||||
var summ = 0, xind = 0, yind = 0;
|
|
||||||
for (xind; xind <= this._cols.length-1; xind++) {
|
|
||||||
|
|
||||||
var column_width = this._cols[xind];
|
|
||||||
summ += column_width;
|
|
||||||
if (summ>pos.x){ //index of section
|
|
||||||
var ratio = (pos.x-(summ-column_width))/column_width;
|
|
||||||
ratio = (ratio < 0) ? 0: ratio;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
summ = 0;
|
|
||||||
for (yind; yind < this._colsS.heights.length; yind++) {
|
|
||||||
summ+=this._colsS.heights[yind];
|
|
||||||
if (summ>pos.y)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.fields={};
|
|
||||||
if(!obj.y_unit[yind]) {
|
|
||||||
yind=obj.y_unit.length-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yind >= 0 && obj.y_unit[yind]) {
|
|
||||||
pos.section = pos.fields[obj.y_property] = obj.y_unit[yind].key;
|
|
||||||
if (ev) {
|
|
||||||
ev[obj.y_property] = pos.section;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.x = 0;
|
|
||||||
|
|
||||||
var end_date;
|
|
||||||
if(xind >= obj._trace_x.length) { // if our event is at the end of the view
|
|
||||||
end_date = scheduler.date.add(obj._trace_x[obj._trace_x.length-1], obj.x_step, obj.x_unit);
|
|
||||||
} else {
|
|
||||||
var max_date = (obj._trace_x[xind+1]) ? obj._trace_x[xind+1] : scheduler.date.add(obj._trace_x[obj._trace_x.length-1], obj.x_step, obj.x_unit);
|
|
||||||
var timestamp_diff = Math.ceil(ratio*(max_date-obj._trace_x[xind]));
|
|
||||||
end_date = new Date(+obj._trace_x[xind]+timestamp_diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._drag_mode == "move" && this._drag_id && this._drag_event) { // as we can simply be calling _locate_cell_timeline
|
|
||||||
var ev = this.getEvent(this._drag_id);
|
|
||||||
var drag_event = this._drag_event;
|
|
||||||
|
|
||||||
if (!drag_event._move_delta) {
|
|
||||||
drag_event._move_delta = (ev.start_date-end_date)/60000;
|
|
||||||
}
|
|
||||||
|
|
||||||
end_date = scheduler.date.add(end_date, drag_event._move_delta, "minute");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._drag_mode == "resize" && ev) {
|
|
||||||
pos.resize_from_start = !!(Math.abs(ev.start_date-end_date) < Math.abs(ev.end_date-end_date));
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.y = Math.round((end_date-this._min_date)/(1000*60*this.config.time_step));
|
|
||||||
pos.custom = true;
|
|
||||||
pos.shift = this.config.time_step //step_diff;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.render_timeline_event = function(ev, attach){
|
|
||||||
var section = ev[this.y_property]; // section id
|
|
||||||
|
|
||||||
var sorder = ev._sorder;
|
|
||||||
|
|
||||||
var x_start = _getX(ev, false, this._step);
|
|
||||||
var x_end = _getX(ev, true, this._step);
|
|
||||||
|
|
||||||
var event_height = this.event_dy;
|
|
||||||
if (this.event_dy == "full") {
|
|
||||||
if (this.section_autoheight) {
|
|
||||||
event_height = this._section_height[section] - 6;
|
|
||||||
} else {
|
|
||||||
event_height = this.dy - 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.resize_events) {
|
|
||||||
event_height = Math.max(Math.floor(event_height / ev._count), this.event_min_dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
var hb = event_height - 2;// takes into account css sizes (border/padding)
|
|
||||||
if (!ev._inner && this.event_dy == "full") {
|
|
||||||
hb=(hb+2)*(ev._count-sorder)-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var y = 2+sorder*event_height+(sorder?(sorder*2):0); // original top + number_of_events * event_dy + default event top/bottom borders
|
|
||||||
if (scheduler.config.cascade_event_display) {
|
|
||||||
y =2+sorder*scheduler.config.cascade_event_margin+(sorder?(sorder*2):0);
|
|
||||||
}
|
|
||||||
|
|
||||||
var section_height = event_height+y+2;
|
|
||||||
if(!this._events_height[section] || (this._events_height[section] < section_height)){
|
|
||||||
this._events_height[section] = section_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cs = scheduler.templates.event_class(ev.start_date,ev.end_date,ev);
|
|
||||||
cs = "dhx_cal_event_line "+(cs||"");
|
|
||||||
|
|
||||||
var bg_color = (ev.color?("background:"+ev.color+";"):"");
|
|
||||||
var color = (ev.textColor?("color:"+ev.textColor+";"):"");
|
|
||||||
var text = scheduler.templates.event_bar_text(ev.start_date,ev.end_date,ev);
|
|
||||||
|
|
||||||
var html='<div event_id="'+ev.id+'" class="'+cs+'" style="'+bg_color+''+color+'position:absolute; top:'+y+'px; height: '+hb+'px; left:'+x_start+'px; width:'+Math.max(0,x_end-x_start)+'px;'+(ev._text_style||"")+'">';
|
|
||||||
if (scheduler.config.drag_resize){
|
|
||||||
var dhx_event_resize = 'dhx_event_resize';
|
|
||||||
html += ("<div class='"+dhx_event_resize+" "+dhx_event_resize+"_start' style='height: "+hb+"px;'></div><div class='"+dhx_event_resize+" "+dhx_event_resize+"_end' style='height: "+hb+"px;'></div>");
|
|
||||||
}
|
|
||||||
html += (text+'</div>');
|
|
||||||
|
|
||||||
if (!attach)
|
|
||||||
return html;
|
|
||||||
else {
|
|
||||||
var d = document.createElement("DIV");
|
|
||||||
d.innerHTML = html;
|
|
||||||
var ind = this.order[section];
|
|
||||||
var parent = scheduler._els["dhx_cal_data"][0].firstChild.rows[ind].cells[1].firstChild;
|
|
||||||
|
|
||||||
scheduler._rendered.push(d.firstChild);
|
|
||||||
parent.appendChild(d.firstChild);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function trace_events(){
|
|
||||||
//minimize event set
|
|
||||||
var evs = scheduler.get_visible_events();
|
|
||||||
var matrix =[];
|
|
||||||
for (var i=0; i < this.y_unit.length; i++)
|
|
||||||
matrix[i]=[];
|
|
||||||
|
|
||||||
//next code defines row for undefined key
|
|
||||||
//most possible it is an artifact of incorrect configuration
|
|
||||||
if (!matrix[y])
|
|
||||||
matrix[y]=[];
|
|
||||||
|
|
||||||
for (var i=0; i < evs.length; i++) {
|
|
||||||
var y = this.order[evs[i][this.y_property]];
|
|
||||||
var x = 0;
|
|
||||||
while (this._trace_x[x+1] && evs[i].start_date>=this._trace_x[x+1]) x++;
|
|
||||||
while (this._trace_x[x] && evs[i].end_date>this._trace_x[x]) {
|
|
||||||
if (!matrix[y][x]) matrix[y][x]=[];
|
|
||||||
matrix[y][x].push(evs[i]);
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function used to get X (both start and end) coordinates for timeline bar view
|
|
||||||
function _getX(ev, isEndPoint, step) {
|
|
||||||
var x = 0;
|
|
||||||
var date = (isEndPoint) ? ev.end_date : ev.start_date;
|
|
||||||
if(date.valueOf()>scheduler._max_date.valueOf())
|
|
||||||
date = scheduler._max_date;
|
|
||||||
var delta = date - scheduler._min_date_timeline;
|
|
||||||
if (delta<0) {
|
|
||||||
column_offset = 0;
|
|
||||||
} else {
|
|
||||||
var index = Math.round( delta/(step*scheduler._cols[0]) ); // results varies ~0.9 - ~24.17, e.g. that way we get 1 and 24
|
|
||||||
if(index>scheduler._cols.length) // if columns really small it's possible to get incorrect index
|
|
||||||
index = scheduler._cols.length;
|
|
||||||
for (var k=0; k<index; k++) {
|
|
||||||
x += scheduler._cols[k];
|
|
||||||
}
|
|
||||||
var column_date = scheduler.date.add(scheduler._min_date_timeline, scheduler.matrix[scheduler._mode].x_step*index, scheduler.matrix[scheduler._mode].x_unit);
|
|
||||||
delta = date - column_date;
|
|
||||||
var column_offset = Math.floor(delta/step);
|
|
||||||
}
|
|
||||||
x += (isEndPoint) ? column_offset-14 : column_offset+1;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
function get_events_html(evs) {
|
|
||||||
var html = "";
|
|
||||||
if (evs && this.render != "cell"){
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
var stack=[];
|
|
||||||
var evs_length = evs.length;
|
|
||||||
// prepare events for render
|
|
||||||
for (var j=0; j<evs_length; j++){
|
|
||||||
var ev = evs[j];
|
|
||||||
ev._inner = false;
|
|
||||||
|
|
||||||
// cutting stack from the last -> first event side
|
|
||||||
while (stack.length) {
|
|
||||||
if (stack[stack.length-1].end_date.valueOf() <= ev.start_date.valueOf()) {
|
|
||||||
stack.splice(stack.length-1,1);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cutting stack from the first -> last event side
|
|
||||||
var sorderSet = false;
|
|
||||||
for(var p=0; p<stack.length; p++){
|
|
||||||
var t_ev = stack[p];
|
|
||||||
if(t_ev.end_date.valueOf()<=ev.start_date.valueOf()){
|
|
||||||
sorderSet = true;
|
|
||||||
ev._sorder=t_ev._sorder;
|
|
||||||
stack.splice(p,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 (var h = 0; h < stack.length; h++) {
|
|
||||||
var _is_sorder = false;
|
|
||||||
for (var t = 0; t < stack.length; t++) {
|
|
||||||
if (stack[t]._sorder == h) {
|
|
||||||
_is_sorder = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!_is_sorder) {
|
|
||||||
ev._sorder = h;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ev._inner = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var _max_sorder = stack[0]._sorder;
|
|
||||||
for (var w = 1; w < stack.length; w++)
|
|
||||||
if (stack[w]._sorder > _max_sorder)
|
|
||||||
_max_sorder = stack[w]._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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// fix _count for every event
|
|
||||||
for (var m=0; m < evs.length; m++) {
|
|
||||||
evs[m]._count = stack.max_count;
|
|
||||||
}
|
|
||||||
// render events
|
|
||||||
for (var v=0; v<evs_length; v++) {
|
|
||||||
html+=scheduler.render_timeline_event.call(this, evs[v], false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function y_scale(d) {
|
|
||||||
var html = "<table style='table-layout:fixed;' cellspacing='0' cellpadding='0'>";
|
|
||||||
var evs=[];
|
|
||||||
if(scheduler._load_mode)
|
|
||||||
scheduler._load();
|
|
||||||
if (this.render == "cell")
|
|
||||||
evs = trace_events.call(this);
|
|
||||||
else {
|
|
||||||
var tevs = scheduler.get_visible_events();
|
|
||||||
for (var j=0; j<tevs.length; j++){
|
|
||||||
var ind = this.order[ tevs[j][this.y_property] ];
|
|
||||||
if (!evs[ind]) evs[ind] = [];
|
|
||||||
evs[ind].push(tevs[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var summ = 0;
|
|
||||||
for (var i=0; i < scheduler._cols.length; i++)
|
|
||||||
summ+=scheduler._cols[i];
|
|
||||||
|
|
||||||
var step = new Date();
|
|
||||||
step = (scheduler.date.add(step, this.x_step*this.x_size, this.x_unit)-step)/summ;
|
|
||||||
|
|
||||||
this._step = step;
|
|
||||||
this._summ = summ;
|
|
||||||
|
|
||||||
var heights = scheduler._colsS.heights=[];
|
|
||||||
|
|
||||||
this._events_height = {};
|
|
||||||
this._section_height = {};
|
|
||||||
for (var i=0; i<this.y_unit.length; i++){
|
|
||||||
|
|
||||||
var stats = this._logic(this.render, this.y_unit[i], this); // obj with custom style
|
|
||||||
|
|
||||||
scheduler._merge(stats, {
|
|
||||||
height: this.dy
|
|
||||||
});
|
|
||||||
|
|
||||||
//autosize height, if we have a free space
|
|
||||||
if(this.section_autoheight) {
|
|
||||||
if (this.y_unit.length * stats.height < d.offsetHeight) {
|
|
||||||
stats.height = Math.max(stats.height, Math.floor((d.offsetHeight - 1) / this.y_unit.length));
|
|
||||||
}
|
|
||||||
this._section_height[this.y_unit[i].key] = stats.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler._merge(stats, {
|
|
||||||
//section 1
|
|
||||||
tr_className: "",
|
|
||||||
style_height: "height:"+stats.height+"px;",
|
|
||||||
style_width: "width:"+(this.dx-1)+"px;",
|
|
||||||
td_className: "dhx_matrix_scell"+((scheduler.templates[this.name+"_scaley_class"](this.y_unit[i].key, this.y_unit[i].label, this.y_unit[i]))?" "+scheduler.templates[this.name+"_scaley_class"](this.y_unit[i].key, this.y_unit[i].label, this.y_unit[i]):''),
|
|
||||||
td_content: scheduler.templates[this.name+'_scale_label'](this.y_unit[i].key, this.y_unit[i].label, this.y_unit[i]),
|
|
||||||
//section 2
|
|
||||||
summ_width: "width:"+summ+"px;",
|
|
||||||
//section 3
|
|
||||||
table_className: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
// generating events html in a temporary file, calculating their height
|
|
||||||
var events_html = get_events_html.call(this, evs[i]);
|
|
||||||
|
|
||||||
if(this.fit_events){
|
|
||||||
var rendered_height = this._events_height[this.y_unit[i].key]||0;
|
|
||||||
stats.height = (rendered_height>stats.height)?rendered_height:stats.height;
|
|
||||||
stats.style_height = "height:"+stats.height+"px;";
|
|
||||||
this._section_height[this.y_unit[i].key] = stats.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// section 1
|
|
||||||
html+="<tr class='"+stats.tr_className+"' style='"+stats.style_height+"'><td class='"+stats.td_className+"' style='"+stats.style_width+" height:"+(stats.height-1)+"px;'>"+stats.td_content+"</td>";
|
|
||||||
|
|
||||||
if (this.render == "cell"){
|
|
||||||
for (var j=0; j < scheduler._cols.length; j++) {
|
|
||||||
html+="<td class='dhx_matrix_cell "+scheduler.templates[this.name+"_cell_class"](evs[i][j],this._trace_x[j],this.y_unit[i])+"' style='width:"+(scheduler._cols[j]-1)+"px'><div style='width:"+(scheduler._cols[j]-1)+"px'>"+scheduler.templates[this.name+"_cell_value"](evs[i][j])+"</div></td>";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//section 2
|
|
||||||
html+="<td><div style='"+stats.summ_width+" "+stats.style_height+" position:relative;' class='dhx_matrix_line'>";
|
|
||||||
|
|
||||||
// adding events
|
|
||||||
html += events_html;
|
|
||||||
|
|
||||||
//section 3
|
|
||||||
html+="<table class='"+stats.table_className+"' cellpadding='0' cellspacing='0' style='"+stats.summ_width+" "+stats.style_height+"' >";
|
|
||||||
for (var j=0; j < scheduler._cols.length; j++)
|
|
||||||
html+="<td class='dhx_matrix_cell "+scheduler.templates[this.name+"_cell_class"](evs[i],this._trace_x[j],this.y_unit[i])+"' style='width:"+(scheduler._cols[j]-1)+"px'><div style='width:"+(scheduler._cols[j]-1)+"px'></div></td>";
|
|
||||||
html+="</table>";
|
|
||||||
html+="</div></td>";
|
|
||||||
}
|
|
||||||
html+="</tr>";
|
|
||||||
}
|
|
||||||
html += "</table>";
|
|
||||||
this._matrix = evs;
|
|
||||||
//d.scrollTop = 0; //fix flickering in FF; disabled as it was impossible to create dnd event if scroll was used (window jumped to the top)
|
|
||||||
d.innerHTML = html;
|
|
||||||
|
|
||||||
scheduler._rendered = [];
|
|
||||||
var divs = scheduler._obj.getElementsByTagName("DIV");
|
|
||||||
for (var i=0; i < divs.length; i++)
|
|
||||||
if (divs[i].getAttribute("event_id"))
|
|
||||||
scheduler._rendered.push(divs[i]);
|
|
||||||
|
|
||||||
this._scales = {};
|
|
||||||
for (var i=0; i < d.firstChild.rows.length; i++) {
|
|
||||||
heights.push(d.firstChild.rows[i].offsetHeight);
|
|
||||||
var unit_key = this.y_unit[i].key;
|
|
||||||
var scale = this._scales[unit_key] = (scheduler._isRender('cell')) ? d.firstChild.rows[i] : d.firstChild.rows[i].childNodes[1].getElementsByTagName('div')[0];
|
|
||||||
scheduler.callEvent("onScaleAdd", [scale, unit_key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function x_scale(h){
|
|
||||||
var current_sh = scheduler.xy.scale_height;
|
|
||||||
var original_sh = this._header_resized||scheduler.xy.scale_height;
|
|
||||||
scheduler._cols=[]; //store for data section, each column width
|
|
||||||
scheduler._colsS={height:0}; // heights of the y sections
|
|
||||||
this._trace_x =[]; // list of dates per cells
|
|
||||||
var summ = scheduler._x-this.dx-18; //border delta, whole width
|
|
||||||
var left = [this.dx]; // left margins, initial left margin
|
|
||||||
var header = scheduler._els['dhx_cal_header'][0];
|
|
||||||
header.style.width = (left[0]+summ)+'px';
|
|
||||||
|
|
||||||
scheduler._min_date_timeline = scheduler._min_date;
|
|
||||||
|
|
||||||
var start = scheduler._min_date;
|
|
||||||
for (var k=0; k<this.x_size; k++){
|
|
||||||
// dates calculation
|
|
||||||
this._trace_x[k]=new Date(start);
|
|
||||||
start = scheduler.date.add(start, this.x_step, this.x_unit);
|
|
||||||
|
|
||||||
// position calculation
|
|
||||||
scheduler._cols[k]=Math.floor(summ/(this.x_size-k));
|
|
||||||
summ -= scheduler._cols[k];
|
|
||||||
left[k+1] = left[k] + scheduler._cols[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
h.innerHTML = "<div></div>";
|
|
||||||
|
|
||||||
if(this.second_scale){
|
|
||||||
// additional calculations
|
|
||||||
var mode = this.second_scale.x_unit;
|
|
||||||
var control_dates = [this._trace_x[0]]; // first control date
|
|
||||||
var second_cols = []; // each column width of the secondary row
|
|
||||||
var second_left = [this.dx, this.dx]; // left margins of the secondary row
|
|
||||||
var t_index = 0; // temp index
|
|
||||||
for (var l = 0; l < this._trace_x.length; l++) {
|
|
||||||
var date = this._trace_x[l];
|
|
||||||
var res = is_new_interval(mode, date, control_dates[t_index]);
|
|
||||||
|
|
||||||
if(res) { // new interval
|
|
||||||
++t_index; // starting new interval
|
|
||||||
control_dates[t_index] = date; // updating control date as we moved to the new interval
|
|
||||||
second_left[t_index+1] = second_left[t_index];
|
|
||||||
}
|
|
||||||
var t = t_index+1;
|
|
||||||
second_cols[t_index] = scheduler._cols[l] + (second_cols[t_index]||0);
|
|
||||||
second_left[t] += scheduler._cols[l];
|
|
||||||
}
|
|
||||||
|
|
||||||
h.innerHTML = "<div></div><div></div>";
|
|
||||||
var top = h.firstChild;
|
|
||||||
top.style.height = (original_sh)+'px'; // actually bottom header takes 21px
|
|
||||||
var bottom = h.lastChild;
|
|
||||||
bottom.style.position = "relative";
|
|
||||||
|
|
||||||
for (var m = 0; m < control_dates.length; m++) {
|
|
||||||
var tdate = control_dates[m];
|
|
||||||
var scs = scheduler.templates[this.name+"_second_scalex_class"](tdate);
|
|
||||||
var head=document.createElement("DIV"); head.className="dhx_scale_bar dhx_second_scale_bar"+((scs)?(" "+scs):"");
|
|
||||||
scheduler.set_xy(head,second_cols[m]-1,original_sh-3,second_left[m],0); //-1 for border, -3 = -2 padding -1 border bottom
|
|
||||||
head.innerHTML = scheduler.templates[this.name+"_second_scale_date"](tdate);
|
|
||||||
top.appendChild(head);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.xy.scale_height = original_sh; // fix for _render_x_header which uses current scale_height value
|
|
||||||
h = h.lastChild; // h - original scale
|
|
||||||
for (var i=0; i<this._trace_x.length; i++){
|
|
||||||
start = this._trace_x[i];
|
|
||||||
scheduler._render_x_header(i, left[i], start, h);
|
|
||||||
var cs = scheduler.templates[this.name+"_scalex_class"](start);
|
|
||||||
if (cs)
|
|
||||||
h.lastChild.className += " "+cs;
|
|
||||||
}
|
|
||||||
scheduler.xy.scale_height = current_sh; // restoring current value
|
|
||||||
|
|
||||||
var trace = this._trace_x;
|
|
||||||
h.onclick = function(e){
|
|
||||||
var pos = locate_hcell(e);
|
|
||||||
if (pos)
|
|
||||||
scheduler.callEvent("onXScaleClick",[pos.x, trace[pos.x], e||event]);
|
|
||||||
};
|
|
||||||
h.ondblclick = function(e){
|
|
||||||
var pos = locate_hcell(e);
|
|
||||||
if (pos)
|
|
||||||
scheduler.callEvent("onXScaleDblClick",[pos.x, trace[pos.x], e||event]);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function is_new_interval(mode, date, control_date){ // mode, date to check, control_date for which period should be checked
|
|
||||||
switch(mode) {
|
|
||||||
case "hour":
|
|
||||||
return ((date.getHours() != control_date.getHours()) || is_new_interval("day", date, control_date));
|
|
||||||
case "day":
|
|
||||||
return !(date.getDate() == control_date.getDate() && date.getMonth() == control_date.getMonth() && date.getFullYear() == control_date.getFullYear());
|
|
||||||
case "week":
|
|
||||||
return !(scheduler.date.getISOWeek(date) == scheduler.date.getISOWeek(control_date) && date.getFullYear() == control_date.getFullYear());
|
|
||||||
case "month":
|
|
||||||
return !(date.getMonth() == control_date.getMonth() && date.getFullYear() == control_date.getFullYear());
|
|
||||||
case "year":
|
|
||||||
return !(date.getFullYear() == control_date.getFullYear());
|
|
||||||
default:
|
|
||||||
return false; // same interval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function set_full_view(mode){
|
|
||||||
if (mode){
|
|
||||||
scheduler.set_sizes();
|
|
||||||
_init_matrix_tooltip();
|
|
||||||
//we need to have day-rounded scales for navigation
|
|
||||||
//in same time, during rendering scales may be shifted
|
|
||||||
var temp = scheduler._min_date;
|
|
||||||
x_scale.call(this,scheduler._els["dhx_cal_header"][0]);
|
|
||||||
y_scale.call(this,scheduler._els["dhx_cal_data"][0]);
|
|
||||||
scheduler._min_date = temp;
|
|
||||||
scheduler._els["dhx_cal_date"][0].innerHTML=scheduler.templates[this.name+"_date"](scheduler._min_date, scheduler._max_date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function hideToolTip(){
|
|
||||||
if (scheduler._tooltip){
|
|
||||||
scheduler._tooltip.style.display = "none";
|
|
||||||
scheduler._tooltip.date = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function showToolTip(obj,pos,offset){
|
|
||||||
if (obj.render != "cell") return;
|
|
||||||
var mark = pos.x+"_"+pos.y;
|
|
||||||
var evs = obj._matrix[pos.y][pos.x];
|
|
||||||
|
|
||||||
if (!evs) return hideToolTip();
|
|
||||||
|
|
||||||
evs.sort(function(a,b){ return a.start_date>b.start_date?1:-1; });
|
|
||||||
|
|
||||||
if (scheduler._tooltip){
|
|
||||||
if (scheduler._tooltip.date == mark) return;
|
|
||||||
scheduler._tooltip.innerHTML="";
|
|
||||||
} else {
|
|
||||||
var t = scheduler._tooltip = document.createElement("DIV");
|
|
||||||
t.className = "dhx_tooltip";
|
|
||||||
document.body.appendChild(t);
|
|
||||||
t.onclick = scheduler._click.dhx_cal_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
var html = "";
|
|
||||||
|
|
||||||
for (var i=0; i<evs.length; i++){
|
|
||||||
var bg_color = (evs[i].color?("background-color:"+evs[i].color+";"):"");
|
|
||||||
var color = (evs[i].textColor?("color:"+evs[i].textColor+";"):"");
|
|
||||||
html+="<div class='dhx_tooltip_line' event_id='"+evs[i].id+"' style='"+bg_color+""+color+"'>";
|
|
||||||
html+="<div class='dhx_tooltip_date'>"+(evs[i]._timed?scheduler.templates.event_date(evs[i].start_date):"")+"</div>";
|
|
||||||
html+="<div class='dhx_event_icon icon_details'> </div>";
|
|
||||||
html+=scheduler.templates[obj.name+"_tooltip"](evs[i].start_date, evs[i].end_date,evs[i])+"</div>";
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler._tooltip.style.display="";
|
|
||||||
scheduler._tooltip.style.top = "0px";
|
|
||||||
|
|
||||||
if (document.body.offsetWidth-offset.left-scheduler._tooltip.offsetWidth < 0)
|
|
||||||
scheduler._tooltip.style.left = offset.left-scheduler._tooltip.offsetWidth+"px";
|
|
||||||
else
|
|
||||||
scheduler._tooltip.style.left = offset.left+pos.src.offsetWidth+"px";
|
|
||||||
|
|
||||||
scheduler._tooltip.date = mark;
|
|
||||||
scheduler._tooltip.innerHTML = html;
|
|
||||||
|
|
||||||
if (document.body.offsetHeight-offset.top-scheduler._tooltip.offsetHeight < 0)
|
|
||||||
scheduler._tooltip.style.top= offset.top-scheduler._tooltip.offsetHeight+pos.src.offsetHeight+"px";
|
|
||||||
else
|
|
||||||
scheduler._tooltip.style.top= offset.top+"px";
|
|
||||||
}
|
|
||||||
|
|
||||||
function _init_matrix_tooltip() {
|
|
||||||
dhtmlxEvent(scheduler._els["dhx_cal_data"][0], "mouseover", function(e){
|
|
||||||
var obj = scheduler.matrix[scheduler._mode];
|
|
||||||
if (!obj || obj.render != "cell")
|
|
||||||
return;
|
|
||||||
if (obj){
|
|
||||||
var pos = scheduler._locate_cell_timeline(e);
|
|
||||||
var e = e || event;
|
|
||||||
var src = e.target||e.srcElement;
|
|
||||||
if (pos)
|
|
||||||
return showToolTip(obj,pos,getOffset(pos.src));
|
|
||||||
}
|
|
||||||
hideToolTip();
|
|
||||||
});
|
|
||||||
_init_matrix_tooltip=function(){};
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.renderMatrix = function(mode, refresh) {
|
|
||||||
if (!refresh)
|
|
||||||
scheduler._els['dhx_cal_data'][0].scrollTop=0;
|
|
||||||
|
|
||||||
scheduler._min_date = scheduler.date[this.name+"_start"](scheduler._date);
|
|
||||||
scheduler._max_date = scheduler.date.add(scheduler._min_date, this.x_size*this.x_step, this.x_unit);
|
|
||||||
scheduler._table_view = true;
|
|
||||||
if (this.second_scale) {
|
|
||||||
if (mode && !this._header_resized) {
|
|
||||||
this._header_resized = scheduler.xy.scale_height;
|
|
||||||
scheduler.xy.scale_height *= 2;
|
|
||||||
scheduler._els['dhx_cal_header'][0].className += " dhx_second_cal_header";
|
|
||||||
}
|
|
||||||
if (!mode && this._header_resized) {
|
|
||||||
scheduler.xy.scale_height /= 2;
|
|
||||||
this._header_resized = false;
|
|
||||||
var header = scheduler._els['dhx_cal_header'][0];
|
|
||||||
header.className = header.className.replace(/ dhx_second_cal_header/gi,"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set_full_view.call(this,mode);
|
|
||||||
};
|
|
||||||
|
|
||||||
function html_index(el) {
|
|
||||||
var p = el.parentNode.childNodes;
|
|
||||||
for (var i=0; i < p.length; i++)
|
|
||||||
if (p[i] == el) return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
function locate_hcell(e){
|
|
||||||
e = e||event;
|
|
||||||
var trg = e.target?e.target:e.srcElement;
|
|
||||||
while (trg && trg.tagName != "DIV")
|
|
||||||
trg=trg.parentNode;
|
|
||||||
if (trg && trg.tagName == "DIV"){
|
|
||||||
var cs = trg.className.split(" ")[0];
|
|
||||||
if (cs == "dhx_scale_bar")
|
|
||||||
return { x:html_index(trg), y:-1, src:trg, scale:true };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scheduler._locate_cell_timeline = function(e){
|
|
||||||
e = e||event;
|
|
||||||
var trg = e.target?e.target:e.srcElement;
|
|
||||||
|
|
||||||
var res = {};
|
|
||||||
var view = scheduler.matrix[scheduler._mode];
|
|
||||||
var pos = scheduler.getActionData(e);
|
|
||||||
|
|
||||||
for (var xind = 0; xind < view._trace_x.length-1; xind++) {
|
|
||||||
if (+pos.date <= view._trace_x[xind+1]) // | 8:00, 8:30 | 8:15 should be checked against 8:30
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.x = xind;
|
|
||||||
res.y = view.order[pos.section];
|
|
||||||
var diff = scheduler._isRender('cell') ? 1 : 0;
|
|
||||||
res.src = view._scales[pos.section].getElementsByTagName('td')[xind+diff];
|
|
||||||
|
|
||||||
if (trg.className.split(" ")[0] == "dhx_matrix_scell") { // Y scale
|
|
||||||
res.x = -1;
|
|
||||||
res.src = trg;
|
|
||||||
res.scale = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
var old_click = scheduler._click.dhx_cal_data;
|
|
||||||
scheduler._click.dhx_marked_timespan = scheduler._click.dhx_cal_data = function(e){
|
|
||||||
var ret = old_click.apply(this,arguments);
|
|
||||||
var obj = scheduler.matrix[scheduler._mode];
|
|
||||||
if (obj){
|
|
||||||
var pos = scheduler._locate_cell_timeline(e);
|
|
||||||
if (pos){
|
|
||||||
if (pos.scale)
|
|
||||||
scheduler.callEvent("onYScaleClick",[pos.y, obj.y_unit[pos.y], e||event]);
|
|
||||||
else
|
|
||||||
scheduler.callEvent("onCellClick",[pos.x, pos.y, obj._trace_x[pos.x], (((obj._matrix[pos.y]||{})[pos.x])||[]), e||event]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.dblclick_dhx_marked_timespan = scheduler.dblclick_dhx_matrix_cell = function(e){
|
|
||||||
var obj = scheduler.matrix[scheduler._mode];
|
|
||||||
if (obj){
|
|
||||||
var pos = scheduler._locate_cell_timeline(e);
|
|
||||||
if (pos){
|
|
||||||
if (pos.scale)
|
|
||||||
scheduler.callEvent("onYScaleDblClick",[pos.y, obj.y_unit[pos.y], e||event]);
|
|
||||||
else
|
|
||||||
scheduler.callEvent("onCellDblClick",[pos.x, pos.y, obj._trace_x[pos.x], (((obj._matrix[pos.y]||{})[pos.x])||[]), e||event]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.dblclick_dhx_matrix_scell = function(e){
|
|
||||||
return scheduler.dblclick_dhx_matrix_cell(e);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler._isRender = function(mode){
|
|
||||||
return (scheduler.matrix[scheduler._mode] && scheduler.matrix[scheduler._mode].render == mode);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onCellDblClick", function (x, y, a, b, event){
|
|
||||||
if (this.config.readonly|| (event.type == "dblclick" && !this.config.dblclick_create)) return;
|
|
||||||
|
|
||||||
var obj = scheduler.matrix[scheduler._mode];
|
|
||||||
var event_options = {};
|
|
||||||
event_options['start_date'] = obj._trace_x[x];
|
|
||||||
event_options['end_date'] = (obj._trace_x[x+1]) ? obj._trace_x[x+1] : scheduler.date.add(obj._trace_x[x], obj.x_step, obj.x_unit);
|
|
||||||
event_options[scheduler.matrix[scheduler._mode].y_property] = obj.y_unit[y].key;
|
|
||||||
scheduler.addEventNow(event_options, null, event);
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeDrag", function (event_id, mode, native_event_object){
|
|
||||||
return !scheduler._isRender("cell");
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventChanged", function(id, ev) {
|
|
||||||
ev._timed = this.is_one_day_event(ev);
|
|
||||||
});
|
|
||||||
var old_render_marked_timespan = scheduler._render_marked_timespan;
|
|
||||||
scheduler._render_marked_timespan = function(options, area, unit_id) {
|
|
||||||
if (!scheduler.config.display_marked_timespans)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode]) {
|
|
||||||
if (scheduler._isRender('cell'))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var view_opts = scheduler.matrix[scheduler._mode];
|
|
||||||
var blocks = [];
|
|
||||||
|
|
||||||
var units = [];
|
|
||||||
var areas = [];
|
|
||||||
if (!unit_id) { // should draw for every unit
|
|
||||||
var order = view_opts.order;
|
|
||||||
for (var key in order) {
|
|
||||||
if (order.hasOwnProperty(key)) {
|
|
||||||
units.push(key);
|
|
||||||
areas.push(view_opts._scales[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
areas = [area];
|
|
||||||
units = [unit_id]
|
|
||||||
}
|
|
||||||
|
|
||||||
var min_date = scheduler._min_date;
|
|
||||||
var max_date = scheduler._max_date;
|
|
||||||
var dates = [];
|
|
||||||
|
|
||||||
if (options.days > 6) {
|
|
||||||
var specific_date = new Date(options.days);
|
|
||||||
if (scheduler.date.date_part(new Date(min_date)) <= +specific_date && +max_date >= +specific_date)
|
|
||||||
dates.push(specific_date);
|
|
||||||
} else {
|
|
||||||
dates.push.apply(dates, scheduler._get_dates_by_index(options.days));
|
|
||||||
}
|
|
||||||
|
|
||||||
var zones = options.zones;
|
|
||||||
var css_classes = scheduler._get_css_classes_by_config(options);
|
|
||||||
|
|
||||||
for (var j=0; j<units.length; j++) {
|
|
||||||
area = areas[j];
|
|
||||||
unit_id = units[j];
|
|
||||||
|
|
||||||
for (var i=0; i<dates.length; i++) {
|
|
||||||
var date = dates[i];
|
|
||||||
for (var k=0; k<zones.length; k += 2) {
|
|
||||||
var zone_start = zones[k];
|
|
||||||
var zone_end = zones[k+1];
|
|
||||||
var start_date = new Date(+date + zone_start*60*1000);
|
|
||||||
var end_date = new Date(+date + zone_end*60*1000);
|
|
||||||
|
|
||||||
if (!(scheduler._min_date < end_date && scheduler._max_date > start_date))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var block = scheduler._get_block_by_config(options);
|
|
||||||
block.className = css_classes;
|
|
||||||
|
|
||||||
var start_pos = _getX({start_date: start_date}, false, view_opts._step)-1;
|
|
||||||
var end_pos = _getX({start_date: end_date}, false, view_opts._step)-1;
|
|
||||||
var width = end_pos - start_pos-1;
|
|
||||||
var height = view_opts._section_height[unit_id]-1;
|
|
||||||
|
|
||||||
block.style.cssText = "height: "+height+"px; left: "+start_pos+"px; width: "+width+"px; top: 0;";
|
|
||||||
|
|
||||||
area.insertBefore(block, area.firstChild);
|
|
||||||
blocks.push(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return blocks;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return old_render_marked_timespan.apply(scheduler, [options, area, unit_id]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var old_append_mark_now = scheduler._append_mark_now;
|
|
||||||
scheduler._append_mark_now = function(day_index) {
|
|
||||||
if (scheduler.matrix && scheduler.matrix[scheduler._mode]) {
|
|
||||||
var n_date = new Date();
|
|
||||||
var zone_start = scheduler._get_zone_minutes(n_date);
|
|
||||||
var options = {
|
|
||||||
days: +scheduler.date.date_part(n_date),
|
|
||||||
zones: [zone_start, zone_start+1],
|
|
||||||
css: "dhx_matrix_now_time",
|
|
||||||
type: "dhx_now_time"
|
|
||||||
};
|
|
||||||
return scheduler._render_marked_timespan(options);
|
|
||||||
} else {
|
|
||||||
return old_append_mark_now.apply(scheduler, [day_index]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onViewChange", function(date, mode) {
|
|
||||||
if (scheduler.matrix && scheduler.matrix[mode]) {
|
|
||||||
if (scheduler.markNow) {
|
|
||||||
scheduler.markNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onScaleAdd", function(scale, unit_key) {
|
|
||||||
var timespans = scheduler._marked_timespans;
|
|
||||||
|
|
||||||
if (timespans && scheduler.matrix && scheduler.matrix[scheduler._mode]) {
|
|
||||||
var mode = scheduler._mode;
|
|
||||||
|
|
||||||
var min_date = scheduler._min_date;
|
|
||||||
var max_date = scheduler._max_date;
|
|
||||||
var global_data = timespans["global"];
|
|
||||||
|
|
||||||
for (var t_date = scheduler.date.date_part(new Date(min_date)); t_date < max_date; t_date = scheduler.date.add(t_date, 1, "day")) {
|
|
||||||
var day_value = +t_date;
|
|
||||||
var day_index = t_date.getDay();
|
|
||||||
var r_configs = [];
|
|
||||||
|
|
||||||
var day_types = global_data[day_value]||global_data[day_index];
|
|
||||||
r_configs.push.apply(r_configs, scheduler._get_configs_to_render(day_types));
|
|
||||||
|
|
||||||
if (timespans[mode] && timespans[mode][unit_key]) {
|
|
||||||
var unit_types = scheduler._get_types_to_render(timespans[mode][unit_key][day_index], timespans[mode][unit_key][day_value]);
|
|
||||||
r_configs.push.apply(r_configs, scheduler._get_configs_to_render(unit_types));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i=0; i<r_configs.length; i++) {
|
|
||||||
var config = r_configs[i];
|
|
||||||
var day = config.days;
|
|
||||||
if (day < 7) {
|
|
||||||
day = day_value;
|
|
||||||
scheduler._render_marked_timespan(config, scale, unit_key);
|
|
||||||
day = day_index;
|
|
||||||
} else {
|
|
||||||
scheduler._render_marked_timespan(config, scale, unit_key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,172 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
window.dhtmlXTooltip = {};
|
|
||||||
|
|
||||||
dhtmlXTooltip.config = {
|
|
||||||
className: 'dhtmlXTooltip tooltip',
|
|
||||||
timeout_to_display: 50,
|
|
||||||
delta_x: 15,
|
|
||||||
delta_y: -20
|
|
||||||
};
|
|
||||||
|
|
||||||
dhtmlXTooltip.tooltip = document.createElement('div');
|
|
||||||
dhtmlXTooltip.tooltip.className = dhtmlXTooltip.config.className;
|
|
||||||
|
|
||||||
dhtmlXTooltip.show = function(event, text) { //browser event, text to display
|
|
||||||
var dhxTooltip = dhtmlXTooltip;
|
|
||||||
var tooltip_div = this.tooltip;
|
|
||||||
var tooltip_div_style = tooltip_div.style;
|
|
||||||
dhxTooltip.tooltip.className = dhxTooltip.config.className;
|
|
||||||
var pos = this.position(event);
|
|
||||||
|
|
||||||
var target = event.target || event.srcElement;
|
|
||||||
if (this.isTooltip(target)) {
|
|
||||||
return;
|
|
||||||
} // if we are over tooltip -- do nothing, just return (so tooltip won't move)
|
|
||||||
|
|
||||||
var offsetleft = 0;
|
|
||||||
var offsettop = 0;
|
|
||||||
var pobj = scheduler._obj;
|
|
||||||
if (pobj.offsetParent) {
|
|
||||||
do {
|
|
||||||
offsetleft += pobj.offsetLeft;
|
|
||||||
offsettop += pobj.offsetTop;
|
|
||||||
} while (pobj = pobj.offsetParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
var actual_x = pos.x + (dhxTooltip.config.delta_x || 0) - offsetleft;
|
|
||||||
var actual_y = pos.y - (dhxTooltip.config.delta_y || 0) - offsettop;
|
|
||||||
|
|
||||||
tooltip_div_style.visibility = "hidden";
|
|
||||||
|
|
||||||
if (tooltip_div_style.removeAttribute) {
|
|
||||||
tooltip_div_style.removeAttribute("right");
|
|
||||||
tooltip_div_style.removeAttribute("bottom");
|
|
||||||
} else {
|
|
||||||
tooltip_div_style.removeProperty("right");
|
|
||||||
tooltip_div_style.removeProperty("bottom");
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip_div_style.left = "0";
|
|
||||||
tooltip_div_style.top = "0";
|
|
||||||
|
|
||||||
this.tooltip.innerHTML = text;
|
|
||||||
scheduler._obj.appendChild(this.tooltip);
|
|
||||||
|
|
||||||
var tooltip_width = this.tooltip.offsetWidth;
|
|
||||||
var tooltip_height = this.tooltip.offsetHeight;
|
|
||||||
var parent_scrollLeft = scheduler._obj.parentNode.scrollLeft || 0;
|
|
||||||
var visible_width = Math.min(scheduler._obj.offsetWidth, scheduler._obj.parentNode.offsetWidth);
|
|
||||||
|
|
||||||
if ((visible_width - actual_x - (scheduler.xy.margin_left || 0) - tooltip_width) < 0) { // tooltip is out of the right page bound
|
|
||||||
if (tooltip_div_style.removeAttribute)
|
|
||||||
tooltip_div_style.removeAttribute("left");
|
|
||||||
else
|
|
||||||
tooltip_div_style.removeProperty("left");
|
|
||||||
tooltip_div_style.right = (scheduler._obj.offsetWidth - parent_scrollLeft - actual_x + 2 * (dhxTooltip.config.delta_x || 0)) + "px";
|
|
||||||
} else {
|
|
||||||
if (actual_x < 0) { // tooltips is out of the left page bound
|
|
||||||
tooltip_div_style.left = (pos.x + Math.abs(dhxTooltip.config.delta_x || 0)) + "px";
|
|
||||||
} else { // normal situation
|
|
||||||
tooltip_div_style.left = (actual_x + parent_scrollLeft) + "px";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((scheduler._obj.offsetHeight - actual_y - (scheduler.xy.margin_top || 0) - tooltip_height) < 0) { // tooltip is below bottom of the page
|
|
||||||
if (tooltip_div_style.removeAttribute)
|
|
||||||
tooltip_div_style.removeAttribute("top");
|
|
||||||
else
|
|
||||||
tooltip_div_style.removeProperty("top");
|
|
||||||
tooltip_div_style.bottom = (scheduler._obj.offsetHeight - actual_y - 2 * (dhxTooltip.config.delta_y || 0)) + "px";
|
|
||||||
} else {
|
|
||||||
if (actual_y < 0) { // tooltip is higher then top of the page
|
|
||||||
tooltip_div_style.top = (pos.y + Math.abs(dhxTooltip.config.delta_y || 0)) + "px";
|
|
||||||
}
|
|
||||||
else { // normal situation
|
|
||||||
tooltip_div_style.top = actual_y + "px";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip_div_style.visibility = "visible";
|
|
||||||
};
|
|
||||||
|
|
||||||
dhtmlXTooltip.hide = function() {
|
|
||||||
if (this.tooltip.parentNode) {
|
|
||||||
this.tooltip.parentNode.removeChild(this.tooltip);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
dhtmlXTooltip.delay = function(method, object, params, delay) {
|
|
||||||
if (this.tooltip._timeout_id) {
|
|
||||||
window.clearTimeout(this.tooltip._timeout_id);
|
|
||||||
}
|
|
||||||
this.tooltip._timeout_id = setTimeout(function() {
|
|
||||||
var ret = method.apply(object, params);
|
|
||||||
method = object = params = null;
|
|
||||||
return ret;
|
|
||||||
}, delay || this.config.timeout_to_display);
|
|
||||||
};
|
|
||||||
|
|
||||||
dhtmlXTooltip.isTooltip = function(node) {
|
|
||||||
var res = false;
|
|
||||||
while (node && !res) {
|
|
||||||
res = (node.className == this.tooltip.className);
|
|
||||||
node = node.parentNode;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
dhtmlXTooltip.position = function(ev) {
|
|
||||||
ev = ev || window.event;
|
|
||||||
if (ev.pageX || ev.pageY) //FF, KHTML
|
|
||||||
return {x:ev.pageX, y:ev.pageY};
|
|
||||||
//IE
|
|
||||||
var d = ((window._isIE) && (document.compatMode != "BackCompat")) ? document.documentElement : document.body;
|
|
||||||
return {
|
|
||||||
x:ev.clientX + d.scrollLeft - d.clientLeft,
|
|
||||||
y:ev.clientY + d.scrollTop - d.clientTop
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onMouseMove", function(event_id, e) { // (scheduler event_id, browser event)
|
|
||||||
var ev = window.event || e;
|
|
||||||
var target = ev.target || ev.srcElement;
|
|
||||||
var dhxTooltip = dhtmlXTooltip;
|
|
||||||
|
|
||||||
if (event_id || dhxTooltip.isTooltip(target)) { // if we are over event or tooltip
|
|
||||||
var event = scheduler.getEvent(event_id) || scheduler.getEvent(dhxTooltip.tooltip.event_id);
|
|
||||||
if (!event)
|
|
||||||
return;
|
|
||||||
dhxTooltip.tooltip.event_id = event.id;
|
|
||||||
var text = scheduler.templates.tooltip_text(event.start_date, event.end_date, event);
|
|
||||||
if (!text) return dhxTooltip.hide();
|
|
||||||
|
|
||||||
var evt = undefined;
|
|
||||||
if (_isIE) { //make a copy of event, will be used in timed call
|
|
||||||
evt = document.createEventObject(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!scheduler.callEvent("onBeforeTooltip", [event_id, event]) || !text)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dhxTooltip.delay(dhxTooltip.show, dhxTooltip, [(evt || ev), text]); // showing tooltip
|
|
||||||
} else {
|
|
||||||
dhxTooltip.delay(dhxTooltip.hide, dhxTooltip, []);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onBeforeDrag", function() {
|
|
||||||
dhtmlXTooltip.hide();
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventDeleted", function() {
|
|
||||||
dhtmlXTooltip.hide();
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
/* Could be redifined */
|
|
||||||
scheduler.templates.tooltip_date_format = scheduler.date.date_to_str("%Y-%m-%d %H:%i");
|
|
||||||
|
|
||||||
scheduler.templates.tooltip_text = function(start, end, event) {
|
|
||||||
return "<b>Event:</b> " + event.text + "<br/><b>Start date:</b> " + scheduler.templates.tooltip_date_format(start) + "<br/><b>End date:</b> " + scheduler.templates.tooltip_date_format(end);
|
|
||||||
};
|
|
|
@ -1,292 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.attachEvent("onTimelineCreated", function (obj){
|
|
||||||
|
|
||||||
if(obj.render == "tree") {
|
|
||||||
obj.y_unit_original = obj.y_unit;
|
|
||||||
obj.y_unit = scheduler._getArrayToDisplay(obj.y_unit_original);
|
|
||||||
|
|
||||||
scheduler.attachEvent('onOptionsLoadStart', function(){
|
|
||||||
obj.y_unit = scheduler._getArrayToDisplay(obj.y_unit_original);
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.form_blocks[obj.name]={
|
|
||||||
render:function(sns) {
|
|
||||||
var _result = "<div class='dhx_section_timeline' style='overflow: hidden; height: "+sns.height+"px'></div>";
|
|
||||||
return _result;
|
|
||||||
},
|
|
||||||
set_value:function(node,value,ev,config){
|
|
||||||
var options = scheduler._getArrayForSelect(scheduler.matrix[config.type].y_unit_original, config.type);
|
|
||||||
node.innerHTML = '';
|
|
||||||
var temp_select = document.createElement('select');
|
|
||||||
node.appendChild(temp_select);
|
|
||||||
|
|
||||||
var select = node.getElementsByTagName('select')[0];
|
|
||||||
|
|
||||||
for(var i=0; i<options.length; i++) {
|
|
||||||
var temp_option = document.createElement('option');
|
|
||||||
temp_option.value = options[i].key;
|
|
||||||
if(temp_option.value == ev[scheduler.matrix[config.type].y_property])
|
|
||||||
temp_option.selected = true;
|
|
||||||
temp_option.innerHTML = options[i].label;
|
|
||||||
select.appendChild(temp_option);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
get_value:function(node,ev,config){
|
|
||||||
return node.firstChild.value;
|
|
||||||
},
|
|
||||||
focus:function(node){
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeViewRender", function (render_name, y_unit, timeline){
|
|
||||||
var res = {};
|
|
||||||
if(render_name == "tree"){
|
|
||||||
var height;
|
|
||||||
// section 1
|
|
||||||
var tr_className, style_height, td_className;
|
|
||||||
var div_expand;
|
|
||||||
// section 3
|
|
||||||
var table_className;
|
|
||||||
if(y_unit.children) {
|
|
||||||
height = timeline.folder_dy||timeline.dy;
|
|
||||||
if(timeline.folder_dy && !timeline.section_autoheight) {
|
|
||||||
style_height = "height:"+timeline.folder_dy+"px;";
|
|
||||||
}
|
|
||||||
tr_className = "dhx_row_folder";
|
|
||||||
td_className = "dhx_matrix_scell folder";
|
|
||||||
div_expand = "<div class='dhx_scell_expand'>"+((y_unit.open)?'-':'+')+"</div>";
|
|
||||||
table_className = (timeline.folder_events_available)?"dhx_data_table folder_events":"dhx_data_table folder";
|
|
||||||
} else {
|
|
||||||
height = timeline.dy;
|
|
||||||
tr_className = "dhx_row_item";
|
|
||||||
td_className = "dhx_matrix_scell item";
|
|
||||||
div_expand = '';
|
|
||||||
table_className = "dhx_data_table";
|
|
||||||
}
|
|
||||||
td_content = "<div class='dhx_scell_level"+y_unit.level+"'>"+div_expand+"<div class='dhx_scell_name'>"+(scheduler.templates[timeline.name+'_scale_label'](y_unit.key, y_unit.label, y_unit)||y_unit.label)+"</div></div>";
|
|
||||||
|
|
||||||
res = {
|
|
||||||
height: height,
|
|
||||||
style_height: style_height,
|
|
||||||
//section 1
|
|
||||||
tr_className: tr_className,
|
|
||||||
td_className: td_className,
|
|
||||||
td_content: td_content,
|
|
||||||
//section 3
|
|
||||||
table_className: table_className
|
|
||||||
};
|
|
||||||
};
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
|
|
||||||
var section_id_before; // section id of the event before dragging (to bring it back if user drop's event on folder without folder_events_available)
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeEventChanged", function(event_object, native_event, is_new) {
|
|
||||||
if (scheduler._isRender("tree")) { // if mode's render == tree
|
|
||||||
var section = scheduler.getSection(event_object[scheduler.matrix[scheduler._mode].y_property]);
|
|
||||||
if (section && typeof section.children != 'undefined' && !scheduler.matrix[scheduler._mode].folder_events_available) { // section itself could be not defined in case of new event (addEventNow)
|
|
||||||
if (!is_new) { //if old - move back
|
|
||||||
event_object[scheduler.matrix[scheduler._mode].y_property] = section_id_before;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onBeforeDrag", function (event_id, mode, native_event_object){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
var cell = scheduler._locate_cell_timeline(native_event_object);
|
|
||||||
if(cell) {
|
|
||||||
var section_id = scheduler.matrix[scheduler._mode].y_unit[cell.y].key;
|
|
||||||
if(typeof scheduler.matrix[scheduler._mode].y_unit[cell.y].children != "undefined" && !scheduler.matrix[scheduler._mode].folder_events_available) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var ev = scheduler.getEvent(event_id);
|
|
||||||
section_id_before = section_id||ev[scheduler.matrix[scheduler._mode].y_property]; // either event id or section_id will be available
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler._getArrayToDisplay = function(array){ // function to flatten out hierarhical array, used for tree view
|
|
||||||
var result = [];
|
|
||||||
var fillResultArray = function(array, lvl){
|
|
||||||
var level = lvl||0;
|
|
||||||
for(var i=0; i<array.length; i++) {
|
|
||||||
array[i].level = level;
|
|
||||||
if(typeof array[i].children != "undefined" && typeof array[i].key == "undefined")
|
|
||||||
array[i].key=scheduler.uid();
|
|
||||||
result.push(array[i]);
|
|
||||||
if(array[i].open && array[i].children) {
|
|
||||||
fillResultArray(array[i].children, level+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fillResultArray(array);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
scheduler._getArrayForSelect = function(array, mode){ // function to flatten out hierarhical array, used for tree view
|
|
||||||
var result = [];
|
|
||||||
var fillResultArray = function(array){
|
|
||||||
for(var i=0; i<array.length; i++) {
|
|
||||||
if(scheduler.matrix[mode].folder_events_available) {
|
|
||||||
result.push(array[i]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(typeof array[i].children == "undefined") {
|
|
||||||
result.push(array[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(array[i].children)
|
|
||||||
fillResultArray(array[i].children, mode);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fillResultArray(array);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
scheduler._toggleFolderDisplay(4) -- toggle display of the section with key 4 (closed -> open)
|
|
||||||
scheduler._toggleFolderDisplay(4, true) -- open section with the key 4 (doesn't matter what status was before). False - close.
|
|
||||||
scheduler._toggleFolderDisplay(4, false, true) -- close ALL sections. Key is not used in such condition.
|
|
||||||
*/
|
|
||||||
scheduler._toggleFolderDisplay = function(key, status, all_sections){ // used for tree view
|
|
||||||
var marked;
|
|
||||||
var toggleElement = function(key, array, status, all_sections) {
|
|
||||||
for (var i=0; i<array.length; i++) {
|
|
||||||
if((array[i].key == key || all_sections) && array[i].children) {
|
|
||||||
array[i].open = (typeof status != "undefined") ? status : !array[i].open;
|
|
||||||
marked = true;
|
|
||||||
if(!all_sections && marked)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(array[i].children) {
|
|
||||||
toggleElement(key,array[i].children, status, all_sections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
toggleElement(key,scheduler.matrix[scheduler._mode].y_unit_original, status, all_sections);
|
|
||||||
scheduler.matrix[scheduler._mode].y_unit = scheduler._getArrayToDisplay(scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
scheduler.callEvent("onOptionsLoad",[]);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onCellClick", function (x, y, a, b, event){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
if(!scheduler.matrix[scheduler._mode].folder_events_available) {
|
|
||||||
if(typeof scheduler.matrix[scheduler._mode].y_unit[y].children != "undefined") {
|
|
||||||
scheduler._toggleFolderDisplay(scheduler.matrix[scheduler._mode].y_unit[y].key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onYScaleClick", function (index, value, event){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
if(typeof value.children != "undefined") {
|
|
||||||
scheduler._toggleFolderDisplay(value.key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.getSection = function(id){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
var obj;
|
|
||||||
var findElement = function(key, array) {
|
|
||||||
for (var i=0; i<array.length; i++) {
|
|
||||||
if(array[i].key == key)
|
|
||||||
obj = array[i];
|
|
||||||
if(array[i].children)
|
|
||||||
findElement(key,array[i].children);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
findElement(id, scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
return obj||null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.deleteSection = function(id){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
var result = false;
|
|
||||||
var deleteElement = function(key, array) {
|
|
||||||
for (var i=0; i<array.length; i++) {
|
|
||||||
if(array[i].key == key) {
|
|
||||||
array.splice(i,1);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
if(result)
|
|
||||||
break;
|
|
||||||
if(array[i].children)
|
|
||||||
deleteElement(key,array[i].children);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
deleteElement(id, scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
scheduler.matrix[scheduler._mode].y_unit = scheduler._getArrayToDisplay(scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
scheduler.callEvent("onOptionsLoad",[]);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.deleteAllSections = function(){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
scheduler.matrix[scheduler._mode].y_unit_original = [];
|
|
||||||
scheduler.matrix[scheduler._mode].y_unit = scheduler._getArrayToDisplay(scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
scheduler.callEvent("onOptionsLoad",[]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.addSection = function(obj, parent_id){
|
|
||||||
if(scheduler._isRender("tree")) {
|
|
||||||
var result = false;
|
|
||||||
var addElement = function(obj, parent_key, array) {
|
|
||||||
if(!parent_id) {
|
|
||||||
array.push(obj);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (var i=0; i<array.length; i++) {
|
|
||||||
if(array[i].key == parent_key && typeof array[i].children != "undefined") {
|
|
||||||
array[i].children.push(obj);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
if(result)
|
|
||||||
break;
|
|
||||||
if(array[i].children)
|
|
||||||
addElement(obj,parent_key,array[i].children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
addElement(obj, parent_id, scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
scheduler.matrix[scheduler._mode].y_unit = scheduler._getArrayToDisplay(scheduler.matrix[scheduler._mode].y_unit_original);
|
|
||||||
scheduler.callEvent("onOptionsLoad",[]);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
scheduler.openAllSections = function() {
|
|
||||||
if(scheduler._isRender("tree"))
|
|
||||||
scheduler._toggleFolderDisplay(1, true, true);
|
|
||||||
};
|
|
||||||
scheduler.closeAllSections = function() {
|
|
||||||
if(scheduler._isRender("tree"))
|
|
||||||
scheduler._toggleFolderDisplay(1, false, true);
|
|
||||||
};
|
|
||||||
scheduler.openSection = function(section_id){
|
|
||||||
if(scheduler._isRender("tree"))
|
|
||||||
scheduler._toggleFolderDisplay(section_id, true);
|
|
||||||
};
|
|
||||||
scheduler.closeSection = function(section_id){
|
|
||||||
if(scheduler._isRender("tree"))
|
|
||||||
scheduler._toggleFolderDisplay(section_id, false);
|
|
||||||
};
|
|
|
@ -1,226 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler._props = {};
|
|
||||||
scheduler.createUnitsView=function(name,property,list,size,step,skip_incorrect){
|
|
||||||
if (typeof name == "object"){
|
|
||||||
list = name.list;
|
|
||||||
property = name.property;
|
|
||||||
size = name.size||0;
|
|
||||||
step = name.step||1;
|
|
||||||
skip_incorrect = name.skip_incorrect;
|
|
||||||
name = name.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler._props[name]={map_to:property, options:list, step:step, position:0 };
|
|
||||||
if(size>scheduler._props[name].options.length){
|
|
||||||
scheduler._props[name]._original_size = size;
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
scheduler._props[name].size = size;
|
|
||||||
scheduler._props[name].skip_incorrect = skip_incorrect||false;
|
|
||||||
|
|
||||||
scheduler.date[name+"_start"]= scheduler.date.day_start;
|
|
||||||
scheduler.templates[name+"_date"] = function(date){
|
|
||||||
return scheduler.templates.day_date(date);
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.templates[name+"_scale_date"] = function(date){
|
|
||||||
var list = scheduler._props[name].options;
|
|
||||||
if (!list.length) return "";
|
|
||||||
var index = (scheduler._props[name].position||0)+Math.floor((scheduler._correct_shift(date.valueOf(),1)-scheduler._min_date.valueOf())/(60*60*24*1000));
|
|
||||||
if (list[index].css)
|
|
||||||
return "<span class='"+list[index].css+"'>"+list[index].label+"</span>";
|
|
||||||
else
|
|
||||||
return list[index].label;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.date["add_"+name]=function(date,inc){ return scheduler.date.add(date,inc,"day"); };
|
|
||||||
scheduler.date["get_"+name+"_end"]=function(date){
|
|
||||||
return scheduler.date.add(date,scheduler._props[name].size||scheduler._props[name].options.length,"day");
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onOptionsLoad",function(){
|
|
||||||
var pr = scheduler._props[name];
|
|
||||||
var order = pr.order = {};
|
|
||||||
var list = pr.options;
|
|
||||||
for(var i=0; i<list.length;i++)
|
|
||||||
order[list[i].key]=i;
|
|
||||||
if(pr._original_size && pr.size==0){
|
|
||||||
pr.size = pr._original_size;
|
|
||||||
delete pr.original_size;
|
|
||||||
}
|
|
||||||
if(pr.size > list.length) {
|
|
||||||
pr._original_size = pr.size;
|
|
||||||
pr.size = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pr.size = pr._original_size||pr.size;
|
|
||||||
if (scheduler._date && scheduler._mode == name)
|
|
||||||
scheduler.setCurrentView(scheduler._date, scheduler._mode);
|
|
||||||
});
|
|
||||||
scheduler.callEvent("onOptionsLoad",[]);
|
|
||||||
};
|
|
||||||
scheduler.scrollUnit=function(step){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
if (pr){
|
|
||||||
pr.position=Math.min(Math.max(0,pr.position+step),pr.options.length-pr.size);
|
|
||||||
this.update_view();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
(function(){
|
|
||||||
var _removeIncorrectEvents = function(evs) {
|
|
||||||
var pr = scheduler._props[scheduler._mode];
|
|
||||||
if(pr && pr.order && pr.skip_incorrect) {
|
|
||||||
var correct_events = [];
|
|
||||||
for(var i=0; i<evs.length; i++) {
|
|
||||||
if(typeof pr.order[evs[i][pr.map_to]] != "undefined") {
|
|
||||||
correct_events.push(evs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evs.splice(0,evs.length);
|
|
||||||
evs.push.apply(evs,correct_events);
|
|
||||||
}
|
|
||||||
return evs;
|
|
||||||
};
|
|
||||||
var old_pre_render_events_table = scheduler._pre_render_events_table;
|
|
||||||
scheduler._pre_render_events_table=function(evs,hold) {
|
|
||||||
evs = _removeIncorrectEvents(evs);
|
|
||||||
return old_pre_render_events_table.apply(this, [evs, hold]);
|
|
||||||
};
|
|
||||||
var old_pre_render_events_line = scheduler._pre_render_events_line;
|
|
||||||
scheduler._pre_render_events_line = function(evs,hold){
|
|
||||||
evs = _removeIncorrectEvents(evs);
|
|
||||||
return old_pre_render_events_line.apply(this, [evs, hold]);
|
|
||||||
};
|
|
||||||
var fix_und=function(pr,ev){
|
|
||||||
if (pr && typeof pr.order[ev[pr.map_to]] == "undefined"){
|
|
||||||
var s = scheduler;
|
|
||||||
var dx = 24*60*60*1000;
|
|
||||||
var ind = Math.floor((ev.end_date - s._min_date)/dx);
|
|
||||||
//ev.end_date = new Date(s.date.time_part(ev.end_date)*1000+s._min_date.valueOf());
|
|
||||||
//ev.start_date = new Date(s.date.time_part(ev.start_date)*1000+s._min_date.valueOf());
|
|
||||||
ev[pr.map_to] = pr.options[Math.min(ind+pr.position,pr.options.length-1)].key;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var t = scheduler._reset_scale;
|
|
||||||
|
|
||||||
var oldive = scheduler.is_visible_events;
|
|
||||||
scheduler.is_visible_events = function(e){
|
|
||||||
var res = oldive.apply(this,arguments);
|
|
||||||
if (res){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
if (pr && pr.size){
|
|
||||||
var val = pr.order[e[pr.map_to]];
|
|
||||||
if (val < pr.position || val >= pr.size+pr.position )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
scheduler._reset_scale = function(){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
var ret = t.apply(this,arguments);
|
|
||||||
if (pr){
|
|
||||||
this._max_date=this.date.add(this._min_date,1,"day");
|
|
||||||
|
|
||||||
var d = this._els["dhx_cal_data"][0].childNodes;
|
|
||||||
for (var i=0; i < d.length; i++)
|
|
||||||
d[i].className = d[i].className.replace("_now",""); //clear now class
|
|
||||||
|
|
||||||
if (pr.size && pr.size < pr.options.length){
|
|
||||||
|
|
||||||
var h = this._els["dhx_cal_header"][0];
|
|
||||||
var arrow = document.createElement("DIV");
|
|
||||||
if (pr.position){
|
|
||||||
arrow.className = "dhx_cal_prev_button";
|
|
||||||
arrow.style.cssText="left:1px;top:2px;position:absolute;"
|
|
||||||
arrow.innerHTML = " "
|
|
||||||
h.firstChild.appendChild(arrow);
|
|
||||||
arrow.onclick=function(){
|
|
||||||
scheduler.scrollUnit(pr.step*-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pr.position+pr.size<pr.options.length){
|
|
||||||
arrow = document.createElement("DIV");
|
|
||||||
arrow.className = "dhx_cal_next_button";
|
|
||||||
arrow.style.cssText="left:auto; right:0px;top:2px;position:absolute;"
|
|
||||||
arrow.innerHTML = " "
|
|
||||||
h.lastChild.appendChild(arrow);
|
|
||||||
arrow.onclick=function(){
|
|
||||||
scheduler.scrollUnit(pr.step);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
};
|
|
||||||
var r = scheduler._get_event_sday;
|
|
||||||
scheduler._get_event_sday=function(ev){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
if (pr){
|
|
||||||
fix_und(pr,ev);
|
|
||||||
return pr.order[ev[pr.map_to]]-pr.position;
|
|
||||||
}
|
|
||||||
return r.call(this,ev);
|
|
||||||
};
|
|
||||||
var l = scheduler.locate_holder_day;
|
|
||||||
scheduler.locate_holder_day=function(a,b,ev){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
if (pr && ev) {
|
|
||||||
fix_und(pr,ev);
|
|
||||||
return pr.order[ev[pr.map_to]]*1+(b?1:0)-pr.position;
|
|
||||||
}
|
|
||||||
return l.apply(this,arguments);
|
|
||||||
};
|
|
||||||
var p = scheduler._mouse_coords;
|
|
||||||
scheduler._mouse_coords=function(){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
var pos=p.apply(this,arguments);
|
|
||||||
if (pr){
|
|
||||||
if(!this._drag_event) this._drag_event = {};
|
|
||||||
var ev = this._drag_event;
|
|
||||||
if (this._drag_id && this._drag_mode){
|
|
||||||
ev = this.getEvent(this._drag_id);
|
|
||||||
this._drag_event._dhx_changed = true;
|
|
||||||
}
|
|
||||||
var unit_ind = Math.min(pos.x+pr.position,pr.options.length-1);
|
|
||||||
var key = pr.map_to;
|
|
||||||
pos.section = ev[key]=pr.options[unit_ind].key;
|
|
||||||
pos.x = 0;
|
|
||||||
}
|
|
||||||
return pos;
|
|
||||||
};
|
|
||||||
var o = scheduler._time_order;
|
|
||||||
scheduler._time_order = function(evs){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
if (pr){
|
|
||||||
evs.sort(function(a,b){
|
|
||||||
return pr.order[a[pr.map_to]]>pr.order[b[pr.map_to]]?1:-1;
|
|
||||||
});
|
|
||||||
} else
|
|
||||||
o.apply(this,arguments);
|
|
||||||
};
|
|
||||||
scheduler.attachEvent("onEventAdded",function(id,ev){
|
|
||||||
if (this._loading) return true;
|
|
||||||
for (var a in scheduler._props){
|
|
||||||
var pr = scheduler._props[a];
|
|
||||||
if (typeof ev[pr.map_to] == "undefined")
|
|
||||||
ev[pr.map_to] = pr.options[0].key;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler.attachEvent("onEventCreated",function(id,n_ev){
|
|
||||||
var pr = scheduler._props[this._mode];
|
|
||||||
if (pr && n_ev){
|
|
||||||
var ev = this.getEvent(id);
|
|
||||||
this._mouse_coords(n_ev);
|
|
||||||
fix_und(pr,ev);
|
|
||||||
this.event_updated(ev);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
})();
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.attachEvent("onTemplatesReady",function(){
|
|
||||||
var first = true;
|
|
||||||
var s2d = scheduler.date.str_to_date("%Y-%m-%d");
|
|
||||||
var d2s = scheduler.date.date_to_str("%Y-%m-%d");
|
|
||||||
scheduler.attachEvent("onBeforeViewChange",function(om,od,m,d){
|
|
||||||
if (first){
|
|
||||||
first = false;
|
|
||||||
var p={};
|
|
||||||
var data=(document.location.hash||"").replace("#","").split(",");
|
|
||||||
for (var i=0; i < data.length; i++) {
|
|
||||||
var s = data[i].split("=");
|
|
||||||
if (s.length==2)
|
|
||||||
p[s[0]]=s[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.date || p.mode){
|
|
||||||
try{
|
|
||||||
this.setCurrentView((p.date?s2d(p.date):null),(p.mode||null));
|
|
||||||
} catch(e){
|
|
||||||
//assuming that mode is not available anymore
|
|
||||||
this.setCurrentView((p.date?s2d(p.date):null),m);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var text = "#date="+d2s(d||od)+",mode="+(m||om);
|
|
||||||
document.location.hash = text;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,256 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler._wa = {};
|
|
||||||
scheduler.xy.week_agenda_scale_height = 20;
|
|
||||||
scheduler.templates.week_agenda_event_text = function(start_date, end_date, event, date) {
|
|
||||||
return scheduler.templates.event_date(start_date) + " " + event.text;
|
|
||||||
};
|
|
||||||
scheduler.date.week_agenda_start = scheduler.date.week_start;
|
|
||||||
scheduler.date.week_agenda_end = function(date) {
|
|
||||||
return scheduler.date.add(date, 7, "day");
|
|
||||||
};
|
|
||||||
scheduler.date.add_week_agenda = function(date, inc) {
|
|
||||||
return scheduler.date.add(date, inc * 7, "day");
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerReady", function() {
|
|
||||||
var t = scheduler.templates;
|
|
||||||
if (!t.week_agenda_date)
|
|
||||||
t.week_agenda_date = t.week_date;
|
|
||||||
});
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var scale_date_format = scheduler.date.date_to_str("%l, %F %d");
|
|
||||||
scheduler.templates.week_agenda_scale_date = function(date) {
|
|
||||||
return scale_date_format(date);
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
scheduler.attachEvent("onTemplatesReady", function() {
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerResize", function() {
|
|
||||||
if (this._mode == "week_agenda") {
|
|
||||||
this.week_agenda_view(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
var old = scheduler.render_data;
|
|
||||||
scheduler.render_data = function(evs) {
|
|
||||||
if (this._mode == "week_agenda") {
|
|
||||||
scheduler.week_agenda_view(true);
|
|
||||||
} else
|
|
||||||
return old.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
var getColumnSizes = function() {
|
|
||||||
// widths
|
|
||||||
scheduler._cols = [];
|
|
||||||
var twidth = parseInt(scheduler._els['dhx_cal_data'][0].style.width);
|
|
||||||
scheduler._cols.push(Math.floor(twidth / 2));
|
|
||||||
scheduler._cols.push(twidth - scheduler._cols[0] - 1); // To add border between columns
|
|
||||||
|
|
||||||
// heights
|
|
||||||
scheduler._colsS = {
|
|
||||||
0: [],
|
|
||||||
1: []
|
|
||||||
};
|
|
||||||
var theight = parseInt(scheduler._els['dhx_cal_data'][0].style.height);
|
|
||||||
for (var i = 0; i < 3; i++) {
|
|
||||||
scheduler._colsS[0].push(Math.floor(theight / (3 - scheduler._colsS[0].length)));
|
|
||||||
theight -= scheduler._colsS[0][i];
|
|
||||||
}
|
|
||||||
scheduler._colsS[1].push(scheduler._colsS[0][0]);
|
|
||||||
scheduler._colsS[1].push(scheduler._colsS[0][1]);
|
|
||||||
// last two days
|
|
||||||
theight = scheduler._colsS[0][scheduler._colsS[0].length - 1];
|
|
||||||
scheduler._colsS[1].push(Math.floor(theight / 2));
|
|
||||||
scheduler._colsS[1].push(theight - scheduler._colsS[1][scheduler._colsS[1].length - 1]);
|
|
||||||
};
|
|
||||||
var fillWeekAgendaTab = function() {
|
|
||||||
getColumnSizes();
|
|
||||||
scheduler._els["dhx_cal_data"][0].innerHTML = '';
|
|
||||||
scheduler._rendered = [];
|
|
||||||
var html = '';
|
|
||||||
for (var i = 0; i < 2; i++) {
|
|
||||||
var width = scheduler._cols[i];
|
|
||||||
var column_css = 'dhx_wa_column';
|
|
||||||
if (i == 1)
|
|
||||||
column_css += ' dhx_wa_column_last';
|
|
||||||
html += "<div class='" + column_css + "' style='width: " + width + "px;'>";
|
|
||||||
for (var k = 0; k < scheduler._colsS[i].length; k++) {
|
|
||||||
var scale_height = scheduler.xy.week_agenda_scale_height - 2;
|
|
||||||
var height = scheduler._colsS[i][k] - scale_height - 2;
|
|
||||||
var day = Math.min(6, k * 2 + i);
|
|
||||||
html += "<div class='dhx_wa_day_cont'><div style='height:" + scale_height + "px; line-height:" + scale_height + "px;' class='dhx_wa_scale_bar'></div><div style='height:" + height + "px;' class='dhx_wa_day_data' day='" + day + "'></div></div>";
|
|
||||||
}
|
|
||||||
html += "</div>";
|
|
||||||
}
|
|
||||||
scheduler._els["dhx_cal_date"][0].innerHTML = scheduler.templates[scheduler._mode + "_date"](scheduler._min_date, scheduler._max_date, scheduler._mode);
|
|
||||||
scheduler._els["dhx_cal_data"][0].innerHTML = html;
|
|
||||||
var all_divs = scheduler._els["dhx_cal_data"][0].getElementsByTagName('div');
|
|
||||||
var day_divs = [];
|
|
||||||
for (var i = 0; i < all_divs.length; i++) {
|
|
||||||
if (all_divs[i].className == 'dhx_wa_day_cont')
|
|
||||||
day_divs.push(all_divs[i]);
|
|
||||||
}
|
|
||||||
scheduler._wa._selected_divs = [];
|
|
||||||
var events = scheduler.get_visible_events(); // list of events to be displayed in current week
|
|
||||||
var tstart = scheduler.date.week_start(scheduler._date);
|
|
||||||
var tend = scheduler.date.add(tstart, 1, "day");
|
|
||||||
for (var i = 0; i < 7; i++) {
|
|
||||||
day_divs[i]._date = tstart;
|
|
||||||
var scale_bar = day_divs[i].childNodes[0];
|
|
||||||
var events_div = day_divs[i].childNodes[1];
|
|
||||||
scale_bar.innerHTML = scheduler.templates.week_agenda_scale_date(tstart);
|
|
||||||
var evs = []; // events which will be displayed in the current day
|
|
||||||
for (var j = 0; j < events.length; j++) {
|
|
||||||
var tev = events[j];
|
|
||||||
if (tev.start_date < tend && tev.end_date > tstart)
|
|
||||||
evs.push(tev);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
for (var k = 0; k < evs.length; k++) {
|
|
||||||
var ev = evs[k];
|
|
||||||
var ev_div = document.createElement('div');
|
|
||||||
scheduler._rendered.push(ev_div);
|
|
||||||
var ev_class = scheduler.templates.event_class(ev.start_date, ev.end_date, ev);
|
|
||||||
ev_div.className = 'dhx_wa_ev_body' + (ev_class ? (' ' + ev_class) : '');
|
|
||||||
if (ev._text_style)
|
|
||||||
ev_div.style.cssText = ev._text_style;
|
|
||||||
if (ev.color)
|
|
||||||
ev_div.style.background = ev.color;
|
|
||||||
if (ev.textColor)
|
|
||||||
ev_div.style.color = ev.textColor;
|
|
||||||
if (scheduler._select_id && ev.id == scheduler._select_id && !(!scheduler.config.week_agenda_select && scheduler.config.week_agenda_select !== undefined)) {
|
|
||||||
ev_div.className += " dhx_cal_event_selected";
|
|
||||||
scheduler._wa._selected_divs.push(ev_div);
|
|
||||||
}
|
|
||||||
var position = "";
|
|
||||||
if (!ev._timed) {
|
|
||||||
position = "middle";
|
|
||||||
if (ev.start_date.valueOf() >= tstart.valueOf() && ev.start_date.valueOf() <= tend.valueOf())
|
|
||||||
position = "start";
|
|
||||||
if (ev.end_date.valueOf() >= tstart.valueOf() && ev.end_date.valueOf() <= tend.valueOf())
|
|
||||||
position = "end";
|
|
||||||
}
|
|
||||||
ev_div.innerHTML = scheduler.templates.week_agenda_event_text(ev.start_date, ev.end_date, ev, tstart, position);
|
|
||||||
ev_div.setAttribute('event_id', ev.id);
|
|
||||||
events_div.appendChild(ev_div);
|
|
||||||
}
|
|
||||||
tstart = scheduler.date.add(tstart, 1, "day");
|
|
||||||
tend = scheduler.date.add(tend, 1, "day");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.week_agenda_view = function(mode) {
|
|
||||||
scheduler._min_date = scheduler.date.week_start(scheduler._date);
|
|
||||||
scheduler._max_date = scheduler.date.add(scheduler._min_date, 1, "week");
|
|
||||||
scheduler.set_sizes();
|
|
||||||
if (mode) { // mode enabled
|
|
||||||
scheduler._table_view = scheduler._allow_dnd = true;
|
|
||||||
|
|
||||||
// hiding default top border from dhx_cal_data
|
|
||||||
scheduler._wa._prev_data_border = scheduler._els['dhx_cal_data'][0].style.borderTop;
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.borderTop = 0;
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.overflowY = 'hidden';
|
|
||||||
|
|
||||||
// cleaning dhx_cal_date from the previous date
|
|
||||||
scheduler._els['dhx_cal_date'][0].innerHTML = "";
|
|
||||||
|
|
||||||
// 1 to make navline to be over data
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.top = (parseInt(scheduler._els['dhx_cal_data'][0].style.top) - scheduler.xy.bar_height - 1) + 'px';
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.height = (parseInt(scheduler._els['dhx_cal_data'][0].style.height) + scheduler.xy.bar_height + 1) + 'px';
|
|
||||||
|
|
||||||
scheduler._els['dhx_cal_header'][0].style.display = 'none';
|
|
||||||
fillWeekAgendaTab();
|
|
||||||
} else { // leaving week_agenda mode
|
|
||||||
scheduler._table_view = scheduler._allow_dnd = false;
|
|
||||||
|
|
||||||
// restoring default top border to dhx_cal_data
|
|
||||||
if (scheduler._wa._prev_data_border)
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.borderTop = scheduler._wa._prev_data_border;
|
|
||||||
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.overflowY = 'auto';
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.top = (parseInt(scheduler._els['dhx_cal_data'][0].style.top) + scheduler.xy.bar_height) + 'px';
|
|
||||||
scheduler._els['dhx_cal_data'][0].style.height = (parseInt(scheduler._els['dhx_cal_data'][0].style.height) - scheduler.xy.bar_height) + 'px';
|
|
||||||
scheduler._els['dhx_cal_header'][0].style.display = 'block';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler.mouse_week_agenda = function(pos) {
|
|
||||||
var native_event = pos.ev;
|
|
||||||
var src = native_event.srcElement || native_event.target;
|
|
||||||
while (src.parentNode) {
|
|
||||||
if (src._date)
|
|
||||||
var date = src._date;
|
|
||||||
src = src.parentNode;
|
|
||||||
}
|
|
||||||
if (!date)
|
|
||||||
return pos;
|
|
||||||
pos.x = 0;
|
|
||||||
var diff = date.valueOf() - scheduler._min_date.valueOf();
|
|
||||||
pos.y = Math.ceil(( diff / (1000 * 60) ) / this.config.time_step);
|
|
||||||
if (this._drag_mode == 'move') {
|
|
||||||
this._drag_event._dhx_changed = true;
|
|
||||||
this._select_id = this._drag_id;
|
|
||||||
for (var i = 0; i < scheduler._rendered.length; i++) {
|
|
||||||
if (scheduler._drag_id == this._rendered[i].getAttribute('event_id'))
|
|
||||||
var event_div = this._rendered[i];
|
|
||||||
}
|
|
||||||
if (!scheduler._wa._dnd) {
|
|
||||||
var div = event_div.cloneNode(true);
|
|
||||||
this._wa._dnd = div;
|
|
||||||
div.className = event_div.className;
|
|
||||||
div.id = 'dhx_wa_dnd';
|
|
||||||
div.className += ' dhx_wa_dnd';
|
|
||||||
document.body.appendChild(div);
|
|
||||||
}
|
|
||||||
var dnd_div = document.getElementById('dhx_wa_dnd');
|
|
||||||
dnd_div.style.top = ((native_event.pageY || native_event.clientY) + 20) + "px";
|
|
||||||
dnd_div.style.left = ((native_event.pageX || native_event.clientX) + 20) + "px";
|
|
||||||
}
|
|
||||||
return pos;
|
|
||||||
};
|
|
||||||
scheduler.attachEvent('onBeforeEventChanged', function(event_object, native_event, is_new) {
|
|
||||||
if (this._mode == 'week_agenda') {
|
|
||||||
if (this._drag_mode == 'move') {
|
|
||||||
var dnd = document.getElementById('dhx_wa_dnd');
|
|
||||||
dnd.parentNode.removeChild(dnd);
|
|
||||||
scheduler._wa._dnd = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.attachEvent("onEventSave", function(id, data, is_new_event) {
|
|
||||||
if (is_new_event && this._mode == 'week_agenda')
|
|
||||||
this._select_id = id;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler._wa._selected_divs = [];
|
|
||||||
|
|
||||||
scheduler.attachEvent("onClick", function(event_id, native_event_object) {
|
|
||||||
if (this._mode == 'week_agenda' && !(!scheduler.config.week_agenda_select && scheduler.config.week_agenda_select !== undefined)) {
|
|
||||||
if (scheduler._wa._selected_divs) {
|
|
||||||
for (var i = 0; i < this._wa._selected_divs.length; i++) {
|
|
||||||
var div = this._wa._selected_divs[i];
|
|
||||||
div.className = div.className.replace(/ dhx_cal_event_selected/, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.for_rendered(event_id, function(event_div) {
|
|
||||||
event_div.className += " dhx_cal_event_selected";
|
|
||||||
scheduler._wa._selected_divs.push(event_div);
|
|
||||||
});
|
|
||||||
scheduler.select(event_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,276 +0,0 @@
|
||||||
/*
|
|
||||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
|
||||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
|
||||||
*/
|
|
||||||
scheduler.config.year_x = 4;
|
|
||||||
scheduler.config.year_y = 3;
|
|
||||||
scheduler.config.year_mode_name = "year";
|
|
||||||
scheduler.xy.year_top = 0;
|
|
||||||
|
|
||||||
scheduler.templates.year_date = function(date) {
|
|
||||||
return scheduler.date.date_to_str(scheduler.locale.labels.year_tab + " %Y")(date);
|
|
||||||
};
|
|
||||||
scheduler.templates.year_month = scheduler.date.date_to_str("%F");
|
|
||||||
scheduler.templates.year_scale_date = scheduler.date.date_to_str("%D");
|
|
||||||
scheduler.templates.year_tooltip = function(s, e, ev) {
|
|
||||||
return ev.text
|
|
||||||
};
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var is_year_mode = function() {
|
|
||||||
return scheduler._mode == scheduler.config.year_mode_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.dblclick_dhx_month_head = function(e) {
|
|
||||||
if (is_year_mode()) {
|
|
||||||
var t = (e.target || e.srcElement);
|
|
||||||
if (t.parentNode.className.indexOf("dhx_before") != -1 || t.parentNode.className.indexOf("dhx_after") != -1) return false;
|
|
||||||
var start = this.templates.xml_date(t.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.getAttribute("date"));
|
|
||||||
start.setDate(parseInt(t.innerHTML, 10));
|
|
||||||
var end = this.date.add(start, 1, "day")
|
|
||||||
if (!this.config.readonly && this.config.dblclick_create)
|
|
||||||
this.addEventNow(start.valueOf(), end.valueOf(), e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var chid = scheduler.changeEventId;
|
|
||||||
scheduler.changeEventId = function() {
|
|
||||||
chid.apply(this, arguments);
|
|
||||||
if (is_year_mode())
|
|
||||||
this.year_view(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var old = scheduler.render_data;
|
|
||||||
var to_attr = scheduler.date.date_to_str("%Y/%m/%d");
|
|
||||||
var from_attr = scheduler.date.str_to_date("%Y/%m/%d");
|
|
||||||
scheduler.render_data = function(evs) {
|
|
||||||
if (!is_year_mode()) return old.apply(this, arguments);
|
|
||||||
for (var i = 0; i < evs.length; i++)
|
|
||||||
this._year_render_event(evs[i]);
|
|
||||||
};
|
|
||||||
|
|
||||||
var clear = scheduler.clear_view;
|
|
||||||
scheduler.clear_view = function() {
|
|
||||||
if (!is_year_mode()) return clear.apply(this, arguments);
|
|
||||||
for (var date in marked) {
|
|
||||||
if (marked.hasOwnProperty(date)) {
|
|
||||||
var div = marked[date];
|
|
||||||
div.className = "dhx_month_head";
|
|
||||||
div.setAttribute("date", "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
marked = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.hideToolTip = function() {
|
|
||||||
if (this._tooltip) {
|
|
||||||
this._tooltip.style.display = "none";
|
|
||||||
this._tooltip.date = new Date(9999, 1, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.showToolTip = function(date, pos, e, src) {
|
|
||||||
if (this._tooltip) {
|
|
||||||
if (this._tooltip.date.valueOf() == date.valueOf()) return;
|
|
||||||
this._tooltip.innerHTML = "";
|
|
||||||
} else {
|
|
||||||
var t = this._tooltip = document.createElement("DIV");
|
|
||||||
t.className = "dhx_tooltip";
|
|
||||||
document.body.appendChild(t);
|
|
||||||
t.onclick = scheduler._click.dhx_cal_data;
|
|
||||||
|
|
||||||
}
|
|
||||||
var evs = this.getEvents(date, this.date.add(date, 1, "day"));
|
|
||||||
var html = "";
|
|
||||||
|
|
||||||
for (var i = 0; i < evs.length; i++) {
|
|
||||||
var ev = evs[i];
|
|
||||||
var bg_color = (ev.color ? ("background:" + ev.color + ";") : "");
|
|
||||||
var color = (ev.textColor ? ("color:" + ev.textColor + ";") : "");
|
|
||||||
|
|
||||||
html += "<div class='dhx_tooltip_line' style='" + bg_color + "" + color + "' event_id='" + evs[i].id + "'>";
|
|
||||||
html += "<div class='dhx_tooltip_date' style='" + bg_color + "" + color + "'>" + (evs[i]._timed ? this.templates.event_date(evs[i].start_date) : "") + "</div>";
|
|
||||||
html += "<div class='dhx_event_icon icon_details'> </div>";
|
|
||||||
html += this.templates.year_tooltip(evs[i].start_date, evs[i].end_date, evs[i]) + "</div>";
|
|
||||||
}
|
|
||||||
|
|
||||||
this._tooltip.style.display = "";
|
|
||||||
this._tooltip.style.top = "0px";
|
|
||||||
|
|
||||||
|
|
||||||
if (document.body.offsetWidth - pos.left - this._tooltip.offsetWidth < 0)
|
|
||||||
this._tooltip.style.left = pos.left - this._tooltip.offsetWidth + "px";
|
|
||||||
else
|
|
||||||
this._tooltip.style.left = pos.left + src.offsetWidth + "px";
|
|
||||||
|
|
||||||
this._tooltip.date = date;
|
|
||||||
this._tooltip.innerHTML = html;
|
|
||||||
|
|
||||||
if (document.body.offsetHeight - pos.top - this._tooltip.offsetHeight < 0)
|
|
||||||
this._tooltip.style.top = pos.top - this._tooltip.offsetHeight + src.offsetHeight + "px";
|
|
||||||
else
|
|
||||||
this._tooltip.style.top = pos.top + "px";
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler._init_year_tooltip = function() {
|
|
||||||
dhtmlxEvent(scheduler._els["dhx_cal_data"][0], "mouseover", function(e) {
|
|
||||||
if (!is_year_mode()) return;
|
|
||||||
|
|
||||||
var e = e || event;
|
|
||||||
var src = e.target || e.srcElement;
|
|
||||||
if (src.tagName.toLowerCase() == 'a') // fix for active links extension (it adds links to the date in the cell)
|
|
||||||
src = src.parentNode;
|
|
||||||
if ((src.className || "").indexOf("dhx_year_event") != -1)
|
|
||||||
scheduler.showToolTip(from_attr(src.getAttribute("date")), getOffset(src), e, src);
|
|
||||||
else
|
|
||||||
scheduler.hideToolTip();
|
|
||||||
});
|
|
||||||
this._init_year_tooltip = function() {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.attachEvent("onSchedulerResize", function() {
|
|
||||||
if (is_year_mode()) {
|
|
||||||
this.year_view(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
scheduler._get_year_cell = function(d) {
|
|
||||||
//there can be more than 1 year in view
|
|
||||||
//year can start not from January
|
|
||||||
var m = d.getMonth() + 12 * (d.getFullYear() - this._min_date.getFullYear()) - this.week_starts._month;
|
|
||||||
var t = this._els["dhx_cal_data"][0].childNodes[m];
|
|
||||||
var d = this.week_starts[m] + d.getDate() - 1;
|
|
||||||
|
|
||||||
|
|
||||||
return t.childNodes[2].firstChild.rows[Math.floor(d / 7)].cells[d % 7].firstChild;
|
|
||||||
};
|
|
||||||
|
|
||||||
var marked = {};
|
|
||||||
scheduler._mark_year_date = function(d, ev) {
|
|
||||||
var date = to_attr(d);
|
|
||||||
var c = this._get_year_cell(d);
|
|
||||||
var ev_class = this.templates.event_class(ev.start_date, ev.end_date, ev);
|
|
||||||
if (!marked[date]) {
|
|
||||||
c.className = "dhx_month_head dhx_year_event";
|
|
||||||
c.setAttribute("date", date);
|
|
||||||
marked[date] = c;
|
|
||||||
}
|
|
||||||
c.className += (ev_class) ? (" "+ev_class) : "";
|
|
||||||
};
|
|
||||||
scheduler._unmark_year_date = function(d) {
|
|
||||||
this._get_year_cell(d).className = "dhx_month_head";
|
|
||||||
};
|
|
||||||
scheduler._year_render_event = function(ev) {
|
|
||||||
var d = ev.start_date;
|
|
||||||
if (d.valueOf() < this._min_date.valueOf())
|
|
||||||
d = this._min_date;
|
|
||||||
else d = this.date.date_part(new Date(d));
|
|
||||||
|
|
||||||
while (d < ev.end_date) {
|
|
||||||
this._mark_year_date(d, ev);
|
|
||||||
d = this.date.add(d, 1, "day");
|
|
||||||
if (d.valueOf() >= this._max_date.valueOf())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scheduler.year_view = function(mode) {
|
|
||||||
if (mode) {
|
|
||||||
var temp = scheduler.xy.scale_height;
|
|
||||||
scheduler.xy.scale_height = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler._els["dhx_cal_header"][0].style.display = mode ? "none" : "";
|
|
||||||
scheduler.set_sizes();
|
|
||||||
|
|
||||||
if (mode)
|
|
||||||
scheduler.xy.scale_height = temp;
|
|
||||||
|
|
||||||
|
|
||||||
scheduler._table_view = mode;
|
|
||||||
if (this._load_mode && this._load()) return;
|
|
||||||
|
|
||||||
if (mode) {
|
|
||||||
scheduler._init_year_tooltip();
|
|
||||||
scheduler._reset_year_scale();
|
|
||||||
if (scheduler._load_mode && scheduler._load()) return scheduler._render_wait = true;
|
|
||||||
scheduler.render_view_data();
|
|
||||||
} else {
|
|
||||||
scheduler.hideToolTip();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scheduler._reset_year_scale = function() {
|
|
||||||
this._cols = [];
|
|
||||||
this._colsS = {};
|
|
||||||
var week_starts = []; //start day of first week in each month
|
|
||||||
var b = this._els["dhx_cal_data"][0];
|
|
||||||
|
|
||||||
var c = this.config;
|
|
||||||
b.scrollTop = 0; //fix flickering in FF
|
|
||||||
b.innerHTML = "";
|
|
||||||
|
|
||||||
var dx = Math.floor(parseInt(b.style.width) / c.year_x);
|
|
||||||
var dy = Math.floor((parseInt(b.style.height) - scheduler.xy.year_top) / c.year_y);
|
|
||||||
if (dy < 190) {
|
|
||||||
dy = 190;
|
|
||||||
dx = Math.floor((parseInt(b.style.width) - scheduler.xy.scroll_width) / c.year_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
var summ = dx - 11;
|
|
||||||
var left = 0;
|
|
||||||
var week_template = document.createElement("div");
|
|
||||||
var dummy_date = this.date.week_start(new Date());
|
|
||||||
for (var i = 0; i < 7; i++) {
|
|
||||||
this._cols[i] = Math.floor(summ / (7 - i));
|
|
||||||
this._render_x_header(i, left, dummy_date, week_template);
|
|
||||||
dummy_date = this.date.add(dummy_date, 1, "day");
|
|
||||||
summ -= this._cols[i];
|
|
||||||
left += this._cols[i];
|
|
||||||
}
|
|
||||||
week_template.lastChild.className += " dhx_scale_bar_last";
|
|
||||||
|
|
||||||
var sd = this.date[this._mode + "_start"](this.date.copy(this._date));
|
|
||||||
var ssd = sd;
|
|
||||||
|
|
||||||
for (var i = 0; i < c.year_y; i++)
|
|
||||||
for (var j = 0; j < c.year_x; j++) {
|
|
||||||
var d = document.createElement("DIV");
|
|
||||||
d.style.cssText = "position:absolute;";
|
|
||||||
d.setAttribute("date", this.templates.xml_format(sd));
|
|
||||||
d.innerHTML = "<div class='dhx_year_month'></div><div class='dhx_year_week'>" + week_template.innerHTML + "</div><div class='dhx_year_body'></div>";
|
|
||||||
d.childNodes[0].innerHTML = this.templates.year_month(sd);
|
|
||||||
|
|
||||||
var dd = this.date.week_start(sd);
|
|
||||||
var ed = this._reset_month_scale(d.childNodes[2], sd, dd);
|
|
||||||
|
|
||||||
var r = d.childNodes[2].firstChild.rows;
|
|
||||||
for (var k=r.length; k<6; k++) {
|
|
||||||
r[0].parentNode.appendChild(r[0].cloneNode(true));
|
|
||||||
for (var ri=0; ri < r[k].childNodes.length; ri++) {
|
|
||||||
r[k].childNodes[ri].className = "dhx_after";
|
|
||||||
r[k].childNodes[ri].firstChild.innerHTML = scheduler.templates.month_day(ed);
|
|
||||||
ed = scheduler.date.add(ed,1,"day");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.appendChild(d);
|
|
||||||
|
|
||||||
d.childNodes[1].style.height = d.childNodes[1].childNodes[0].offsetHeight + "px"; // dhx_year_week should have height property so that day dates would get correct position. dhx_year_week height = height of it's child (with the day name)
|
|
||||||
var dt = Math.round((dy - 190) / 2);
|
|
||||||
d.style.marginTop = dt + "px";
|
|
||||||
this.set_xy(d, dx - 10, dy - dt - 10, dx * j + 5, dy * i + 5 + scheduler.xy.year_top);
|
|
||||||
|
|
||||||
week_starts[i * c.year_x + j] = (sd.getDay() - (this.config.start_on_monday ? 1 : 0) + 7) % 7;
|
|
||||||
sd = this.date.add(sd, 1, "month");
|
|
||||||
|
|
||||||
}
|
|
||||||
this._els["dhx_cal_date"][0].innerHTML = this.templates[this._mode + "_date"](ssd, sd, this._mode);
|
|
||||||
this.week_starts = week_starts;
|
|
||||||
week_starts._month = ssd.getMonth();
|
|
||||||
this._min_date = ssd;
|
|
||||||
this._max_date = sd;
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,48 +0,0 @@
|
||||||
3.5
|
|
||||||
Ability to show multiple scheduler's per page (PRO version only)
|
|
||||||
Supports loading JSON directly from Connectors
|
|
||||||
Custom events rendering
|
|
||||||
Timeline view improved (support for drag, resize, event height control)
|
|
||||||
New 'dhx_terrace' skin
|
|
||||||
New options for blocking dates
|
|
||||||
Marking time intervals
|
|
||||||
Highlighting time intervals
|
|
||||||
New API methods: updateView, showEvent, getRenderedEvent, getActionData
|
|
||||||
JSMessage included
|
|
||||||
Grid view
|
|
||||||
New configuration options
|
|
||||||
Simplified access to lightbox section objects
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3.0
|
|
||||||
Version of scheduler for touch phones
|
|
||||||
WeekAgenda view
|
|
||||||
Netbook friendly lightbox form
|
|
||||||
Cascade event display
|
|
||||||
Simple way to define a color for event
|
|
||||||
Drag and drop of the details form
|
|
||||||
Custom buttons for the details form
|
|
||||||
Current time marker in day and week view
|
|
||||||
Multiline header for timeline view
|
|
||||||
Configurable work-time bounds
|
|
||||||
API to access lightbox values
|
|
||||||
|
|
||||||
build 120111:
|
|
||||||
- updated dhtmlxscheduker_mobile.js
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2.3
|
|
||||||
Map view was added
|
|
||||||
Cell mode for Timeline view was added
|
|
||||||
Tree mode for Timeline view was added
|
|
||||||
Tooltips for all views were added
|
|
||||||
Abbility to create new events by double click or by drag-and-drop in Timeline mode
|
|
||||||
Abbility to move events by drop-and-drag in Timeline mode
|
|
||||||
Abbility to create new events by external drag and drop
|
|
||||||
Multiselect section for details form
|
|
||||||
Checkbox, combo, radio - sections for details form
|
|
||||||
Api of mini-calendar extension extended
|
|
||||||
Custom form implementation simplified
|
|
||||||
|
|
|
@ -0,0 +1,608 @@
|
||||||
|
/*!
|
||||||
|
* FullCalendar v1.6.4 Stylesheet
|
||||||
|
* Docs & License: http://arshaw.com/fullcalendar/
|
||||||
|
* (c) 2013 Adam Shaw
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
.fc {
|
||||||
|
direction: ltr;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html .fc,
|
||||||
|
.fc table {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc td,
|
||||||
|
.fc th {
|
||||||
|
padding: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Header
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-header td {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-left {
|
||||||
|
width: 25%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-right {
|
||||||
|
width: 25%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-title {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-title h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-header-space {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-button {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* buttons edges butting together */
|
||||||
|
|
||||||
|
.fc-header .fc-button {
|
||||||
|
margin-right: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-corner-right, /* non-theme */
|
||||||
|
.fc-header .ui-corner-right { /* theme */
|
||||||
|
margin-right: 0; /* back to normal */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* button layering (for border precedence) */
|
||||||
|
|
||||||
|
.fc-header .fc-state-hover,
|
||||||
|
.fc-header .ui-state-hover {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-state-down {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header .fc-state-active,
|
||||||
|
.fc-header .ui-state-active {
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Content
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-content {
|
||||||
|
clear: both;
|
||||||
|
zoom: 1; /* for IE7, gives accurate coordinates for [un]freezeContentHeight */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-view {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Cell Styles
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-widget-header, /* <th>, usually */
|
||||||
|
.fc-widget-content { /* <td>, usually */
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-highlight { /* <td> today cell */ /* TODO: add .fc-today to <th> */
|
||||||
|
background: #fcf8e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-cell-overlay { /* semi-transparent rectangle while dragging */
|
||||||
|
background: #bce8f1;
|
||||||
|
opacity: .3;
|
||||||
|
filter: alpha(opacity=30); /* for IE */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Buttons
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-button {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 .6em;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 1.9em;
|
||||||
|
line-height: 1.9em;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-default { /* non-theme */
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-default.fc-corner-left { /* non-theme */
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-default.fc-corner-right { /* non-theme */
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Our default prev/next buttons use HTML entities like ‹ › « »
|
||||||
|
and we'll try to make them look good cross-browser.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.fc-text-arrow {
|
||||||
|
margin: 0 .1em;
|
||||||
|
font-size: 2em;
|
||||||
|
font-family: "Courier New", Courier, monospace;
|
||||||
|
vertical-align: baseline; /* for IE7 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-button-prev .fc-text-arrow,
|
||||||
|
.fc-button-next .fc-text-arrow { /* for ‹ › */
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* icon (for jquery ui) */
|
||||||
|
|
||||||
|
.fc-button .fc-icon-wrap {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-button .ui-icon {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
margin-top: -50%;
|
||||||
|
*margin-top: 0;
|
||||||
|
*top: -50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
button states
|
||||||
|
borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.fc-state-default {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
|
||||||
|
background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
|
||||||
|
background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
|
||||||
|
background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
color: #333;
|
||||||
|
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-hover,
|
||||||
|
.fc-state-down,
|
||||||
|
.fc-state-active,
|
||||||
|
.fc-state-disabled {
|
||||||
|
color: #333333;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-hover {
|
||||||
|
color: #333333;
|
||||||
|
text-decoration: none;
|
||||||
|
background-position: 0 -15px;
|
||||||
|
-webkit-transition: background-position 0.1s linear;
|
||||||
|
-moz-transition: background-position 0.1s linear;
|
||||||
|
-o-transition: background-position 0.1s linear;
|
||||||
|
transition: background-position 0.1s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-down,
|
||||||
|
.fc-state-active {
|
||||||
|
background-color: #cccccc;
|
||||||
|
background-image: none;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-state-disabled {
|
||||||
|
cursor: default;
|
||||||
|
background-image: none;
|
||||||
|
opacity: 0.65;
|
||||||
|
filter: alpha(opacity=65);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Global Event Styles
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event-container > * {
|
||||||
|
z-index: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-container > .ui-draggable-dragging,
|
||||||
|
.fc-event-container > .ui-resizable-resizing {
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event {
|
||||||
|
border: 1px solid #3a87ad; /* default BORDER color */
|
||||||
|
background-color: #3a87ad; /* default BACKGROUND color */
|
||||||
|
color: #fff; /* default TEXT color */
|
||||||
|
font-size: .85em;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.fc-event {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.fc-event,
|
||||||
|
.fc-event-draggable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-rtl .fc-event {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-inner {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-time,
|
||||||
|
.fc-event-title {
|
||||||
|
padding: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .ui-resizable-handle {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 99999;
|
||||||
|
overflow: hidden; /* hacky spaces (IE6/7) */
|
||||||
|
font-size: 300%; /* */
|
||||||
|
line-height: 50%; /* */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Horizontal Events
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event-hori {
|
||||||
|
border-width: 1px 0;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-ltr .fc-event-hori.fc-event-start,
|
||||||
|
.fc-rtl .fc-event-hori.fc-event-end {
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-ltr .fc-event-hori.fc-event-end,
|
||||||
|
.fc-rtl .fc-event-hori.fc-event-start {
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resizable */
|
||||||
|
|
||||||
|
.fc-event-hori .ui-resizable-e {
|
||||||
|
top: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||||
|
right: -3px !important;
|
||||||
|
width: 7px !important;
|
||||||
|
height: 100% !important;
|
||||||
|
cursor: e-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-hori .ui-resizable-w {
|
||||||
|
top: 0 !important;
|
||||||
|
left: -3px !important;
|
||||||
|
width: 7px !important;
|
||||||
|
height: 100% !important;
|
||||||
|
cursor: w-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-hori .ui-resizable-handle {
|
||||||
|
_padding-bottom: 14px; /* IE6 had 0 height */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Reusable Separate-border Table
|
||||||
|
------------------------------------------------------------*/
|
||||||
|
|
||||||
|
table.fc-border-separate {
|
||||||
|
border-collapse: separate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate th,
|
||||||
|
.fc-border-separate td {
|
||||||
|
border-width: 1px 0 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate th.fc-last,
|
||||||
|
.fc-border-separate td.fc-last {
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate tr.fc-last th,
|
||||||
|
.fc-border-separate tr.fc-last td {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-border-separate tbody tr.fc-first td,
|
||||||
|
.fc-border-separate tbody tr.fc-first th {
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Month View, Basic Week View, Basic Day View
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-grid th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-week-number {
|
||||||
|
width: 22px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-week-number div {
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-grid .fc-day-number {
|
||||||
|
float: right;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-grid .fc-other-month .fc-day-number {
|
||||||
|
opacity: 0.3;
|
||||||
|
filter: alpha(opacity=30); /* for IE */
|
||||||
|
/* opacity with small font can sometimes look too faded
|
||||||
|
might want to set the 'color' property instead
|
||||||
|
making day-numbers bold also fixes the problem */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-grid .fc-day-content {
|
||||||
|
clear: both;
|
||||||
|
padding: 2px 2px 1px; /* distance between events and day edges */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* event styles */
|
||||||
|
|
||||||
|
.fc-grid .fc-event-time {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* right-to-left */
|
||||||
|
|
||||||
|
.fc-rtl .fc-grid .fc-day-number {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-rtl .fc-grid .fc-event-time {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Agenda Week View, Agenda Day View
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-agenda table {
|
||||||
|
border-collapse: separate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-days th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .fc-agenda-axis {
|
||||||
|
width: 50px;
|
||||||
|
padding: 0 4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .fc-week-number {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .fc-day-content {
|
||||||
|
padding: 2px 2px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make axis border take precedence */
|
||||||
|
|
||||||
|
.fc-agenda-days .fc-agenda-axis {
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-days .fc-col0 {
|
||||||
|
border-left-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all-day area */
|
||||||
|
|
||||||
|
.fc-agenda-allday th {
|
||||||
|
border-width: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-allday .fc-day-content {
|
||||||
|
min-height: 34px; /* TODO: doesnt work well in quirksmode */
|
||||||
|
_height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* divider (between all-day and slots) */
|
||||||
|
|
||||||
|
.fc-agenda-divider-inner {
|
||||||
|
height: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-widget-header .fc-agenda-divider-inner {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* slot rows */
|
||||||
|
|
||||||
|
.fc-agenda-slots th {
|
||||||
|
border-width: 1px 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots td {
|
||||||
|
border-width: 1px 0 0;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots td div {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots tr.fc-slot0 th,
|
||||||
|
.fc-agenda-slots tr.fc-slot0 td {
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots tr.fc-minor th,
|
||||||
|
.fc-agenda-slots tr.fc-minor td {
|
||||||
|
border-top-style: dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda-slots tr.fc-minor th.ui-widget-header {
|
||||||
|
*border-top-style: solid; /* doesn't work with background in IE6/7 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Vertical Events
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event-vert {
|
||||||
|
border-width: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert.fc-event-start {
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert.fc-event-end {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert .fc-event-time {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert .fc-event-inner {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #fff;
|
||||||
|
opacity: .25;
|
||||||
|
filter: alpha(opacity=25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */
|
||||||
|
.fc-select-helper .fc-event-bg {
|
||||||
|
display: none\9; /* for IE6/7/8. nested opacity filters while dragging don't work */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resizable */
|
||||||
|
|
||||||
|
.fc-event-vert .ui-resizable-s {
|
||||||
|
bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||||
|
width: 100% !important;
|
||||||
|
height: 8px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
line-height: 8px !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
font-family: monospace;
|
||||||
|
text-align: center;
|
||||||
|
cursor: s-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-agenda .ui-resizable-resizing { /* TODO: better selector */
|
||||||
|
_overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
/* Events
|
||||||
|
-----------------------------------------------------*/
|
||||||
|
|
||||||
|
.fc-event {
|
||||||
|
background: #fff !important;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for vertical events */
|
||||||
|
|
||||||
|
.fc-event-bg {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event .ui-resizable-handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*!
|
||||||
|
* FullCalendar v1.6.1 Google Calendar Plugin
|
||||||
|
* Docs & License: http://arshaw.com/fullcalendar/
|
||||||
|
* (c) 2013 Adam Shaw
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
|
||||||
|
var fc = $.fullCalendar;
|
||||||
|
var formatDate = fc.formatDate;
|
||||||
|
var parseISO8601 = fc.parseISO8601;
|
||||||
|
var addDays = fc.addDays;
|
||||||
|
var applyAll = fc.applyAll;
|
||||||
|
|
||||||
|
|
||||||
|
fc.sourceNormalizers.push(function(sourceOptions) {
|
||||||
|
if (sourceOptions.dataType == 'gcal' ||
|
||||||
|
sourceOptions.dataType === undefined &&
|
||||||
|
(sourceOptions.url || '').match(/^(http|https):\/\/www.google.com\/calendar\/feeds\//)) {
|
||||||
|
sourceOptions.dataType = 'gcal';
|
||||||
|
if (sourceOptions.editable === undefined) {
|
||||||
|
sourceOptions.editable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
fc.sourceFetchers.push(function(sourceOptions, start, end) {
|
||||||
|
if (sourceOptions.dataType == 'gcal') {
|
||||||
|
return transformOptions(sourceOptions, start, end);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function transformOptions(sourceOptions, start, end) {
|
||||||
|
|
||||||
|
var success = sourceOptions.success;
|
||||||
|
var data = $.extend({}, sourceOptions.data || {}, {
|
||||||
|
'start-min': formatDate(start, 'u'),
|
||||||
|
'start-max': formatDate(end, 'u'),
|
||||||
|
'singleevents': true,
|
||||||
|
'max-results': 9999
|
||||||
|
});
|
||||||
|
|
||||||
|
var ctz = sourceOptions.currentTimezone;
|
||||||
|
if (ctz) {
|
||||||
|
data.ctz = ctz = ctz.replace(' ', '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.extend({}, sourceOptions, {
|
||||||
|
url: sourceOptions.url.replace(/\/basic$/, '/full') + '?alt=json-in-script&callback=?',
|
||||||
|
dataType: 'jsonp',
|
||||||
|
data: data,
|
||||||
|
startParam: false,
|
||||||
|
endParam: false,
|
||||||
|
success: function(data) {
|
||||||
|
var events = [];
|
||||||
|
if (data.feed.entry) {
|
||||||
|
$.each(data.feed.entry, function(i, entry) {
|
||||||
|
var startStr = entry['gd$when'][0]['startTime'];
|
||||||
|
var start = parseISO8601(startStr, true);
|
||||||
|
var end = parseISO8601(entry['gd$when'][0]['endTime'], true);
|
||||||
|
var allDay = startStr.indexOf('T') == -1;
|
||||||
|
var url;
|
||||||
|
$.each(entry.link, function(i, link) {
|
||||||
|
if (link.type == 'text/html') {
|
||||||
|
url = link.href;
|
||||||
|
if (ctz) {
|
||||||
|
url += (url.indexOf('?') == -1 ? '?' : '&') + 'ctz=' + ctz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (allDay) {
|
||||||
|
addDays(end, -1); // make inclusive
|
||||||
|
}
|
||||||
|
events.push({
|
||||||
|
id: entry['gCal$uid']['value'],
|
||||||
|
title: entry['title']['$t'],
|
||||||
|
url: url,
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
allDay: allDay,
|
||||||
|
location: entry['gd$where'][0]['valueString'],
|
||||||
|
description: entry['content']['$t']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var args = [events].concat(Array.prototype.slice.call(arguments, 1));
|
||||||
|
var res = applyAll(success, this, args);
|
||||||
|
if ($.isArray(res)) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// legacy
|
||||||
|
fc.gcalFeed = function(url, sourceOptions) {
|
||||||
|
return $.extend({}, sourceOptions, { url: url, dataType: 'gcal' });
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
})(jQuery);
|
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright (c) 2013 Adam Shaw
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,4 @@
|
||||||
|
web_fullcalendar.css: web_fullcalendar.sass
|
||||||
|
sass --trace -t expanded web_fullcalendar.sass web_fullcalendar.css
|
||||||
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
@charset "utf-8";
|
|
||||||
.openerp .oe_view_manager_view_calendar {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.openerp .oe_calendar_sidebar {
|
|
||||||
width: 200px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
.openerp .oe_calendar {
|
|
||||||
background-color: white;
|
|
||||||
min-height: 600px;
|
|
||||||
border-right: 1px solid #eeeeee;
|
|
||||||
}
|
|
||||||
.openerp .oe_calendar .oe_calendar_filter {
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
.openerp .oe_calendar .dhx_cal_select_menu .dhx_menu_icon.icon_edit {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.openerp .oe_calendar .dhx_cal_navline, .openerp .oe_calendar .dhx_cal_header {
|
|
||||||
z-index: auto;
|
|
||||||
}
|
|
||||||
.openerp .oe_calendar.oe_cal_month .dhx_cal_data table tr td:last-child div.dhx_month_body {
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhx_cal_tab {
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhx_cal_tab.active {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhx_cal_today_button {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhx_cal_event .dhx_body {
|
|
||||||
width: auto !important;
|
|
||||||
height: 28px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dhx_scale_hour {
|
|
||||||
height: 42px !important;
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
@charset "utf-8"
|
|
||||||
|
|
||||||
.openerp
|
|
||||||
.oe_view_manager_view_calendar
|
|
||||||
position: relative
|
|
||||||
|
|
||||||
.openerp
|
|
||||||
.oe_calendar_sidebar
|
|
||||||
width: 200px
|
|
||||||
padding: 5px
|
|
||||||
|
|
||||||
.oe_calendar
|
|
||||||
background-color: white
|
|
||||||
min-height: 600px
|
|
||||||
border-right: 1px solid #eee
|
|
||||||
|
|
||||||
.oe_calendar_filter
|
|
||||||
padding: 0 10px
|
|
||||||
|
|
||||||
// Dhtmlx Scheduler css overrides
|
|
||||||
.dhx_cal_select_menu .dhx_menu_icon.icon_edit
|
|
||||||
display: none
|
|
||||||
.dhx_cal_navline, .dhx_cal_header
|
|
||||||
// dhtmlx sets the index to 3 (in glossy theme)
|
|
||||||
// I didn't found the reason yet but it overlaps the
|
|
||||||
// dropdown menus and I want to avoid a z-index war.
|
|
||||||
z-index: auto
|
|
||||||
|
|
||||||
&.oe_cal_month .dhx_cal_data
|
|
||||||
|
|
||||||
table tr td:last-child div.dhx_month_body
|
|
||||||
padding-right: 5px
|
|
||||||
|
|
||||||
// Hack for calender {{{
|
|
||||||
.dhx_cal_tab
|
|
||||||
height: 18px
|
|
||||||
.dhx_cal_tab.active
|
|
||||||
height: 20px
|
|
||||||
.dhx_cal_today_button
|
|
||||||
height: 20px
|
|
||||||
.dhx_cal_event .dhx_body
|
|
||||||
width: auto !important
|
|
||||||
height: 28px !important
|
|
||||||
.dhx_scale_hour
|
|
||||||
height: 42px !important
|
|
||||||
// End hack }}}
|
|
||||||
|
|
||||||
// au BufWritePost,FileWritePost *.sass :!sass --style expanded --line-numbers <afile> > "%:p:r.css"
|
|
||||||
// vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker:
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
@charset "utf-8";
|
||||||
|
.openerp .oe_view_manager_view_calendar {
|
||||||
|
position: relative; }
|
||||||
|
.openerp .oe_calendar_table {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 5px; }
|
||||||
|
|
||||||
|
.openerp .oe_searchview.oe_searchview_open_drawer .oe_searchview_drawer {
|
||||||
|
z-index: 10; }
|
||||||
|
|
||||||
|
.openerp td.oe_calendar_sidebar_container {
|
||||||
|
padding: 10px; }
|
||||||
|
|
||||||
|
img.attendee_head {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px; }
|
||||||
|
|
||||||
|
.openerp .oe_calendar_table .attendee_head {
|
||||||
|
float: right;
|
||||||
|
margin-left: 1px;
|
||||||
|
size: 18px !important; }
|
||||||
|
.openerp .oe_calendar_table .cal_avatar {
|
||||||
|
height: 24px;
|
||||||
|
width: 24px; }
|
||||||
|
.openerp .oe_calendar_table .cal_opacity {
|
||||||
|
opacity: 0.6; }
|
||||||
|
.openerp .oe_calendar_table .event_color_1 {
|
||||||
|
background-color: #a4bdfc;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_2 {
|
||||||
|
background-color: #7ae7bf;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_3 {
|
||||||
|
background-color: #dbadff;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_4 {
|
||||||
|
background-color: #ff887c;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_5 {
|
||||||
|
background-color: #fbd75b;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_6 {
|
||||||
|
background-color: #ffb878;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_7 {
|
||||||
|
background-color: #46d6db;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_8 {
|
||||||
|
background-color: #e1e1e1;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_9 {
|
||||||
|
background-color: #5484ed;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_10 {
|
||||||
|
background-color: #51b749;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .event_color_11 {
|
||||||
|
background-color: #dc2127;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_1 {
|
||||||
|
border-color: #ac725e;
|
||||||
|
background-color: #ac725e;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_2 {
|
||||||
|
border-color: #d06b64;
|
||||||
|
background-color: #d06b64;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_3 {
|
||||||
|
border-color: #f83a22;
|
||||||
|
background-color: #f83a22;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_4 {
|
||||||
|
border-color: #fa573c;
|
||||||
|
background-color: #fa573c;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_5 {
|
||||||
|
border-color: #ff7537;
|
||||||
|
background-color: #ff7537;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_6 {
|
||||||
|
border-color: #ffad46;
|
||||||
|
background-color: #ffad46;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_7 {
|
||||||
|
border-color: #42d692;
|
||||||
|
background-color: #42d692;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_8 {
|
||||||
|
border-color: #16a765;
|
||||||
|
background-color: #16a765;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_9 {
|
||||||
|
border-color: #7bd148;
|
||||||
|
background-color: #7bd148;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_10 {
|
||||||
|
border-color: #b3dc6c;
|
||||||
|
background-color: #b3dc6c;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_11 {
|
||||||
|
border-color: #fbe983;
|
||||||
|
background-color: #fbe983;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_12 {
|
||||||
|
border-color: #fad165;
|
||||||
|
background-color: #fad165;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_13 {
|
||||||
|
border-color: #92e1c0;
|
||||||
|
background-color: #92e1c0;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_14 {
|
||||||
|
border-color: #9fe1e7;
|
||||||
|
background-color: #9fe1e7;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_15 {
|
||||||
|
border-color: #9fc6e7;
|
||||||
|
background-color: #9fc6e7;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_16 {
|
||||||
|
border-color: #4986e7;
|
||||||
|
background-color: #4986e7;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_17 {
|
||||||
|
border-color: #9a9cff;
|
||||||
|
background-color: #9a9cff;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_18 {
|
||||||
|
border-color: #b99aff;
|
||||||
|
background-color: #b99aff;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_19 {
|
||||||
|
border-color: #c2c2c2;
|
||||||
|
background-color: #c2c2c2;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_20 {
|
||||||
|
border-color: #cabdbf;
|
||||||
|
background-color: #cabdbf;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_21 {
|
||||||
|
border-color: #cca6ac;
|
||||||
|
background-color: #cca6ac;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_22 {
|
||||||
|
border-color: #f691b2;
|
||||||
|
background-color: #f691b2;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_23 {
|
||||||
|
border-color: #cd74e6;
|
||||||
|
background-color: #cd74e6;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .calendar_color_24 {
|
||||||
|
border-color: #a47ae2;
|
||||||
|
background-color: #a47ae2;
|
||||||
|
color: #0d0d0d; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_1 {
|
||||||
|
border-bottom: 4px solid #a4bdfc; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_2 {
|
||||||
|
border-bottom: 4px solid #7ae7bf; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_3 {
|
||||||
|
border-bottom: 4px solid #dbadff; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_4 {
|
||||||
|
border-bottom: 4px solid #ff887c; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_5 {
|
||||||
|
border-bottom: 4px solid #fbd75b; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_6 {
|
||||||
|
border-bottom: 4px solid #ffb878; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_7 {
|
||||||
|
border-bottom: 4px solid #46d6db; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_8 {
|
||||||
|
border-bottom: 4px solid #e1e1e1; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_9 {
|
||||||
|
border-bottom: 4px solid #5484ed; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_10 {
|
||||||
|
border-bottom: 4px solid #51b749; }
|
||||||
|
.openerp .oe_calendar_table .underline_ecolor_11 {
|
||||||
|
border-bottom: 4px solid #dc2127; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_1 {
|
||||||
|
border-bottom: 4px solid #ac725e; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_2 {
|
||||||
|
border-bottom: 4px solid #d06b64; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_3 {
|
||||||
|
border-bottom: 4px solid #f83a22; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_4 {
|
||||||
|
border-bottom: 4px solid #fa573c; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_5 {
|
||||||
|
border-bottom: 4px solid #ff7537; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_6 {
|
||||||
|
border-bottom: 4px solid #ffad46; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_7 {
|
||||||
|
border-bottom: 4px solid #42d692; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_8 {
|
||||||
|
border-bottom: 4px solid #16a765; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_9 {
|
||||||
|
border-bottom: 4px solid #7bd148; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_10 {
|
||||||
|
border-bottom: 4px solid #b3dc6c; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_11 {
|
||||||
|
border-bottom: 4px solid #fbe983; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_12 {
|
||||||
|
border-bottom: 4px solid #fad165; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_13 {
|
||||||
|
border-bottom: 4px solid #92e1c0; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_14 {
|
||||||
|
border-bottom: 4px solid #9fe1e7; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_15 {
|
||||||
|
border-bottom: 4px solid #9fc6e7; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_16 {
|
||||||
|
border-bottom: 4px solid #4986e7; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_17 {
|
||||||
|
border-bottom: 4px solid #9a9cff; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_18 {
|
||||||
|
border-bottom: 4px solid #b99aff; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_19 {
|
||||||
|
border-bottom: 4px solid #c2c2c2; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_20 {
|
||||||
|
border-bottom: 4px solid #cabdbf; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_21 {
|
||||||
|
border-bottom: 4px solid #cca6ac; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_22 {
|
||||||
|
border-bottom: 4px solid #f691b2; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_23 {
|
||||||
|
border-bottom: 4px solid #cd74e6; }
|
||||||
|
.openerp .oe_calendar_table .underline_color_24 {
|
||||||
|
border-bottom: 4px solid #a47ae2; }
|
||||||
|
.openerp .oe_calendar_table .color_1 {
|
||||||
|
color: #ac725e; }
|
||||||
|
.openerp .oe_calendar_table .color_2 {
|
||||||
|
color: #d06b64; }
|
||||||
|
.openerp .oe_calendar_table .color_3 {
|
||||||
|
color: #f83a22; }
|
||||||
|
.openerp .oe_calendar_table .color_4 {
|
||||||
|
color: #fa573c; }
|
||||||
|
.openerp .oe_calendar_table .color_5 {
|
||||||
|
color: #ff7537; }
|
||||||
|
.openerp .oe_calendar_table .color_6 {
|
||||||
|
color: #ffad46; }
|
||||||
|
.openerp .oe_calendar_table .color_7 {
|
||||||
|
color: #42d692; }
|
||||||
|
.openerp .oe_calendar_table .color_8 {
|
||||||
|
color: #16a765; }
|
||||||
|
.openerp .oe_calendar_table .color_9 {
|
||||||
|
color: #7bd148; }
|
||||||
|
.openerp .oe_calendar_table .color_10 {
|
||||||
|
color: #b3dc6c; }
|
||||||
|
.openerp .oe_calendar_table .color_11 {
|
||||||
|
color: #fbe983; }
|
||||||
|
.openerp .oe_calendar_table .color_12 {
|
||||||
|
color: #fad165; }
|
||||||
|
.openerp .oe_calendar_table .color_13 {
|
||||||
|
color: #92e1c0; }
|
||||||
|
.openerp .oe_calendar_table .color_14 {
|
||||||
|
color: #9fe1e7; }
|
||||||
|
.openerp .oe_calendar_table .color_15 {
|
||||||
|
color: #9fc6e7; }
|
||||||
|
.openerp .oe_calendar_table .color_16 {
|
||||||
|
color: #4986e7; }
|
||||||
|
.openerp .oe_calendar_table .color_17 {
|
||||||
|
color: #9a9cff; }
|
||||||
|
.openerp .oe_calendar_table .color_18 {
|
||||||
|
color: #b99aff; }
|
||||||
|
.openerp .oe_calendar_table .color_19 {
|
||||||
|
color: #c2c2c2; }
|
||||||
|
.openerp .oe_calendar_table .color_20 {
|
||||||
|
color: #cabdbf; }
|
||||||
|
.openerp .oe_calendar_table .color_21 {
|
||||||
|
color: #cca6ac; }
|
||||||
|
.openerp .oe_calendar_table .color_22 {
|
||||||
|
color: #f691b2; }
|
||||||
|
.openerp .oe_calendar_table .color_23 {
|
||||||
|
color: #cd74e6; }
|
||||||
|
.openerp .oe_calendar_table .color_24 {
|
||||||
|
color: #a47ae2; }
|
||||||
|
.openerp .oe_calendar_table .oe_calendar_buttons_add_contact .add_contacts_link_btn {
|
||||||
|
margin-top: 10px; }
|