1 /*------------------------------------------------------------------------------- 2 * Xataface Web Application Framework 3 * Copyright (C) 2005-2009 Web Lite Solutions Corp (shannah@sfu.ca) 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 *------------------------------------------------------------------------------- 19 */ 20 /** 21 * This jquery plugin allows you to convert any HTML element or field into 22 * a record browser. Clicking the browser button will open a modal dialog 23 * that allows the user to search and browse through a number of records 24 * in a table. 25 * 26 * Example usage: 27 * 28 * <a href="#" id="selector">Click me to find stuff</a> 29 * ... 30 * 31 * $('#selector').RecordBrowser({ 32 * table: 'people', 33 * filters: { 34 * group_id: 10 35 * }, 36 * callback: function(values){ 37 * // values is an object with the records that the user 38 * // selected 39 * for ( var id in values ){ 40 * // id is the id of the record 41 * // values[id] is the title of the record 42 * } 43 * } 44 * }); 45 * 46 * Alternatively you could use the RecordBrowserWidget function to convert a text field 47 * into a RecordBrowser: 48 * 49 * <input type="text" id="textfield"/> 50 * ... 51 * $('#textfield').RecordBrowserWidget({ 52 * table: 'people', 53 * filters: { 54 * group_id: 10 55 * }, 56 * callback: function(values){ 57 * // values is an object with the records that the user 58 * // selected 59 * for ( var id in values ){ 60 * // id is the id of the record 61 * // values[id] is the title of the record 62 * } 63 * } 64 * }); 65 * 66 */ 67 (function ($){ 68 var xataface = {}; 69 xataface.RecordBrowser = function(o){ 70 /** 71 * The name of the table to browse for records in. 72 * @var string 73 */ 74 this.table = null; 75 76 /** 77 * The name of the column to use as the value in the option list. 78 * Set this value to __id__ to use the record id. 79 * If this value is blank, then the primary key is used so long as 80 * the primary key only has a single column. If it is a compound 81 * primary key, then the record id is used by default. 82 * @var string 83 */ 84 this.value = null; 85 86 /** 87 * The name of the column to use as the title in the option list. 88 * Set this value to __title__ to use the record title ( or leave blank). 89 * 90 * @var string 91 */ 92 this.text = null; 93 94 /** 95 * Search filters to add to the query. 96 * @var object 97 */ 98 this.filters = {}; 99 100 /** 101 * Callback function to be called with the selected values. 102 * function(values){} 103 * @var function 104 */ 105 this.callback = null; 106 107 /** 108 * The document element that is used to display the dialog. 109 * @var HTMLDOMElement 110 */ 111 this.el = document.createElement('div'); 112 113 /** 114 * The base url to the RecordBrowser directory. 115 * @var string 116 */ 117 this.baseURL = DATAFACE_URL+'/js/RecordBrowser'; 118 119 for ( var i in o ){ 120 this[i] = o[i]; 121 } 122 123 /** 124 * A flag to indicate whether the record select list 125 * needs to be updated when updateRecords() is called. 126 * The list would need to be updated if the filter parameters change. 127 * @var boolean 128 */ 129 this.dirty = true; 130 $('head').append('<link rel="stylesheet" type="text/css" href="'+DATAFACE_URL+'/css/smoothness/jquery-ui-1.7.2.custom.css"/>'); 131 132 133 134 135 } 136 137 xataface.RecordBrowser.prototype = { 138 display : function(){ 139 var rb = this; 140 $('body').append(this.el); 141 $(this.el).load(this.baseURL+'/templates/RecordBrowser.html', function(){ 142 var dialog = this; 143 var searchChangeHandler = function(){ 144 rb.filterRecords({ 145 '-search' : $(this).val() 146 }); 147 }; 148 $(this).find('.xf-RecordBrowser-search-field') 149 .keyup(searchChangeHandler) 150 .change(searchChangeHandler); 151 //.blur(searchChangeHandler); 152 //$(this).find('.xf-RecordBrowser-select').css('height', '90%'); 153 $(this).find('.xf-RecordBrowser-select-field') 154 .css('width', '100%') 155 .attr('size', 8); 156 157 $(this).find('.xf-RecordBrowser-addnew-button').RecordDialog({ 158 table: rb.table, 159 callback: function(){ 160 rb.dirty=true; 161 rb.updateRecords(); 162 } 163 }); 164 165 $(this).dialog({ 166 'title': 'Select Record', 167 'buttons' : { 168 'Select' : function(){ 169 var out = {}; 170 $(dialog).find('.xf-RecordBrowser-select-field :selected').each(function(i, selected){ 171 out[$(selected).attr('value')] = $(selected).text(); 172 }); 173 174 if ( rb.callback ) rb.callback(out); 175 $(this).dialog("close"); 176 177 }, 178 'Cancel' : function(){ 179 $(this).dialog("close"); 180 181 } 182 183 }, 184 'modal' : true, 185 'resize': function(event, ui){ 186 $(dialog).find('.xf-RecordBrowser-select-field').css('height', ($(dialog).height()-60)+'px'); 187 188 } 189 }); 190 191 rb.updateRecords(); 192 }); 193 }, 194 195 filterRecords : function(filter){ 196 197 for ( var i in filter ){ 198 if ( this.filters[i] != filter[i] ) this.dirty = true; 199 this.filters[i] = filter[i]; 200 } 201 this.updateRecords(); 202 }, 203 204 updateRecords : function(){ 205 206 if ( this.dirty ){ 207 var sel = $(this.el).find('.xf-RecordBrowser-select-field'); 208 var val = $(sel).val(); 209 //var el = $(this.el); 210 sel.load(this.getDataURL(), function(){ 211 sel.val(val); 212 }); 213 this.dirty = false; 214 } 215 }, 216 217 getDataURL : function(){ 218 var url = DATAFACE_SITE_HREF+'?-action=RecordBrowser_data&-table='+encodeURIComponent(this.table); 219 if ( this.value ) url += '&-value='+encodeURIComponent(this.value); 220 if ( this.text ) url += '&-text='+encodeURIComponent(this.text); 221 for ( var i in this.filters ){ 222 url += '&'+encodeURIComponent(i)+'='+encodeURIComponent(this.filters[i]); 223 } 224 return url; 225 } 226 227 }; 228 229 $.fn.RecordBrowser = function(options){ 230 231 return this.each(function(){ 232 var obj = $(this); 233 obj.click(function(){ 234 if ( typeof(options.click) == 'function' ){ 235 options.click(); 236 } 237 var rb = new xataface.RecordBrowser(options); 238 rb.display(); 239 }); 240 }); 241 }; 242 243 $.fn.RecordBrowserWidget = function(options){ 244 return this.each(function(){ 245 246 var obj = $(this); 247 if ( obj.hasClass("xf-RecordBrowserWidget") ){ 248 // This field is already a record browser with different 249 // settings. We need to change it. So we remove the old 250 // display field. 251 var oldDisplayField = obj.next(); 252 var oldButton = oldDisplayField.next(); 253 oldDisplayField.remove(); 254 oldButton.remove(); 255 256 obj.removeClass('xf-RecordBrowserWidget'); 257 } 258 259 260 var displayField = document.createElement('input'); 261 $(displayField).attr('type','text') 262 .addClass('xf-RecordBrowserWidget-displayField') 263 //.css('width', obj.width()+'px') 264 //.css('height', obj.height()+'px') 265 .css('cursor', 'pointer') 266 //.css('border', '1px solid black') 267 .attr('readonly', 1); 268 269 270 $(displayField).insertAfter(this); 271 272 obj.css('display','none') 273 .addClass('xf-RecordBrowserWidget'); 274 275 if ( !options.frozen ){ 276 obj.change(function(){ 277 var id; 278 if ( options.value && options.value != '__id__' ){ 279 id = encodeURIComponent(options.value)+'='+encodeURIComponent(obj.val()); 280 } else { 281 id = obj.val(); 282 } 283 var url = DATAFACE_SITE_HREF+'?-action=RecordBrowser_lookup_single&-table='+options.table+'&-id='+encodeURIComponent(id); 284 if ( options.text ) url += '&-text='+encodeURIComponent(options.text); 285 $.get(url, function(text){ 286 287 $(displayField).val(text); 288 }); 289 }); 290 var a = document.createElement('a'); 291 $(a).addClass('xf-RecordBrowser-button') 292 .css('cursor', 'pointer') 293 .html('<img src="'+DATAFACE_URL+'/images/search_icon.gif" border="0" /><span class="xf-RecordBrowser-button-label"> Lookup</span>'); 294 $(a).find('.xf-RecordBrowser-button-label') 295 .css('display', 'none'); 296 297 $(a).insertAfter(displayField); 298 if ( !options.callback ){ 299 options.callback = function(vals){ 300 for ( var i in vals ){ 301 //$(displayField).val(vals[i]); 302 obj.val(i); 303 obj.trigger('change'); 304 } 305 }; 306 } 307 $(a).RecordBrowser(options); 308 $(displayField).RecordBrowser(options); 309 } else { 310 //alert(obj.val()); 311 } 312 313 if ( obj.val() ){ 314 var id; 315 if ( options.value && options.value != '__id__' ){ 316 id = encodeURIComponent(options.value)+'='+encodeURIComponent(obj.val()); 317 } else { 318 id = obj.val(); 319 } 320 var url = DATAFACE_SITE_HREF+'?-action=RecordBrowser_lookup_single&-table='+options.table+'&-id='+encodeURIComponent(id); 321 if ( options.text ) url += '&-text='+encodeURIComponent(options.text); 322 $.get(url, function(text){ 323 //alert(text); 324 $(displayField).val(text); 325 }); 326 } 327 328 329 }); 330 }; 331 })(jQuery);