diff --git a/e107_plugins/pm/pm.php b/e107_plugins/pm/pm.php index 5baccb963..365f61506 100755 --- a/e107_plugins/pm/pm.php +++ b/e107_plugins/pm/pm.php @@ -11,14 +11,24 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_plugins/pm/pm.php,v $ -| $Revision: 1.9 $ -| $Date: 2009-02-02 17:42:59 $ -| $Author: e107steved $ +| $Revision: 1.10 $ +| $Date: 2009-07-21 14:44:11 $ +| $Author: e107coders $ +----------------------------------------------------------------------------+ */ $retrieve_prefs[] = 'pm_prefs'; require_once("../../class2.php"); + + if($_POST['keyword']) + { + pm_user_lookup(); + } + + + + + require_once(e_PLUGIN."pm/pm_class.php"); require_once(e_PLUGIN."pm/pm_func.php"); $lan_file = e_PLUGIN."pm/languages/".e_LANGUAGE.".php"; @@ -129,6 +139,12 @@ if("get" == $action) exit; } +$eplug_js[] = e_FILE."jslib/prototype/prototype.js"; +$eplug_js[] = e_PLUGIN."pm/textboxlist.js"; +$eplug_js[] = e_PLUGIN."pm/test.js"; +$eplug_css[] = e_PLUGIN."pm/test.css"; +// test. + require_once(HEADERF); if(isset($_POST['postpm'])) @@ -436,5 +452,53 @@ function post_pm() $_POST['from_id'] = USERID; return $msg.$pm->add($_POST); } +} + + +function pm_user_lookup() +{ + global $sql; + + + $query = "SELECT * FROM #user WHERE user_name REGEXP '^".$_POST['keyword']."' "; + if($sql -> db_Select_gen($query)) + { + echo "["; + while($row = $sql-> db_Fetch()) + { + $u[] = "{\"caption\":\"".$row['user_name']."\",\"value\":".$row['user_id']."}"; + } + + echo implode(",",$u); + echo "]"; + + // echo "[{\"caption\":\"Manuel Mujica Lainez\",\"value\":4},{\"caption\":\"Gustavo Nielsen\",\"value\":3},{\"caption\":\"Silvina Ocampo\",\"value\":3},{\"caption\":\"Victoria Ocampo\", \"value\":3},{\"caption\":\"Hector German Oesterheld\", \"value\":3},{\"caption\":\"Olga Orozco\", \"value\":3},{\"caption\":\"Juan L. Ortiz\", \"value\":3},{\"caption\":\"Alicia Partnoy\", \"value\":3},{\"caption\":\"Roberto Payro\", \"value\":3},{\"caption\":\"Ricardo Piglia\", \"value\":3},{\"caption\":\"Felipe Pigna\", \"value\":3},{\"caption\":\"Alejandra Pizarnik\", \"value\":3},{\"caption\":\"Antonio Porchia\", \"value\":3},{\"caption\":\"Juan Carlos Portantiero\", \"value\":3},{\"caption\":\"Manuel Puig\", \"value\":3},{\"caption\":\"Andres Rivera\", \"value\":3},{\"caption\":\"Mario Rodriguez Cobos\", \"value\":3},{\"caption\":\"Arturo Andres Roig\", \"value\":3},{\"caption\":\"Ricardo Rojas\", \"value\":3}]"; + } + + exit; +} + +function headerjs() +{ +return " "; + + + + + } ?> \ No newline at end of file diff --git a/e107_plugins/pm/pm_shortcodes.php b/e107_plugins/pm/pm_shortcodes.php index 6884acae9..f061fa875 100755 --- a/e107_plugins/pm/pm_shortcodes.php +++ b/e107_plugins/pm/pm_shortcodes.php @@ -11,9 +11,9 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_plugins/pm/pm_shortcodes.php,v $ -| $Revision: 1.9 $ -| $Date: 2009-02-02 17:43:00 $ -| $Author: e107steved $ +| $Revision: 1.10 $ +| $Date: 2009-07-21 14:44:13 $ +| $Author: e107coders $ +----------------------------------------------------------------------------+ */ if (!defined('e107_INIT')) { exit; } @@ -31,6 +31,27 @@ if($pm_info['from_name']) require_once(e_HANDLER."user_select_class.php"); $us = new user_select; $type = ($pm_prefs['dropdown'] == TRUE ? 'list' : 'popup'); + + +$ret = "
    + +
  1. + +
    + +
    Type the name of a user
    +
      + +
    + +
    +
  2. +
