Main /

Share Point 2010 Cascading Lookups

Share Point 2010 Cascading Lookups

/ HomePage / Computer / Software / SharePoint / SharePoint2010CascadingLookups

Kaskadierte Lookup-Felder unter SharePoint 2010 mit SPCD

Aufgabenstellung

Oft kommt es vor dass man voneinander abhängige Drop-Down-Felder in einem Formular benötigt. Man wählt im ersten Drop-Down ein Item aus, das zweite Drop-Down enthält dann nur noch die von der ersten Auswahl abhängigen Elemente.

Wichtig:

Im nachfolgenden Text sind Listennamen grün und Feldnamen blau dargestellt.

In unserem Beispiel existieren drei Listen: Meilensteine , Teilprojekte und Arbeitspakete . Ein Meilenstein besteht aus mehreren Teilprojekten, ein Teilprojekt aus mehreren Arbeitspaketen.

Demzufolge enthält Arbeitspakete ein Lookup-Feld namens Teilprojekt auf Title von Teilprojekte und Teilprojekte wiederum ein Lookup-Feld namens Arbeitspaket auf Title von Arbeitspakete.

Die Standard-Task-Liste einer Teamsite soll nun um die Auswahl eines Arbeitspaketes erweitert werden um ein Task einem Arbeitspaket zuzuordnen. Da sich alle Arbeitspakete "flat" in Arbeitspakete befinden, ist es dem User nicht zuzumuten diese direkt auszuwählen, da er so nicht sehen kann welchen Teilprojekten und Meilensteinen das ausgewählte Arbeitspaket zugeordnet ist.

Er soll sich also über Meilensteine und Teilprojekten zu den Arbeitspaketen "durchhangeln" können.

Lösung

Für Sharepoint 2007 existiert eine Lösung bei Codeplex [1] die rein auf JavaScript basiert und prinzipiell auch unter Sharepoint 2010 funktioniert. Wie das Script unter 2010 einzubinden und anzuwenden ist, steht in diesem Blogeintrag [2].

Alternativ kann man auch den kompletten JavaScript-Source in das HTML Form Web Part packen.

Wichtig:

Das HTML Form Web Part muss sich unterhalb des Formulars befinden, sonst funktioniert das Script nicht!

In unserem Fall müssen der Task-Liste drei Lookup-Felder hinzugefügt werden, je eins für Meilensteine (Meilenstein) , Teilprojekte (Teilprojekt) und Arbeitspakete (Arbeitspaket) die auf das Title-Feld der jeweiligen Listen verweisen.

Wir brauchen außerdem zwei cascadeDropdown Instanzen da wir eine dreistufige Kaskadierung haben möchten.

Die Aufrufe sehen so aus:

 var ccd1 = new cascadeDropdowns("Meilenstein", "Teilprojekt", "Meilenstein", "Teilprojekte", "Title");
 var ccd2 = new cascadeDropdowns("Teilprojekt", "Arbeitspaket", "Teilprojekt", "Arbeitspakete", "Title");

Sofern sich alle beteiligten Listen auf dem gleichen Web befinden funktioniert es damit. Unter Sharepoint 2010 muß dies jedoch nicht so sein...

Site Content Types,Site Columns und Lookup Listen auf höheren Ebenen

Hat man die Lookups nicht direkt an die Task-Liste geflanscht sondern über einen von Task geerbten Site Content Type mit drei neuen Site Colums definiert, hat man die Möglichkeit die drei Listen auf einer höheren Ebene als die Task-Liste anzusiedeln und trotzdem per Lookup darauf zu verweisen, einfach indem man der Task-Liste den neuen Content-Type zuweist. In diesem Fall funktioniert das SPCD-Script nicht mehr, da es die Listen im gleichen Web erwartet.

Das Script ermittelt die List-Items über Die Web-Service-Methode GetListItems, die im Script so aufgerufen wird, dass sie auf dem aktuellen Web arbeitet. Der Methode kann jedoch auch die GUID eines anderen Webs mittels des Parameters webID übergeben werden. Um das relativ bequem per Funktionsaufruf zu machen wird das SPCD-Script geringfügig geändert:

Änderung an der Funktion CascadeDropdowns

Alt:

 function cascadeDropdowns(ParentDropDownTitle, ChildDropDownTitle,
 Child2ParentFieldIntName, ChildListNameOrGuid,
 ChildLookupTargetField) {
        this.parentLookup = new LookupField(ParentDropDownTitle);
        this.childLookup = new LookupField(ChildDropDownTitle);
        this.childList = ChildListNameOrGuid;
        this.child2ParentLink = Child2ParentFieldIntName;
        this.childLookupTargetField = ChildLookupTargetField;
        CascadingDropdowns.push(this);
 }

