CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: Client Object Model

JSOM: Alter a column’s DisplayName

Here is another article in my JSOM series. For one month ago I showed how to alter a column’s ShowInDisplayForm property with JSOM. This time I’ll show a code sample for changing a column’s (field’s) display name. If you want to alter the displayname with Server Object Model, grab the code in the sharepoint.stackexchange.com: Change Field’s DisplayName in a List.

var ctx = SP.ClientContext.get_current(),              //SP.ClientContext
    field = ctx.get_web()                              //SP.Web
               .get_lists()                            //SP.ListCollection
               .getByTitle('MyList')                   //SP.List
	       .get_fields()                           //SP.FieldCollection
	       .getByInternalNameOrTitle("Body");      //SP.Field
ctx.load(field, "Title");                              //load only Title
ctx.executeQueryAsync(function() {
	field.set_title("Beskrivning");
	field.update();
	ctx.executeQueryAsync();
});

GeoLocation Field in SharePoint 2013

In SharePoint 2013 Preview there is a new type of field: GeoLocation which is, like the old SPUrlField, a pair of values. The geolocation is described as longitude and latitude.

Unfortunately you can’t add this field in list settings. You have to create this in code. In the provided link you can find the code C# code which uses the Client Object Model. In another link  you can find an example how to create the geolocation file using Server Object Model (in FeatureActivated EventReceiver).

If you know me, you might already know that I will propose a JavaScript solution. Here is the code to create a geolocation field in an existing list using JSOM:

var ctx = SP.ClientContext.get_current(),
	list = ctx.get_web()
		.get_lists()
		.getByTitle("CheckIns"),
	fields = list.get_fields();

fields.addFieldAsXml("<Field Type='Geolocation' DisplayName='Location'/>", true); 
list.update(); 
ctx.load(list); 
ctx.executeQueryAsync();

Add the location in the UI. There you can define long and lat, or use your current location:

To add a list item with a geolocation we can use jsom as well. This code adds a new list item with Cheboksary geolocation:

var ctx = SP.ClientContext.get_current(),
	list = ctx.get_web()
		.get_lists()
		.getByTitle("CheckIns"),
	itemCreateInfo = new SP.ListItemCreationInformation(),
	item = list.addItem(itemCreateInfo),
	point = "POINT (47.23 56.13)";
item.set_item('Title', 'Cheboksary');
item.set_item('Location', point);
item.update();
ctx.load(item);
ctx.executeQueryAsync();

When you open the list again, you will see this:

Happy coding!

Paging with JSOM

If there are many list items you try retrieve with javascript object model,paging could be very useful. Today I came across a wonderful blog post series about javascript object model in SharePoint: The SharePoint javascript object model – Resources and Real World Examples posted by David Mann and published on Aptilon Blog.

There is an example how to achieve paging with JSOM. The key is items.get_listItemCollectionPosition() and query.set_listItemCollectionPosition()

I have refactored David’s example to avoid global variables and to put into a module. Here is it. If you have a Tasks list in your site with many items, just hit F12 to open the console and paste this and see the result:

(function(SP) {
   var 
      ctx = SP.ClientContext.get_current(),
      list = ctx.get_web().get_lists().getByTitle('Tasks'),
      position,
      enumerator,
      view = '<View><ViewFields><FieldRef Name="Title"/></ViewFields><RowLimit>10</RowLimit></View>',
      query = new SP.CamlQuery(),
      items,
      init = function() {
         query.set_viewXml(view);			
      },
      loadChunks = function() {
         query.set_listItemCollectionPosition(position);
         items = list.getItems(query);
         ctx.load(items);
         ctx.executeQueryAsync(success, error);
      },
      success = function() {
         console.log("\nFound Matching Items! ");
         enumerator = items.getEnumerator();
         while(enumerator.moveNext()) {
            console.log("Title: " + enumerator.get_current().get_item("Title") );
         }
         position = items.get_listItemCollectionPosition();
         //when there are no items position is null
         position && loadChunks();
      },
      error = function(sender, args) {
         console.log('Request failed. Error: ' + args.get_message() + '. StackTrace: ' + args.get_stackTrace());
      };

   init();
   loadChunks();
})(SP);