"; + +return $ret; + + + if(check_class($pm_prefs['multi_class'])) { $ret = $us->select_form($type, 'textarea.pm_to'); diff --git a/e107_plugins/pm/test.css b/e107_plugins/pm/test.css new file mode 100644 index 000000000..0fc5fc65d --- /dev/null +++ b/e107_plugins/pm/test.css @@ -0,0 +1,40 @@ +/* TextboxList sample CSS */ +ul.holder { margin: 0; border: 1px solid #999; overflow: hidden; height: auto !important; height: 1%; padding: 4px 5px 0; } +*:first-child+html ul.holder { padding-bottom: 2px; } * html ul.holder { padding-bottom: 2px; } /* ie7 and below */ +ul.holder li { float: left; list-style-type: none; margin: 0 5px 4px 0; } +ul.holder li.bit-box, ul.holder li.bit-input input { font: 11px "Lucida Grande", "Verdana"; } +ul.holder li.bit-box { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; border: 1px solid #CAD8F3; background: #DEE7F8; padding: 1px 5px 2px; } +ul.holder li.bit-box-focus { border-color: #598BEC; background: #598BEC; color: #fff; } +ul.holder li.bit-input input { width: 150px; margin: 0; border: none; outline: 0; padding: 3px 0 2px; } /* no left/right padding here please */ +ul.holder li.bit-input input.smallinput { width: 20px; } + +/* Facebook demo CSS */ +form, #add { border: 1px solid #999; width: 550px; margin: 50px; padding: 20px 30px 10px; } +form ol { font: 11px "Lucida Grande", "Verdana"; margin: 0; padding: 0; } +form ol li.input-text { margin-bottom: 10px; list-style-type: none; border-bottom: 1px dotted #999; padding-bottom: 10px; } +form ol li.input-text label { font-weight: bold; cursor: pointer; display: block; font-size: 13px; margin-bottom: 10px; } +form ol li.input-text input { width: 500px; padding: 5px 5px 6px; font: 11px "Lucida Grande", "Verdana"; border: 1px solid #999; } +form ul.holder { width: 500px; } +#facebook-list ul.holder li.bit-box, #apple-list ul.holder li.bit-box { padding-right: 15px; position: relative; } +#apple-list ul.holder li.bit-input { margin: 0; } +#apple-list ul.holder li.bit-input input.smallinput { width: 5px; } +ul.holder li.bit-hover { background: #BBCEF1; border: 1px solid #6D95E0; } +ul.holder li.bit-box-focus { border-color: #598BEC; background: #598BEC; color: #fff; } +ul.holder li.bit-box a.closebutton { position: absolute; right: 4px; top: 5px; display: block; width: 7px; height: 7px; font-size: 1px; background: url('images/close.gif'); } +ul.holder li.bit-box a.closebutton:hover { background-position: 7px; } +ul.holder li.bit-box-focus a.closebutton, ul.holder li.bit-box-focus a.closebutton:hover { background-position: bottom; } + +/* Autocompleter */ + +#facebook-auto { display: none; position: absolute; width: 512px; background: #eee; } +#facebook-auto .default { padding: 5px 7px; border: 1px solid #ccc; border-width: 0 1px 1px; } +#facebook-auto ul { display: none; margin: 0; padding: 0; overflow: auto; } +#facebook-auto ul li { padding: 5px 12px; z-index: 1000; cursor: pointer; margin: 0; list-style-type: none; border: 1px solid #ccc; border-width: 0 1px 1px; font: 11px "Lucida Grande", "Verdana"; } +#facebook-auto ul li em { font-weight: bold; font-style: normal; background: #ccc; } +#facebook-auto ul li.auto-focus { background: #4173CC; color: #fff; } +#facebook-auto ul li.auto-focus em { background: none; } + +#demo ul.holder li.bit-input input { padding: 2px 0 1px; border: 1px solid #999; } +#add a { color: #666; } +#add-test { width: 100px; padding: 2px; } +#button_container { margin-left: 70px; margin-bottom: 30px;} \ No newline at end of file diff --git a/e107_plugins/pm/test.js b/e107_plugins/pm/test.js new file mode 100644 index 000000000..041e994d3 --- /dev/null +++ b/e107_plugins/pm/test.js @@ -0,0 +1,209 @@ +/* + Proto!MultiSelect 0.2 + - Prototype version required: 6.0 + + Credits: + - Idea: Facebook + - Guillermo Rauch: Original MooTools script + - Ran Grushkowsky/InteRiders Inc. : Porting into Prototype and further development + + Changelog: + - 0.1: translation of MooTools script + - 0.2: renamed from Proto!TextboxList to Proto!MultiSelect, added new features/bug fixes + added feature: support to fetch list on-the-fly using AJAX Credit: Cheeseroll + added feature: support for value/caption + added feature: maximum results to display, when greater displays a scrollbar Credit: Marcel + added feature: filter by the beginning of word only or everywhere in the word Credit: Kiliman + added feature: shows hand cursor when going over options + bug fix: the click event stopped working + bug fix: the cursor does not 'travel' when going up/down the list Credit: Marcel +*/ + +/* Copyright: InteRiders - Distributed under MIT - Keep this message! */ + +var FacebookList = Class.create(TextboxList, { + + loptions: $H({ + autocomplete: { + 'opacity': 0.8, + 'maxresults': 10, + 'minchars': 1 + } + }), + + initialize: function($super,element, autoholder, options, func) { + $super(element, options); + this.data = []; + this.autoholder = $(autoholder).setOpacity(this.loptions.get('autocomplete').opacity); + this.autoholder.observe('mouseover',function() {this.curOn = true;}.bind(this)).observe('mouseout',function() {this.curOn = false;}.bind(this)); + this.autoresults = this.autoholder.select('ul').first(); + var children = this.autoresults.select('li'); + children.each(function(el) { this.add({value:el.readAttribute('value'),caption:el.innerHTML}); }, this); + }, + + autoShow: function(search) { + this.autoholder.setStyle({'display': 'block'}); + this.autoholder.descendants().each(function(e) { e.hide() }); + if(! search || ! search.strip() || (! search.length || search.length < this.loptions.get('autocomplete').minchars)) + { + this.autoholder.select('.default').first().setStyle({'display': 'block'}); + this.resultsshown = false; + } else { + this.resultsshown = true; + this.autoresults.setStyle({'display': 'block'}).update(''); + if (this.options.get('wordMatch')) + var regexp = new RegExp("(^|\\s)"+search,'i') + else + var regexp = new RegExp(search,'i') + var count = 0; + this.data.filter(function(str) { return str ? regexp.test(str.evalJSON(true).caption) : false; }).each(function(result, ti) { + count++; + if(ti >= this.loptions.get('autocomplete').maxresults) return; + var that = this; + var el = new Element('li'); + el.observe('click',function(e) { + e.stop(); + that.autoAdd(this); + }).observe('mouseover',function() { + that.autoFocus(this); + }).update(this.autoHighlight(result.evalJSON(true).caption, search)); + this.autoresults.insert(el); + el.cacheData('result', result.evalJSON(true)); + if(ti == 0) this.autoFocus(el); + }, this); + } + if (count > this.options.get('results')) + this.autoresults.setStyle({'height': (this.options.get('results')*24)+'px'}); + else + this.autoresults.setStyle({'height': (count?(count*24):0)+'px'}); + return this; + }, + + autoHighlight: function(html, highlight) { + return html.gsub(new RegExp(highlight,'i'), function(match) { + return '' + match[0] + ''; + }); + }, + + autoHide: function() { + this.resultsshown = false; + this.autoholder.hide(); + return this; + }, + + autoFocus: function(el) { + if(! el) return; + if(this.autocurrent) this.autocurrent.removeClassName('auto-focus'); + this.autocurrent = el.addClassName('auto-focus'); + return this; + }, + + autoMove: function(direction) { + if(!this.resultsshown) return; + this.autoFocus(this.autocurrent[(direction == 'up' ? 'previous' : 'next')]()); + this.autoresults.scrollTop = this.autocurrent.positionedOffset()[1]-this.autocurrent.getHeight(); + return this; + }, + + autoFeed: function(text) { + if (this.data.indexOf(Object.toJSON(text)) == -1) + this.data.push(Object.toJSON(text)); + return this; + }, + + autoAdd: function(el) { + if(!el || ! el.retrieveData('result')) return; + this.add(el.retrieveData('result')); + delete this.data[this.data.indexOf(Object.toJSON(el.retrieveData('result')))]; + this.autoHide(); + var input = this.lastinput || this.current.retrieveData('input'); + input.clear().focus(); + return this; + }, + + createInput: function($super,options) { + var li = $super(options); + var input = li.retrieveData('input'); + input.observe('keydown', function(e) { + this.dosearch = false; + switch(e.keyCode) { + case Event.KEY_UP: e.stop(); return this.autoMove('up'); + case Event.KEY_DOWN: e.stop(); return this.autoMove('down'); + case Event.KEY_RETURN: + e.stop(); + if(! this.autocurrent) break; + this.autoAdd(this.autocurrent); + this.autocurrent = false; + this.autoenter = true; + break; + case Event.KEY_ESC: + this.autoHide(); + if(this.current && this.current.retrieveData('input')) + this.current.retrieveData('input').clear(); + break; + default: this.dosearch = true; + } + }.bind(this)); + input.observe('keyup',function(e) { + + switch(e.keyCode) { + case Event.KEY_UP: + case Event.KEY_DOWN: + case Event.KEY_RETURN: + case Event.KEY_ESC: + break; + default: + if (!Object.isUndefined(this.options.get('fetchFile'))) { + new Ajax.Request(this.options.get('fetchFile'), { + parameters: {keyword: input.value}, + onSuccess: function(transport) { + transport.responseText.evalJSON(true).each(function(t){this.autoFeed(t)}.bind(this)); + this.autoShow(input.value); + }.bind(this) + }); + } + else + if(this.dosearch) this.autoShow(input.value); + } + }.bind(this)); + input.observe(Prototype.Browser.IE ? 'keydown' : 'keypress', function(e) { + if(this.autoenter) e.stop(); + this.autoenter = false; + }.bind(this)); + return li; + }, + + createBox: function($super,text, options) { + var li = $super(text, options); + li.observe('mouseover',function() { + this.addClassName('bit-hover'); + }).observe('mouseout',function() { + this.removeClassName('bit-hover') + }); + var a = new Element('a', { + 'href': '#', + 'class': 'closebutton' + } + ); + a.observe('click',function(e) { + e.stop(); + if(! this.current) this.focus(this.maininput); + this.dispose(li); + }.bind(this)); + li.insert(a).cacheData('text', Object.toJSON(text)); + return li; + } + +}); + +Element.addMethods({ + onBoxDispose: function(item,obj) { obj.autoFeed(item.retrieveData('text').evalJSON(true)); }, + onInputFocus: function(el,obj) { obj.autoShow(); }, + onInputBlur: function(el,obj) { + obj.lastinput = el; + if(!obj.curOn) { + obj.blurhide = obj.autoHide.bind(obj).delay(0.1); + } + }, + filter:function(D,E){var C=[];for(var B=0,A=this.length;B + - Guillermo Rauch: Original MooTools script + - Ran Grushkowsky/InteRiders Inc. : Porting into Prototype and further development + + Changelog: + - 0.1: translation of MooTools script + - 0.2: renamed from Proto!TextboxList to Proto!MultiSelect, added new features/bug fixes + added feature: support to fetch list on-the-fly using AJAX Credit: Cheeseroll + added feature: support for value/caption + added feature: maximum results to display, when greater displays a scrollbar Credit: Marcel + added feature: filter by the beginning of word only or everywhere in the word Credit: Kiliman + added feature: shows hand cursor when going over options + bug fix: the click event stopped working + bug fix: the cursor does not 'travel' when going up/down the list Credit: Marcel +*/ + +/* Copyright: InteRiders - Distributed under MIT - Keep this message! */ + +var ResizableTextbox = Class.create({ + + options: $H({ + min: 5, + max: 500, + step: 7 + }), + + initialize: function(element, options) { + var that = this; + this.options.update(options); + this.el = $(element); + this.width = this.el.offsetWidth; + this.el.observe( + 'keyup', function() { + var newsize = that.options.get('step') * $F(this).length; + if(newsize <= that.options.get('min')) newsize = that.width; + if(! ($F(this).length == this.retrieveData('rt-value') || newsize <= that.options.min || newsize >= that.options.max)) + this.setStyle({'width': newsize}); + }).observe('keydown', function() { + this.cacheData('rt-value', $F(this).length); + }); + } +}); + +var TextboxList = Class.create({ + + options: $H({/* + onFocus: $empty, + onBlur: $empty, + onInputFocus: $empty, + onInputBlur: $empty, + onBoxFocus: $empty, + onBoxBlur: $empty, + onBoxDispose: $empty,*/ + resizable: {}, + className: 'bit', + separator: '###', + extrainputs: true, + startinput: true, + hideempty: true, + fetchFile: undefined, + results: 10, + wordMatch: false + }), + + initialize: function(element, options) { + this.options.update(options); + this.element = $(element).hide(); + this.bits = new Hash(); + this.events = new Hash(); + this.count = 0; + this.current = false; + this.maininput = this.createInput({'class': 'maininput'}); + this.holder = new Element('ul', { + 'class': 'holder' + }).insert(this.maininput); + this.element.insert({'before':this.holder}); + this.holder.observe('click', function(event){ + event.stop(); + if(this.maininput != this.current) this.focus(this.maininput); + }.bind(this)); + this.makeResizable(this.maininput); + this.setEvents(); + }, + + setEvents: function() { + document.observe(Prototype.Browser.IE ? 'keydown' : 'keypress', function(e) { + if(! this.current) return; + if(this.current.retrieveData('type') == 'box' && e.keyCode == Event.KEY_BACKSPACE) e.stop(); + }.bind(this)); + + document.observe( + 'keyup', function(e) { + e.stop(); + if(! this.current) return; + switch(e.keyCode){ + case Event.KEY_LEFT: return this.move('left'); + case Event.KEY_RIGHT: return this.move('right'); + case Event.KEY_DELETE: + case Event.KEY_BACKSPACE: return this.moveDispose(); + } + }.bind(this)).observe( + 'click', function() { document.fire('blur'); }.bindAsEventListener(this) + ); + }, + + update: function() { + this.element.value = this.bits.values().join(this.options.get('separator')); + return this; + }, + + add: function(text, html) { + var id = this.options.get('className') + '-' + this.count++; + var el = this.createBox($pick(html, text), {'id': id}); + (this.current || this.maininput).insert({'before':el}); + el.observe('click', function(e) { + e.stop(); + this.focus(el); + }.bind(this)); + this.bits.set(id, text.value); + if(this.options.get('extrainputs') && (this.options.get('startinput') || el.previous())) this.addSmallInput(el,'before'); + return el; + }, + + addSmallInput: function(el, where) { + var input = this.createInput({'class': 'smallinput'}); + el.insert({}[where] = input); + input.cacheData('small', true); + this.makeResizable(input); + if(this.options.get('hideempty')) input.hide(); + return input; + }, + + dispose: function(el) { + this.bits.unset(el.id); + if(el.previous() && el.previous().retrieveData('small')) el.previous().remove(); + if(this.current == el) this.focus(el.next()); + if(el.retrieveData('type') == 'box') el.onBoxDispose(this); + el.remove(); + return this; + }, + + focus: function(el, nofocus) { + if(! this.current) el.fire('focus'); + else if(this.current == el) return this; + this.blur(); + el.addClassName(this.options.get('className') + '-' + el.retrieveData('type') + '-focus'); + if(el.retrieveData('small')) el.setStyle({'display': 'block'}); + if(el.retrieveData('type') == 'input') { + el.onInputFocus(this); + if(! nofocus) this.callEvent(el.retrieveData('input'), 'focus'); + } + else el.fire('onBoxFocus'); + this.current = el; + return this; + }, + + blur: function(noblur) { + if(! this.current) return this; + if(this.current.retrieveData('type') == 'input') { + var input = this.current.retrieveData('input'); + if(! noblur) this.callEvent(input, 'blur'); + input.onInputBlur(this); + } + else this.current.fire('onBoxBlur'); + if(this.current.retrieveData('small') && ! input.get('value') && this.options.get('hideempty')) + this.current.hide(); + this.current.removeClassName(this.options.get('className') + '-' + this.current.retrieveData('type') + '-focus'); + this.current = false; + return this; + }, + + createBox: function(text, options) { + return new Element('li', options).addClassName(this.options.get('className') + '-box').update(text.caption).cacheData('type', 'box'); + }, + + createInput: function(options) { + var li = new Element('li', {'class': this.options.get('className') + '-input'}); + var el = new Element('input', Object.extend(options,{'type': 'text'})); + el.observe('click', function(e) { e.stop(); }).observe('focus', function(e) { if(! this.isSelfEvent('focus')) this.focus(li, true); }.bind(this)).observe('blur', function() { if(! this.isSelfEvent('blur')) this.blur(true); }.bind(this)).observe('keydown', function(e) { this.cacheData('lastvalue', this.value).cacheData('lastcaret', this.getCaretPosition()); }); + var tmp = li.cacheData('type', 'input').cacheData('input', el).insert(el); + return tmp; + }, + + callEvent: function(el, type) { + this.events.set(type, el); + el[type](); + }, + + isSelfEvent: function(type) { + return (this.events.get(type)) ? !! this.events.unset(type) : false; + }, + + makeResizable: function(li) { + var el = li.retrieveData('input'); + el.cacheData('resizable', new ResizableTextbox(el, Object.extend(this.options.get('resizable'),{min: el.offsetWidth, max: (this.element.getWidth()?this.element.getWidth():0)}))); + return this; + }, + + checkInput: function() { + var input = this.current.retrieveData('input'); + return (! input.retrieveData('lastvalue') || (input.getCaretPosition() === 0 && input.retrieveData('lastcaret') === 0)); + }, + + move: function(direction) { + var el = this.current[(direction == 'left' ? 'previous' : 'next')](); + if(el && (! this.current.retrieveData('input') || ((this.checkInput() || direction == 'right')))) this.focus(el); + return this; + }, + + moveDispose: function() { + if(this.current.retrieveData('type') == 'box') return this.dispose(this.current); + if(this.checkInput() && this.bits.keys().length && this.current.previous()) return this.focus(this.current.previous()); + } + +}); + +//helper functions +Element.addMethods({ + getCaretPosition: function() { + if (this.createTextRange) { + var r = document.selection.createRange().duplicate(); + r.moveEnd('character', this.value.length); + if (r.text === '') return this.value.length; + return this.value.lastIndexOf(r.text); + } else return this.selectionStart; + }, + cacheData: function(element, key, value) { + if (Object.isUndefined(this[$(element).identify()]) || !Object.isHash(this[$(element).identify()])) + this[$(element).identify()] = $H(); + this[$(element).identify()].set(key,value); + return element; + }, + retrieveData: function(element,key) { + return this[$(element).identify()].get(key); + } +}); + +function $pick(){for(var B=0,A=arguments.length;B