Neu:

 function cascadeDropdowns(ParentDropDownTitle, ChildDropDownTitle,
 Child2ParentFieldIntName, ChildListNameOrGuid,
 ChildLookupTargetField, WebID) {
        this.parentLookup = new LookupField(ParentDropDownTitle);
        this.childLookup = new LookupField(ChildDropDownTitle);
        this.childList = ChildListNameOrGuid;
        this.child2ParentLink = Child2ParentFieldIntName;
        this.childLookupTargetField = ChildLookupTargetField;
        this.webID = WebID;
        CascadingDropdowns.push(this);
 }
Änderung an der Funktion getQuery2Run

Alt:

function getQuery2Run(CascadingDropdown) {
        var selectedId;
        if(CascadingDropdown.parentLookup.isDropDown) {
                selectedId = CascadingDropdown.parentLookup.Object.options[CascadingDropdown.parentLookup.Object.selectedIndex].value;
        }
        else {
                selectedId = CascadingDropdown.parentLookup.Opthid.value;
        }
        var result = '<?xml version="1.0" encoding="utf-8"?>' +
        '<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">' +
          '<soap12:Body>' +
                '<GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">' +
                '<listName>' + CascadingDropdown.childList + '</listName>' +
                        '<query>' +
                                '<Query>' +
                                (selectedId==0?'':'<Where><Eq><FieldRef LookupId="TRUE" Name="' + CascadingDropdown.child2ParentLink + '" /><Value Type="Counter">' + selectedId + '</Value></Eq></Where>') +
                                '<OrderBy><FieldRef Name="' + CascadingDropdown.childLookupTargetField + '" /></OrderBy>' +
                                '</Query>' +
                        '</query>' +
                        '<viewFields><ViewFields>' +
                                '<FieldRef Name="' + CascadingDropdown.childLookupTargetField + '" /><FieldRef Name="ID" />' +
                        '</ViewFields></viewFields>' +
                '</GetListItems>' +
          '</soap12:Body>' +
        '</soap12:Envelope>'
        //alert(result);
        return result;
}

Neu:

function getQuery2Run(CascadingDropdown) {
        var selectedId;
        if(CascadingDropdown.parentLookup.isDropDown) {
                selectedId = CascadingDropdown.parentLookup.Object.options[CascadingDropdown.parentLookup.Object.selectedIndex].value;
        }
        else {
                selectedId = CascadingDropdown.parentLookup.Opthid.value;
        }
        var result = '<?xml version="1.0" encoding="utf-8"?>' +
        '<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">' +
          '<soap12:Body>' +
                '<GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">' +
                '<listName>' + CascadingDropdown.childList + '</listName>' +
                '<webID>' + CascadingDropdown.webID + '</webID>'+
                        '<query>' +
                                '<Query>' +
                                (selectedId==0?'':'<Where><Eq><FieldRef LookupId="TRUE" Name="' + CascadingDropdown.child2ParentLink + '" /><Value Type="Counter">' + selectedId + '</Value></Eq></Where>') +
                                '<OrderBy><FieldRef Name="' + CascadingDropdown.childLookupTargetField + '" /></OrderBy>' +
                                '</Query>' +
                        '</query>' +
                        '<viewFields><ViewFields>' +
                                '<FieldRef Name="' + CascadingDropdown.childLookupTargetField + '" /><FieldRef Name="ID" />' +
                        '</ViewFields></viewFields>' +
                '</GetListItems>' +
          '</soap12:Body>' +
        '</soap12:Envelope>'
        //alert(result);
        return result;
}
geänderter Aufruf

Im Aufruf wird nun die GUID des Webs übergeben auf denen die drei Listen Meilensteine , Teilprojekte und Arbeitspakete liegen. Die GUID lässt sich mit dem SharePoint Manager herausfinden.

var ccd1 = new cascadeDropdowns("Meilenstein", "Teilprojekt", "Meilenstein", "VTeilprojekte", "Title","{0ed51ef9-26e9-4d26-8ff3-7cd61e1879b0}");
var ccd2 = new cascadeDropdowns("Teilprojekt", "Arbeitspaket", "Teilprojekt", "VArbeitspakete", "Title","{0ed51ef9-26e9-4d26-8ff3-7cd61e1879b0}");

Sonderlich schön ist dies natürlich nicht. Vielleicht werde ich bei Gelegenheit das Script erweitern, so dass mit dem Namen des Webs gearbeitet werden kann, oder besser einfach mit "parent" o.ä.

bis dann...

/Elsni

Referenzen

Frische Änderungen | Menü editieren
zuletzt geändert am 03.11.2011 11:18 Uhr von Elsni
Edit Page | Page History