JSOM: Alter a column’s ShowInDisplayForm property

When you create a content type, you can define if your fields will be shown in DisplayForm, EditForm, NewForm. You can hide or show them, just as Yaroslav Pentsarsky says. If your list is already provisioned, you can change them with Server Object Model, why not in PowerShell: Technet: Setting ShowInDisplayForm, ShowInEditForm, ShowInNewForm properties with powershell.

If you don’t have access to the server, then the same can be done with JSOM. Here is the code:

var ctx = SP.ClientContext.get_current(),              //SP.ClientContext
    field = ctx.get_web()                              //SP.Web
               .get_lists()                            //SP.ListCollection
               .getByTitle('MyList')                   //SP.List
	       .get_fields()                           //SP.FieldCollection
	       .getByInternalNameOrTitle("Site");      //SP.Field
ctx.load(field, "SchemaXml");                          //load only SchemaXml
ctx.executeQueryAsync(function() {
	var s = field.get_schemaXml(),
	    s1 = s.replace('ShowInDisplayForm="FALSE"', 
                           'ShowInDisplayForm="TRUE"');
	field.set_schemaXml(s1);
	field.update();
	ctx.executeQueryAsync();
});

Next: JSOM: Alter a column’s DisplayName.

$().SPServices is best for SOAP

SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.

Three ways to get list items

Just a little comparison. We’ll retrieve Titles from Tasks list (Oppgaver in nb-no).
listdata.svc

$.getJSON("/_vti_bin/ListData.svc/Oppgaver()?$select=Tittel")
	.done(function(data){
	  var tasks = data.d.results;
		for(var t in tasks) {
			var title = tasks[t].Tittel;
			console.log(title);
		}
	})
	.fail(function() {
		console.log("error");
	});

Pay attention to the field name: Tittel. I think it is the biggest shortcoming of listdata.svc: the fact that we can’t use the internal (static) field names.
Client Object Model

var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var taskList = web.get_lists().getByTitle("Oppgaver");
var query = new SP.CamlQuery("<ViewFields><FieldRef Name='Title' /></ViewFields>");
var tasks = taskList.getItems(query);
ctx.load(tasks);
ctx.executeQueryAsync(function() {
	var listEnumerator = tasks.getEnumerator();
	while(listEnumerator.moveNext()) {
		var task = listEnumerator.get_current();
		var title = task.get_item("Title");
		console.log(title);
	}
}, function() {
	console.log("error");
});

SPServices

$().SPServices({
    operation: "GetListItems",
    async: true,
    listName: "Oppgaver",
    CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
    completefunc: function (xData, Status) {
        $(xData.responseXML).SPFilterNode("z:row").each(function() {
            console.log( $(this).attr("ows_Title") );        
        });
    }
});
SPServices and SocialDataService

Let’s try to find the count of comments for an url. To do so we must create a SOAP envelope in javascript, send it and handle the response result:

var strUrl = "http://dev/Sider/Help.aspx";
var request = "<soap:Envelope \
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \
    xmlns:xsd='http://www.w3.org/2001/XMLSchema' \
    xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> \
    <soap:Body>    \
      <CountCommentsOnUrl \
          xmlns='http://microsoft.com/webservices/SharePointPortalServer/SocialDataService'> \
        <url>" + strUrl + "</url> \
      </CountCommentsOnUrl> \
     </soap:Body> \
  </soap:Envelope>";

