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);
}