recordselect 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/assets/javascripts/jquery/record_select.js~ +543 -0
- data/app/assets/javascripts/prototype/record_select.js~ +419 -0
- data/app/views/record_select/_list.html.erb~ +31 -0
- data/assets/javascripts/jquery/record_select.js +3 -0
- data/assets/javascripts/prototype/record_select.js +3 -0
- data/lib/record_select/extensions/localization.rb~ +14 -0
- data/lib/record_select/helpers/record_select_helper.rb~ +209 -0
- data/lib/record_select/version.rb +1 -1
- data/lib/record_select/version.rb~ +9 -0
- metadata +25 -21
| @@ -0,0 +1,419 @@ | |
| 1 | 
            +
            document.observe("dom:loaded", function() {
         | 
| 2 | 
            +
              RecordSelect.document_loaded = true;
         | 
| 3 | 
            +
              document.on('ajax:before', 'div.record-select * li.record a', function(event) {
         | 
| 4 | 
            +
                var link = event.findElement();
         | 
| 5 | 
            +
                if (link) {
         | 
| 6 | 
            +
                  if (RecordSelect.notify(link) == false) {
         | 
| 7 | 
            +
                    event.stop();
         | 
| 8 | 
            +
                  } else {
         | 
| 9 | 
            +
                    link.toggleClassName("selected");
         | 
| 10 | 
            +
                  }
         | 
| 11 | 
            +
                }
         | 
| 12 | 
            +
                return true;
         | 
| 13 | 
            +
              });  
         | 
| 14 | 
            +
            });    
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Form.Element.AfterActivity = function(element, callback, delay) {
         | 
| 17 | 
            +
              element = $(element);
         | 
| 18 | 
            +
              if (!delay) delay = 0.25;
         | 
| 19 | 
            +
              new Form.Element.Observer(element, delay, function(element, value) {
         | 
| 20 | 
            +
                // TODO: display loading indicator
         | 
| 21 | 
            +
                if (element.activity_timer) clearTimeout(element.activity_timer);
         | 
| 22 | 
            +
                element.activity_timer = setTimeout(function() {
         | 
| 23 | 
            +
                  callback(element.value);
         | 
| 24 | 
            +
                }, delay * 1000 + 50);
         | 
| 25 | 
            +
              });
         | 
| 26 | 
            +
            }
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            var RecordSelect = new Object();
         | 
| 29 | 
            +
            RecordSelect.document_loaded = false;
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            RecordSelect.notify = function(item) {
         | 
| 32 | 
            +
              var e = Element.up(item, '.record-select-handler');
         | 
| 33 | 
            +
              var onselect = e.onselect || e.getAttribute('onselect');
         | 
| 34 | 
            +
              if (typeof onselect != 'function') onselect = eval(onselect);
         | 
| 35 | 
            +
              if (onselect)
         | 
| 36 | 
            +
              {
         | 
| 37 | 
            +
                try {
         | 
| 38 | 
            +
                  onselect(item.parentNode.id.substr(2), (item.down('label') || item).innerHTML.unescapeHTML(), e);
         | 
| 39 | 
            +
                } catch(e) {
         | 
| 40 | 
            +
                  alert(e);
         | 
| 41 | 
            +
                }
         | 
| 42 | 
            +
                return false;
         | 
| 43 | 
            +
              }
         | 
| 44 | 
            +
              else return true;
         | 
| 45 | 
            +
            };
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            RecordSelect.render_page = function(record_select_id, page) {
         | 
| 48 | 
            +
              var page_element = $$('#' + record_select_id + ' ol')[0];
         | 
| 49 | 
            +
              if (page_element) Element.replace(page_element, page);
         | 
| 50 | 
            +
            };
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            RecordSelect.Abstract = Class.create();
         | 
