0% found this document useful (0 votes)
61 views14 pages

CrudeSP Manual

CrudeSP is a JavaScript library that allows for creating, updating, deleting, and viewing list items in SharePoint lists and document libraries. It uses client-side APIs and provides a query syntax to select data from lists using conditions, ordering, pagination, and joins between lists.

Uploaded by

LEandro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views14 pages

CrudeSP Manual

CrudeSP is a JavaScript library that allows for creating, updating, deleting, and viewing list items in SharePoint lists and document libraries. It uses client-side APIs and provides a query syntax to select data from lists using conditions, ordering, pagination, and joins between lists.

Uploaded by

LEandro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

crudeSP

guide

Introduction
CrudeSP (csp) is a JavaScript library which eases handling listitems in SharePoint lists and document
libraries. CrudeSP provides all the functions to create, update delete and view list entries as well as
uploading to document libraries. It also comes with its own CAML-builder to select data efficiently.

Requirements and integration


CrudeSP is a service for SharePoint and can only run on SharePoint Apps and Solutions. It uses client
side SharePoint CSOM and REST services to interact with the host system and jQuery. In order to get
crudeSP working you need to load SharePoints JavaScript files (SP.Core.js, SP.Runtime.js), jQuery
(which itself is an integral part of SharePoint client scripting) and the csp.js file (or csp-min.js file in
production) in your project.

<script
<script
<script
<script

type="text/javascript"
type="text/javascript"
type="text/javascript"
type="text/javascript"

src="/_layouts/15/zeiterfassung2015/scripts/jquery-2.1.1.js" />
src="/_layouts/15/SP.Runtime.js" />
src="/_layouts/15/SP.Core.js" />
src="/_layouts/15/project/scripts/csp.js" />

Using crudeSP
CrudeSP as a query provider orientates itself roughly on SQLs syntax, allowing you to use the basic
select, where and orderBy keywords for data selection. In order to explain the query structure we
use a SharePoint list called test with its visible columns Title and salary. Its contents are:

Title
Anthony
Bert
Clara

salary
9999
2000
5000

A basic csp-query to return all the data of test:


var op = new csp.Operation({
site: "https://mySharePoint.corporationcorporation.com/project",
select: "Title, salary",
list: "test",
debug: true
});
op.readItems(function (output) {
console.log(output.length + " lines returned");
},function (message) { console.log(message); });

Firstly a new csp.Operation-object called op is instantiated with the properties site, select, list
and debug. Property site sets the SharePoint-site of the desired list. If an app runs on the same site
where the list is stored on, you dont have to set site as csp infers the current site context when the
property is not set. In select you can define the columns to return. Attention, these columns are
case-sensitive and will throw errors if the case or spelling is not right. list defines the SharePoint list
or library to retrieve data from and debug: true adds a debug mode which throws more precise
error messages, helping you debug your queries.
Secondly you call an operation method from the instantiated object op. Following methods are
available:

readItems(success, failure)
updateItems(success, failure)
deleteItems(success, failure)
createItems(success, failure)
uploadToLibrary(success, failure)

Because csp runs asynchronously, these methods generally take two callback methods as arguments.
The first one is executed when the operation is successful and the second one fires in case something
fails.

Reading list items


The csp-query-provider includes the possibility to select data based on conditions. In SharePointCSOM queries this is facilitated by CAML. The csp-CAML-generator allows for a lightweight sql-esque
syntax which gets converted to CAML. The CAML generator supports the following operands:
"<>"
"="
"<"
">"
"<="
">="

"!="

not equal
equal
less than
greater than
less or equal than
greater or equal than

"IS NULL"
"IS NOT NULL
"CONTAINS"
"BEGINS WITH"
"IN"
"and" "or" ( )

field is null
field is not null
field contains value
field value begins with
field equals value in list
logical operators

var op = new csp.Operation({


select: "Title, salary",
list: "test",
where: "Title = 'Anthony'1 or salary > 4000",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Title);
}
},function (message) { console.log(message); });

csp uses commas (,) for separation. You may put strings in quotation marks and you should do so if the string
contains a comma as this would break your query. See character escaping

The next query shows the usage of brackets:


var op = new csp.Operation({
select: "Title, salary",
list: "test",
where: "Title = 'Anthony' or (salary > 1000 and salary < 3000)",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Title);
}
},function (message) { console.log(message); });

To select items based on a single ID it is possible to solely pass an integer to the where property:
var op = new csp.Operation({
select: "Title, salary",
list: "test",
where: 3,
debug: true
});

The keyword In can be used to provide a list of conditions to meet within a single column:
var op = new csp.Operation({
select: "Title, salary, ID",
list: "test",
where: "ID in 1,2,3",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Title + " " + output[item].salary + " " +
output[item].ID);
}
}, function (message) { console.log(message); });

