This project has moved and is read-only. For the latest updates, please go here.

Bug with SPLookupField and "saving" the form

Dec 20, 2012 at 4:27 PM

Hi Guys,

First of all a big thank you for the people who have been involved in writing this awesome library.

Came across a little bug which took me a while to get my head around and thought I would feed it back to the community.

There is a problem when populating a SPLookupField with "Complex" display in IE (lookup column with more than 20 items - autocomplete activated). This control is using a "Hidden" field that is then grabbed when sending the data to the server (the "opthid" attribute of the control). If not set, even if auto-populated this value will not be set unless the user actually changes the selection.

Anyway, here are the changes I have made to the code in bold below:

 

	/*
	 *	SPLookupField class
	 *	Supports single select lookup fields
	 */
	SPLookupField = Class.create(SPField, {
		initialize: function ($super, spParams) {
			$super(spParams);
			
			var controls = this.Controls.select('input');
			if (1 === controls.length) {
				// autocomplete lookup
				this.Textbox = controls[0];
				
				this.GetValue = function () {
					return this.Textbox.getValue();
				};
				
				this.SetValue = function (value) {
					var choices, hash;
					var selectedID;

					// a list item ID was passed to the function so attempt to lookup the text value
					choices = this.Textbox.readAttribute('choices');
					hash = new Hash();

					// JSLint error here but not much I can do...
					choices.scan(/(([^\|]|\|\|)+)\|(\d+)/, function (match) {
						hash.set(match[3], match[1].replace(/\|\|/g, '|'));
					});
					
					if (Object.isNumber(value)) {
						this.Textbox.setValue(hash.get(value.toString()));
						
						// If we have the ID, set the Hidden field value to be this ID
						selectedID = value.toString();
					} else {
						this.Textbox.setValue(value);

						// If we have the "value" find its ID in the Hashtable
						selectedID = hash.index(value.toString());
					}
					
					// We also need to set the associated hidden field with the correct value...
					opthid = this.Textbox.readAttribute('opthid');
					
					jQuery('input[name="' + opthid + '"]').val(selectedID);					
					
					updateReadOnlyLabel(this);
					return this;
				};
				
			} else {
				controls = this.Controls.select('select');
				if (1 === controls.length) {
					// regular dropdown lookup
					this.Dropdown = controls[0];
					
					this.GetValue = function () {
						return this.Dropdown.options[this.Dropdown.selectedIndex].text;
					};
					
					this.SetValue = function (value) {
						if (Object.isNumber(value)) {
							this.Dropdown.setValue(value);
						} else {
							var i, numOptions;
							// need to set the dropdown based on text
							numOptions = this.Dropdown.options.length;
							for (i = 0; i < numOptions; i += 1) {
								if (this.Dropdown.options[i].text === value) {
									this.Dropdown.selectedIndex = i;
									break;
								}
							}
						}
						updateReadOnlyLabel(this);
						return this;
					};
				}
			}
		}
	});

 

That's it, hope this helps and will make it to the main code branch!

Fantastic idea and very clean code, so refreshing to work with this library :)

Cheers & happy coding.

Etienne

Mar 9, 2013 at 7:42 PM
Etienne,
Terribly sorry it has taken so long for me to respond... Thank you for figuring this out and reporting it (with code no less!). I tweaked it a little bit (so as to not use jQuery calls) and incorporated it into the newest bugfix release 0.8.2.
Thanks,
Kit