| 53 | 
            +
            Object.extend(RecordSelect.Abstract.prototype, {
         | 
| 54 | 
            +
              /**
         | 
| 55 | 
            +
               * obj - the id or element that will anchor the recordselect to the page
         | 
| 56 | 
            +
               * url - the url to run the recordselect
         | 
| 57 | 
            +
               * options - ??? (check concrete classes)
         | 
| 58 | 
            +
               */
         | 
| 59 | 
            +
              initialize: function(obj, url, options) {
         | 
| 60 | 
            +
                this.obj = $(obj);
         | 
| 61 | 
            +
                this.url = url;
         | 
| 62 | 
            +
                this.options = options;
         | 
| 63 | 
            +
                this.container;
         | 
| 64 | 
            +
                if (this.options.onchange && typeof this.options.onchange != 'function') {
         | 
| 65 | 
            +
                  this.options.onchange = eval(this.options.onchange);
         | 
| 66 | 
            +
                }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                if (RecordSelect.document_loaded) this.onload();
         | 
| 69 | 
            +
                else Event.observe(window, 'load', this.onload.bind(this));
         | 
| 70 | 
            +
              },
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              /**
         | 
| 73 | 
            +
               * Finish the setup - IE doesn't like doing certain things before the page loads
         | 
| 74 | 
            +
               * --override--
         | 
| 75 | 
            +
               */
         | 
| 76 | 
            +
              onload: function() {},
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              /**
         | 
| 79 | 
            +
               * the onselect event handler - when someone clicks on a record
         | 
| 80 | 
            +
               * --override--
         | 
| 81 | 
            +
               */
         | 
| 82 | 
            +
              onselect: function(id, value) {
         | 
| 83 | 
            +
                alert(id + ': ' + value);
         | 
| 84 | 
            +
              },
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              /**
         | 
| 87 | 
            +
               * opens the recordselect
         | 
| 88 | 
            +
               */
         | 
| 89 | 
            +
              open: function() {
         | 
| 90 | 
            +
                if (this.is_open()) return;
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                new Ajax.Updater(this.container, this.url, {
         | 
| 93 | 
            +
                  method: 'get',
         | 
| 94 | 
            +
                  evalScripts: true,
         | 
| 95 | 
            +
                  asynchronous: true,
         | 
| 96 | 
            +
                  onComplete: function() {
         | 
| 97 | 
            +
                    this.show();
         | 
| 98 | 
            +
                    // needs to be mousedown so the event doesn't get canceled by other code (see issue #26)
         | 
| 99 | 
            +
                    Element.observe(document.body, 'mousedown', this.onbodyclick.bindAsEventListener(this));
         | 
| 100 | 
            +
                  }.bind(this)
         | 
| 101 | 
            +
                });
         | 
| 102 | 
            +
              },
         | 
| 103 | 
            +
             | 
| 104 | 
            +
              /**
         | 
| 105 | 
            +
               * positions and reveals the recordselect
         | 
| 106 | 
            +
               */
         | 
| 107 | 
            +
              show: function() {
         | 
| 108 | 
            +
                var offset = Position.cumulativeOffset(this.obj),
         | 
| 109 | 
            +
                    top = Element.getHeight(this.obj) + offset[1],
         | 
| 110 | 
            +
                    window_height = document.viewport.getHeight();
         | 
| 111 | 
            +
                this.container.style.left = offset[0] + 'px';
         | 
| 112 | 
            +
                if (top + Element.getHeight(this.container) > window_height)
         | 
| 113 | 
            +
                  this.container.style.bottom = (window_height - offset[1]) + 'px';
         | 
| 114 | 
            +
                else this.container.style.top = top + 'px';
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                if (this._use_iframe_mask()) {
         | 
| 117 | 
            +
                  this.container.insertAdjacentHTML('afterEnd', '<iframe src="javascript:false;" class="record-select-mask" />');
         | 
| 118 | 
            +
                  var mask = this.container.next('iframe');
         | 
| 119 | 
            +
                  mask.style.left = this.container.style.left;
         | 
| 120 | 
            +
                  mask.style.top = this.container.style.top;
         | 
| 121 | 
            +
                }
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                this.container.show();
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                if (this._use_iframe_mask()) {
         | 
| 126 | 
            +
                  var dimensions = this.container.immediateDescendants().first().getDimensions();
         | 
| 127 | 
            +
                  mask.style.width = dimensions.width + 'px';
         | 
| 128 | 
            +
                  mask.style.height = dimensions.height + 'px';
         | 
| 129 | 
            +
                }
         | 
| 130 | 
            +
              },
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              /**
         | 
| 133 | 
            +
               * closes the recordselect by emptying the container
         | 
| 134 | 
            +
               */
         | 
| 135 | 
            +
              close: function() {
         | 
| 136 | 
            +
                if (this._use_iframe_mask()) {
         | 
| 137 | 
            +
                  this.container.next('iframe').remove();
         | 
| 138 | 
            +
                }
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                this.container.hide();
         | 
| 141 | 
            +
                // hopefully by using remove() instead of innerHTML we won't leak memory
         | 
| 142 | 
            +
                this.container.immediateDescendants().invoke('remove');
         | 
| 143 | 
            +
              },
         | 
| 144 | 
            +
             | 
| 145 | 
            +
              /**
         | 
| 146 | 
            +
               * returns true/false for whether the recordselect is open
         | 
| 147 | 
            +
               */
         | 
| 148 | 
            +
              is_open: function() {
         | 
| 149 | 
            +
            	  return (!this.container.innerHTML.blank())
         | 
| 150 | 
            +
              },
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              /**
         | 
| 153 | 
            +
               * when the user clicks outside the dropdown
         | 
| 154 | 
            +
               */
         | 
| 155 | 
            +
              onbodyclick: function(ev) {
         | 
| 156 | 
            +
                if (!this.is_open()) return;
         | 
| 157 | 
            +
                var elem = $(Event.element(ev));
         | 
| 158 | 
            +
                var ancestors = elem.ancestors();
         | 
| 159 | 
            +
                ancestors.push(elem);
         | 
| 160 | 
            +
                if (ancestors.include(this.container) || ancestors.include(this.obj)) return;
         | 
| 161 | 
            +
                this.close();
         | 
| 162 | 
            +
              },
         | 
| 163 | 
            +
             | 
| 164 | 
            +
              /**
         | 
| 165 | 
            +
               * creates and initializes (and returns) the recordselect container
         | 
| 166 | 
            +
               */
         | 
| 167 | 
            +
              create_container: function() {
         | 
| 168 | 
            +
                new Insertion.Bottom(document.body, '<div class="record-select-container record-select-handler"></div>');
         | 
| 169 | 
            +
                e = document.body.childNodes[document.body.childNodes.length - 1];
         | 
| 170 | 
            +
                e.onselect = this.onselect.bind(this);
         | 
| 171 | 
            +
                e.style.display = 'none';
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                return $(e);
         | 
| 174 | 
            +
              },
         | 
| 175 | 
            +
             | 
| 176 | 
            +
              /**
         | 
| 177 | 
            +
               * all the behavior to respond to a text field as a search box
         | 
| 178 | 
            +
               */
         | 
| 179 | 
            +
              _respond_to_text_field: function(text_field) {
         | 
| 180 | 
            +
                // attach the events to start this party
         | 
| 181 | 
            +
                text_field.observe('focus', this.open.bind(this));
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                // the autosearch event - needs to happen slightly late (keyup is later than keypress)
         | 
| 184 | 
            +
                text_field.observe('keyup', function() {
         | 
| 185 | 
            +
                  if (!this.is_open()) return;
         | 
| 186 | 
            +
                  this.container.down('.text-input').value = text_field.value;
         | 
| 187 | 
            +
                }.bind(this));
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                // keyboard navigation, if available
         | 
| 190 | 
            +
                if (this.onkeydown) {
         | 
| 191 | 
            +
                  text_field.observe('keydown', this.onkeydown.bind(this));
         | 
| 192 | 
            +
                }
         | 
| 193 | 
            +
              },
         | 
| 194 | 
            +
             | 
| 195 | 
            +
              _use_iframe_mask: function() {
         | 
| 196 | 
            +
                return this.container.insertAdjacentHTML ? true : false;
         | 
| 197 | 
            +
              }
         | 
| 198 | 
            +
            });
         | 