jQuery.ajax({
  type: "POST",
  async: true,
  url: '/_vti_bin/SocialDataService.asmx?op=CountCommentsOnUrl',
  data: request,
  contentType: "text/xml; charset=utf-8",
  dataType: "xml",
  success: function (content, txtFunc, xhr) {
    var count = jQuery(content).find('CountCommentsOnUrlResult').text();
    console.log(count);
  }
});

It works but, we have to handle the creating of SOAP envelope in our javascript code which can be error prone. SPServices provides a nice abstraction layer and handles many scenarios. The same operation in SPServices:

$().SPServices({
  operation: "CountCommentsOnUrl",
  async: true,
  url:"http://dev/Sider/Help.aspx",
  completefunc: function (xData, Status) {
    var result = $(xData.responseXML).find("CountCommentsOnUrlResult")[0];
    console.log($(result).text());
  }
});

In both cases we have to iterate through responseXML. This is a sample responseXML for CountCommentsOnUrl from SocialDataService.asmx:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
      <CountCommentsOnUrlResponse
          xmlns="http://microsoft.com/webservices/SharePointPortalServer/SocialDataService">
      <CountCommentsOnUrlResult>1</CountCommentsOnUrlResult>
    </CountCommentsOnUrlResponse>
  </soap:Body>
</soap:Envelope>

Get current user and handle a success callback

In my previous post I needed the accound id of the current user for posting new list items. To retrieve the id, we can push this to the client from the code behind, or get the current user using Client Object Model.

To provide a more generic way we can write a js function which get the current user. But we must even provide some callback functionality, otherwise we don’t know if the operation was successful or not. Let’s be inspired by success and error properties in $.ajax:

function retrieveCurrentUser(success, error) {
    ExecuteOrDelayUntilScriptLoaded(function () {
        var ctx = new SP.ClientContext.get_current();
        var web = ctx.get_web();
        ctx.load(web);
        var user = web.get_currentUser();
        user.retrieve();
        ctx.executeQueryAsync(function () {
            success(user);
        }, function (data) {
            error(data);
        });
    }, "SP.js");
}

Then success function can receive the user account like:

function doSomething(user) {
   console.log("user name: " + user.get_loginName());
}
function errorCallback(data) {
   console.log("hmpf, didn't work, why?");
}
retrieveCurrentUser(doSomething, errorCallback);
EDIT

If you just need current user id, as I needed, there is actually a better way. I saw a solution for another problem in sharepoint.stackexhange and found this:

var userid = _spPageContextInfo.userId;

More background information about _spPageContextInfo can be found on Ted Pattison’s blog. The userId of ther current user can be got through:

 var userid = _spUserId;

Uppdatera web med js

Här är ett litet exempel:

 function updateTitle() { 
   var ctx = new SP.ClientContext.get_current();
   this.web = ctx.get_web(); 
   web.set_title('Examensarbete 2011'); 
   this.web.update(); 
  ctx.executeQueryAsync(
     Function.createDelegate(this, this.onUpdate), 
     Function.createDelegate(this, this.onFail)); } 
function onUpdate(sender, args) { 
   alert('title updated'); 
} 
function onFail(sender, args) { 
   alert('failed to update title. Error:'+args.get_message()); 
}
Вула Чăвашла

VulaCV - Чăвашла вулаттаракан сайт

Discovering SharePoint

And going crazy doing it

Bram de Jager talking Office 365, SharePoint and Azure

My view and thoughts on Productivity and more.

My programming life

and everything in between

SharePoint Development Lab by @avishnyakov

It is a good place to share some SharePoint stories and development practices.

SharePoint Dragons

Nikander & Margriet on SharePoint

Paul J. Swider - RealActivity

RealActivity is a specialized healthcare services and solution advisory firm.

Mai Omar Desouki - Avid SharePointer

Egyptian & Vodafoner - Senior SharePoint Consultant

Cameron Dwyer | Office 365, SharePoint, Outlook, OnePlace Solutions

Office 365, SharePoint, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points!!

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

Aryan Nava

BigData and Blockchain expert in Toronto

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint