SPservices has this great auto lookup field for single lookup values (well.. great in that it saves time writing it yourself using the Jquery autolookup plugin with a CAML query on the lookup list).
But what if you want to lookup multiple values for a multi lookup situation AND that if you would want to insert items when they do not exist? I see that he has added a `link` option SPLookupAddNew but I do not like a link since I dont want to confuse readers to get lost and besides that it resets all selected values in their lookup.
So I wrote a little code that uses the spautocomplete box and adds and insert or add button after it, depending on what the user is entering in the textbox. If the user then presses `add` (or selects it from the autocomplete box) it is added to the multi select box and if the user presses “insert” it is inserted in the lookup list + added to the selection also so it works seamlessly for the end-user.
No doubt this has written already by someone out there but I could not find it that quickly via Google so it was quicker to write it myself.
/**
* Event Handler for key/mouse on add/insert buttons on singlelookupfield
*
* @since 0.1
* @param obj @event the event passed
* @param obj @objLookup the static lookup object
*/
function SingleLookupEventHandler(event, objLookup) {
var singleValueEntered = $(objLookup.singleLookupSelector).val();
if (event.type === 'click') {addChoice(singleValueEntered,objLookup);} else {
var valueExists = false;
$(objLookup.singleAutoLookupSelector + " LI").each(
function () {if ($(this).text() === singleValueEntered) {valueExists = true;}
});
if (singleValueEntered.length > objLookup.singleLookupColumnNameTrigger) {
if (valueExists == false) {InsertButton(singleValueEntered, objLookup);}
else {AddButton(singleValueEntered, objLookup);}
} else {resetFields(objLookup,false);}
}
}
/**
* Inserts one new list item in a list + updates the multilookup column + hides the insert button
*
* @since 0.1
* @param string @text
* @param string @columnName the multilookup column
* @param string @listName the list to insert into
*/
function insertOne(singleValueEntered, objLookup) {
$().SPServices({
operation: "UpdateListItems",
async: false,
batchCmd: "New",
listName: objLookup.sourceList,
valuepairs: [[objLookup.sourceColumnName, singleValueEntered],["Title", objLookup.insertListAnnotation]],
completefunc: function(xData, Status) {
var newId = $(xData.responseXML).SPFilterNode("z:row").attr("ows_ID");
insertChoice(newId, singleValueEntered, objLookup)
addChoice(singleValueEntered, objLookup)
resetFields(objLookup,false);
}
});
}
/**
* Inits an "Insert/Add Button"
*
* @since 0.1
* @param object @objLookup the static lookup object
*/
function initButon(objLookup) {
var addButton = '<button type="button" id="'+objLookup.buttonId+'">Add ></button>';
$(objLookup.singleLookupSelector).after(addButton);
$(objLookup.buttonSelector).addClass('ms-input');
resetFields(objLookup,false);
}
/**
* Resets fields: removes button, empties textfield + autocomplete pulldown
*
* @since 0.1
* @param object @objLookup the static lookup object
*/
function resetFields(objLookup,complete) {
$("#"+objLookup.buttonId).hide();
if (complete) {
$(objLookup.singleLookupSelector).val('');
$(objLookup.singleAutoLookupSelector).hide();
}
}
/**
* Adds an "Insert Button"
*
* @since 0.1
* @param string @singleValueEntered the value entered in the textbox
* @param object @objLookup the static lookup object
*/
function InsertButton(singleValueEntered, objLookup) {
$(objLookup.buttonSelector).text(objLookup.insertAnnotation);
$(objLookup.buttonSelector).css('background-color', 'red');
$(objLookup.buttonSelector).show();
$(objLookup.buttonSelector).unbind('click');
$(objLookup.buttonSelector).click(function() {insertOne(singleValueEntered, objLookup);})
}
/**
* Adds an "Add Button"
*
* @since 0.1
* @param string @singleValueEntered the value entered in the textbox
* @param object @objLookup the static lookup object
*/
function AddButton(singleValueEntered, objLookup) {
$(objLookup.buttonSelector).text(objLookup.addAnnotation);
$(objLookup.buttonSelector).css('background-color', '#ccc');
$(objLookup.buttonSelector).show();
$(objLookup.buttonSelector).unbind('click');
$(objLookup.buttonSelector).click(function() {addChoice(singleValueEntered,objLookup);})
selectValue(singleValueEntered, objLookup);
}
/**
* Selects a value in the multilookup OOTB field
*
* @since 0.1
* @param obj @objLookup the static lookup object
*/
function selectValue(singleValueEntered, objLookup) {
$(objLookup.multiLookupPossibleSelector + " option").each(function () {
if ($(this).text() == singleValueEntered) {
$(this).val(1);
$(this).select();
}
});
}
/**
* Inserts a new value to the multilookup OOTB field
*
* @since 0.1
* @param number @id the id of the inserted list item
* @param string @singleValueEntered the value of the column of the inserted list item
* @param object @objLookup the static lookup object
*/
function insertChoice(id, singleValueEntered, objLookup) {
$(objLookup.multiLookupPossibleSelector).append($('<option>', {
value : id,
text : singleValueEntered
}));
}
/**
* Adds a selected value to the multilookup OOTB field
*
* @since 0.1
* @param string @singleValueEntered the value entered in the textbox
* @param object @objLookup the static lookup object
*/
function addChoice(singleValueEntered, objLookup) {
$(objLookup.multiLookupPossibleSelector+ " option").each(function () {
if ($(this).text() == singleValueEntered) {
$(this).appendTo($(objLookup.multiLookupSelectedSelector));
var multilookupPickerVal = $(objLookup.multiLookupselector).val();
if ($(objLookup.multiLookupselector).val() == undefined
|| $(objLookup.multiLookupselector).val().length == 0) {
$(objLookup.multiLookupselector).val($(this).val() + "|t" + $(this).text());
}
else {
$(objLookup.multiLookupselector).val(multilookupPickerVal
+ "|t" + $(this).val() + "|t" + $(this).text());
}
}
});
resetFields(objLookup,true);
}
/**
* Removes a selected value from the multilookup OOTB field
*
* @since 0.1
* @param string @singleValueEntered the value entered in the textbox
* @param object @objLookup the static lookup object
*/
function removeChoice(singleValueEntered, objLookup) {
$(objLookup.multiLookupSelectedSelector + " option").each(function () {
if ($(this).text() == singleValueEntered) {
$(this).appendTo($(objLookup.multiLookupPossibleSelector));
var multilookupPickerVal = $(objLookup.multiLookupselector).val();
var valToRemove = $(this).val() + "|t" + $(this).text();
var newValue = multilookupPickerVal.replace(valToRemove, "");
$(objLookup.multiLookupselector).val(newValue);
}
});
}
/**
* Hides a field from a form
*
* @since 0.1
* @param string @fieldId the Id of the field
*/
function hideField(fieldId) {
$(":input[id$='" + fieldId + "']").parents('tr').first().hide();
}
/**
* Jquery Init / Start
*
*/
$(document).ready(function() {
if (is_transportcontract()) {
// init
var dirNameColumnId = 'onetidIOFile';
var objLookup = new Object();
objLookup.singleLookupColumnName = 'SingleItemLookup';
objLookup.singleLookupColumnNameTrigger = 3;
objLookup.singleLookupSelector = ":input[title$='" + objLookup.singleLookupColumnName+"']";
objLookup.singleAutoLookupSelector = "#SPAutocomplete_" + objLookup.singleLookupColumnName;
objLookup.multiLookupColumnName = 'ItemLookup';
objLookup.multiLookupColumnId = 'MultiLookupPicker';
objLookup.multiLookupselector = "[id$='" + objLookup.multiLookupColumnId + "']";
objLookup.multiLookupSelectedSelector = "[title='" + objLookup.multiLookupColumnName + " selected values']";
objLookup.multiLookupPossibleSelector = "[title='" + objLookup.multiLookupColumnName + " possible values']";
objLookup.sourceColumnName = 'ItemNr';
objLookup.sourceList = 'ItemList';
objLookup.buttonId = 'ButtonId';
objLookup.buttonSelector = "#"+objLookup.buttonId;
objLookup.addAnnotation = 'Add >';
objLookup.insertAnnotation = 'Insert >';
objLookup.insertListAnnotation = 'Inserted by me!';
// hide the foldername
hideField(dirNameColumnId);
// init the autocomplete lookup column using spservices
$().SPServices.SPAutocomplete({
sourceList: objLookup.sourceList,
sourceColumn: objLookup.sourceColumnName,
columnName: objLookup.singleLookupColumnName,
ignoreCase: true,
numChars: objLookup.singleLookupColumnNameTrigger,
highlightClass: "ms-bold",
slideDownSpeed: 1000,
debug: false
});
// init add/hide button
initButon(objLookup);
// add eventhandler on keyup on single lookup
$(objLookup.singleLookupSelector).keyup(function(event) {
SingleLookupEventHandler(event,objLookup);
});
// add eventhandler on mouseclick on spautocomplete box single lookup
$(objLookup.singleAutoLookupSelector).click(function() {
SingleLookupEventHandler(event,objLookup);
})
}
});
For the add/remove in the OOTB box I used the great trick from Derek Gustaff using the append Jquery function which moves stuff around in the DOM, pretty handy.