| 199 | 
            +
             | 
| 200 | 
            +
            /**
         | 
| 201 | 
            +
             * Adds keyboard navigation to RecordSelect objects
         | 
| 202 | 
            +
             */
         | 
| 203 | 
            +
            Object.extend(RecordSelect.Abstract.prototype, {
         | 
| 204 | 
            +
              current: null,
         | 
| 205 | 
            +
             | 
| 206 | 
            +
              /**
         | 
| 207 | 
            +
               * keyboard navigation - where to intercept the keys is up to the concrete class
         | 
| 208 | 
            +
               */
         | 
| 209 | 
            +
              onkeydown: function(ev) {
         | 
| 210 | 
            +
                var elem;
         | 
| 211 | 
            +
                switch (ev.keyCode) {
         | 
| 212 | 
            +
                  case Event.KEY_UP:
         | 
| 213 | 
            +
                    if (this.current && this.current.up('.record-select')) elem = this.current.previous();
         | 
| 214 | 
            +
                    if (!elem) elem = this.container.getElementsBySelector('ol li.record').last();
         | 
| 215 | 
            +
                    this.highlight(elem);
         | 
| 216 | 
            +
                    break;
         | 
| 217 | 
            +
                  case Event.KEY_DOWN:
         | 
| 218 | 
            +
                    if (this.current && this.current.up('.record-select')) elem = this.current.next();
         | 
| 219 | 
            +
                    if (!elem) elem = this.container.getElementsBySelector('ol li.record').first();
         | 
| 220 | 
            +
                    this.highlight(elem);
         | 
| 221 | 
            +
                    break;
         | 
| 222 | 
            +
                  case Event.KEY_SPACE:
         | 
| 223 | 
            +
                  case Event.KEY_RETURN:
         | 
| 224 | 
            +
                    if (this.current) this.current.down('a').onclick();
         | 
| 225 | 
            +
                    break;
         | 
| 226 | 
            +
                  case Event.KEY_RIGHT:
         | 
| 227 | 
            +
                    elem = this.container.down('li.pagination.next');
         | 
| 228 | 
            +
                    if (elem) elem.down('a').onclick();
         | 
| 229 | 
            +
                    break;
         | 
| 230 | 
            +
                  case Event.KEY_LEFT:
         | 
| 231 | 
            +
                    elem = this.container.down('li.pagination.previous');
         | 
| 232 | 
            +
                    if (elem) elem.down('a').onclick();
         | 
| 233 | 
            +
                    break;
         | 
| 234 | 
            +
                  case Event.KEY_ESC:
         | 
| 235 | 
            +
                    this.close();
         | 
| 236 | 
            +
                    break;
         | 
| 237 | 
            +
                  default:
         | 
| 238 | 
            +
                    return;
         | 
| 239 | 
            +
                }
         | 
| 240 | 
            +
                Event.stop(ev); // so "enter" doesn't submit the form, among other things(?)
         | 
| 241 | 
            +
              },
         | 
| 242 | 
            +
             | 
| 243 | 
            +
              /**
         | 
| 244 | 
            +
               * moves the highlight to a new object
         | 
| 245 | 
            +
               */
         | 
| 246 | 
            +
              highlight: function(obj) {
         | 
| 247 | 
            +
                if (this.current) this.current.removeClassName('current');
         | 
| 248 | 
            +
                this.current = $(obj);
         | 
| 249 | 
            +
                obj.addClassName('current');
         | 
| 250 | 
            +
              }
         | 
| 251 | 
            +
            });
         | 
