MDL-26502 check browser - fix for Symbian (backported)
[moodle.git] / lib / ajax / block_classes.js
blob16ec6869e18e45f725e75353a952e83094c53994
1 /**
2  * library for ajaxcourse formats, the classes and related functions for drag and drop blocks
3  * 
4  * this library requires a 'main' object created in calling document
5  *
6  * $Id$ 
7  */
10 //set Drag and Drop to Intersect mode: 
11 YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT; 
14 /**
15  * class for draggable block, extends YAHOO.util.DDProxy
16  */
17 function block_class(id,group,config){
18     this.init_block(id,group,config);
20 YAHOO.extend(block_class, YAHOO.util.DDProxy);
22 block_class.prototype.debug = false;
25 block_class.prototype.init_block = function(id, sGroup, config) {
27     if (!id) {
28         return;
29     }
31     //Drag and Drop
32     this.init(id, sGroup, config);
33     this.initFrame();
34     this.createFrame();
36     this.is = 'block';
37     this.instanceId = this.getEl().id.replace(/inst/i, '');
39     // Add the drag class (move handle) only to blocks that need it.
40     YAHOO.util.Dom.addClass(this.getEl(), 'drag');
42     this.addInvalidHandleType('a');
44     var s = this.getEl().style;
45     s.opacity = 0.76;
46     s.filter = "alpha(opacity=76)";
48     // specify that this is not currently a drop target
49     this.isTarget = false;
51     this.region = YAHOO.util.Region.getRegion(this.getEl());
52     this.type = block_class.TYPE;
54     //DHTML
55     this.viewbutton = null;
56     this.originalClass = this.getEl().className;
58     this.init_buttons();
62 block_class.prototype.startDrag = function(x, y) {
63     //operates in intersect mode
64     YAHOO.util.DDM.mode = YAHOO.util.DDM.INTERSECT;
65     
66     YAHOO.log(this.id + " startDrag");
68     var dragEl = this.getDragEl();
69     var clickEl = this.getEl();
71     dragEl.innerHTML = clickEl.innerHTML; 
72     dragEl.className = clickEl.className; 
73     dragEl.style.color = this.DDM.getStyle(clickEl, "color");;
74     dragEl.style.backgroundColor = this.DDM.getStyle(clickEl, "backgroundColor");
75     dragEl.style.border = '0px';
77     var s = clickEl.style;
78     s.opacity = .1;
79     s.filter = "alpha(opacity=10)";
81     var targets = YAHOO.util.DDM.getRelated(this, true);
82     YAHOO.log(targets.length + " targets");
83     
84     //restyle side boxes to highlight
85     for (var i=0; i<targets.length; i++) {
86        
87         var targetEl = targets[i].getEl();
88         
89         targetEl.style.background = "#fefff0";
90         targetEl.opacity = .3;
91         targetEl.filter = "alpha(opacity=30)";
92     }
95 block_class.prototype.endDrag = function() {
96     // reset the linked element styles
97     var s = this.getEl().style;
98     s.opacity = 1;
99     s.filter = "alpha(opacity=100)";
100     this.resetTargets();
101     }
104 block_class.prototype.onDragDrop = function(e, id) {
105     // get the drag and drop object that was targeted
106     var oDD;
107     
108     if ("string" == typeof id) {
109         oDD = YAHOO.util.DDM.getDDById(id);
110     } else {
111         oDD = YAHOO.util.DDM.getBestMatch(id);
112     }
113     
114     var el = this.getEl();
115    
116     if (this.debug) {
117         YAHOO.log("id="+id+" el="+e+" x="+YAHOO.util.Dom.getXY(this.getDragEl()));
118     }
119     //var collisions = this.find_collisions(e,id);
121     this.move_block(id);
122     //YAHOO.util.DDM.moveToEl(el, oDD.getEl());
123   
124     this.resetTargets();
128 block_class.prototype.find_target = function(column){
129         var collisions = column.find_sub_collision(YAHOO.util.Region.getRegion(this.getDragEl()));
131         //determine position
132         var insertbefore = null;
133         if(collisions.length == 0)
134           return;
135        
136        insertbefore = column.blocks[collisions[0][0]];    
137        
138         return insertbefore;
139     }
141 block_class.prototype.resetTargets = function() {
142         // reset the target styles
143         var targets = YAHOO.util.DDM.getRelated(this, true);
144         for (var i=0; i<targets.length; i++) {
145             var targetEl = targets[i].getEl();
146             targetEl.style.background = "";
147             targetEl.opacity = 1;
148             targetEl.filter = "alpha(opacity=100)";            
149         }
150     }
152 block_class.prototype.move_block = function(columnid){
153         if(this.debug)YAHOO.log("Dropped on "+columnid[0]);
154         //var column = YAHOO.util.DDM.getDDById(columnid[0].);
155         column = columnid[0];
156         var inserttarget = this.find_target(column);
158         if(this.debug && inserttarget != null)YAHOO.log("moving "+this.getEl().id+" before "+inserttarget.getEl().id+" - parentNode="+this.getEl().parentNode.id);
160         if (this.getEl() == inserttarget) {
161             if(this.debug)YAHOO.log("Dropping on self, resetting");
162             this.endDrag();
163             return;
164         }
166         //remove from document
167         if (this.getEl().parentNode != null) {
168             this.getEl().parentNode.removeChild(this.getEl());
169         }
170         //insert into correct place
171         if (inserttarget != null && inserttarget.getEl().parentNode != null) {
172             inserttarget.getEl().parentNode.insertBefore(this.getEl(),inserttarget.getEl());           
173             positiontoinsert = "before";
174             if (inserttarget.getEl().id != 'rinst0' || inserttarget.getEl().id == 'rinst0'){
175                 positiontoinsertid = inserttarget.getEl().id;
176             } else if (main.adminBlock.parentNode.nextSibling != null) {
177                 positiontoinsertid = main.adminBlock.parentNode.nextSibling.id;
178             } else {
179                 positiontoinsertid = inserttarget.getEl().id;
180             }
181             
182         } else if (column == main.rightcolumn && column.getEl() != null ) {//if right side insert before admin block
183             column.getEl().insertBefore(this.getEl(),main.tempBlock.childNode);            
184             positiontoinsert = "after";
185             positiontoinsertid = main.tempBlock.parentNode;
186         } else {
187             column.getEl().appendChild(this.getEl());
188             positiontoinsert = "after";
189             positiontoinsertid = column.getEl().id;
190         }
191                
192         this.reset_regions();
193         
194         //remove block from current array
195         if (main.rightcolumn.has_block(this)) {
196               main.rightcolumn.remove_block(this);
197         } else if (main.leftcolumn.has_block(this)) {
198               main.leftcolumn.remove_block(this);
199         }
200         
201         //insert into new array
202         column.insert_block(this,inserttarget);
207 block_class.prototype.reset_regions = function() {
208     var blockcount = main.blocks.length; 
209     for (i=0; i<blockcount; i++) {
210         main.blocks[i].region = YAHOO.util.Region.getRegion(main.blocks[i].getEl());        
211     }
215 block_class.prototype.init_buttons = function() {
216     var viewbutton = main.mk_button('a', '/t/hide.gif', main.portal.strings['hide'], [['class', 'icon hide']]);
217     YAHOO.util.Event.addListener(viewbutton, 'click', this.toggle_hide, this, true);
219     var deletebutton = main.mk_button('a', '/t/delete.gif', main.portal.strings['delete'], [['class', 'icon delete']]);
220     YAHOO.util.Event.addListener(deletebutton, 'click', this.delete_button, this, true);
222     this.viewbutton = viewbutton;
224     buttonCont = YAHOO.util.Dom.getElementsByClassName('commands', 'div', this.getEl())[0];
226     if (buttonCont) {
227         buttonCont.appendChild(viewbutton);
228         buttonCont.appendChild(deletebutton);
229     }
233 block_class.prototype.toggle_hide = function(e, target, isCosmetic) {
234     var strhide = main.portal.strings['hide'];
235     var strshow = main.portal.strings['show'];
236     if (YAHOO.util.Dom.hasClass(this.getEl(), 'hidden')) {
237         this.getEl().className = this.originalClass;
238         this.viewbutton.childNodes[0].src = this.viewbutton.childNodes[0].src.replace(/show.gif/i, 'hide.gif');
239         this.viewbutton.childNodes[0].alt = this.viewbutton.childNodes[0].alt.replace(strshow, strhide);
240         this.viewbutton.title = this.viewbutton.title.replace(strshow, strhide);
242         if (!isCosmetic) {
243             main.connect('POST', 'class=block&field=visible', null,
244                     'value=1&instanceId='+this.instanceId);
245         }
246     } else {
247         this.originalClass = this.getEl().className;
248         this.getEl().className = "hidden sideblock";
249         this.viewbutton.childNodes[0].src = this.viewbutton.childNodes[0].src.replace(/hide.gif/i,'show.gif');
250         this.viewbutton.childNodes[0].alt = this.viewbutton.childNodes[0].alt.replace(strhide, strshow);
251         this.viewbutton.title = this.viewbutton.title.replace(strhide, strshow);
253         if (!isCosmetic) {
254             main.connect('POST', 'class=block&field=visible', null,
255                     'value=0&instanceId='+this.instanceId);
256         }
257     }
261 block_class.prototype.delete_button = function() { 
262     // Remove from local model.
263     if (main.rightcolumn.has_block(this)) {
264         main.rightcolumn.remove_block(this);
265     } else if (main.leftcolumn.has_block(this)) {
266         main.leftcolumn.remove_block(this);
267     } 
268     // Remove block from the drag and drop group in YUI.
269     this.removeFromGroup('blocks');
271     // Remove from remote model.
272     main.connect('POST', 'class=block&action=DELETE&instanceId='+this.instanceId);
273         
274     // Remove from view
275     main.blocks.splice(main.get_block_index(this), 1);
276     this.getEl().parentNode.removeChild(this.getEl());
278     if (this.debug) {
279         YAHOO.log("Deleting "+this.getEl().id);
280     }
284 block_class.prototype.updatePosition = function(index, columnId) {
285     //update the db for the position    
286     main.connectQueue_add('POST', 'class=block&field=position&positiontoinsert='+positiontoinsert +'&positiontoinsertid='+positiontoinsertid, null,
287             'value='+index+'&column='+columnId+'&instanceId='+this.instanceId);
289     if (this.debug) {
290         YAHOO.log("Updating position of "+this.getEl().id+" to index "+index+" on column "+columnId);
291     }
296  * column class, DD targets
297  */
299 function column_class(id,group,config,ident){
300     this.init_column(id,group,config,ident);
302 YAHOO.extend(column_class, YAHOO.util.DDTarget);
304 column_class.prototype.debug = false;
306 column_class.prototype.init_column = function(id, group,config,ident){
307         if (!id) { return; }
308         
309         this.initTarget(id,group,config);
310         this.blocks = new Array();
311         this.ident = ident;
312         
313 //      YAHOO.log("init_column "+id+"-"+el.id);
314         this.region = YAHOO.util.Region.getRegion(id);    
316     }
319 column_class.prototype.find_sub_collision = function(dragRegion){ 
320         if(this.debug)YAHOO.log("Finding Collisions on "+this.getEl().id+" with "+this.blocks.length+" blocks");
321         //find collisions with sub_elements(blocks), return array of collisions with regions of collision        
322         var collisions = new Array();      
323         for(i=0;i<this.blocks.length;i++){
324             if(this.debug)YAHOO.log("testing region "+this.blocks[i].region+" against" + dragRegion + "intersect ="+this.blocks[i].region.intersect(dragRegion));
325             var intersect = this.blocks[i].region.intersect(dragRegion);
326             if(intersect != null){
327                 index = collisions.length;
328                 collisions[index] = new Array();
329                 collisions[index][0] = i;
330                 collisions[index][1] = this.blocks[i].region.intersect(dragRegion);
331                 if(this.debug)YAHOO.log(index+" Collides with "+this.blocks[i].getEl().id+" area" + collisions[index][1].getArea());
332             }
333         }
334       return collisions;  
335     }
337 column_class.prototype.add_block = function(el){
338        this.blocks[this.blocks.length] = el;
339      }
341 column_class.prototype.insert_block = function(el,targetel){
342         var blockcount = this.blocks.length;
343         var found = -1;
344         var tempStore = nextStore = null;
345         for(var i=0;i<blockcount;i++){
346             if (found >= 0) {
347                 tempStore = this.blocks[i];
348                 this.blocks[i] = nextStore;
349                 nextStore = tempStore;           
350                                                 
351             }else if(this.blocks[i] == targetel){
352                 found = i;
353                 nextStore = this.blocks[i];
354                 this.blocks[i] = el;               
355                 blockcount++;
356             }                        
357         }
358         
359         if(found<0){//insert at end
360             found = this.blocks.length; 
361             this.add_block(el);              
362                     
363         }
364         
365         el.updatePosition(found,this.ident);
366     }
368 column_class.prototype.has_block = function(el){
369         var blockcount = this.blocks.length;
370         for(var i=0;i<blockcount;i++)
371             if(this.blocks[i]==el)
372                  return true;
373         return false;
374     }
375     
376     
377 column_class.prototype.remove_block = function(el){
378         var blockcount = this.blocks.length;
379         var found = false;
380         for(var i=0;i<blockcount;i++){
381             if(this.blocks[i]==el || found){
382                if(!found)
383                     found = true;
384           
385                if(i < blockcount-1){
386                    this.blocks[i] = this.blocks[i+1];                   
387                }else{
388                     this.blocks.pop();                     
389                }
390             }
391         }
392         YAHOO.log("column "+this.indent+" has "+blockcount+"blocks");
393     }
394     
395     
396