How to load attachment in client context? - sharepoint

I have a list with attachments. I want to fetch list records with attachment as a url in anchor tag.
For ex- when user selects ID-100 then all its data will be retrieved and attachment in anchor tag to open it.
I used JSOM for this and it is working fine but it is giving error when there is no documents attached.
Please help-
var clientContext = new SP.ClientContext.get_current();
var oList=clientContext.get_web().get_lists().getByTitle(varListName);
var camlQuery = new SP.CamlQuery();
//var camlQuery = "<View><Query><Where><Eq><FieldRef Name='ID' /><Value Type='Integer'>1</Value></Eq></Where></Query></View>";
camlQuery.set_viewXml("<View><Query><Where>" +
"<Eq><FieldRef Name=\"ID\"/><Value Type=\"Number\">" + varid + "</Value></Eq>" +
"</where><OrderBy></OrderBy></Query><RowLimit>1</RowLimit></View>");
this.collListItem = oList.getItems(camlQuery);
var attachmentFolder = clientContext.get_web().getFolderByServerRelativeUrl('Lists/' + varListName + '/Attachments/' + varid);
this.attachmentFiles = attachmentFolder.get_files();
clientContext.load(collListItem);
clientContext.load(attachmentFiles);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

We can first check if the item has attachment or not via ListItem.Attachments property.
In case if list List Item contains attachments, submit a second request to retrieve attachment files.
this.collListItem = oList.getItems(camlQuery);
var listItemEnumerator = collListItem.getEnumerator();
// on query success
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
var hasAttachments = item.get_fieldValues()['Attachments'];
// getAttachmentFiles ....
}
BR

Related

Not able to query SharePoint from Nintex form custom JavaScript

I'm trying to query the SharePoint list using JSOM from Nintex custom javascript. My intention is to show the data in Nintex multiLine textbox. I can query data from SharePoint and display it in the Nintex edit form and not able to query from the Nintex view/display form.
Any thoughts? Thanks!.
Please refer the below code
var clientContext;
var oListItem;
var workFlowListName = "sharepoint Tasks";
var requestId = 1;
var pollSP;
function checkSPLoad() {
if (clientContext) {
window.clearInterval(pollSP);
if (requestId)
GetPFItems();
}
}
function GetPFItems() {
var oList = clientContext.get_web().get_lists().getByTitle(workFlowListName);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View><Query><Where><Eq><FieldRef Name='ID' /><Value Type='Text'>" + requestId
+ "</Value></Eq></Where></Query></View>");
this.collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
clientContext.executeQueryAsync(Function.createDelegate(this, this.PFQuerySucceeded),
Function.createDelegate(this, this.onQueryFailed));
}
function PFQuerySucceeded(sender, args) {
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
pfTaskName = oListItem.get_item('TaskName');
NWF$('#'+'sampleTextBox').val(pfTaskName);
}
}
function onQueryFailed(sender, args) { }
Why your CAML Query has data type as Text for ID field? Also, You need to configure multiline textbox's setting and make display mode as Edit. This should start getting populated.

Extracting information from "Created By" field

Is there any way I could extract the department or email information from the "Created By" field in a custom list?
You should be more specific how you want to extract the information, if it's javascript or c# or via UI.
Here is a simple example, maybe you can do something with it. Let me know if you have any questions.
var ctx = new SP.ClientContext.get_current();
var web = ctx.get_web();
var list = web.get_lists().getByTitle('Kalender');
//this query can be done in other ways, I'm getting all items
var query = SP.CamlQuery.createAllItemsQuery();
var items = list.getItems(query);
ctx.load(items);
ctx.executeQueryAsync(function () {
var itemsEnum = items.getEnumerator();
while (itemsEnum.moveNext()) {
var item = itemsEnum.get_current();
var author = item.get_item('Author');
console.log("Email: " + author.get_email());
console.log("Name: " + author.get_lookupValue());
console.log("ID: " + author.get_lookupId());
}
}, function(sender, args) {
console.log(args.get_message());
});

Update ProjectedField with JOIN in Sharepoint using Javascript client object model