| 252 | 
            +
             | 
| 253 | 
            +
            /**
         | 
| 254 | 
            +
             * Used by link_to_record_select
         | 
| 255 | 
            +
             * The options hash should contain a onselect: key, with a javascript function as value
         | 
| 256 | 
            +
             */
         | 
| 257 | 
            +
            RecordSelect.Dialog = Class.create();
         | 
| 258 | 
            +
            RecordSelect.Dialog.prototype = Object.extend(new RecordSelect.Abstract(), {
         | 
| 259 | 
            +
              onload: function() {
         | 
| 260 | 
            +
                this.container = this.create_container();
         | 
| 261 | 
            +
                this.obj.observe('click', this.toggle.bind(this));
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                if (this.onkeypress) this.obj.observe('keypress', this.onkeypress.bind(this));
         | 
| 264 | 
            +
              },
         | 
| 265 | 
            +
             | 
| 266 | 
            +
              onselect: function(id, value) {
         | 
| 267 | 
            +
                if (this.options.onselect(id, value) != false) this.close();
         | 
| 268 | 
            +
              },
         | 
| 269 | 
            +
             | 
| 270 | 
            +
              toggle: function() {
         | 
| 271 | 
            +
                if (this.is_open()) this.close();
         | 
| 272 | 
            +
                else this.open();
         | 
| 273 | 
            +
              }
         | 
| 274 | 
            +
            });
         | 
| 275 | 
            +
             | 
| 276 | 
            +
            /**
         | 
| 277 | 
            +
             * Used by record_select_field helper
         | 
| 278 | 
            +
             * The options hash may contain id: and label: keys, designating the current value
         | 
| 279 | 
            +
             * The options hash may also include an onchange: key, where the value is a javascript function (or eval-able string) for an callback routine
         | 
| 280 | 
            +
             * and field_name: key, where value will be set as name of the input field.
         | 
| 281 | 
            +
             */
         | 
| 282 | 
            +
            RecordSelect.Single = Class.create();
         | 
| 283 | 
            +
            RecordSelect.Single.prototype = Object.extend(new RecordSelect.Abstract(), {
         | 
| 284 | 
            +
              onload: function() {
         | 
| 285 | 
            +
                // initialize the container
         | 
| 286 | 
            +
                this.container = this.create_container();
         | 
| 287 | 
            +
                this.container.addClassName('record-select-autocomplete');
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                // create the hidden input
         | 
| 290 | 
            +
                new Insertion.After(this.obj, '<input type="hidden" name="" value="" />')
         | 
| 291 | 
            +
                this.hidden_input = this.obj.next();
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                // transfer the input name from the text input to the hidden input
         | 
| 294 | 
            +
                this.hidden_input.name = this.obj.name;
         | 
| 295 | 
            +
                this.obj.name = this.options.field_name || '';
         | 
| 296 | 
            +
             | 
| 297 | 
            +
                // initialize the values
         | 
| 298 | 
            +
                if (this.options.label) this.set(this.options.id, this.options.label);
         | 
| 299 | 
            +
             | 
| 300 | 
            +
                this._respond_to_text_field(this.obj);
         | 
| 301 | 
            +
                if (this.obj.focused) this.open(); // if it was focused before we could attach observers
         | 
| 302 | 
            +
              },
         | 
| 303 | 
            +
             | 
| 304 | 
            +
              close: function() {
         | 
| 305 | 
            +
                // if they close the dialog with the text field empty, then delete the id value
         | 
| 306 | 
            +
                if (this.obj.value == '') this.set('', '');
         | 
| 307 | 
            +
             | 
| 308 | 
            +
                RecordSelect.Abstract.prototype.close.call(this);
         | 
| 309 | 
            +
              },
         | 
| 310 | 
            +
             | 
| 311 | 
            +
              onselect: function(id, value) {
         | 
| 312 | 
            +
                this.set(id, value);
         | 
| 313 | 
            +
                if (this.options.onchange) this.options.onchange.call(this, id, value);
         | 
| 314 | 
            +
                this.obj.fire('recordselect:change', {"id": id, "label": value});
         | 
| 315 | 
            +
                this.close();
         | 
| 316 | 
            +
              },
         | 
| 317 | 
            +
             | 
| 318 | 
            +
              /**
         | 
| 319 | 
            +
               * sets the id/label
         | 
| 320 | 
            +
               */
         | 
| 321 | 
            +
              set: function(id, label) {
         | 
| 322 | 
            +
                this.obj.value = label.unescapeHTML();
         | 
| 323 | 
            +
                this.hidden_input.value = id;
         | 
| 324 | 
            +
              }
         | 
| 325 | 
            +
            });
         | 
| 326 | 
            +
             | 
| 327 | 
            +
            /**
         | 
| 328 | 
            +
             * Used by record_select_autocomplete helper
         | 
| 329 | 
            +
             * The options hash may contain label: key, designating the current value
         | 
| 330 | 
            +
             * The options hash may also include an onchange: key, where the value is a javascript function (or eval-able string) for an callback routine.
         | 
| 331 | 
            +
             */
         | 
