Project Description

Simplifies creation of SharePoint CAML queries for client-side scripts. Can be used with either SharePoint Client Object Model or SPServices.

Nuget:

PM> Install-Package CamlJs

What's new in Release 2.0

Bracket expressions and partial query generation

This is the main improvement comparing to the version 1.0, where you couldn't create complex queries because of lack of bracket expressions support.

Two new methods were added to the builder chain in order to support that: Any & All.

/** Adds And clauses to the query. Use for creating bracket-expressions in conjuction with CamlBuilder.Expression(). */
All(...conditions: IExpression[]): IExpression;

 

/** Adds Or clauses to the query. Use for creating bracket-expressions in conjuction with CamlBuilder.Expression(). */
Any(...conditions: IExpression[]): IExpression;


You can use these methods in conjunction with CamlBuilder.Expression() for creating bracket expressions, for example like this:

var camlQuery = new CamlBuilder().Where().Any(
    CamlBuilder.Expression().TextField("Email").EqualTo("support@google.com"), 
    CamlBuilder.Expression().TextField("Email").EqualTo("plus@google.com"), 
    CamlBuilder.Expression().TextField("Title").BeginsWith("[Google]"), 
    CamlBuilder.Expression().TextField("Content").Contains("Google")
).ToString();


As a side effect, you can now create parts of your query separately via CamlBuilder.Expression(), and then merge them together at some point later. Also you can use CamlBuilder.Expression() for defining CAMLQuery attribute in SPServices.

Better Intellisense

Intellisense significantly improved: now different types of fields have different sets of comparison options. Field usage is made more obvious.

  1. LookupField element improved. No more misleading "casting" of lookups to the target field types: now lookup fields expose methods Id() and ValueAs<type of field>().
  2. BooleanField element added for fields of boolean type.
  3. UrlField element added for fields of type URL.
  4. DateRangesOverlap element improved. It turns out, you cannot use this element in CSOM, because CSOM ignores QueryOptions element. But you still can use DateRangesOverlap with SPServices.
  5. UserField element improved.

Migration from version 1.0 to version 2.0

None of old elements were removed, but syntax is now more strict, thus in some cases it is possible that some migration will be necessary. Please, post your problems to discussions, if you will have any.

Also, please keep in mind that some elements were marked as deprecated:

  1. LookupIdField element marked as deprecated and will be removed in the next major release. Please, use LookupField(...).Id() instead.
  2. Membership element marked as deprecated and will be removed in the next major release. Functionality of Membership element was replaced with set of methods under UserField element.

TypeScript implementation

CamlBuilder is now implemented in TypeScript and thus can be used seamlessly by Typescript developers. Of course, you can still use JavaScript version for pure JS development.

Internally, TypeScript unit tests (tsUnit) are now used, helping to make the library much more stable. New tests are added.

Nuget

CamlBuilder is now available via Nuget.

JavaScript:

PM> Install-Package CamlJs



TypeScript definitions:

PM> Install-Package camljs.TypeScript.DefinitelyTyped

 

Basics

To start with, let's assume we need to fetch all Google-related letters from some mailbox list, using SharePoint Client Object Model. To generate the corresponding query using Caml Builder, 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 expected CAML:

<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>

, which then could be used in SP.CamlQuery.

Very good so far, and have a look at some other examples!

First of all, cannot resist to mention, that CamlBuilder covers almost all Query elements, described at 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>

The last example at this section:

    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>

Usability

Besides of readability, CamlBuilder pretends to be very handy in development, because you can use intellisense and inline documentation:

This will help to catch a bunch of errors when writing code, and surely prevent from typos and misunderstandings, so the benefits could be really magnificient!

Contribute

Any contributions are highly appreciated!

Last edited Sep 14 at 9:34 PM by omlin, version 10