MDL-24316 ajax course edit now works with orphaned activities
[moodle.git] / lib / ajax / section_classes.js
1 /**
2  * library for ajaxcourse formats, the classes and related functions for
3  * sections and resources.
4  *
5  * This library requires a 'main' object created in calling document.
6  *
7  * Drag and drop notes:
8  *
9  *   Dropping an activity or resource on a section will always add the activity
10  *   or resource at the end of that section.
11  *
12  *   Dropping an activity or resource on another activity or resource will
13  *   always move the former just above the latter.
14  */
17 /**
18  * section_class
19  */
20 function section_class(id, group, config, isDraggable) {
21     this.init_section(id, group, config, isDraggable);
22 }
24 YAHOO.extend(section_class, YAHOO.util.DDProxy);
27 section_class.prototype.debug = false;
30 section_class.prototype.init_section = function(id, group, config, isDraggable) {
32     if (!id) {
33         return;
34     }
36     this.is = 'section';
37     this.sectionId = null; // Section number. This is NOT the section id from
38                             // the database.
40     if (!isDraggable) {
41         this.initTarget(id, group, config);
42         this.removeFromGroup('sections');
43     } else {
44         this.init(id, group, config);
45         this.handle = null;
46     }
48     this.createFrame();
49     this.isTarget = true;
51     this.resources = [];
52     this.numberDisplay = null; // Used to display the section number on the top left
53                                 // of the section. Not used in all course formats.
54     this.summary = null;
55     this.content_div = null;
56     this.hidden = false;
57     this.highlighted = false;
58     this.showOnly = false;
59     this.resources_ul = null;
60     this.process_section();
62     this.viewButton = null;
63     this.highlightButton = null;
64     this.showOnlyButton = null;
65     this.init_buttons();
67     if (isDraggable) {
68         this.add_handle();
69     }
70     if (this.debug) {
71         YAHOO.log("init_section "+id+" draggable="+isDraggable);
72     }
73     if (YAHOO.util.Dom.hasClass(this.getEl(),'hidden')) {
74         this.toggle_hide(null,null,true);
75     }
76 };
79 section_class.prototype.init_buttons = function() {
80     if (this.sectionId > main.portal.numsections) {
81         // no need to do anything in orphaned sections
82         return;
83     }
85     var commandContainer = YAHOO.util.Dom.getElementsByClassName('right',null,this.getEl())[0];
87     //clear all but show only button
88     var commandContainerCount = commandContainer.childNodes.length;
90     for (var i=(commandContainerCount-1); i>0; i--) {
91         commandContainer.removeChild(commandContainer.childNodes[i])
92     }
94     if (main.getString('courseformat', this.sectionId) != "weeks" && this.sectionId > 0) {
95         var highlightbutton = main.mk_button('div', main.portal.icons['marker'], main.getString('marker', this.sectionId));
96         YAHOO.util.Event.addListener(highlightbutton, 'click', this.mk_marker, this, true);
97         commandContainer.appendChild(highlightbutton);
98         this.highlightButton = highlightbutton;
99     }
100     if (this.sectionId > 0) {
101         var viewbutton = main.mk_button('div', main.portal.icons['hide'], main.getString('hidesection', this.sectionId),
102                 [['title', main.portal.strings['hide'] ]]);
103         YAHOO.util.Event.addListener(viewbutton, 'click', this.toggle_hide, this,true);
104         commandContainer.appendChild(viewbutton);
105         this.viewButton = viewbutton;
106     }
107 };
110 section_class.prototype.add_handle = function() {
111     var handleRef = main.mk_button('a', main.portal.icons['move_2d'], main.getString('movesection', this.sectionId),
112             [['title', main.portal.strings['move'] ], ['style','cursor:move']]);
114     YAHOO.util.Dom.generateId(handleRef, 'sectionHandle');
116     this.handle = handleRef;
118     this.getEl().childNodes[0].appendChild(handleRef);
119     this.setHandleElId(this.handle.id);
120 };
123 section_class.prototype.process_section = function() {
124     this.content_div = YAHOO.util.Dom.getElementsByClassName('content',null,this.getEl())[0];
126     if (YAHOO.util.Dom.hasClass(this.getEl(),'current')) {
127         this.highlighted = true;
128         main.marker = this;
129     }
131     // Create holder for display number for access later
133     this.numberDisplay = document.createElement('div');
134     this.numberDisplay.innerHTML = this.getEl().childNodes[0].innerHTML;
135     this.getEl().childNodes[0].innerHTML = '';
136     this.getEl().childNodes[0].appendChild(this.numberDisplay);
138     this.sectionId = this.id.replace(/section-/i, ''); // Okay, we will have to change this if we
139     // ever change the id attributes format
140     // for the sections.
141     if (this.debug) {
142         YAHOO.log("Creating section "+this.getEl().id+" in position "+this.sectionId);
143     }
145     // Find/edit resources
146     this.resources_ul = this.content_div.getElementsByTagName('ul')[0];
147     if (!this.resources_ul) {
148         this.resources_ul = document.createElement('ul');
149         this.resources_ul.className='section';
150         this.content_div.insertBefore(this.resources_ul, this.content_div.lastChild);
151     }
152     var resource_count = this.resources_ul.getElementsByTagName('li').length;
154     for (var i=0;i<resource_count;i++) {
155         var resource = this.resources_ul.getElementsByTagName('li')[i];
156         this.resources[this.resources.length] = new resource_class(resource.id, 'resources', null, this);
157     }
159     var sum = YAHOO.util.Dom.getElementsByClassName('summary', null, this.getEl());
160     if (sum[0]) {
161         this.summary = sum[0].firstChild.data || '';
162     } else {
163         // orphaned activities
164         this.summary = null;
165     }
166 };
169 section_class.prototype.startDrag = function(x, y) {
170     //operates in point mode
171     YAHOO.util.DDM.mode = YAHOO.util.DDM.POINT;
173     //remove from resources group temporarily
174     this.removeFromGroup('resources');
176     //reinitialize dd element
177     this.getDragEl().innerHTML = '';
179     var targets = YAHOO.util.DDM.getRelated(this, true);
181     if (this.debug) {
182         YAHOO.log(this.id + " startDrag, "+targets.length + " targets");
183     }
184 };
187 section_class.prototype.onDragDrop = function(e, id) {
188     // get the drag and drop object that was targeted
189     var target = YAHOO.util.DDM.getDDById(id);
191     if (this.debug) {
192         YAHOO.log("Section dropped on id="+id+" (I am "+this.getEl().id+") x="
193                 +YAHOO.util.Dom.getXY(this.getDragEl()));
194     }
195     this.move_to_section(target);
197     //add back to resources group
198     this.addToGroup('resources');
199 };
202 section_class.prototype.endDrag = function() {
203     //nessicary to defeat default action
205     //add back to resources group
206     this.addToGroup('resources');
207 };
210 section_class.prototype.move_to_section = function(target) {
211     var tempDiv = document.createElement('div');
212     var tempStore = null;
213     var sectionCount = main.sections.length;
214     var found = null;
216     //determine if original is above or below target and adjust loop
217     var oIndex = main.get_section_index(this);
218     var tIndex = main.get_section_index(target);
220     if (oIndex == -1) {
221         // source must exist
222         return;
223     }
224     if (tIndex == -1) {
225         // target must exist
226         return;
227     }
228     if (this.debug) {
229         YAHOO.log("original is at: "+oIndex+" target is at:"+tIndex+" of "+(sectionCount-1));
230     }
231     if (oIndex < tIndex) {
232         var loopCondition = 'i<sectionCount';
233         var loopStart = 1;
234         var loopInc = 'i++';
235         var loopmodifier = 'i - 1';
236         var targetOffset = 0;
237     } else {
238         var loopCondition = 'i > 0';
239         var loopStart = sectionCount - 1;
240         var loopInc = 'i--';
241         var loopmodifier = 'i + 1';
242         var targetOffset = 1;
243     }
245     //move on backend
246     main.connect('POST','class=section&field=move',null,'id='+this.sectionId+'&value=' + (target.sectionId - targetOffset));
248     //move on front end
249     for (var i=loopStart; eval(loopCondition); eval(loopInc)) {
251         if ((main.sections[i] == this) && !found) {
252             //encounter with original node
253             if (this.debug) {
254                 YAHOO.log("Found Original "+main.sections[i].getEl().id);
255             }
256             if (main.sections[i] == this) {
257                 found = true;
258             }
259         } else if (main.sections[i] == target) {
260             //encounter with target node
261             if (this.debug) {
262                 YAHOO.log("Found target "+main.sections[i].getEl().id);
263             }
264             main.sections[i].swap_with_section(main.sections[eval(loopmodifier)]);
265             main.sections[i].swap_dates(main.sections[eval(loopmodifier)]);
266             found = false;
267             break;
268         } else if (found) {
269             //encounter with nodes inbetween
270             main.sections[i].swap_with_section(main.sections[eval(loopmodifier)]);
271             main.sections[i].swap_dates(main.sections[eval(loopmodifier)]);
272         }
273     }
274 };
277 section_class.prototype.swap_with_section = function(sectionIn) {
278     var tmpStore = null;
280     var thisIndex = main.get_section_index(this);
281     var targetIndex = main.get_section_index(sectionIn);
282     if (thisIndex == -1) {
283         // source must exist
284         return;
285     }
286     if (targetIndex == -1) {
287         // target must exist
288         return;
289     }
291     main.sections[targetIndex] = this;
292     main.sections[thisIndex] = sectionIn;
294     this.changeId(targetIndex);
295     sectionIn.changeId(thisIndex);
297     if (this.debug) {
298         YAHOO.log("Swapping "+this.getEl().id+" with "+sectionIn.getEl().id);
299     }
300     // Swap the sections.
301     YAHOO.util.DDM.swapNode(this.getEl(), sectionIn.getEl());
303     // Sections contain forms to add new resources/activities. These forms
304     // have not been updated to reflect the new positions of the sections that
305     // we have swapped. Let's swap the two sections' forms around.
306     if (this.getEl().getElementsByTagName('form')[0].parentNode
307             && sectionIn.getEl().getElementsByTagName('form')[0].parentNode) {
309         YAHOO.util.DDM.swapNode(this.getEl().getElementsByTagName('form')[0].parentNode,
310                 sectionIn.getEl().getElementsByTagName('form')[0].parentNode);
311     } else {
312         YAHOO.log("Swapping sections: form not present in one or both sections", "warn");
313     }
314 };
317 section_class.prototype.toggle_hide = function(e,target,superficial) {
318     if (this.sectionId > main.portal.numsections) {
319         // no need to do anything in orphaned sections
320         return;
321     }
323     var strhide = main.portal.strings['hide'];
324     var strshow = main.portal.strings['show'];
325     if (this.hidden) {
326         YAHOO.util.Dom.removeClass(this.getEl(), 'hidden');
327         this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/show/i, 'hide');
328         this.viewButton.childNodes[0].alt = this.viewButton.childNodes[0].alt.replace(strshow, strhide);
329         this.viewButton.childNodes[0].title = this.viewButton.childNodes[0].title.replace(strshow, strhide); //IE hack.
330         this.viewButton.title = this.viewButton.title.replace(strshow, strhide);
331         this.hidden = false;
333         if (!superficial) {
334             main.connect('POST', 'class=section&field=visible', null, 'value=1&id='+this.sectionId);
335             for (var x=0; x<this.resources.length; x++) {
336                 this.resources[x].toggle_hide(null, null, true, this.resources[x].hiddenStored);
337                 this.resources[x].hiddenStored = null;
338             }
339         }
341     } else {
342         YAHOO.util.Dom.addClass(this.getEl(), 'hidden');
343         this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/hide/i, 'show');
344         this.viewButton.childNodes[0].alt = this.viewButton.childNodes[0].alt.replace(strhide, strshow);
345         this.viewButton.childNodes[0].title = this.viewButton.childNodes[0].title.replace(strhide, strshow); //IE hack.
346         this.viewButton.title = this.viewButton.title.replace(strhide, strshow);
347         this.hidden = true;
349         if (!superficial) {
350             main.connect('POST', 'class=section&field=visible', null, 'value=0&id='+this.sectionId);
351             for (var x=0; x<this.resources.length; x++) {
352                 this.resources[x].hiddenStored = this.resources[x].hidden;
353                 this.resources[x].toggle_hide(null, null, true, true);
354             }
355         }
356     }
357 };
360 section_class.prototype.toggle_highlight = function() {
361     if (this.highlighted) {
362         YAHOO.util.Dom.removeClass(this.getEl(), 'current');
363         this.highlighted = false;
364     } else {
365         YAHOO.util.Dom.addClass(this.getEl(), 'current');
366         this.highlighted = true;
367     }
368 };
371 section_class.prototype.mk_marker = function() {
372     if (main.marker != this) {
373         main.update_marker(this);
374     } else {
375         // If currently the marker
376         main.marker = null;
378         main.connect('POST', 'class=course&field=marker', null, 'value=0');
379         this.toggle_highlight();
380     }
381 };
384 section_class.prototype.changeId = function(newId) {
385     this.sectionId = newId;
386     this.numberDisplay.firstChild.data = newId;
388     //main.connectQueue_add('POST','class=section&field=all',null,'id='+newId+"&summary="+main.mk_safe_for_transport(this.summary)+"&sequence="+this.write_sequence_list(true)+'&visible='+(this.hidden?0:1))
390     if (main.marker == this) {
391         main.update_marker(this);
392     }
393 };
396 section_class.prototype.get_resource_index = function(el) {
397     for (var x=0; x<this.resources.length; x++) {
398         if (this.resources[x] == el) {
399             return x;
400         }
401     }
402     YAHOO.log("Could not find resource to remove "+el.getEl().id, "error");
403     return -1;
404 };
407 section_class.prototype.remove_resource = function(el) {
409     var resourceEl = el.getEl();
410     var parentEl = resourceEl.parentNode;
411     if (!parentEl) {
412         return false;
413     }
415     var resourceCount = this.resources.length;
417     if (resourceCount == 1) {
418         if (this.resources[0] == el) {
419             this.resources = new Array();
420         }
421     } else {
422         var found = false;
423         for (var i=0; i<resourceCount; i++) {
424             if (found) {
425                 this.resources[i - 1] = this.resources[i];
426                 if (i == resourceCount - 1) {
427                     this.resources = this.resources.slice(0, -1);
428                     resourceCount--;
429                 }
430                 this.resources[i - 1].update_index(i - 1);
431             } else if (this.resources[i] == el) {
432                 found = true;
433             }
434         }
435     }
436     // Remove any extra text nodes to keep DOM clean.
437     var kids = parentEl.childNodes;
439     for (var i=0; i<kids.length; i++) {
440         if (kids[i].nodeType == 3) {
441             YAHOO.log('Removed extra text node.');
442             parentEl.removeChild(kids[i]);
443         }
444     }
445     parentEl.removeChild(resourceEl);
447     this.write_sequence_list();
448     return true;
449 };
452 section_class.prototype.insert_resource = function(el, targetel) {
453     var resourcecount = this.resources.length;
454     var found = false;
455     var tempStore = nextStore = null;
457     //update in backend
458     var targetId = '';
459     if (targetel) {
460         targetId = targetel.id;
461     }
462     if (this.debug) {
463         YAHOO.log('id='+el.id+', beforeId='+targetId+', sectionId='+this.sectionId);
464     }
465     main.connect('POST', 'class=resource&field=move', null,
466             'id='+el.id+'&beforeId='+targetId+'&sectionId='+this.sectionId);
468     //if inserting into a hidden resource hide
469     if (this.hidden) {
470         el.hiddenStored = el.hidden;
471         el.toggle_hide(null, null, true, true);
472     } else {
473         if (el.hiddenStored != null) {
474             el.toggle_hide(null, null, true, el.hiddenStored);
475             el.hiddenStored = null;
476         }
477     }
478     //update model
479     if (!targetel) {
480         this.resources[this.resources.length] = el;
481     } else {
482         for (var i=0; i<resourcecount; i++) {
483             if (found) {
484                 tempStore = this.resources[i];
485                 this.resources[i] = nextStore;
486                 nextStore = tempStore;
488                 if (nextStore != null)
489                     nextStore.update_index(i+1);
491             } else if (this.resources[i] == targetel) {
492                 found = true;
493                 nextStore = this.resources[i];
494                 this.resources[i] = el;
495                 resourcecount++;
497                 this.resources[i].update_index(i, this.ident);
498                 nextStore.update_index(i + 1);
499             }
500         }
501     }
502     //update on frontend
503     if (targetel) {
504         this.resources_ul.insertBefore(el.getEl(), targetel.getEl());
505         //this.resources_ul.insertBefore(document.createTextNode(' '), targetel.getEl());
506     } else {
507         this.resources_ul.appendChild(el.getEl());
508         //this.resources_ul.appendChild(document.createTextNode(' '));
509     }
510     el.parentObj = this;
511 };
514 section_class.prototype.write_sequence_list = function(toReturn) {
515     var listOutput = '';
517     for (var i=0; i<this.resources.length; i++) {
518         listOutput += this.resources[i].id;
519         if (i != (this.resources.length-1)) {
520             listOutput += ',';
521         }
522     }
523     if (toReturn) {
524         return listOutput;
525     }
526 };
531 /**
532  * resource_class extends util.DDProxy
533  */
534 function resource_class(id,group,config,parentObj) {
535     this.init_resource(id,group,config,parentObj);
538 YAHOO.extend(resource_class, YAHOO.util.DDProxy);
541 resource_class.prototype.debug = false;
544 resource_class.prototype.init_resource = function(id, group, config, parentObj) {
545     if (!id) {
546         YAHOO.log("Init resource, NO ID FOUND!", 'error');
547         return;
548     }
550     // Some constants.
551     this.NOGROUPS = 0;
552     this.SEPARATEGROUPS = 1;
553     this.VISIBLEGROUPS = 2;
555     this.is = 'resource';
556     this.init(id, group, config);
557     this.createFrame();
558     this.isTarget = true;
560     this.id = this.getEl().id.replace(/module-/i, '');
562     this.hidden = false;
563     if (YAHOO.util.Dom.hasClass(this.getEl().getElementsByTagName('a')[0], 'dimmed') ||
564         YAHOO.util.Dom.hasClass(this.getEl().getElementsByTagName('div')[0], 'dimmed_text')) {
565         this.hidden = true;
566     }
567     this.hiddenStored = null;
569     this.groupmode = null;  // Can be null (i.e. does not apply), 0, 1 or 2.
571     this.linkContainer = this.getEl().getElementsByTagName('a')[0];
572     this.divContainer = this.getEl().getElementsByTagName('div')[0];
574     this.commandContainer = null;
575     this.indentLeftButton = null;
576     this.indentRightButton = null;
577     this.viewButton = null;
578     this.groupButton = null;
579     this.handle = null;
580     this.init_buttons();
582     this.parentObj = parentObj;
584     if (this.debug) {
585         YAHOO.log("init_resource "+id+" parent = "+parentObj.getEl().id);
586     }
587 };
590 /**
591  * The current strategy is to look at the DOM tree to get information on the
592  * resource and it's current mode. This is bad since we are dependant on
593  * the html that is output from serverside logic. Seemingly innocuous changes
594  * like changing the language string for the title of a button will break
595  * our JavaScript here. This is brittle.
596  *
597  * First, we clear the buttons container. Then:
598  *   We need to add the new-style move handle.
599  *   The old style move button (up/down) needs to be removed.
600  *   Move left button (if any) needs an event handler.
601  *   Move right button (if any) needs an event handler.
602  *   Update button stays as it is. Add it back.
603  *   Delete button needs an event handler.
604  *   Visible button is a toggle. It needs an event handler too.
605  *   Group mode button is a toggle. It needs an event handler too.
606  */
607 resource_class.prototype.init_buttons = function() {
609     var commandContainer = YAHOO.util.Dom.getElementsByClassName('commands',
610             'span', this.getEl())[0];
612     if (commandContainer == null) {
613         YAHOO.log('Cannot find command container for '+this.getEl().id, 'error');
614         return;
615     }
617     // Language strings.
618     var strgroupsnone = main.portal.strings['groupsnone']+' ('+main.portal.strings['clicktochange']+')';
619     var strgroupsseparate = main.portal.strings['groupsseparate']+' ('+main.portal.strings['clicktochange']+')';
620     var strgroupsvisible = main.portal.strings['groupsvisible']+' ('+main.portal.strings['clicktochange']+')';
622     this.commandContainer = commandContainer;
623     var buttons = commandContainer.getElementsByTagName('a');
625     // Buttons that we might need to add back in.
626     var moveLeft = false;
627     var moveRight = false;
628     var updateButton = null;
630     // for RTL support
631     var isrtl = (document.getElementsByTagName("html")[0].dir=="rtl");
633     for (var x=0; x<buttons.length; x++) {
634         if (buttons[x].className == 'editing_moveleft') {
635             moveLeft = true;
636         } else if (buttons[x].className == 'editing_moveright') {
637             moveRight = true;
638         } else if (buttons[x].className == 'editing_update') {
639             updateButton = buttons[x].cloneNode(true);
640         } else if (buttons[x].className == 'editing_groupsnone') {
641             this.groupmode = this.NOGROUPS;
642         } else if (buttons[x].className == 'editing_groupsseparate') {
643             this.groupmode = this.SEPARATEGROUPS;
644         } else if (buttons[x].className == 'editing_groupsvisible') {
645             this.groupmode = this.VISIBLEGROUPS;
646         }
647     }
649     if (updateButton == null) {
650         // Update button must always be present.
651         YAHOO.log('Cannot find updateButton for '+this.getEl().id, 'error');
652     }
654     // Clear all the buttons.
655     commandContainer.innerHTML = '';
657     // Add move-handle for drag and drop.
658     var handleRef = main.mk_button('a', main.portal.icons['move_2d'], main.portal.strings['move'],
659             [['style', 'cursor:move']],
660             [['height', '11'], ['width', '11'], ['style', 'margin-right:3px; border:0;']]);
662     YAHOO.util.Dom.generateId(handleRef, 'sectionHandle');
663     this.handle = handleRef;
664     commandContainer.appendChild(handleRef);
665     this.setHandleElId(this.handle.id);
667     // Add indentation buttons if needed (move left, move right).
668     if (moveLeft) {
669         var button = main.mk_button('a', main.portal.icons['backwards'], main.portal.strings['moveleft'],
670                 [['class', 'editing_moveleft']]);
671         YAHOO.util.Event.addListener(button, 'click', this.indent_left, this, true);
672         commandContainer.appendChild(button);
673         this.indentLeftButton = button;
674     }
676     if (moveRight) {
677         var button = main.mk_button('a', main.portal.icons['forwards'], main.portal.strings['moveright'],
678                 [['class', 'editing_moveright']]);
679         YAHOO.util.Event.addListener(button, 'click', this.indent_right, this, true);
680         commandContainer.appendChild(button);
681         this.indentRightButton = button;
682     }
684     // Add edit button back in.
685     commandContainer.appendChild(updateButton);
687     // Add the delete button.
688     var button = main.mk_button('a', main.portal.icons['delete'], main.portal.strings['delete']);
689     YAHOO.util.Event.addListener(button, 'click', this.delete_button, this, true);
690     commandContainer.appendChild(button);
692     // Add the hide or show button.
693     if (this.hidden) {
694         var button = main.mk_button('a', main.portal.icons['show'], main.portal.strings['show']);
695     } else {
696         var button = main.mk_button('a', main.portal.icons['hide'], main.portal.strings['hide']);
697     }
698     YAHOO.util.Event.addListener(button, 'click', this.toggle_hide, this, true);
699     commandContainer.appendChild(button);
700     this.viewButton = button;
702     // Add the groupmode button if needed.
703     if (this.groupmode != null) {
704         if (this.groupmode == this.NOGROUPS) {
705             var button = main.mk_button('a', main.portal.icons['groupn'], strgroupsnone);
706         } else if (this.groupmode == this.SEPARATEGROUPS) {
707             var button = main.mk_button('a', main.portal.icons['groups'], strgroupsseparate);
708         } else {
709             var button = main.mk_button('a', main.portal.icons['groupv'], strgroupsvisible);
710         }
711         YAHOO.util.Event.addListener(button, 'click', this.toggle_groupmode, this, true);
712         commandContainer.appendChild(button);
713         this.groupButton = button;
714     }
715 };
718 resource_class.prototype.indent_left = function() {
720     var spacer = YAHOO.util.Dom.getElementsByClassName('spacer',
721             'img', this.getEl())[0];
722     if (!spacer) {
723         if (this.debug) {
724             YAHOO.log('Could not indent left: spacer image does not exist', 'error');
725         }
726         return false;
727     }
728     if (spacer.width > 20) {
729         spacer.width -= 20;
730     } else {
731         // Remove the spacer.
732         resource = this.getEl();
733         resource.removeChild(spacer);
735         // Remove the indent left button as well.
736         var commandContainer = YAHOO.util.Dom.getElementsByClassName('commands',
737                 'span', this.getEl())[0];
739         commandContainer.removeChild(this.indentLeftButton);
740         this.indentLeftButton = null;
741     }
742     main.connect('POST', 'class=resource&field=indentleft', null, 'id='+this.id);
743     return true;
744 };
747 resource_class.prototype.indent_right = function() {
749     // for RTL support
750     var isrtl = (document.getElementsByTagName("html")[0].dir=="rtl");
752     var spacer = YAHOO.util.Dom.getElementsByClassName('spacer',
753             'img', this.getEl())[0];
754     if (!spacer) {
755         var spacer = document.createElement('img');
757         spacer.setAttribute('src', main.portal.icons['spacerimg']);
758         spacer.className = 'spacer';
759         spacer.setAttribute('alt', '');
760         spacer.setAttribute('width', '20');
761         spacer.setAttribute('height', '12');
763         var resource = this.getEl();
764         resource.insertBefore(spacer, resource.childNodes[0]);
765     } else {
766         spacer.width += 20;
767     }
768     // Add a indent left button if none is present.
769     var commandContainer = YAHOO.util.Dom.getElementsByClassName('commands',
770             'span', this.getEl())[0];
772     if (!this.indentLeftButton) {
773         var button = main.mk_button('a', main.portal.icons['backwards'], main.portal.strings['moveleft'],
774                 [['class', 'editing_moveleft']]);
775         YAHOO.util.Event.addListener(button, 'click', this.indent_left, this, true);
776         commandContainer.insertBefore(button, this.indentRightButton);
777         this.indentLeftButton = button;
778     }
779     main.connect('POST', 'class=resource&field=indentright', null, 'id='+this.id);
780     return true;
781 };
784 resource_class.prototype.toggle_hide = function(target, e, superficial, force) {
785     var strhide = main.portal.strings['hide'];
786     var strshow = main.portal.strings['show'];
787     if (force != null) {
788         if (this.debug) {
789             YAHOO.log("Resource "+this.getEl().id+" forced to "+force);
790         }
791         this.hidden = !force;
792     }
793     if (this.hidden) {
794         YAHOO.util.Dom.removeClass(this.linkContainer, 'dimmed');
795         YAHOO.util.Dom.removeClass(this.divContainer, 'dimmed_text');
796         this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/show/i, 'hide');
797         this.viewButton.childNodes[0].alt = this.viewButton.childNodes[0].alt.replace(strshow, strhide);
798         this.viewButton.title = this.viewButton.title.replace(strshow, strhide);
799         this.hidden = false;
801         if (!superficial) {
802             main.connect('POST', 'class=resource&field=visible', null, 'value=1&id='+this.id);
803         }
804     } else {
805         YAHOO.util.Dom.addClass(this.linkContainer, 'dimmed');
806         YAHOO.util.Dom.addClass(this.divContainer, 'dimmed_text');
807         this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/hide/i, 'show');
808         this.viewButton.childNodes[0].alt = this.viewButton.childNodes[0].alt.replace(strhide, strshow);
809         this.viewButton.title = this.viewButton.title.replace(strhide, strshow);
810         this.hidden = true;
812         if (!superficial) {
813             main.connect('POST', 'class=resource&field=visible', null, 'value=0&id='+this.id);
814         }
815     }
816 };
819 resource_class.prototype.groupImages = ['groupn', 'groups', 'groupv'];
822 resource_class.prototype.toggle_groupmode = function() {
823     this.groupmode++;
824     if (this.groupmode > 2) {
825         this.groupmode = 0;
826     }
828     var newtitle = this.groupButton.title;
830     switch (this.groupmode) {
831         case 0:
832             newtitle = main.portal.strings['groupsnone']+' ('+main.portal.strings['clicktochange']+')';
833             break;
834         case 1:
835             newtitle = main.portal.strings['groupsseparate']+' ('+main.portal.strings['clicktochange']+')';
836             break;
837         case 2:
838             newtitle = main.portal.strings['groupsvisible']+' ('+main.portal.strings['clicktochange']+')';
839             break;
840     }
842     this.groupButton.getElementsByTagName('img')[0].alt = newtitle;
843     this.groupButton.title = newtitle;
845     this.groupButton.getElementsByTagName('img')[0].src = main.portal.icons[this.groupImages[this.groupmode]];
846     main.connect('POST', 'class=resource&field=groupmode', null, 'value='+this.groupmode+'&id='+this.id);
847 };
850 resource_class.prototype.delete_button = function() {
851     if (this.debug) {
852     YAHOO.log("Deleting "+this.getEl().id+" from parent "+this.parentObj.getEl().id);
853     }
854     if (!confirm(main.getString('deletecheck', main.getString(this.is)+" "+this.id))) {
855         return false;
856     }
857     this.parentObj.remove_resource(this);
858     main.connect('POST', 'class=resource&action=DELETE&id='+this.id);
859 };
862 resource_class.prototype.update_index = function(index) {
863     if (this.debug) {
864         YAHOO.log("Updating Index for resource "+this.getEl().id+" to "+index);
865     }
866 };
869 resource_class.prototype.startDrag = function(x, y) {
870     YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT;
872     //reinitialize dd element
873     this.getDragEl().innerHTML = '';
875     var targets = YAHOO.util.DDM.getRelated(this, true);
876     if (this.debug) {
877         YAHOO.log(this.id + " startDrag "+targets.length + " targets");
878     }
879 };
882 resource_class.prototype.clear_move_markers = function(target) {
883     if (target.is == 'section') {
884         resources = target.resources;
885     } else {
886         resources = target.parentObj.resources;
887     }
888     for (var i=0; i<resources.length; i++) {
889         if (resources[i].getEl() != null) {
890             YAHOO.util.Dom.setStyle(resources[i].getEl().id, 'border', 'none');
891         }
892     }
893 };
896 resource_class.prototype.onDragOver = function(e, ids) {
897     var target = YAHOO.util.DDM.getBestMatch(ids);
899     this.clear_move_markers(target);
901     if (target != this && (target.is == 'resource' || target.is == 'activity')) {
902         // Add a top border to show where the drop will place the resource.
903         YAHOO.util.Dom.setStyle(target.getEl().id, 'border-top', '1px solid #BBB');
904     } else if (target.is == 'section' && target.resources.length > 0) {
905         // We need to have a border at the bottom of the last activity in
906         // that section.
907         if (target.resources[target.resources.length - 1].getEl() != null) {
908             YAHOO.util.Dom.setStyle(target.resources[target.resources.length - 1].getEl().id,
909                 'border-bottom', '1px solid #BBB');
910         }
911     }
912 };
915 resource_class.prototype.onDragOut = function(e, ids) {
916     var target = YAHOO.util.DDM.getBestMatch(ids);
917     if (target) {
918         this.clear_move_markers(target);
919     }
920 };
923 resource_class.prototype.onDragDrop = function(e, ids) {
924     var target = YAHOO.util.DDM.getBestMatch(ids);
925     if (!target) {
926         YAHOO.log('onDragDrop: Target is not valid!', 'error');
927     }
929     if (this.debug) {
930         YAHOO.log("Dropped on section id="+target.sectionId
931                 +", el="+this.getEl().id
932                 +", x="+YAHOO.util.Dom.getXY( this.getDragEl() ));
933     }
934     this.parentObj.remove_resource(this);
936     if (target.is == 'resource' || target.is == 'activity') {
937         target.parentObj.insert_resource(this, target);
938     } else if (target.is == 'section') {
939         target.insert_resource(this);
940     }
941     this.clear_move_markers(target);
942     return;
943 };
946 resource_class.prototype.endDrag = function() {
947     // Eliminates default action
948 };
950 section_class.prototype.swap_dates = function(el){
951     var i=1;
952     var divs = YAHOO.util.Selector.query('div .weekdates');
954     for (div in divs) {
955         divs[div].innerHTML = main.sectiondates[i];
956         i++;
957     }
958 };