| 332 | 
            +
            RecordSelect.Autocomplete = Class.create();
         | 
| 333 | 
            +
            RecordSelect.Autocomplete.prototype = Object.extend(new RecordSelect.Abstract(), {
         | 
| 334 | 
            +
              onload: function() {
         | 
| 335 | 
            +
                // initialize the container
         | 
| 336 | 
            +
                this.container = this.create_container();
         | 
| 337 | 
            +
                this.container.addClassName('record-select-autocomplete');
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                // initialize the values
         | 
| 340 | 
            +
                this.set(this.options.label);
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                this._respond_to_text_field(this.obj);
         | 
| 343 | 
            +
                if (this.obj.focused) this.open(); // if it was focused before we could attach observers
         | 
| 344 | 
            +
              },
         | 
| 345 | 
            +
             | 
| 346 | 
            +
              close: function() {
         | 
| 347 | 
            +
                // if they close the dialog with the text field empty, then delete the id value
         | 
| 348 | 
            +
                if (this.obj.value == '') this.set('', '');
         | 
| 349 | 
            +
             | 
| 350 | 
            +
                RecordSelect.Abstract.prototype.close.call(this);
         | 
| 351 | 
            +
              },
         | 
| 352 | 
            +
             | 
| 353 | 
            +
              onselect: function(id, value) {
         | 
| 354 | 
            +
                this.set(value);
         | 
| 355 | 
            +
                if (this.options.onchange) this.options.onchange.call(this, id, value);
         | 
| 356 | 
            +
                this.obj.fire('recordselect:change', {"id": id, "label": value});
         | 
| 357 | 
            +
                this.close();
         | 
| 358 | 
            +
              },
         | 
| 359 | 
            +
             | 
| 360 | 
            +
              /**
         | 
| 361 | 
            +
               * sets the id/label
         | 
| 362 | 
            +
               */
         | 
| 363 | 
            +
              set: function(label) {
         | 
| 364 | 
            +
                this.obj.value = label.unescapeHTML();
         | 
| 365 | 
            +
              }
         | 
| 366 | 
            +
            });
         | 
| 367 | 
            +
             | 
| 368 | 
            +
            /**
         | 
| 369 | 
            +
             * Used by record_multi_select_field helper.
         | 
| 370 | 
            +
             * Options:
         | 
| 371 | 
            +
             *   list - the id (or object) of the <ul> to contain the <li>s of selected entries
         | 
| 372 | 
            +
             *   current - an array of id:/label: keys designating the currently selected entries
         | 
| 373 | 
            +
             */
         | 
| 374 | 
            +
            RecordSelect.Multiple = Class.create();
         | 