The readItems method returns the data as an array of (JavaScript) objects. This data can be
consumed by using its variable as a parameter in the first - in case of success call back method. The
above query therefore returns:
output = [
{
Title: "Anthony",
salary: 9999,
ID: 1
}, {
Title: "Bert",
salary: 2000,
ID: 2
}
];

The select keyword supports column aliasing and constant expressions. Aliases can be set by adding
as followed by the desired name. The columns in the result set are addressed by the alias whereas
in the query we use their original names. This is especially helpful if you want to aggregate data from
different sources in one view.
Constant expressions can be used to add constant data to a result set. Constant expressions have to
be enclosed in brackets so the camlBuilder can distinguish them from existing fields.

var op = new csp.Operation({


select: "Title as Name, salary as Wage, (5 as Level)",
list: "test",
where: "Title = 'Anthony' or (salary > 1000 and salary < 3000)",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Name + " " + output[item].Wage + " " +
output[item].Level);
}
},function (message) { console.log(message); });

This query returns:


output = [
{
Name: "Anthony",
Wage: 9999,
Level: 5
}, {
Name: "Bert",
Wage: 2000,
Level: 5
}
];

The readItems operation furthermore supports orderBy and take keywords. The sort order in
orderBy is set by following the desired columns name with descending or ascending (default). You
may also use abbreviations desc and asc. The default sort order is ascending when not explicitly
set.
var op = new csp.Operation({
select: "Title as Name, salary as Wage",
list: "test",
debug: true,
orderBy: "salary descending"
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Name + " " + output[item].Wage);
}
},function (message) { console.log(message); });

The take keyword acts like the top or limit keywords known from SQL in that it takes the first n
records from the result set.
var op = new csp.Operation({
select: "Title as Name, salary as Wage",
list: "test",
debug: true,
orderBy: "salary",
take: 1
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Name + " " + output[item].Wage);
}
},function (message) { console.log(message); });

Character escaping

Csp offers character escaping in case reserved characters are used in values (where-property).
Reserved words and characters are:
Single quote
Brackets
and
or

()

And + or can be escaped via enclosing a string in single quotes. As an example a query with
where: title = 'cindy and berta' lets you select the item which title is cindy and berta, while not
enclosing cindy and berta will cause the query to fail. Single quotes and brackets are escaped via
backslash. As javascript automatically escapes this character, you need to use double backslashes to
escape properly. A query for title = cindys restaurant has to be expressed title = cindy\\s restaurant.

Querying for dates

To query a list for date values csp accepts the following formats:
Date:
YYYY-MM-DD

Example

where: begin > 2015-01-01

Date and time:


YYYY-MM-DD HH:MM:SS.sss OR YYYY-MM-DDTHH:MM:SS.sss
YYYY-MM-DD HH:MM:SS OR YYYY-MM-DDTHH:MM:SS
YYYY-MM-DD HH:MM OR YYYY-MM-DDTHH:MM

Examples

where: begin > 2015-03-31 11:00 or where: begin > 2015-03-31T11:00

If an invalid date is entered or a different format is used, csp will treat the date as a string

Joining lists
In order to join two lists a lookup has to be configured on the list that is intended to consume data
from another list. In the following example the consuming list is called Person and the providing list
Job. In Person we added a lookup column called lookup_column.
When using joins, property list must be provided with a join declaration. Unlike SQL the correct
order of the joined lists matters. A consuming list has to be joined to a providing list with a lookup
field configured on the consuming list. Before joining the lists, lets take a look on their contents:
Person
Title
Anthony
Bert
Clara

Job
Level
0
0
1

lookup_column
1
2
3

Title
Salesperson
Lawyer
Actress

PersonId
2
1
3

var op = new csp.Operation({


select: "Title as Name, Level, Job.Title as Profession",
list: Person join Job with lookup_column",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Name + " " + output[item].Level + " " +
output[item].Profession);
}
},function (message) { console.log(message); });

When using debug, csp will display a warning that it cannot thoroughly check for existing fields in
non-primary lists. Also when using debug, csp will warn you if you select columns name which exist in
more than one table without an alias. Doing so makes the two columns undistinguishable in the
output.
It is possible to chain joins. In the following example the list Person consumes data from Job which
itself consumes data from Address. Notice that the names of consumed tables within a join can be
chosen freely. SharePoint infers names of joined lists and foreign keys from lookup columns. Names
are case sensitive and have to be consistent within the query though.

Person

Job

Address

Title
Anthony

Level
0

lookup_column
1

Title
Salesperson

JobId
1

another_lookup
3

Bert

Lawyer

Clara

Actress

Title
Parkway
lane 1337
Stockton
plaza 441/35
Sunshine ave
777

AddressId
1
2

var op = new csp.Operation({


site: "https://mySharePoint.corporation.com/project",
select: "Title as Person, Level, Job.Title as Profession, List_C.Title as Address",
list: "Person join Job with lookup_colum, Job join Address with another_lookup",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Person + " " + output[item].Level + " " +
output[item].Profession + " " + output[item].Address);
}
},function (message) { console.log(message); });

Left-join operations are also available. To demonstrate this, the row containing JobId =3 (Actress) is
removed in table Job:
Person
Title
Anthony
Bert
Clara

Job
Level
0
0
1

lookup_column
1
2
3

Title
PersonId
Salesperson 2
Lawyer
1

var op = new csp.Operation({


select: "Title as Person, Level, Job.Title as Job",
list: "Person left join Job with lookMe",
debug: true
});
op.readItems(function (output) {
for (var item in output) {
console.log(output[item].Person + " " + output[item].Level + " " +
output[item].Job);
}
},
function (message) { console.log(message); });

Currently SharePoint doesnt support right-join. You can still invert the join-order to generate the
desired results.

BDC-Support
When using csp on external lists, you can provide the filter keyword, telling SharePoint to use filters
set in bdc-models. The filter is set by adding a filter-object with the properties name, value and
optionally2 readOperationName to the query.

var op = new csp.Operation({


select: "ID, Department, Parent, Active",
list: "Departments",
filter: {
name: "Aktiv",
value: 1,
readOperationName: "Read List"
},
orderBy: "ID"
});

Creating list items


To add a new person to our list test, we can use the following query, which basically adds dora
with a salary of 12.000. Notice that the values are passed through a values object containing the
fieldnames to be set as properties:
var op = new csp.Operation({
list: "test",
values: {
Title: "dora",
salary: 12000
}
});
op.createItems(function (data) {
console.log("done successfullyly created entry with id: " + data.id);
}, function (msg) {
console.log("something went wrong: " + msg);
});

The success-callback provides you with an object of the data inserted in the database (including id)
If you want to insert more list items in one go you can pass an array of values objects:
var op = new csp.Operation({
list: "test",
debug: true,
values: [

{
Title: "dora",
salary: 12000
}, {
Title: "eugene",
salary: 500
}
]
});
2

When using bdc with visual studio the standard name is ReadList, while SharePoint Desiginer calls
it Read List. csp uses ReadList when the property is not set.

op.createItems(function () {
console.log("done successfullyly");
}, function (msg) {
console.log("something went wrong: " + msg);
});

Please notice only the last item is relayed in the success-callback when inserting list items in bulk.

Changing list item permissions


crudeSP has built in support for setting list item permission on create, update and file upload. In
order to add dora from above with list item permissions a roles object has to be added. Without a
roles object, list items are created/updated with inherited permissions. The following query creates
dora with write permissions set for aGroup:

var op = new csp.Operation({


list: "test",
debug: true,
values: {
Title: "dora",
salary: 12000
},
roles: {
deleteExisting: true,
group: "aGroup",
type: "write"
}
});
op.createItems(function () {
console.log("done successfullyly");
}, function (msg) {
console.log("something went wrong: " + msg);
});

The roles object contains the properties deleteExisting, group and type. Csp always breaks role
inheritance on SharePoint list items in order to be able to add new members. If you add
deleteExtisting: true to your first role, csp will delete all previous roles after breaking the
inheritance. Otherwise it well keep all existing roles and add the desired role.
Within the roles object you can either set the property group if you want to permit a SharePoint
group or the property user which adds rights for single SharePoint users. Users can be set with or
without domain. Property type sets the permission level for the desired users. SharePoints role
types are explained here. Currently these permission levels are available in csp:

read
write
contribute
administrator
guest
webdesigner

If you choose to permit more than one user or group, you can pass an array of roles objects:
roles: [
{
deleteExisting: true,
group: "testGroup",
type: "write"
},{
user: "userName",
type: "read"
}
]

Updating list items


To update SharePoint list items use the updateItems method of the instantiated operation object. To
change the name of clara to clementine in the test list we use the following query:

var updateItem = new csp.Operation({


list: "test",
where: 3,
debug: true,
set: {
Title: "clementine"
}
});
updateItem.updateItems(function () {
console.log("item updated");
}, function (message) {
console.log(message);
});

As mentioned above, csp lets you set list item permissions on update. You can do this with and
without setting columns. The following query sets write permissions for aGroup and read
permissions for userName for items with an id from one to three.

var updateItem = new csp.Operation({


list: "test",
where: "ID in 1,2,3",
debug: true,
roles: [{
deleteExisting: true,
group: "aGroup",
type: "write"
},
{
user: "userName",
type: "read"
}]
});
updateItem.updateItems(function () {
console.log("item updated");
}, function (message) {
console.log(message);
});

Deleting list items

The following query deletes all entries from our test list with an id greater than three:

var op = new csp.Operation({


list: "test",
where: "ID > 3",
debug: true
});
op.deleteItems(function () {
console.log("done successfullyly");
}, function (msg) {
console.log("something went wrong " + msg);
});

Uploading files

Csp supports uploading files to SharePoint document libraries. The file itself is set by the property
file. It takes a file set in an html input field (<input id="inputId" type="file"/>). It is possible to
optionally set the property filename if you want a different file name. By default csp will use the
original filename.
By default files are uploaded to the root folder of the library. Its possible to change the folder using
the folder-property.
The following query uploads a file to the folder archive/2015 in the library testLib, sets read
permissions on the item for user myDomain\me and sets the column aColumnToSet to first draft.

var upload = new csp.Operation({


site: "https://mySharePoint.corporation.com/project",
list: "testLib",
file: $(#inputId)[0].files[0],
folders: Archive/2015
roles: {
deleteExisting: true,
type: "read",
user: "myDomain\\me" *
},
set: {
aColumnToSet: "first draft
}
});
upload.uploadToLibrary(function (data) {
console.log("done successfully");
}, function (msg) {
console.log("didn't work out: " + msg);
});

*Please notice that javascript escapes single \-characters, enter usernames with \\.

Working with folders - create

The method createFolders allows folder creation in document libraries. The following query creates
the nested folders:
Archive

2015

May

in the library ExcelSheets and sets write-permissions for SP-Group Site_Admins on the whole path
after deleting all inherited permissions:

var newFolder = new csp.Operation({


site: "https://mySharePoint.corporation.com/project",
list: "ExcelSheets",
folders: Archive/2015/May
roles: {
deleteExisting: true,
group: "Site_Admins",
type: "write"
}
});
newFolder.createFolders(function () {
console.log("done successfully");
}, function (msg) {
console.log("didn't work out: " + msg);
return false;
});

Its also possible to pass a batch of folders through an array on to the query:
folders: [Archive/2015/May, Archive/2015/June]

Analogously the method updateFolders allows for changing the folder name or permissions while
the method deleteFolders removes folders and their subfolders from the library.

Updating folders

In order to rename folders, specify properties folders and foldersNew, where foldersNew
specifies the new names for the folders. When using arrays, folders and foldersNew must be of
the same length for the query to succeed.
var update = new csp.Operation({
list: "aList",
folders: ["main/sub", "another/sub"],
foldersNew: ["root/sub1", "another/subfolder"],
debug: true
});

update.updateFolders(function () {
console.log("done successfuly");
}, function (msg) {
console.log("didn't work out: " + msg);
return false;
});

It is also possible to update the rights on folders:


var update = new csp.Operation({
list: "aList",
folders: ["main/sub1/sub2"],
roles: {
deleteExisting: true,
user: "test\\test_nobody",
type: "write"
},
debug: true
});
update.updateFolders(function () {
console.log("done successfuly");
}, function (msg) {
console.log("didn't work out: " + msg);
return false;
});

Please notice the folder structure main/sub1/sub2. When assigning permissions to folders, the last
folder in the tree and all of its folders and subfolders (if any) get the permissions set in the query. The
above query will therefore assign write permissions to the user test\test_nobody for the folder
sub2. By specifying solely folder main, the permissions would be propagated downwards to all
folders and subfolders within main including sub1 and sub2.

Deleting folders

The following query shows the deletion of the folders sub1 and other. Again the last folder in a
tree and all of its subfolders will get deleted:

var newFolder = new csp.Operation({


list: "aList",
folders: ["main/sub1", "other"],
debug: true
});
newFolder.deleteFolders(function () {
console.log("done successfuly");
}, function (msg) {
console.log("didn't work out: " + msg);
return false;
});

Additional features:

Username
In order to retrieve the current username you can use the method getName in csp.user:
csp.user.getName(function(name) {
console.log(name);
}, function(msg) {
console.log(msg);
})

getName again takes two callback methods, the first is for a successful request while the second
one gets triggered in case of errors.

Furthermore you can check the membership of a certain user to a group. This is done with the
method isMemberOf in csp.user. It takes the username, groupname, success-method and errormethod as parameters. The following query checks whether Gerald Steinwender is a member of
testGroup what is true.
csp.user.isMemberOf("Gerald Steinwender", "testGroup", function (result) {
console.log(result);
}, function (msg) {
console.log(msg);
});

camlBuilder

csp uses its own caml-builder for data selection. You can also access the caml-builder outside a
csp.Operation by passing a query-object directly to csp.camlBuilder. The caml builder will then return
a valid caml-string. The camlBuilder can be used without references to SharePoints javascript
libraries.

csp.camlBuilder({
select: "ID, name, address, stel, was extra?",
where: "name = clara",
debug: true
})

You might also like