Suppose I have 2 Lists: Teams and Employees. Each team has a number of employees:
Teams
ID
Name
Employees
ID
Name
TeamID (foreign key of Teams)
If I created a Join query of Employees LEFT JOIN Teams, could I then set_item and update the Name field in Teams?
var ctx = SP.ClientContext.get_current();
var list = clientContext.get_web().get_lists().getByTitle('Employees');
var queryText =
"<View>" +
"<Query></Query>" +
"<ProjectedFields>" +
"<Field Name='TeamName' Type='Lookup' List='Team' ShowField='Name' />" +
"</ProjectedFields>" +
"<Joins>" +
"<Join Type='INNER' ListAlias='Team'>" +
"<Eq>" +
"<FieldRef Name='TeamID' RefType='Id'/>" +
"<FieldRef List='Team' Name='ID'/>" +
"</Eq>" +
"</Join>" +
"</Joins>" +
"<ViewFields>" +
"<FieldRef Name='TeamName'/>" +
"</ViewFields>" +
"</View>";
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(queryText);
var listItemsCollection = list.getItems(camlQuery);
ctx.executeQueryAsync(onSuccess, onError);
And then, update the TeamName field:
var first = listItemsCollection.get_data()[0];
first.set_item("TeamName", "something");
first.update();
ctx.executeQueryAsync(onSuccess, onError);
Is this supported? (I currently have not way of trying this)
If not, what could be the alternative?
No, only those fields that contains list item could be updated. But you could consider the following approach for updating projected fields.
Since projected fields are returned as lookup values, you could retrieve projected list item and update it's properties as demonstrated below:
var listTitle = 'Employees';
var joinListTitle = 'Teams'
var joinFieldName = 'TeamID';
var projectedFields = ['Name'];
getListItems(listTitle,joinListTitle,joinFieldName,projectedFields,
function(items){
var item = items.get_data()[0]; //get first item
var itemId = item.get_item('TeamsName').get_lookupId(); //get projected list item id
var propertiesToUpdate = {'Name': 'New Team Name'};
updateListItem(joinListTitle,itemId,propertiesToUpdate,function(item){
console.log('List Item has been updated');
},
logError);
},
logError);
where
function createJoinQuery(joinListTitle,joinFieldName,projectedFields,joinType)
{
var queryText =
"<View>" +
"<Query/>" +
"<ProjectedFields>";
for(var idx in projectedFields) {
queryText += String.format("<Field Name='{0}{1}' Type='Lookup' List='{0}' ShowField='{1}' />",joinListTitle,projectedFields[idx]);
}
queryText +=
"</ProjectedFields>" +
"<Joins>" +
"<Join Type='{2}' ListAlias='{0}'>" +
"<Eq>" +
"<FieldRef Name='{1}' RefType='Id'/>" +
"<FieldRef List='{0}' Name='ID'/>" +
"</Eq>" +
"</Join>" +
"</Joins>" +
"</View>";
var qry = new SP.CamlQuery();
qry.set_viewXml(String.format(queryText,joinListTitle,joinFieldName,joinType));
return qry;
}
function getListItems(listTitle,joinListTitle,joinFieldName,projectedFields,success,error)
{
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var list = web.get_lists().getByTitle(listTitle);
var items = list.getItems(createJoinQuery(joinListTitle,joinFieldName,projectedFields,'INNER'));
ctx.load(items);
ctx.executeQueryAsync(
function() {
success(items);
},
error
);
}
function updateListItem(listTitle,itemId, propertiesToUpdate,success,error)
{
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var list = web.get_lists().getByTitle(listTitle);
var listItem = list.getItemById(itemId);
for(var name in propertiesToUpdate) {
listItem.set_item(name,propertiesToUpdate[name]);
}
listItem.update();
ctx.executeQueryAsync(function() {
success(listItem);
},error);
}

prevent double meeting sharepoint calendar csom

I am trying to make it if the date and time are already booked in the calender dont book, i am using this code and nothing get displayed? Any Sugestions?
var context = SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists();
var targetList;
function createItem() {
targetList = list.getByTitle("AppbokningarList");
var listItemCreation = new SP.ListItemCreationInformation();
var newItem = targetList.addItem(listItemCreation);
var listItemTitle = document.getElementById('Textrubrik').value;
alert(listItemTitle);
var listItemCustom = document.getElementById('datepicker').value;
alert(listItemCustom);
var listItemFromTime = document.getElementById('timepicker').value;
alert(listItemFromTime);
var listItemtoDate = document.getElementById('datepickerto').value;
alert(listItemtoDate);
var listItemToTime = document.getElementById('timepickerTo').value;
alert(listItemToTime);
var listItemBeskrivning = document.getElementById('Textbeskrivning').value;
alert(listItemBeskrivning);
newItem.set_item('Title', listItemTitle);
var result = listItemCustom + " " + listItemFromTime;
newItem.set_item('EventDate', result);
var result2 = listItemtoDate + " " + listItemToTime;
newItem.set_item('EndDate', result2);
newItem.set_item('Description', listItemBeskrivning);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<Where><Geq><FieldRef Name='EventDate' /><Value Type='DateTime'>" + result + "</Value></Geq><Leq><FieldRef Name='EndDate' /><Value Type='DateTime'>" + result2 + "</Value></Leq><FieldRef Name='RecurrenceID' /></Where>");
this.collListItem = targetList.getItems(camlQuery);
context.load(collListItem);
var property = new SP.EventProperties();
if (collListItem > 0) {
property.cancel = true;
}
newItem.update();
context.load(newItem);
context.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded),Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded(sender, args) {
var succeded = "Mötet är nu bokat!";
alert(succeded);
}
function onQueryFailed(sender, args) {
var failed = "Redan bokat!";
alert(failed);
}
Look at all your set_items. Most likely your date fields need an actual date object to be stored successfully to SP.
var currDate = new Date();
listItem.set_item('DateColumn',currDate);
listItem.update();
Cool stuff here to: http://alexeybbb.blogspot.com/2012/09/sharepoint15-js-update-datetime-field.html

Sharepoint: How to easily get related child items using JSOM

