if (typeof(Class) === 'undefined') { /* Simple Inheritance http://ejohn.org/blog/simple-javascript-inheritance/ */ (function(){ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // The base Class implementation (does nothing) this.Class = function(){}; // Create a new Class that inherits from this class Class.extend = function(prop) { var _super = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; var prototype = new this(); initializing = false; // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } // The dummy class constructor function Class() { // All construction is actually done in the init method if ( !initializing && this.init ) this.init.apply(this, arguments); } // Populate our constructed prototype object Class.prototype = prototype; // Enforce the constructor to be what we expect Class.constructor = Class; // And make this class extendable Class.extend = arguments.callee; return Class; }; })(); } /* jQuery delayed observer (c) 2007 - Maxime Haineault (max@centdessin.com) Special thanks to Stephen Goguen & Tane Piper. Slight modifications by Elliot Winkler */ if (typeof(jQuery.fn.delayedObserver) === 'undefined') { (function($){ $.extend($.fn, { delayedObserver: function(callback, delay, options){ return this.each(function(){ var el = $(this); var op = options || {}; el.data('oldval', el.val()) .data('delay', delay || 0.5) .data('condition', op.condition || function() { return ($(this).data('oldval') == $(this).val()); }) .data('callback', callback) [(op.event||'keyup')](function(){ if (el.data('condition').apply(el)) { return; } else { if (el.data('timer')) { clearTimeout(el.data('timer')); } el.data('timer', setTimeout(function(){ var callback = el.data('callback'); if (callback) callback.apply(el); }, el.data('delay') * 1000)); el.data('oldval', el.val()); } }); }); } }); })(jQuery); } jQuery(document).ready(function() { RecordSelect.document_loaded = true; jQuery(document).on('click', 'div.record-select li.record', function(event) { var link = jQuery(this); if (link.length) { RecordSelect.select_item(link); return false; } return true; }); }); var RecordSelect = new Object(); RecordSelect.document_loaded = false; RecordSelect.select_item = function(item) { var rs = item.closest('.record-select-handler').data('recordselect'); if (rs) { try { var label = item.find('label').first().text().trim(), text = item.text().trim(); rs.obj.focus(); rs.onselect(item.attr('id').substr(2), label || text, text, item); } catch(e) { alert(e); } } } RecordSelect.observe = function(id) { var form = jQuery("#" + id); form.find('input.text-input').delayedObserver(function() { if (form.closest('body').length) form.trigger("submit"); }, 0.35); } RecordSelect.render_page = function(record_select_id, page) { jQuery('#' + record_select_id + ' ol').first().replaceWith(page); }; RecordSelect.Abstract = Class.extend({ /** * obj - the id or element that will anchor the recordselect to the page * url - the url to run the recordselect * options - ??? (check concrete classes) */ init: function(obj, url, options) { if (typeof(obj) == 'string') obj = '#' + obj; this.obj = jQuery(obj); this.url = url; this.options = options; this.container; if (this.options.onchange && typeof this.options.onchange != 'function') { this.options.onchange = eval(this.options.onchange); } if (RecordSelect.document_loaded) { this.onload(); } else { var _this = this; jQuery(document).ready(function() { _this.onload(); }) } }, /** * Finish the setup - IE doesn't like doing certain things before the page loads * --override-- */ onload: function() {}, /** * the onselect event handler - when someone clicks on a record * --override-- */ onselect: function(id, value, text, item) { alert(id + ': ' + value); }, /** * opens the recordselect */ open: function() { if (this.is_open()) return; var _this = this; jQuery.rails.fire(_this.obj, 'recordselect:before'); _this.container.html(''); _this.container.show(); var params = _this.obj.data('params'); var search_params = jQuery.param({search: _this.obj.val()}); params = params ? [params, search_params].join("&") : search_params; jQuery.ajax({ url: this.url, //type: "POST", data: params, //dataType: options.ajax_data_type, success: function(data){ _this.container.html(data); if (!_this.container.is(':visible')) _this.close(); else { _this.container.find('.text-input').val(_this.obj.val()); RecordSelect.observe(_this.container.find('form').attr('id')); _this.container.hide(); // needed to get right document height to position first time _this.show(); jQuery(document.body).mousedown(jQuery.proxy(_this, "onbodyclick")); } } }); }, /** * positions and reveals the recordselect */ show: function() { var offset = this.obj.offset(), scroll = jQuery(window).scrollTop(), window_height = jQuery(window).height(); if (this.fixed) offset.top -= scroll; // get fixed position var top = this.obj.outerHeight() + offset.top, document_height = jQuery(document).height(); this.container.show(); var height = this.container.outerHeight(); this.container.css('left', offset.left); this.container.css('top', ''); this.container.css('bottom', ''); if ((this.fixed || this.body_static) && top + height > window_height) { this.container.css('bottom', window_height - offset.top); } else { var below_space = window_height-(top-scroll), above_space = offset.top - scroll, position; if (below_space < height) { if (above_space >= height) position = 'bottom'; else position = above_space < below_space ? 'top' : 'bottom'; } else position = 'top'; if (position == 'top') this.container.css('top', top); else this.container.css('bottom', document_height - offset.top); } if (this._use_iframe_mask()) { this.container.after('