From 6bd91ddffe86ebeb10420f05a232f8e779eaf86d Mon Sep 17 00:00:00 2001 From: Dieter Hametner Date: Sun, 29 Jul 2007 17:41:38 +0000 Subject: - Made vdr ajax requests work also via a static page. This is for browsers that don't support javascript (e.g. PDA browsers) - Implemented for AJAX request a visual notification how requested action performed. - Adapted styles for this. - Moded images for rounded boxes (formerly tip-hint-??.png) to central image directory and renamed them according to their color. This makes them reusable in different themes. - Adapted themes to this move. --- live/js/live/infowin.js | 167 ++++++++++++++++++++++++++++++++------------ live/js/live/liveajax.js | 2 +- live/js/live/pageenhance.js | 50 +++++++++++-- live/js/live/vdr_status.js | 8 ++- 4 files changed, 172 insertions(+), 55 deletions(-) (limited to 'live/js') diff --git a/live/js/live/infowin.js b/live/js/live/infowin.js index 1e35438..d12bd53 100644 --- a/live/js/live/infowin.js +++ b/live/js/live/infowin.js @@ -35,6 +35,7 @@ var InfoWin = new Class({ onShow: Class.empty, onHide: Class.empty, onDomExtend: Class.empty, + destroyOnHide: false, className: 'info', wm: false, // overide default window manager. draggable: true, @@ -42,15 +43,17 @@ var InfoWin = new Class({ buttonimg: 'transparent.png', bodyselect: 'div.content', titleselect: 'div.caption', - idSuffix: '-win-id', + classSuffix: '-win', + idSuffix: '-id', offsets: {'x': -16, 'y': -16} }, initialize: function(id, options){ this.setOptions(options); this.wm = this.options.wm || InfoWin.$wm; - this.winFrame = $(id + this.options.idSuffix); + this.winFrame = $(id + this.options.classSuffix + this.options.idSuffix); if (!$defined(this.winFrame)){ + this.buildFrame(id); this.build(id); this.wm.register(this); } @@ -63,40 +66,29 @@ var InfoWin = new Class({ // must return true if the body of the InfoWin has been filled // with the user data, false otherwise. build: function(id){ - this.winFrame = new Element('div', { - 'id': id + this.options.idSuffix, - 'class': this.options.className + '-win', - 'styles': { - 'position': 'absolute', - 'top': '0', - 'left': '0' - } - }); - // header of window: upper shadows, corners title and controls var top = new Element('div', { - 'class': this.options.className + '-win-top' + 'class': this.options.className + this.options.classSuffix + '-top' }).inject(this.winFrame); if (this.options.draggable) this.winFrame.makeDraggable({'handle': top}); top = new Element('div', { - 'class': this.options.className + '-win-c' + 'class': this.options.className + this.options.classSuffix + '-c' }).inject(top); this.titleBox = new Element('div', { - 'class': this.options.className + '-win-t' + 'class': this.options.className + this.options.classSuffix + '-t' }).inject(top); this.buttonBox = new Element('div', { - 'class': this.options.className + '-win-b' + 'class': this.options.className + this.options.classSuffix + '-b' }).inject(top); var cls = new Element('div', { 'class': 'close' }).inject(this.buttonBox); - var self = this; cls.addEvent('click', function(event){ var event = new Event(event); event.stop(); - return self.hide(); - }); + return this.hide(); + }.bind(this)); cls = new Element('img', { 'src': this.options.buttonimg, 'alt': 'close', @@ -106,22 +98,22 @@ var InfoWin = new Class({ // body of window: user content. var bdy = new Element('div', { - 'class': this.options.className + '-win-body' + 'class': this.options.className + this.options.classSuffix + '-body' }).inject(this.winFrame); bdy = new Element('div', { - 'class': this.options.className + '-win-c' + 'class': this.options.className + this.options.classSuffix + '-c' }).inject(bdy); this.winBody = new Element('div', { - 'class': this.options.className + '-win-s' + 'class': this.options.className + this.options.classSuffix + '-s' }).inject(bdy); // bottom border of window: lower shadows and corners, optional // resize handle. var bot = new Element('div', { - 'class': this.options.className + '-win-bot' + 'class': this.options.className + this.options.classSuffix + '-bot' }).inject(this.winFrame); bot = new Element('div', { - 'class': this.options.className + '-win-c' + 'class': this.options.className + this.options.classSuffix + '-c' }).inject(bot); if (this.options.resizable) { @@ -134,18 +126,37 @@ var InfoWin = new Class({ return this.fillBody(id); }, + buildFrame: function(id){ + this.winFrame = new Element('div', { + 'id': id + this.options.classSuffix + this.options.idSuffix, + 'class': this.options.className + this.options.classSuffix, + 'styles': { + 'position': 'absolute', + 'top': '0', + 'left': '0' + } + }); + }, + show: function(event){ - if (this.options.timeout) - this.timer = this.hide.delay(this.options.timeout, this); this.position(event); this.fireEvent('onShow', [this.winFrame]); this.wm.raise(this); + if (this.options.timeout) + this.timer = this.hide.delay(this.options.timeout, this); return false; }, hide: function(){ this.fireEvent('onHide', [this.winFrame]); - this.wm.bury(this); + if (this.options.destroyOnHide) { + this.wm.unregister(this); + for (var z in this) this[z] = null; + this.destroyed = true; + } + else { + this.wm.bury(this); + } return false; }, @@ -188,10 +199,10 @@ Class: InfoWin.Manager */ InfoWin.Manager = new Class({ options: { - zIndex: 100, closedContainer: 'infowin-closed', openedContainer: 'infowin-opened', onRegister: Class.empty, + onUnregister: Class.empty, onRaise: Class.empty, onBury: Class.empty }, @@ -216,23 +227,25 @@ InfoWin.Manager = new Class({ }, register: function(infoWin){ - var self = this; this.fireEvent('onRegister', [infoWin]); infoWin.winFrame.addEvent('click', function(){ - self.raise(infoWin); - }); + this.raise(infoWin); + }.bind(this)); infoWin.winFrame.inject(this.closedWins); }, + unregister: function(infoWin){ + this.fireEvent('onUnregister', [infoWin]); + infoWin.winFrame.remove(); + }, + raise: function(infoWin){ this.fireEvent('onRaise', [infoWin]); - infoWin.winFrame.remove(); infoWin.winFrame.inject(this.openedWins); }, bury: function(infoWin){ this.fireEvent('onBury', [infoWin]); - infoWin.winFrame.remove(); infoWin.winFrame.inject(this.closedWins); } }); @@ -260,21 +273,20 @@ InfoWin.Ajax = InfoWin.extend({ initialize: function(id, url, options){ this.parent(id, options); if ($defined(this.ajaxResponse)) { - var self = this; this.addEvent('onError', function(){ - self.hide.delay(1000, self); - }); + this.hide.delay(1000, this); + }.bind(this)); var ajax = new Ajax(url, { update: this.ajaxResponse, onComplete: function(text, xmldoc){ - self.fillTitle(id); - self.fillBody(id); - self.ajaxResponse.empty(); - }, + this.fillTitle(id); + this.fillBody(id); + this.ajaxResponse.remove(); + }.bind(this), onFailure: function(transport){ - self.titleBox.setHTML(self.options.errorMsg); - self.fireEvent('onError', [id, url]); - } + this.titleBox.setHTML(this.options.errorMsg); + this.fireEvent('onError', [id, url]); + }.bind(this) }).request('async=1'); } }, @@ -293,4 +305,71 @@ InfoWin.Ajax = InfoWin.extend({ } }); -InfoWin.Ajax.implement(new Events, new Options); + +/* +Class: Infowin.Notifier + + Creates a notification popup that disappears automaticaly. + Usefull for a confirmation message after a AJAX action request. + */ + +InfoWin.Notifier = InfoWin.extend({ + options: { + timeout: 2500, + destroyOnHide: true, + className: 'ok', + classSuffix: '-info', + message: '', + offsets: {'x': 16, 'y': 16} + }, + + initialize: function(id, options){ + this.parent(id, options); + }, + + build: function(id){ + /* top border of hint */ + var top = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-top' + }).inject(this.winFrame); + top = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-c' + }).inject(top); + + /* body of tip: some helper divs and content */ + var bdy = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-body' + }).inject(this.winFrame); + bdy = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-c' + }).inject(bdy); + this.winBody = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-s' + }).inject(bdy); + + /* bottom border of tip */ + var bot = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-bot' + }).inject(this.winFrame); + bot = new Element('div', { + 'class': this.options.className + this.options.classSuffix + '-c' + }).inject(bot); + + return this.fillBody(id); + }, + + fillBody: function(id){ + this.winFrame.setStyle('position', 'fixed'); + this.winBody.empty().setHTML(this.options.message); + return true; + }, + + position: function(event){ + var prop = {'x': 'left', 'y': 'top'}; + for (var z in prop) { + var pos = this.options.offsets[z]; + this.winFrame.setStyle(prop[z], pos); + } + } + }); + diff --git a/live/js/live/liveajax.js b/live/js/live/liveajax.js index a6a80ea..756727d 100644 --- a/live/js/live/liveajax.js +++ b/live/js/live/liveajax.js @@ -7,5 +7,5 @@ function LiveSimpleAjaxRequest(url, param, value) { var req = new Ajax(url, { method : 'post' - }).request(param + '=' + value); + }).request(param + '=' + value + '&async=1'); }; diff --git a/live/js/live/pageenhance.js b/live/js/live/pageenhance.js index 6d1ff10..cb2cbb1 100644 --- a/live/js/live/pageenhance.js +++ b/live/js/live/pageenhance.js @@ -11,16 +11,23 @@ var PageEnhance = new Class({ options: { epgLinkSelector: 'a[href^="epginfo.html?epgid"]', + actionLinkSelector: 'a[href^="vdr_request/"]', hintTipSelector: '*[title]', hintClassName: 'hint', + notifyIdPrefix: 'notify', infoWinStrings: { loadingMsg: 'loading', errorMsg: 'an error occured!' - } + }, + notifyStrings: { + successMsg: ' Success!', + errorMsg: ' failed!' + } }, initialize: function(options){ this.setOptions(options); + this.$notifyCount = 0; window.addEvent('domready', this.domReadySetup.bind(this)); window.addEvent('mousedown', this.mouseDownSetup.bind(this)); }, @@ -29,6 +36,7 @@ var PageEnhance = new Class({ domReadySetup: function(){ $$(this.options.epgLinkSelector).each(this.epgPopup.bind(this)); this.addHintTips($$(this.options.hintTipSelector)); + $$(this.options.actionLinkSelector).each(this.vdrRequest.bind(this)); }, // actions applied on mouse down. @@ -36,6 +44,15 @@ var PageEnhance = new Class({ $$('.' + this.options.hintClassName + '-tip').setStyle('visibility', 'hidden'); }, + // registered as 'onDomExtend' event for InfoWin. Takes care to + // enhance the new dom elements too. + domExtend: function(id, elems){ + var sel = '#' + id + ' ' + this.options.hintTipSelector; + elems = $$(sel); + this.addHintTips(elems); + $$('#' + id + ' ' + this.options.actionLinkSelector).each(this.vdrRequest.bind(this)); + }, + // Epg Popup function. Apply to all elements that should // pop up an Epg InfoWin window. epgPopup: function(el){ @@ -61,12 +78,31 @@ var PageEnhance = new Class({ } }, - // registered as 'onDomExtend' event for InfoWin. Takes care to - // enhance the new dom elements too. - domExtend: function(id, elems){ - var sel = '#' + id + ' ' + this.options.hintTipSelector; - elems = $$(sel); - this.addHintTips(elems); + // function that requests an action from the server vdr. + vdrRequest: function(el){ + el.addEvent('click', function(event, element){ + var href = $pick(element.href, ""); + if (href != "") { + this.$notifyCount++; + var req = new Ajax(href, { + method: 'post', + onComplete: function(text, xmldoc) { + try { + var success = xmldoc.getElementsByTagName('response').item(0).firstChild.nodeValue; + new InfoWin.Notifier(this.options.notifyIdPrefix + this.$notifyCount, { + className: success == '1' ? 'ok' : 'err', + message: success == '1' ? this.options.notifyStrings.successMsg : this.options.notifyStrings.errorMsg + }).show(event); + } catch(e) { + } + }.bind(this) + }); + req.request('async=1'); + event.stop(); + return false; + } + return true; + }.bindWithEvent(this, el)); }, // change normal 'title'-Attributes into enhanced hinttips diff --git a/live/js/live/vdr_status.js b/live/js/live/vdr_status.js index d16f2a3..c24ed72 100644 --- a/live/js/live/vdr_status.js +++ b/live/js/live/vdr_status.js @@ -117,7 +117,8 @@ var LiveVdrInfo = Ajax.extend({ case "prevchan": { if (textContent != "") { - docNode.href = "javascript:LiveSimpleAjaxRequest('switch_channel.xml', 'param', '" + textContent + "');"; + // docNode.href = "javascript:LiveSimpleAjaxRequest('switch_channel.xml', 'param', '" + textContent + "');"; + docNode.href = "vdr_request/switch_channel?param=" + textContent; docNode.style.visibility = "visible"; } else { @@ -128,11 +129,12 @@ var LiveVdrInfo = Ajax.extend({ case "pause": case "play": case "rwd": - case "ffw": + case "ffw": case "stop": { if (textContent != "") { - docNode.href = "javascript:LiveSimpleAjaxRequest('" + nodeName + "_recording.xml', 'param', '" + textContent + "');"; + // docNode.href = "javascript:LiveSimpleAjaxRequest('" + nodeName + "_recording.xml', 'param', '" + textContent + "');"; + docNode.href = "vdr_request/" + nodeName + "_recording?param=" + textContent; docNode.style.visibility = "visible"; } else { -- cgit v1.2.3