Socket
Socket
Sign inDemoInstall

@bpa-solutions/camljs

Package Overview
Dependencies
1
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    @bpa-solutions/camljs

Library for creating SharePoint CAML queries client-side. For JSOM, REST or SPServices.


Version published
Maintainers
1
Install size
183 kB
Created

Readme

Source

Installation

Nuget:

PM> Install-Package CamlJs

Nuget TypeScript definitions:

PM> Install-Package camljs.TypeScript.DefinitelyTyped

Npm:

npm install camljs

Npm TypeScript definitions:

npm install @types/camljs

Also check out CamlJs Console - Chrome extension for testing queries with live preview against real lists.

Usage

In browser:

<script type="text/javascript" src="//unpkg.com/camljs"></script>
<script>
    alert(new CamlBuilder().View().ToString());
</script>

In node:

var CamlBuilder = require('camljs');
console.log(new CamlBuilder().View().ToString());

ES2015 modules:

import * as CamlBuilder from 'camljs';
console.log(new CamlBuilder().View().ToString());

Basics

Let's assume we need to fetch all Google-related emails from a SharePoint list where your company stores archived project emails. To generate the corresponding query using CamlJs, you could use following javascript code:

var camlBuilder = new CamlBuilder();

var caml = camlBuilder.Where()
    .TextField("Email").EqualTo("support@google.com")
    .Or()
    .TextField("Email").EqualTo("plus@google.com")
    .Or()
    .TextField("Title").BeginsWith("[Google]")
    .Or()
    .TextField("Content").Contains("Google")
    .ToString();

This will generate the following CAML code:

<Where>
  <Or>
    <Eq>
      <FieldRef Name="Email" />
      <Value Type="Text">support@google.com</Value>
    </Eq>
    <Or>
      <Eq>
        <FieldRef Name="Email" />
        <Value Type="Text">plus@google.com</Value>
      </Eq>
      <Or>
        <BeginsWith>
          <FieldRef Name="Title" />
          <Value Type="Text">[Google]</Value>
        </BeginsWith>
        <Contains>
          <FieldRef Name="Content" />
          <Value Type="Text">Google</Value>
        </Contains>
      </Or>
    </Or>
  </Or>
</Where>

It is also possible to generate SP.CamlQuery object, just change .ToString() to .ToCamlQuery().

Another example:

var caml = camlBuilder.Where()
    .LookupField("Category").Id().In([2, 3, 10])
    .And()
    .DateField("ExpirationDate").LessThanOrEqualTo(CamlBuilder.CamlValues.Now)
    .OrderByDesc("ExpirationDate")
    .ToString()

As you see, the code is pretty clean and readable. The resulting CAML is much more awkward, especially if you imagine it in javascript strings dress, without indentation and highlighting...

<Where>
  <And>
    <In>
      <FieldRef Name="Category" LookupId="TRUE" />
      <Values>
        <Value Type="Integer">2</Value>
        <Value Type="Integer">3</Value>
        <Value Type="Integer">10</Value>
      </Values>
    </In>
    <Leq>
      <FieldRef Name="ExpirationDate" />
      <Value Type="Date">
        <Now />
      </Value>
    </Leq>
  </And>
</Where><OrderBy>
  <FieldRef Name="ExpirationDate" Ascending="FALSE" />
</OrderBy>

Dynamic queries

It's very easy to create dynamic queries with CamlJs by leveraging the CamlBuilder.Expression() construction. It's like a standalone part of query that can be later used in the final new CamlBuilder.Where() or new CamlBuilder.View().

var categories = ["Category 1", "Category 2", "Category 3"];

var categoriesExpressions = categories.map(c => CamlBuilder.Expression().TextField("Category").EqualTo(c));

var caml = new CamlBuilder().Where()
    .Any(categoriesExpressions),
    .ToString();

Result:

