Kleine Helfer – CamlJs
avatar

Manchmal sind es die kleinen Helfer/Tools, die im Projekt große Arbeitsersparnis bringen. Eines dieser Tools möchte ich heute kurz vorstellen. Es handelt sich dabei um CamlJs, eine JavaScript Bibliothek, um SharePoint CAML Abfragen clientseitig zu generieren. Offizielle Webseite:https://github.com/andrei-markeev/camljs

Jeder der schon ein mal eine clientseitige Lösung für SharePoint implementiert hat, kam vermutlich auch an die Stelle, an der Elemente aus Listen geladen werden mussten. Seit ewigen SharePoint-Zeiten ist CAML hierfür das vorgesehen Instrumentarium. Der Nachteil an CAML (seit je her) ist, dass die XML-basierende Syntax ganz umständlich zusammengefummelt werden muss.

Hier ein Beispiel:

public getUserInfo(labelstelle: string, userIds: number[], success: (label: string, data: any[]) => any, error: (msg: string) => any) {
        const context = SP.ClientContext.get_current();
        const userInfoList = context.get_web().get_siteUserInfoList();
        const userDataCollection = [];
        for (const userId of userIds) {
            const query = new SP.CamlQuery();
            const viewXml = "<View> \
                    <Query> \
                       <Where> \
                           <Eq><FieldRef Name='ID' /><Value Type='Integer'>" + userId + "</Value></Eq> \
                       </Where>  \
                    </Query> \
                    <RowLimit>1</RowLimit> \
                  </View>";
            query.set_viewXml(viewXml);
            const items = userInfoList.getItems(query);
            userDataCollection.push(items);
            context.load(items,
                `Include(
                Title,Department,EMail,FirstName,ID,IsActive,JobTitle,LastName,MobilePhone,Name,Office,
                Picture,SipAddress,UserName,WebSite,WorkPhone
            )`        );
        }
        context.executeQueryAsync(() => {
			...

Wenn es, wie im obigen Fall, eine relativ einfache Abfrage ist, ist es noch vertretbar diese von Hand oder bspw. mit Hilfe des U2U CAML Builder Tools zu erstellen. In machen Fällen stößt dies aber an seine Grenzen; zum Beispiel wenn die Abfragen dynamisch generiert und mit logischen Operatoren verknüpft werden müssen.

Genau an dieser Stelle kommt CamlJs ins Spiel! Nach dem Verlinken der Bibliothek in der Seite kann CamlJs einfach und intuitiv verwendet werden. (Ohne umständige String-Basteleien! Smile)

        ...	
	const context = SP.ClientContext.get_current();
        const web = context.get_web();
        const listItemCollection = [];

        for (const listName of queryData.lists) {
            const list = web.get_lists().getByTitle(listName);
            const query = new SP.CamlQuery();

            let viewXml = '';
            let cBuilder = new CamlBuilder().Where().LookupField(queryData.userFieldName).ValueAsText().Contains(queryData.userLogins[0]);

            let index = 0;
            for (const login of queryData.userLogins) {
                if (index > 0) {
                    cBuilder = cBuilder.Or().LookupField(queryData.userFieldName).ValueAsText().Contains(login);
                }
                index++;
            }
            viewXml = '<View><Query>' + cBuilder.ToString() +  '</Query></View>';

            query.set_viewXml(viewXml);
            const collListItem = list.getItems(query);
	    ...

Im obigen Code ist zu sehen wie für eine beliebige Anzahl von Listen CAML-Abfragen für eine beliebige Anzahl von Usern erstellt und abgefeuert werden. Wenn es mehr als einen User gibt, werden diese per OR in der Abfrage ergänzt. Schön überschaubar, oder?

Die Basisabfrage für den ersten User zeigt deutlich, wie die Where-Anweisung und die übrigen Konstrukte der Abfrage intuitive zusammengesetzt werden.

let cBuilder = new CamlBuilder().Where().LookupField(queryData.userFieldName).ValueAsText().Contains(queryData.userLogins[0]);

Alle übrigen User können nun mit einem OR der Abfrage beigefügt werden.

for (const login of queryData.userLogins) {
   if (index > 0) {
     cBuilder = cBuilder.Or().LookupField(queryData.userFieldName).ValueAsText().Contains(login);
   }
   index++;
}

Fazit

Bevor man anfängt unübersichtliche XML-Abfragen per String zusammen zu basteln, lieber gleich zu CamlJs greifen und eine Menge “Lines of Code” und Nerven sparen! Smile

Schreibe einen Kommentar