Queryable Lookup Feld in SharePoint Liste

von Roland Rickborn

Übersicht

Symbolbild

Bei einem großen Kunden soll im Intranet, das auf Microsoft SharePoint 2013 On-premise Basis läuft, eine Plattform für interne Zwecke eingerichtet werden. Die Inhalte, bestehend aus Intranetseiten mit Text und Bildern, aber auch Downloads in Form von PDF- und anderen Textdateien, sollen durch die interne Unternehmensorganisation selbst gepflegt werden können.

Problemstellung

Die Pflege der Inhalte wird von Mitarbeitern durchgeführt, die lediglich über Grundkenntnisse der Bearbeitung von Sharepoint-Seiten verfügen. Das Pflegen von neuen Inhalten soll daher so einfach wie möglich sein und soll keine HTML- oder andere Fachkenntnisse erfordern. Es wird trotzdem ein hoher Grad an Automatisierung bei der Bereitstellung von neuen Inhalten angestrebt. Viele Informationen werden in Listen verwaltet. Eine Hauptliste holt sich ihre Daten per Lookup Typ aus anderen Listen.

Die oben erwähnten Downloads werden in einer Dokumentenbibliothek gepflegt. Die Bibliothek wurde um benutzerdefinierte Felder für die Attribution der Downloads erweitert. Downloads dieser Bibliothek sollen automatisch auf bestimmten anderen Seiten angezeigt werden können. Dabei wird auf den Zielseiten das Content Search Webpart (CSWP) verwendet.

Das Problem besteht darin, dass die Query des CSWP ein Lookup Feld der Dokumentenbibliothek beinhaltet. Die Query kann so allerdings nicht verwendet werden, da Lookup Felder nicht queryable sind [1].

Lösungsansatz

Statt der Verwendung des echten Lookup Typs, wird ein Quasi-Lookup Typ verwendet. Dafür wird ein neues Feld vom Typ Single line of text angelegt. Das Feld wird als Required markiert. Beim Anlegen neuer oder beim Bearbeiten bestehender Items wird das Freitextfeld zu einem pseudo-Feld vom Typ Choice. Die Ermittlung der realen Werte erfolgt mittels JavaScript durch eine CAML Query.

Die Umsetzung dieser Lösung entspricht einem Feld vom Typ Lookup ohne die Option Enforce relationship behaviour. Aus Sicht der neuen Plattform spielt es keine Rolle, ob das Quell-Item noch besteht oder ob es gelöscht wurde.

Lookup befüllen und CAML Query

Um sicherzustellen, dass alle Items mit realen Werten für das Lookup Feld bestehen, muss:

  • das New Item Formular und
  • das Edit Item Formular

entsprechend beim Laden befüllt werden. Außerdem muss die Option Quick Edit deaktiviert werden.

Das Laden unserer Quasi-Lookup Liste mit realen Werten erfolgt durch die nachfolgende JavaScript Funktion:

Listing 1

function getItemsAsArrayBySPList()
{
    var myItemsArray = [];
    $().SPServices({
        operation: "GetListItems",
        listName: "Things",
        async: true,
        CAMLViewFields: "<ViewFields><FieldRef Name='Thing'/></ViewFields>",
        CAMLQuery: "<Query><OrderBy><FieldRef Name='Thing' Type='Text' "+
        	"Ascending='TRUE'></FieldRef></OrderBy></Query>",
        CAMLQueryOptions: "<QueryOptions></QueryOptions>",
        completefunc: function(xData, Status) {
            $(xData.responseXML).SPFilterNode("z:row").each(function () {   
                myItemsArray.push($(this).attr("ows_Thing"));
            });
        }
    });
    return myItemsArray;
}

Anschließend wird das so erhaltene Array als Auswahlliste zu unserem Quasi-Lookup Feld hinzugefügt. Dafür dient die folgende JavaScript Funktion:

Listing 2

function addItemsToChoice(myItemsArray)
{
    $.each(myItemsArray, function( index, value ) {
        var option = "<option value='"+value+"'>"+value+"</option>";
        $( "[title='Thing Required Field']" ).append(option);
    });
}

Damit diese Funktionen beim Laden der Formulare ausgeführt werden, können die beiden Formulare NewForm.aspx und EditForm.aspx editiert werden. Man kann z.B. jeweils ein Script Editor Web Part (SEWP) hinzufügen und den in Listing 3 gezeigten Code als Snippet angeben:

Listing 3

availableThings = getItemsAsArrayBySPList();
availableThings.sort();
addItemsToChoice(availableThings);

Auswahl erkennen und Information speichern

Falls ein bestehendes Item bearbeitet wird, soll natürlich der zuvor gespeicherte Werte des Quasi-Lookup Feldes ausgewählt sein. Dazu muss beim Laden des Formulars ermittelt werden, um welches Item es sich handelt. Dann muss der für dieses Item hinterlegte Wert des Quasi-Lookup Feldes ermittelt werden. Dafür wird in einem ersten Schritt die ID des Items ermittelt, das gerade bearbeitet wird. Die ID kann aus der URL extrahiert werden, was in der folgenden JavaScript Funktion gezeigt wird:

Listing 4

function getIdFromUrl()
{
    var queryStringVals = $().SPServices.SPGetQueryString(); //..EditForm.aspx?ID=20..
    return queryStringVals["ID"];
}

Mit der nun bekannten ID lässt sich die Liste der Items abfragen und so der aktuell ausgewählte Wert unseres Quasi-Lookup Feldes in Erfahrung bringen. Dazu dient die folgende JavaScript Funktion:

Listing 5

function getThingOfItemByID(myID)
{
    var myThing = '';
    $().SPServices({
        operation: "GetListItems",
        listName: "Items",
        async: true,
        CAMLViewFields: "<ViewFields><FieldRef Name='Thing'/></ViewFields>",
        CAMLQuery: "<Query><Where><Eq><FieldRef Name='ID'/><Value "+
        	"Type='Counter'>"+myID+"</Value></Eq></Where></Query>",
        CAMLQueryOptions: "<QueryOptions></QueryOptions>",
        completefunc: function(xData, Status) {
            $(xData.responseXML).SPFilterNode("z:row").each(function () {
                myThing = $(this).attr("ows_Thing");
            });
        }
    });
    return myThing;
}

Hier wird auch ersichtlich, dass die Option Enforce relationship behaviour nicht berücksichtigt werden kann. Denn wird für die genannte ID kein passender Wert zurückgegeben, gibt die Funktion ihrerseits einen leeren Wert zurück. Im Formular führt das dazu, dass kein Wert aus der Liste der vorhandenen Werte als ausgewählt markiert wird.

Im SEWP in EditForm.aspx würde man das Snippet wie folgt ergänzen:

Listing 6

currentID = getDownloadIdFromUrlParameter();
currentThingStr = getThingOfItemByID(currentID);
$( "[title='Thing Required Field']" ).val(currentThingStr); // set drop-down value

Fazit

Es wurde eine einfache und trotzdem robuste Lösung vorgestellt, mit der eine SharePoint Liste um eine Spalte vom Typ Lookup erweitert werden kann, die aber durchsucht werden kann. Damit kann diese Spalte als Argument in einer Query z.B. im CSWP verwendet werden.

Tipp

Im gezeigten Beispiel wurde in der Liste das Feld Thing mit dem Typ Single line of text angelegt. In einer Query würde man danach suchen mit dem Argument ThingOWSCHCS.

Kategorien: Sharepoint

Zurück