| 375 | 
            +
            RecordSelect.Multiple.prototype = Object.extend(new RecordSelect.Abstract(), {
         | 
| 376 | 
            +
              onload: function() {
         | 
| 377 | 
            +
                // initialize the container
         | 
| 378 | 
            +
                this.container = this.create_container();
         | 
| 379 | 
            +
                this.container.addClassName('record-select-autocomplete');
         | 
| 380 | 
            +
             | 
| 381 | 
            +
                // decide where the <li> entries should be placed
         | 
| 382 | 
            +
                if (this.options.list) this.list_container = $(this.options.list);
         | 
| 383 | 
            +
                else this.list_container = this.obj.next('ul');
         | 
| 384 | 
            +
             | 
| 385 | 
            +
                // take the input name from the text input, and store it for this.add()
         | 
| 386 | 
            +
                this.input_name = this.obj.name;
         | 
| 387 | 
            +
                this.obj.name = '';
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                // initialize the list
         | 
| 390 | 
            +
                $A(this.options.current).each(function(c) {
         | 
| 391 | 
            +
                  this.add(c.id, c.label);
         | 
| 392 | 
            +
                }.bind(this));
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                this._respond_to_text_field(this.obj);
         | 
| 395 | 
            +
                if (this.obj.focused) this.open(); // if it was focused before we could attach observers
         | 
| 396 | 
            +
              },
         | 
| 397 | 
            +
             | 
| 398 | 
            +
              onselect: function(id, value) {
         | 
| 399 | 
            +
                this.add(id, value);
         | 
| 400 | 
            +
              },
         | 
| 401 | 
            +
             | 
| 402 | 
            +
              /**
         | 
| 403 | 
            +
               * Adds a record to the selected list
         | 
| 404 | 
            +
               */
         | 
| 405 | 
            +
              add: function(id, label) {
         | 
| 406 | 
            +
                // return silently if this value has already been selected
         | 
| 407 | 
            +
                var already_selected = this.list_container.getElementsBySelector('input').any(function(i) {
         | 
| 408 | 
            +
                  return i.value == id
         | 
| 409 | 
            +
                });
         | 
| 410 | 
            +
                if (already_selected) return;
         | 
| 411 | 
            +
             | 
| 412 | 
            +
                var entry = '<li>'
         | 
| 413 | 
            +
                          + '<a href="#" onclick="$(this.parentNode).remove(); return false;" class="remove">remove</a>'
         | 
| 414 | 
            +
                          + '<input type="hidden" name="' + this.input_name + '" value="' + id + '" />'
         | 
| 415 | 
            +
                          + '<label>' + label + '</label>'
         | 
| 416 | 
            +
                          + '</li>';
         | 
| 417 | 
            +
                new Insertion.Top(this.list_container, entry);
         | 
| 418 | 
            +
              }
         | 
| 419 | 
            +
            });
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            <%
         | 
| 2 | 
            +
            controller ||= params[:controller]
         | 
| 3 | 
            +
            debugger
         | 
| 4 | 
            +
            pagination_url_params = params.merge(:controller => controller, :action => :browse, :search => params[:search], :update => 1)
         | 
| 5 | 
            +
            prev_url = url_for(pagination_url_params.merge(:page => page.prev.number, :escape => false)) if page.prev?
         | 
| 6 | 
            +
            next_url = url_for(pagination_url_params.merge(:page => page.next.number, :escape => false)) if page.next?
         | 
| 7 | 
            +
            -%>
         | 
| 8 | 
            +
            <ol>
         | 
| 9 | 
            +
              <li class="found"><%= rs_(:records_found, :count => page.pager.count,
         | 
| 10 | 
            +
            :model => record_select_config.model.model_name.human(:count => page.pager.count).downcase) %></li>
         | 
| 11 | 
            +
              <% if page.prev? -%>
         | 
| 12 | 
            +
              <li class="pagination previous">
         | 
| 13 | 
            +
                <%= link_to image_tag('record_select/previous.gif', :alt => rs_(:previous)) + " " + rs_(:previous_items,
         | 
| 14 | 
            +
            :count => page.pager.per_page),
         | 
| 15 | 
            +
                                  {:url => prev_url},
         | 
| 16 | 
            +
                                  {:href => prev_url, :method => :get, :remote => true} %>
         | 
| 17 | 
            +
              </li>
         | 
| 18 | 
            +
              <% end -%>
         | 
| 19 | 
            +
              <% page.items.each do |record| -%>
         | 
| 20 | 
            +
              <li class="record <%= cycle 'odd', 'even' %>" id="rs<%= record.id -%>">
         | 
| 21 | 
            +
                <%= render_record_in_list(record, controller) %>
         | 
| 22 | 
            +
              </li>
         | 
| 23 | 
            +
              <% end -%>
         | 
| 24 | 
            +
              <% if page.next? -%>
         | 
| 25 | 
            +
              <li class="pagination next">
         | 
| 26 | 
            +
              <%= link_to (rs_(:next_items, :count => page.pager.per_page) + " " + image_tag('record_select/next.gif', :alt => rs_(:next))).html_safe,
         | 
| 27 | 
            +
                                    {:url => next_url},
         | 
| 28 | 
            +
                                    {:href => next_url, :method => :get, :remote => true} %>
         | 
| 29 | 
            +
              </li>
         | 
| 30 | 
            +
              <% end -%>
         | 
| 31 | 
            +
            </ol>
         |