<Where>
    <Or>
        <Eq>
            <FieldRef Name="Category" />
            <Value Type="Text">Category 1</Value>
        </Eq>
        <Or>
            <Eq>
                <FieldRef Name="Category" />
                <Value Type="Text">Category 2</Value>
            </Eq>
            <Eq>
                <FieldRef Name="Category" />
                <Value Type="Text">Category 3</Value>
            </Eq>
        </Or>
    </Or>
</Where>

While .Any() generates <Or> clauses, .All() will generate <And>.

Elements support

CamlJs supports all Query elements that are described on MSDN.

For example, seldom used Membership element:

var caml = camlBuilder.Where()
    .UserField("AssignedTo").EqualToCurrentUser()
    .Or()
    .UserField("AssignedTo").IsInCurrentUserGroups()
    .GroupBy("ProductTitle")
    .OrderBy("Priority").ThenBy("Title")
    .ToString();

This code will generate following CAML:

<Where>
  <Or>
    <Eq>
      <FieldRef Name="AssignedTo" />
      <Value Type="Integer">
        <UserID />
      </Value>
    </Eq>
    <Membership Type="CurrentUserGroups">
      <FieldRef Name="AssignedTo" />
    </Membership>
  </Or>
</Where>
<GroupBy>
  <FieldRef Name="ProductTitle" />
</GroupBy>
<OrderBy>
  <FieldRef Name="Priority" />
  <FieldRef Name="Title" />
</OrderBy>

You can also create the upper-level View element as supported by SP.CamlQuery object. Scope attribute, ViewFields, Joins and ProjectedFields are supported in this case.

Joining lists via CamlJs is very easy. Here's the example:

var query = new CamlBuilder()
    .View(["Title","Country","Population"])
    .LeftJoin("Country","Country").Select("People","Population")
    .Query()
    .Where()
    .NumberField("Population").LessThan(10)
    .ToString();

The resulting generated CAML query will be the following:

<View>
    <ViewFields>
        <FieldRef Name="Title" />
        <FieldRef Name="Country" />
        <FieldRef Name="Population" />
    </ViewFields>
    <Joins>
        <Join Type="LEFT" ListAlias="Country">
            <Eq>
                <FieldRef Name="Country" RefType="ID" />
                <FieldRef Name="ID" List="Country" />
            </Eq>
        </Join>
    </Joins>
    <ProjectedFields>
        <Field ShowField="People" Type="Lookup" Name="Population" List="Country" />
    </ProjectedFields>
    <Query>
        <Where>
            <Lt>
                <FieldRef Name="Population" />
                <Value Type="Number">10</Value>
            </Lt>
        </Where>
    </Query>
</View>

Modify existing queries

Often you need to modify existing query (e.g. that comes from an existing list view), rather than generate a completely new one. This use case is also supported by CamlJs:

  • CamlBuilder.FromXml(xml) method will create a CamlBuilder object from existing CAML string
  • ReplaceWhere method then allows to replace clause with one generated by CamlJs
  • ModifyWhere().AppendAnd() will add new conditions to existing query using "And" operator
  • ModifyWhere().AppendOr() will add new conditions to existing query using "Or" operator

Example:

var xml = new CamlBuilder().View().Query().Where()
    .UserField("Author").EqualToCurrentUser()
    .ToString();

var query = CamlBuilder.FromXml(xml)
    .ModifyWhere().AppendAnd()
    .LookupField("Country").ValueAsText().BeginsWith("G");

Result:

<View>
  <Query>
    <Where>
      <And>
        <Eq>
          <FieldRef Name="Author" LookupId="TRUE" />
          <Value Type="Integer">
            <UserID />
          </Value>
        </Eq>
        <BeginsWith>
          <FieldRef Name="Country" />
          <Value Type="Text">G</Value>
        </BeginsWith>
      </And>
    </Where>
  </Query>
</View>

Keywords

FAQs

Last updated on 14 Apr 2022

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc