Ed Coyne's AJAX course format, with some cleanups done.
[moodle.git] / lib / ajax / section-resource_classes.js
CommitLineData
0a0bb380 1/*
2 * library for ajaxcourse formats, the classes and related functions for sections and resources
3 * this library requires a 'main' object created in calling document
4 */
5
6
7function section_class(id,group,config,isDraggable){
8 this.init_section(id,group,config,isDraggable);
9}
10YAHOO.extend(section_class, YAHOO.util.DDProxy);
11
12section_class.prototype.init_section = function(id, group,config,isDraggable){
13
14 if (!id) { return; }
15
16 this.is = 'section';
17 this.sectionId = null;
18
19
20 if(!isDraggable){
21 this.initTarget(id,group,config);
22 this.removeFromGroup('sections');
23 }else{
24 this.init(id,group,config);
25 this.handle = null;
26 if(isDraggable)this.add_handle();
27 }
28
29 this.createFrame();
30 this.isTarget = true;
31
32 this.resources = [];
33 this.numberDisplay = null;
34 this.summary = null;
35 this.content_td = null;
36 this.hidden = false;
37 this.highlighted = false;
38 this.showOnly = false;
39 this.resources_ul = null;
40 this.process_section();
41
42 this.viewButton = null;
43 this.highlightButton = null;
44 this.showOnlyButton = null;
45 this.init_buttons();
46
47 this.debug = false;
48 if(this.debug)YAHOO.log("init_section "+id+" draggable="+isDraggable);
49
50
51 if(YAHOO.util.Dom.hasClass(this.getEl(),'hidden'))
52 this.toggle_hide(null,null,true);
53
54
55
56 }
57
58section_class.prototype.init_buttons = function(){
59 var commandContainer = this.getEl().childNodes[2];
60
61 //clear all but show only button
62 var commandContainerCount = commandContainer.childNodes.length;
63 for(var i=(commandContainerCount-1);i>0;i--)
64 commandContainer.removeChild(commandContainer.childNodes[i])
65
66
67 if(!this.isWeekFormat){
68 var highlightbutton = main.mk_button('div','/pix/i/marker.gif');
69 YAHOO.util.Event.addListener(highlightbutton,'click',this.mk_marker,this,true);
70 commandContainer.appendChild(highlightbutton);
71 this.highlightButton = highlightbutton;
72 }
73 var viewbutton = main.mk_button('div','/pix/i/hide.gif');
74 YAHOO.util.Event.addListener(viewbutton,'click',this.toggle_hide,this,true);
75 commandContainer.appendChild(viewbutton);
76 this.viewButton = viewbutton;
77
78
79 var deletebutton = main.mk_button('div','/pix/t/delete.gif');
80 YAHOO.util.Event.addListener(deletebutton,'click',this.delete_button,this,true);
81 commandContainer.appendChild(deletebutton);
82
83
84 }
85
86section_class.prototype.delete_button = function(){
87 this.content_td.childNodes[0].data = '';
88
89 if(this.hidden)
90 this.toggle_hide();
91
92 if(this.highlighted)
93 this.toggle_highlight();
94
95 if(this.debug)YAHOO.log('Deleting '+this.getEl().id);
96
97 main.connect('delete','class=section&id='+this.id);
98 for(var i=0;i<this.resources.length;i++)
99 this.resources[i].delete_button();
100 }
101
102section_class.prototype.add_handle = function(){
103 var handleRef = main.mk_button('div','/pix/i/move_2d.gif',[['style','cursor:move']]);
104 YAHOO.util.Dom.generateId(handleRef,'sectionHandle');
105
106 this.handle = handleRef;
107
108 this.getEl().childNodes[0].appendChild(handleRef);
109 this.setHandleElId(this.handle.id);
110 }
111
112
113section_class.prototype.process_section = function(){
114 this.content_td = this.getEl().childNodes[1];
115
116
117 if(YAHOO.util.Dom.hasClass(this.getEl(),'current')){
118 this.highlighted = true;
119 main.marker = this;
120 }
121
122
123 //create holder for display number for access later
124
125 this.numberDisplay = document.createElement('div');
126 this.numberDisplay.innerHTML = this.getEl().childNodes[0].innerHTML;
127 this.getEl().childNodes[0].innerHTML = '';
128 this.getEl().childNodes[0].appendChild(this.numberDisplay);
129
130 this.sectionId = this.numberDisplay.innerHTML;
131
132
133 //find/edit resources
134
135 this.resources_ul = this.content_td.getElementsByTagName('ul')[0];
136 if(this.resources_ul == null){
137 this.resources_ul = document.createElement('ul');
138 this.resources_ul.className='section';
139 this.content_td.insertBefore(this.resources_ul,this.content_td.childNodes[1]);
140 }
141
142 var resource_count = this.resources_ul.getElementsByTagName('li').length;
143 if(this.debug)YAHOO.log("Found "+resource_count+" resources in "+this.getEl().id);
144
145 for(var i=0;i<resource_count;i++){
146 var resource = this.resources_ul.getElementsByTagName('li')[i];
147 if(YAHOO.util.Dom.hasClass(resource,'resource'))
148 this.resources[this.resources.length] = new resource_class(resource.id,'resources',null,this);
149 else
150 this.resources[this.resources.length] = new activity_class(resource.id,'resources',null,this);
151 }
152
153 this.summary = YAHOO.util.Dom.getElementsByClassName('summary',null,this.getEl())[0].firstChild.data || '';
154
155
156 }
157
158section_class.prototype.startDrag = function(x, y) {
159 //operates in point mode
160 YAHOO.util.DDM.mode = YAHOO.util.DDM.POINT;
161
162 //remove from resources group temporarily
163 this.removeFromGroup('resources');
164
165 //reinitialize dd element
166 this.getDragEl().innerHTML = '';
167
168 var targets = YAHOO.util.DDM.getRelated(this, true);
169 if(this.debug)YAHOO.log(this.sectionId + " startDrag "+targets.length + " targets");
170
171 }
172
173section_class.prototype.onDragDrop = function(e, id) {
174 // get the drag and drop object that was targeted
175 var target = YAHOO.util.DDM.getDDById(id);
176
177 if(this.debug)YAHOO.log("Section dropped on id="+id+" el = "+this.getEl().id+" x="+YAHOO.util.Dom.getXY(this.getDragEl()));
178
179 this.move_to_section(target);
180
181 //add back to resources group
182 this.addToGroup('resources');
183 }
184section_class.prototype.endDrag = function(){
185 //nessicary to defeat default action
186
187 //add back to resources group
188 this.addToGroup('resources');
189 }
190
191section_class.prototype.move_to_section = function(target){
192 var tempTd = document.createElement('td');
193 var tempStore = null;
194 var sectionCount = main.sections.length;
195 var found = null;
196
197 //determine if original is above or below target and adjust loop
198 var oIndex=main.get_section_index(this);
199 var tIndex=main.get_section_index(target);
200
201 if(this.debug)YAHOO.log("original is at: "+oIndex+" target is at:"+tIndex+" of "+(sectionCount-1));
202
203 if(oIndex < tIndex){
204 var loopCondition = 'i<sectionCount';
205 var loopStart = 1;
206 var loopInc = 'i++';
207 var loopmodifier = 'i-1';
208 }else{
209 var loopCondition = 'i>0';
210 var loopStart = sectionCount-1;
211 var loopInc = 'i--';
212 var loopmodifier = 'i+1';
213 }
214
215 for(var i=loopStart;eval(loopCondition);eval(loopInc)){
216
217 if((main.sections[i] == this)&& !found){
218 //enounter with original node
219 if(this.debug)YAHOO.log("Found Original "+main.sections[i].getEl().id);
220 if(main.sections[i] == this){
221 found = true;
222 }
223
224 }else if(main.sections[i] == target){
225 //encounter with target node
226 if(this.debug)YAHOO.log("Found target "+main.sections[i].getEl().id);
227 main.sections[i].swap_with_section(main.sections[eval(loopmodifier)]);
228 found = false;
229 break;
230
231 }else if(found){
232 //encounter with nodes inbetween
233 main.sections[i].swap_with_section(main.sections[eval(loopmodifier)]);
234 }
235 }
236
237 }
238
239
240section_class.prototype.swap_with_section = function(sectionIn){
241 var tmpStore = null;
242
243 thisIndex = main.get_section_index(this);
244 targetIndex = main.get_section_index(sectionIn);
245 main.sections[targetIndex] = this;
246 main.sections[thisIndex] = sectionIn;
247
248 this.changeId(targetIndex);
249 sectionIn.changeId(thisIndex);
250
251 if(this.debug)YAHOO.log("Swapping "+this.getEl().id+" with "+sectionIn.getEl().id);
252
253 YAHOO.util.DDM.swapNode(this.getEl(),sectionIn.getEl());
254
255
256 }
257
258section_class.prototype.toggle_hide = function(e,target,isCosmetic){
259 if(this.hidden){
260 YAHOO.util.Dom.removeClass(this.getEl(),'hidden');
261 this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/show.gif/i,'hide.gif');
262 this.hidden = false;
263
264 if(!isCosmetic)main.connect('post','class=section&field=visible',null,'value=1&id='+this.sectionId);
265 }else{
266 YAHOO.util.Dom.addClass(this.getEl(),'hidden');
267 this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/hide.gif/i,'show.gif');
268 this.hidden = true;
269
270 if(!isCosmetic)main.connect('post','class=section&field=visible',null,'value=0&id='+this.sectionId);
271 }
272 }
273
274section_class.prototype.toggle_highlight = function(){
275 if(this.highlighted){
276 YAHOO.util.Dom.removeClass(this.getEl(),'current');
277 this.highlighted = false;
278 }else{
279 YAHOO.util.Dom.addClass(this.getEl(),'current');
280 this.highlighted = true;
281 }
282 }
283
284section_class.prototype.mk_marker = function(){
285 if(main.marker != this){
286 main.update_marker(this);
287
288 }else{//if currently the marker
289 main.marker = null;
290
291 main.connect('post','class=course&field=marker',null,'value=0');
292 this.toggle_highlight();
293
294 }
295
296 }
297
298section_class.prototype.changeId = function(newId){
299 this.sectionId = newId;
300 this.numberDisplay.firstChild.data = newId;
301
302 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))
303
304 if(main.marker == this)
305 main.update_marker(this);
306 }
307
308section_class.prototype.get_resource_index = function(el){
309 for(var x=0;x<this.resources.length;x++)
310 if(this.resources[x]==el)
311 return x;
312 YAHOO.log("Could not find resource to remove "+el.getEl().id,"error");
313 return -1;
314 }
315
316section_class.prototype.remove_resource = function(el){
317 var resourceCount = this.resources.length;
318 if(resourceCount == 1){
319 if(this.resources[0] == el)
320 this.resources = new Array();
321 }else{
322 var found = false;
323 for(var i=0;i<resourceCount;i++){
324 if(found){
325 this.resources[i-1] = this.resources[i];
326 if(i==resourceCount-1){
327 this.resources = this.resources.slice(0,-1);
328 resourceCount--;
329 }
330 this.resources[i-1].update_index(i-1);
331 }else if(this.resources[i]==el){
332 found = true;
333 }
334 }
335 }
336
337
338 //remove "text" nodes to keep DOM clean
339 var childIndex = null;
340 var childrenCount = this.resources_ul.childNodes.length;
341 for(var i=0;i<childrenCount;i++)
342 if(this.resources_ul.childNodes[i] == el.getEl())
343 childIndex = i;
344 if(childIndex > 0 && childIndex < this.resources_ul.childNodes.length)
345 this.resources_ul.removeChild(this.resources_ul.childNodes[childIndex-1]);
346 YAHOO.log("removing "+el.getEl().id);
347 if(el.getEl().parentNode != null)
348 el.getEl().parentNode.removeChild(el.getEl());
349
350 this.write_sequence_list();
351
352 }
353
354section_class.prototype.insert_resource = function(el,targetel){
355 var resourcecount = this.resources.length;
356 var found = false;
357 var tempStore = nextStore = null;
358
359 if(targetel == null){
360 this.resources[this.resources.length] = el;
361 }else
362 for(var i=0;i<resourcecount;i++){
363 if(found){
364 tempStore = this.resources[i];
365 this.resources[i] = nextStore;
366 nextStore = tempStore;
367
368 if(nextStore != null)
369 nextStore.update_index(i+1);
370
371 }else if(this.resources[i] == targetel){
372 found = true;
373 nextStore = this.resources[i];
374 this.resources[i] = el;
375 resourcecount++;
376
377 this.resources[i].update_index(i,this.ident);
378 nextStore.update_index(i+1);
379 }
380 }
381
382
383 //YAHOO.log("Inserting "+el.getEl().id+" before "+targetel.getEl().id);
384 if(targetel != null){
385 this.resources_ul.insertBefore(el.getEl(),targetel.getEl());
386 this.resources_ul.insertBefore(document.createTextNode(''),targetel.getEl());
387
388 }else{
389 this.resources_ul.appendChild(el.getEl());
390 this.resources_ul.appendChild(document.createTextNode(" "));
391 }
392 el.parentObj = this;
393
394 this.write_sequence_list();
395 main.connect('post','class=resource&field=section',null,'id='+el.id+'&value='+this.sectionId);
396 }
397
398section_class.prototype.write_sequence_list = function(toReturn){
399 var listOutput = '';
400 for(var i=0;i<this.resources.length;i++){
401 listOutput += this.resources[i].id;
402 if(i != (this.resources.length-1))
403 listOutput += ',';
404 }
405
406 if(toReturn)
407 return listOutput;
408
409 main.connect('post','class=section&field=sequence',null,'id='+this.sectionId+'&value='+listOutput);
410 }
411
412
413
414/*
415 * Resource Class extends util.DDProxy
416 */
417
418
419function resource_class(id,group,config,parentObj){
420
421 this.init_resource(id,group,config,parentObj);
422}
423YAHOO.extend(resource_class, YAHOO.util.DDProxy);
424
425resource_class.prototype.init_resource = function(id,group,config,parentObj){
426 if (!id) { return; }
427
428 this.is = 'resource';
429 this.init(id,group,config);
430 this.createFrame();
431 this.isTarget = true;
432
433 this.id = this.getEl().id.replace(/module-/i,'');
434
435 this.hidden = false;
436 if(YAHOO.util.Dom.hasClass(this.getEl().getElementsByTagName('a')[0],'dimmed'))
437 this.hidden = true;
438
439 this.linkContainer = this.getEl().getElementsByTagName('a')[0];
440
441 this.commandContainer = null;
442 this.viewButton = null;
443 this.handle = null;
444 this.init_buttons();
445
446 this.parentObj = parentObj;
447
448 this.debug = false;
449 if(this.debug)YAHOO.log("init_resource "+id+" parent = "+parentObj.getEl().id);
450
451 }
452
453resource_class.prototype.init_buttons = function(){
454 var commandContainer = YAHOO.util.Dom.getElementsByClassName('commands','span',this.getEl())[0];
455 if( commandContainer == null){
456 YAHOO.log('Cannot find command container for '+this.getEl().id,'error');
457 return;
458 }
459
460 this.commandContainer = commandContainer;
461
462 //find edit button
463 var updateButton = null;
464 var buttons = commandContainer.getElementsByTagName('a');
465 for(var x=0;x<buttons.length;x++)
466 if(buttons[x].title == 'Update')
467 updateButton = buttons[x];
468
469 if(updateButton == null)
470 YAHOO.log('Cannot find updateButton for '+this.getEl().id,'error');
471
472 commandContainer.innerHTML = '';
473
474
475 //add move-handle
476 var handleRef = main.mk_button('a','/pix/i/move_2d.gif',[['style','cursor:move']],[['height','11'],['width','11'],['hspace','2'],['border','0']]);
477 YAHOO.util.Dom.generateId(handleRef,'sectionHandle');
478 this.handle = handleRef;
479
480 commandContainer.appendChild(handleRef);
481 this.setHandleElId(this.handle.id);
482
483
484
485 //add edit button back in
486 commandContainer.appendChild(updateButton);
487
488 //add rest
489 var button = main.mk_button('a','/pix/t/delete.gif');
490 YAHOO.util.Event.addListener(button,'click',this.delete_button,this,true);
491 commandContainer.appendChild(button);
492
493 if(this.hidden)
494 var button = main.mk_button('a','/pix/t/show.gif');
495 else
496 var button = main.mk_button('a','/pix/t/hide.gif');
497 YAHOO.util.Event.addListener(button,'click',this.toggle_hide,this,true);
498 commandContainer.appendChild(button);
499 this.viewButton = button;
500
501 }
502
503resource_class.prototype.toggle_hide = function(){
504 if(this.hidden){
505 YAHOO.util.Dom.removeClass(this.linkContainer,'dimmed');
506 this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/show.gif/i,'hide.gif');
507 this.hidden = false;
508
509 main.connect('post','class=resource&field=visible',null,'value=1&id='+this.id);
510 }else{
511 YAHOO.util.Dom.addClass(this.linkContainer,'dimmed');
512 this.viewButton.childNodes[0].src = this.viewButton.childNodes[0].src.replace(/hide.gif/i,'show.gif');
513 this.hidden = true;
514
515 main.connect('post','class=resource&field=visible',null,'value=0&id='+this.id);
516 }
517 }
518
519resource_class.prototype.delete_button = function(){
520 if(this.debug)YAHOO.log("Deleteing "+this.getEl().id+"from parent "+this.parentObj.getEl().id);
521
522 this.getEl().parentNode.removeChild(this.getEl());
523 this.parentObj.remove_resource(this);
524
525 main.connect('delete','class=resource&id='+this.id);
526 }
527
528resource_class.prototype.update_index = function(index){
529 if(this.debug)YAHOO.log("update Index for resource "+this.getEl().id+"to"+index);
530 }
531
532
533resource_class.prototype.startDrag = function(x, y) {
534 //operates in intersect mode
535 YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT;
536
537 //reinitialize dd element
538 this.getDragEl().innerHTML = '';
539
540 var targets = YAHOO.util.DDM.getRelated(this, true);
541 if(this.debug)YAHOO.log(this.id + " startDrag "+targets.length + " targets");
542
543 }
544
545resource_class.prototype.onDragDrop = function(e, ids) {
546 // best fit Id
547 var id=[];
548 for(var i=0;i<ids.length;i++)
549 if(ids[i].is == 'resource')
550 id[id.length] = ids[i];
551
552 if(id.length == 0)
553 id = ids;
554
555
556 // get the drag and drop object that was targeted
557 var target = YAHOO.util.DDM.getBestMatch(id);
558
559 if(this.debug)YAHOO.log("dropped on id="+target+" el = "+this.getEl().id+" x="+YAHOO.util.Dom.getXY(this.getDragEl()));
560
561 this.parentObj.remove_resource(this);
562
563 if(target.is == 'resource'||target.is == 'activity'){
564 target.parentObj.insert_resource(this,target);
565
566 }else if(target.is =='section'){
567 target.insert_resource(this);
568
569 }
570
571 return;
572 }
573
574resource_class.prototype.endDrag = function() {
575 //eliminates default action
576 }
577
578/*
579 * activity Class extends resource class
580 */
581
582
583function activity_class(id,group,config,parentObj){
584 this.init_activity(id,group,config,parentObj);
585}
586YAHOO.extend(activity_class, resource_class);
587
588activity_class.prototype.init_activity = function(id,group,config,parentObj){
589 this.is = 'activity';
590 this.currentGroup = this.get_current_group(id);
591
592 this.init_resource(id,group,config,parentObj);
593
594 this.groupButton= null;
595 this.init_activity_button();
596
597 if(this.debug)YAHOO.log("--init_activity "+id);
598
599 }
600
601activity_class.prototype.groupImages = ['/pix/t/groupn.gif','/pix/t/groups.gif','/pix/t/groupv.gif'];
602
603activity_class.prototype.init_activity_button = function(){
604 var button = main.mk_button('a',this.groupImages[this.currentGroup]);
605 YAHOO.util.Event.addListener(button,'click',this.toggle_group,this,true);
606 this.commandContainer.appendChild(button);
607 this.groupButton = button;
608 }
609
610activity_class.prototype.get_current_group = function(id){
611 if(document.getElementById(id) != null)
612 var groupNodeArray = document.getElementById(id).getElementsByTagName('a');
613 var groupNode = groupNodeArray[groupNodeArray.length-1];
614
615 for(var x=0;x<this.groupImages.length;x++){
616 if(main.portal.wwwroot+this.groupImages[x] == groupNode.getElementsByTagName('img')[0].src){
617 return x;
618 }
619 }
620
621 return 0;
622 }
623
624activity_class.prototype.toggle_group = function(){
625 this.currentGroup++;
626 if(this.currentGroup > 2)
627 this.currentGroup = 0;
628
629 this.groupButton.getElementsByTagName('img')[0].src = main.portal.wwwroot + this.groupImages[this.currentGroup];
630
631 main.connect('post','class=resource&field=groupmode',null,'value='+this.currentGroup+'&id='+this.id);
632 }
633