Layer = { current_opened_layer: false, click_handler: false, defered: null, is_ie6: function() { return (navigator.userAgent.toLowerCase().indexOf('msie 6') != -1) || (navigator.userAgent.toLowerCase().indexOf('msie 7.0') != -1); }, show_row_layer: function(layer_id) { if (!Layer.is_ie6()) { setDisplayForElement('table-row', layer_id); appear(layer_id, {'duration': 1.5}); } else { setDisplayForElement('block', layer_id); showElement(layer_id); } }, /* * Do position one later related to another layer * * align - object with two property: * align.h - horizontal -> 'above', 'under' * align.v - vertial -> 'left', 'center', right' * * default behavior = left + under */ set_position: function(layer_id, positional_obj, align) { var layer = getElement(layer_id); var pos_relative = getElementPosition(positional_obj); var pos = Coordinates(0,0); var dim = getElementDimensions(positional_obj); var layer_dim = getElementDimensions(layer); var viewport_dim = getViewportDimensions(); var viewport_pos = getViewportPosition(); if (!align) { align = {v: 'under', h: 'right'}; } pos.x = parseInt(getStyle(layer, 'top')); pos.y = parseInt(getStyle(layer, 'left')); switch (align.v) { case 'under': pos.y = pos_relative.y + dim.h + 1; break; case 'above': pos.y = pos_relative.y - layer_dim.h + 1; break; case 'center': pos.y = viewport_pos.y + viewport_dim.h/2 - layer_dim.h/2 ; break; } switch (align.h) { case 'right': pos.x = pos_relative.x + dim.w - layer_dim.w ; break; case 'left': pos.x = pos_relative.x; break; case 'center': pos.x = viewport_dim.w/2 - layer_dim.w/2; break; } if (layer_dim.w + pos.x + 5 > viewport_dim.w) { pos.x = viewport_dim.w - 50 - layer_dim.w; } if (pos.x < 5) { pos.x = 5; } setElementPosition(layer, pos); }, show: function(layer_id, positional_obj, align) { var layer = getElement(layer_id); if (Layer.current_opened_layer && Layer.current_opened_layer != layer) { Layer._hide(Layer.current_opened_layer); } if (Layer.current_opened_layer == layer) { return Layer.defered; } Layer.defered = new Deferred(); if (positional_obj) { Layer.set_position(layer_id, positional_obj, align); } showElement(layer); Layer.current_opened_layer = layer; callLater(0, Layer.setup_onclick); return Layer.defered; }, hide: function(obj) { hideElement(obj); Layer.current_opened_layer = false; Layer.remove_onclick(); if (Layer.defered) { Layer.defered.callback() Layer.defered = null; } }, toggle_display : function(layer_id, positional_obj, align) { var layer = getElement(layer_id); var current = Layer.current_opened_layer; if (Layer.current_opened_layer) { Layer.hide(Layer.current_opened_layer); if (layer != current) { // force open layer when request toggle while another layer was opened return Layer.show(layer_id, positional_obj, align); } return null; } else { return Layer.show(layer_id, positional_obj, align); } }, setup_onclick: function() { Layer.click_handler = connect(window, 'onclick', Layer.onclick); }, remove_onclick: function() { if (Layer.click_handler) { disconnect(Layer.click_handler); } }, onclick: function(event) { if (event.target() != Layer.current_opened_layer && !isChildNode(event.target(), Layer.current_opened_layer) ) { Layer.hide(Layer.current_opened_layer); event.stop(); } }, create_layer: function(layer_id, layer_class) { var doc = currentDocument(); if (!layer_class) { layer_class = "layer_widget"; } var layer_div = DIV({'class': layer_class, 'id': layer_id}); appendChildNodes(doc.body, layer_div); return layer_div; }, get_or_create_layer: function(layer_id, layer_class) { var layer = getElement(layer_id); if (!layer) { return Layer.create_layer(layer_id, layer_class); } return layer; } } Ajax = { /* Ajax utility for django Functions: load_json - load json document with additional GET argument action=load_json load_html - expect for DjHDGutils.accept_ajax decorator on view; support debugging through popup window when 500 error occured load_select_list - perform load list with options for items list when it depend on choice in other select list; Example of using load_select_list together with django forms class TextForm(forms.Form): category = forms.ChoiceField(widget=forms.Select(attrs={'onchange': mark_safe("Ajax.load_select_list(this, 'id_subcategory', 'load_subcategory', '');")})) subcategory = forms.ChoiceField() */ debug_window: null, _write_debug: function(msg) { if (!Ajax.debug_window) { Ajax.debug_window = window.open("","debug","scrollbars,width=1024,height=800"); } Ajax.debug_window.focus(); Ajax.debug_window.document.write(msg); Ajax.debug_window.document.close(); }, load_json: function(url, args) { if (!args.action) { args['action'] = 'load_json'; } var base_df = new Deferred(); df = loadJSONDoc(url, args); df.addCallback(function(doc) { if (!doc.status || doc.status != 500) { return base_df.callback(doc); } else if (doc.status == 500) { if (doc.debug) { Ajax._write_debug(doc.debug_msg); } else { alert("Unexpected error while communication with server"); } } return base_df.errback(doc.status); }); df.addErrback(function(error) { return base_df.errback(error); }); return base_df; return df; }, load_html: function(url, args) { var base_df = new Deferred(); df = loadJSONDoc(url, args); df.addCallback(function(doc) { if (doc.status == 200) { return base_df.callback(doc.content); } else if (doc.status == 500) { if (doc.debug) { Ajax._write_debug(doc.debug_msg); } else { alert("Unexpected error while communication with server"); } } return base_df.errback(doc.status); }); df.addErrback(function(error) { return base_df.errback(error); }); return base_df; }, load_select_list: function(obj, target_id, action, url) { var target = getElement(target_id); if (!obj.value) { replaceChildNodes(target); appendChildNodes(target,OPTION({'value':''}, '---------')); } else { df = Ajax.load_json(url, {'function': action, value: obj.value}); df.addCallback( function(doc) { replaceChildNodes(target); appendChildNodes(target,OPTION({'value':''}, '---------')); forEach(doc, function(item) { appendChildNodes(target, OPTION({'value': item.value} , item.label)); }); } ); } } }