Suppose I have 2 Lists: Teams and Employees. Each team has a number of employees:
Teams
ID
Name
Employees
ID
Name
TeamID (foreign key of Teams)
Is it possible to write a query in SharePoint JSOM such that I could do something along the following lines (after the query executes/loads):
var employeesListItems = teamListItem.get_item("Employees")
Does SharePoint Object Model support this in any way?
Clarification: my intent is to reuse the ClientObject as much as I can. I understand that I could query for all employees and all teams, create an array of custom objects for each, and then iterate over employees and push them to onto the "Employees" field of the related Team object. I would like to avoid doing so.
Even though SharePoint CAML supports List Joins and Projections, in that case I would suggest you a different approach.
The following example demonstrates how to retrieve parent/child items using a single request:
function getItemWithDetails(parentListTitle,childListTitle,lookupFieldName,lookupFieldValue,success,error)
{
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var lists = web.get_lists();
var parentList = lists.getByTitle(parentListTitle);
var parentItem = parentList.getItemById(lookupFieldValue);
var childList = lists.getByTitle(childListTitle);
var childItems = childList.getItems(createLookupQuery(lookupFieldName,lookupFieldValue));
ctx.load(parentItem);
ctx.load(childItems);
ctx.executeQueryAsync(
function() {
success(parentItem,childItems);
},
error
);
}
function createLookupQuery(lookFieldName,lookupFieldValue)
{
var queryText =
"<View>" +
"<Query>" +
"<Where>" +
"<Eq>" +
"<FieldRef Name='{0}' LookupId='TRUE'/>" +
"<Value Type='Lookup'>{1}</Value>" +
"</Eq>" +
"</Where>" +
"</Query>" +
"</View>";
var qry = new SP.CamlQuery();
qry.set_viewXml(String.format(queryText,lookFieldName,lookupFieldValue));
return qry;
}
Usage
var parentListTitle = 'Teams';
var childListTitle = 'Employees'
var lookupFieldValue = 1;
var lookupFieldName = 'Team';
getItemWithDetails(parentListTitle,childListTitle,lookupFieldName,lookupFieldValue,
function(teamItem,employeeItems){
//print parent item
console.log(teamItem.get_item('Title'));
//print child items
for(var i = 0; i < employeeItems.get_count(); i++){
var employeeItem = employeeItems.getItemAtIndex(i);
console.log(employeeItem.get_item('Title'));
}
},
function(sender,args){
console.log(args.get_message());
});
Another option is to utilize List Joins and Projections. The following example demonstrates how to retrieve employee list items with projected team items
function getListItems(listTitle,joinListTitle,joinFieldName,projectedFields,success,error)
{
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var list = web.get_lists().getByTitle(listTitle);
var items = list.getItems(createJoinQuery(joinListTitle,joinFieldName,projectedFields));
ctx.load(items);
ctx.executeQueryAsync(
function() {
success(items);
},
error
);
}
function createJoinQuery(joinListTitle,joinFieldName,projectedFields)
{
var queryText =
"<View>" +
"<Query/>" +
"<ProjectedFields>";
for(var idx in projectedFields) {
queryText += String.format("<Field Name='{0}_{1}' Type='Lookup' List='{0}' ShowField='{1}' />",joinListTitle,projectedFields[idx]);
}
queryText +=
"</ProjectedFields>" +
"<Joins>" +
"<Join Type='INNER' ListAlias='{0}'>" +
"<Eq>" +
"<FieldRef Name='{1}' RefType='Id'/>" +
"<FieldRef List='{0}' Name='ID'/>" +
"</Eq>" +
"</Join>" +
"</Joins>" +
"</View>";
var qry = new SP.CamlQuery();
qry.set_viewXml(String.format(queryText,joinListTitle,joinFieldName));
return qry;
}
Usage
var listTitle = 'Employees';
var joinListTitle = 'Teams'
var joinFieldName = 'Team';
var projectedFields = ['ID','Title'];
getListItems(listTitle,joinListTitle,joinFieldName,projectedFields,
function(employeeItems){
//print items
for(var i = 0; i < employeeItems.get_count(); i++){
var employeeItem = employeeItems.getItemAtIndex(i);
var employeeName = employeeItem.get_item('Title');
var teamName = employeeItem.get_item('Teams_Title').get_lookupValue();
console.log(employeeName + ',' + teamName);
}
},
function(sender,args){
console.log(args.get_message());
});
Probably you can not achieve what you want, because of lookup configuration. But you could do the following:
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var lists = web.get_lists();
var teams = lists.getByTitle("Teams");
var employees = lists.getByTitle("Employees");
//just get the first item
var employee = employees.getItemById(1);
ctx.load(employee)
ctx.executeQueryAsync(function() {
var team = employee.get_item("TeamID");
// both the id and the value of the lookup field
var lookupId = team.get_lookupId();
var lookupValue = team.get_lookupValue();
// let's grab all the fields
var fullTeam = teams.getItemById(lookupId)
ctx.load(fullTeam)
ctx.executeQueryAsync({
var name = fullTeam.get_item("Name");
alert("We can get the Name field of the lookup field: " + name);
});
});
I guess, it a bit reverse of what you really intent to achieve but still this way you will exploit CSOM.

Resources