Category Archives: Outdated posts

Accessing user profile information in WSS 3.0 with javascript

18.09.2011 I have posted a new solution which makes this one obsolete. You find the new one here


09.09.2010 Updated the function “getUserInfo”. It no longer requires the list GUID for the user list to be specified in the script.

31.10.2009: Small update for default picture in the example CEWP.

This article describes how to access the “user profile” under WSS 3.0 via javascript. The method used is a query trough the webservice lists.asmx.

I use some code (“interaction.js” and stringBuffer.js”) created by Erucy and published on codeplex.

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

As always we begin like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a subsite named “test” with a subsite named “English” with a document library named “Javascript”):
IMG

You can call this script from any page. In this example i will place it on Default.aspx.

The sourcecode for the “AccessUserProfileInWSS.js” looks like this:
[javascript]
/* getUserInfo – Returns "user info" data from user list in WSS 3.0 (not MOSS user profile)
* ———————————————
* Created by Alexander Bautz
* alexander.bautz@gmail.com
* https://spjsblog.com
* LastMod: 20.09.2009
* ———————————————

Refer these scripts:
interaction.js // Erucy – http://spjslib.codeplex.com
stringBuffer.js // Erucy – http://spjslib.codeplex.com
jQuery // http://jQuery.com

Use:
var ui = getUserInfo(); // If UserId is not specified it assumes it’s logged in user (_spUserId)
alert(ui.Title);
*/

function getUserInfo(UserId){
wsBaseUrl = ‘/_vti_bin/’;
var uiObj = {};
if(typeof(UserId)=="undefined" || UserId==”)UserId = _spUserId;
var arrOfFields = [‘ID’, ‘Name’, ‘Title’, ‘EMail’, ‘Department’, ‘JobTitle’, ‘Notes’, ‘Picture’,
‘IsSiteAdmin’, ‘Created’, ‘Author’, ‘Modified’, ‘Editor’, ‘SipAddress’, ‘Deleted’];
var item = getItemById(‘UserInfo’,UserId,arrOfFields);
if(item != null){
for(i=0;i<arrOfFields.length;i++){
if(item[arrOfFields[i]]!=null){
uiObj[arrOfFields[i]] = item[arrOfFields[i]];
}else{
uiObj[arrOfFields[i]] = ”;
}
}
return uiObj;
}else{
for(i=0;i<arrOfFields.length;i++){
uiObj[arrOfFields[i]] = "User with id " + UserId + " not found.";
}
return uiObj;
}
}
[/javascript]

Save this as a text file and rename to “AccessUserProfileInWSS.js”, then upload to the library as shown above.

You call the script from a standard CEWP like this:
IMG

Sourcecode for CEWP:
[javascript]
<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/interaction.js"></script>
<script type="text/javascript" src="/test/English/Javascript/stringBuffer.js"></script>
<script type="text/javascript" src="/test/English/Javascript/AccessUserProfileInWSS.js"></script>
<script type="text/javascript">

var ui = getUserInfo(); // If UserId is not specified it assumes it’s logged in user (_spUserId)
picSrc = ‘/_layouts/images/person.gif’;
if(ui.Picture!=”){
picSrc = ui.Picture.split(‘, ‘)[0]
}
var str = ”;
str += "Accountname: " + ui.Name + "<br>";
str += "Full name: " + ui.Title + "<br>";
str += "E-mail: " + ui.EMail + "<br>";
str += "Department: " + ui.Department + "<br>";
str += "<img alt=” src=’" + picSrc + "’ />";

document.write(str);
</script>
[/javascript]

And you get a result like this:
IMG

I will follow up this article with an article describing how to hide or show form fields based on membership – or not membership – in a SharePoint group.

Alexander

Return value of all SharePoint fieldtypes with Javascript

This post is old… you will find other ways to do all this in newer posts – Alexander

As promised, here are the post on returning the value of any SharePoint-field with the use of Javascript.
As for now this script is IE only! – as stated earlier, i personally do not use Firefox, and i have not had the time to try to adapt it to Firefox. The main thing that has to be done is to handle the node-issue where Firefox counts line breaks in the code as a node.

I first learned to manipulate list items with javascript here: Microsoft SharePoint Designer Team Blog, and the piece on returning radio button values is a product of this guy here: Markuso.

About the script
This script returns the value of the following SharePoint-fieldTypes

  • Single line text
  • Multiple line text (Plain text)
  • Number
  • Currency
  • Multiple choice check box
  • Date
  • Radio Button
  • Drop down
  • Yes/No
  • Hyperlink
  • Picture
  • Lookup – Single
  • Lookup – Multiple
  • Person (DisplayName or LoginName)

I always use the fields “FieldInternalName” when addressing it in code, it never changes no matter how many times you change the “DisplayName”.

The script:
[sourcecode language=”jscript”]
<script type="text/javascript">
/*************************************************************
Type:
Singelline tekst and multiline tekst (Plain text), Number, Currency = text
Multichoice checkbox = checkbox (returns commaseparated values)
Date (returns date only, but works with both DateOnly and DateAndTime) = date
RadioButton = radio
Dropdown = dropdown
Yes/No = bool
Hyperlink or picture (returns commaseparated: description,url) = url
Lookup – single (below and over 20 items), MultiLookup (returns array) = lookup
Lookup Multiple – you can use plain ‘lookup’, but if you want only "multi" = lookupMulti
Person – DisplayName = personDisplay
Person – LoginName = personLogin
Use: var value = returnValue(‘checkbox’,’FieldInternalNameOfYourField’);
*************************************************************/
function returnValue(type, fieldInternalName) {
var arr = document.getElementsByTagName(‘!’);//get all comments
for (var i=0;i < arr.length; i++ ) {
// Date
if (type==’date’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
var fieldTitle = arr[i].innerHTML.substring(arr[i].innerHTML.indexOf(‘FieldName=’)+11,arr[i].innerHTML.indexOf(‘n’)-2);
var tags = document.getElementsByTagName(‘input’);
for (var i=0; i < tags.length; i++) {
if (tags[i].title == fieldTitle && tags[i].parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.innerHTML.indexOf(‘FieldName="’+fieldTitle+’"’) > -1)
{
return tags[i].value;
}
}
// RadioButton – Credit to http://blog.markuso.com/ – slightly modified by me to use FieldInternalName
}else if(type==’radio’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
var tags = document.getElementsByTagName("input");
for (var i=0; i < tags.length; i++) {
var nameString = tags[i].name;
// get selected radio button value only
if (tags[i].type == "radio") {
var tagParentHTML = tags[i].parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.innerHTML;
if (tagParentHTML.indexOf(‘FieldInternalName="’+fieldInternalName+’"’) > -1) {
var radioButtons = document.getElementsByName(nameString);
var radioValue = "";
for (var x=0; x < radioButtons.length; x++) {
if (radioButtons[x].checked) {
radioValue = radioButtons[x].parentElement.title;
break;
}
}
var o = document.createElement("INPUT");
o.type = "hidden";
o.value = radioValue;
return o.value;
}
}
}
return null;
// Checkbox
}else if(type==’checkbox’) {
var arr = [];
var arrValue = [];
var tags = document.getElementsByTagName("input");
for (var i=0; i < tags.length; i++) {
if (tags[i].type == "checkbox") {
var tagParentHTML = tags[i].parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.innerHTML;
if (tagParentHTML.indexOf(‘FieldInternalName="’+fieldInternalName+’"’) > -1) {
arr.push(tags[i].id);
}
}
}
for (var x=0; x < arr.length; x++) {
var chkBox = document.getElementById(arr[x]);
if (chkBox.checked) {
arrValue.push(chkBox.parentElement.title);
}
}
return arrValue.toString();
// Text or Dropdown
}else if((type==’text’ || type==’dropdown’) && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
return arr[i].parentNode.childNodes[1].childNodes[0].value;
// Hyperlink or Picture
}else if(type==’url’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
// returns commaseparated (description,url) so it can be split later
var hyperlink = [];
hyperlink.push(arr[i].parentNode.childNodes[1].childNodes[4].value);
hyperlink.push(arr[i].parentNode.childNodes[1].childNodes[1].value);
return hyperlink;
// Bool
}else if(type==’bool’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
return arr[i].parentNode.childNodes[1].childNodes[0].checked;
// Lookup
}else if(type==’lookup’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
// Under 20 items
var opt = arr[i].parentNode.childNodes[1].childNodes[0].options;
if(opt!=null) {
for (var x=0;x<opt.length;x++) {
if(opt[x].selected == true) {
return (opt[x].innerHTML);
}
}
}else if(opt==null){
if(arr[i].parentNode.childNodes[1].childNodes[0].childNodes[0]!= null) {
// Over 20 items
return arr[i].parentNode.childNodes[1].childNodes[0].childNodes[0].value;
}else{
// MultiLookup – optionally you can call the script with type=’lookupMulti’
var arrSelected = [];
var fieldId = arr[i].parentNode.childNodes[1].childNodes[0].id;
var selectResultId = fieldId.substr(0,fieldId.indexOf(‘MultiLookupPicker’)) + ‘SelectResult’;
var selectResultField = document.getElementById(selectResultId);
for(var x=0;x < selectResultField.length; x++){
arrSelected.push (selectResultField[x].innerHTML);
}
return arrSelected.toString();
}
}
}
// Lookup Multi (can also use plain ‘lookup’ as spacified above
else if(type==’lookupMulti’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
var arrSelected = [];
var fieldId = arr[i].parentNode.childNodes[1].childNodes[0].id;
var selectResultId = fieldId.substr(0,fieldId.indexOf(‘MultiLookupPicker’)) + ‘SelectResult’;
var selectResultField = document.getElementById(selectResultId);
for(var x=0;x < selectResultField.length; x++){
arrSelected.push (selectResultField[x].innerHTML);
}
return arrSelected.toString();
// Person
}else if(type==’personDisplay’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
var rawString = arr[i].parentNode.childNodes[1].innerHTML;
if(rawString.indexOf(‘isresolved="True"’)>0){
// user resolved OK
// Use these for DisplayName
var displayName = rawString.indexOf(‘displaytext="’);
var start = displayName + 13;
var stopp = displayName + rawString.substring(rawString.indexOf(‘displaytext="’)).indexOf(‘key="’)-2;
var user = rawString.substring(start, stopp);
return user;
}else{
// user not resolved
return "";
}
}else if(type==’personLogin’ && arr[i].innerHTML.match(‘FieldInternalName="’ + fieldInternalName + ‘"’)) {
var rawString = arr[i].parentNode.childNodes[1].innerHTML;
if(rawString.indexOf(‘isresolved="True"’)>0){
// Use these for Loginname
var loginName = rawString.indexOf(‘isresolved="True"’);
var start = loginName + rawString.substring(rawString.indexOf(‘isresolved="True"’)).indexOf(‘key="’)+5;
var stopp = loginName + rawString.substring(rawString.indexOf(‘isresolved="True"’)).indexOf(‘">’);
var user = rawString.substring(start, stopp);
return user;
}else{
// user not resolved
return "";
}
}

}
}
</script>
[/javascript]

You should now be able to return all fieldvalues from SharePoint forms.

Here’s an example of how to use it in the PreSaveAction (add this script and it will always execute between you pressing th “OK-button” and the actual save of the item:
[sourcecode language=”jscript”]
<script type="text/javascript">
function PreSaveAction() {
var checkBoxValue = returnValue(‘checkbox’,’CheckboxesChoice’);
if(checkBoxValue.match(‘Yellow’)==null) {
alert("You did not select Yellow!nnIf you do not select Yellow, you will not be able to save this list item!");
// aborts the save process
return false;
}
// Nothing above has returned false – go through with the save process
return true;
}
</script>
[/javascript]

I will return with more on validating input with both the SharePoint function PreSaveAction and on “events” in the fields themselves.

That’s all for now.

Alexander

Find and hide fields in NewForm, DispForm and EditForm in both IE and Firefox

This post is old… you will find other ways to do all this in newer posts – Alexander

This post will talk about how to use javascript to find a form-field in av SharePoint list form (NewForm, DispForm and EditForm) from its unique FieldInternalName.

When you have found it you can do almost anything you want with it – hide it, make it readOnly, return the value of the field or validate the input. I will come back to this in future posts in this “Series”.

The method i will talk about here is not new – i believe the guys at CleverWorkarounds posted it first, or was it here – I’m not really sure (if you do know who to credit – please let me know!).

Almost everyone uses a method where they search for a field by the fields DisplayName, but this is not a very robust way of doing it as the displayName can easily be altered – and thereby breaking the script.

It has also been talked about using the Id of the field as reference – the id one would believe to be unique – but it is NOT! If you change the column order in the list form – the id changes – it has a reference to the column order in the id.

This leaves only one suitable way to reference fields – by it’s FieldInternalName.
To find the FieldInternalName you can view the source of the page and search for your DisplayName.

One thing to remember when using FieldInternalName is that it newer changes – and therefore the FieldInternalName could end up totally different from the DisplayName.

When creating fields all spaces in the fieldName will be replased with _x0020_, and special characters with its equivalent hex-code – therefore create a proper fieldname first – then edit it to add spaces and special characters. By doing this your FieldInternalName will be readable and makes sense in your code.

The script i have created uses the FieldInternalName to uniquely identify the field, but it works ONLY in Internet Explorer because it searches for a “Comment-tag” which is not recognized in Firefox as a valid HTML tag:
[javascript]
<script type="text/javascript">
function findacontrol(FieldInternalName) {
var arr = document.getElementsByTagName(‘!’);
for (var i=0;i < arr.length; i++ ) {
if (arr[i].innerHTML.match(‘FieldInternalName="’ + FieldInternalName + ‘"’)) {
if(window.location.href.indexOf(‘DispForm.aspx’)>0) {
return arr[i].parentNode.childNodes[1];
}else{
return arr[i].parentNode.childNodes[1].childNodes[0];
}
}
}
}
</script>
[/javascript]

I’m not using Firefox myself, but realized that it would be nice to have this work in Firefox to – almost all my scripts depends on this method of finding fields.

I therefore made a similar script that works on both browsers, but it’s not as sleek as the one for IE only.

The main reason it has to be different is that Firefox does not recognize [sourcecode language=”html”]<!– the comment- tag –>[/javascript] as a valid HTML tag and therefore one have to use the td-tag to search the code. The disadvantage of this approach is that there are far more td-tags than comments in the code and it must loop trough more code in the hunt for “your field”.

One other thing Firefox does different than IE, is childNodes and nextSibling. Firefox treats line breaks in the code as a node and therefore the depth of childNodes in the script must be different for the two.

Script for both IE and Firefox:
[sourcecode language=”jscript”]
<script type="text/javascript">
function findacontrolCrossBrowser(FieldInternalName) {
var arr = document.getElementsByTagName(‘td’);
for (var i=0;i < arr.length; i++ ) {
if (arr[i].innerHTML.match(‘FieldInternalName="’ + FieldInternalName + ‘"’) && arr[i].className == ‘ms-formbody’) {
if(window.location.href.indexOf(‘DispForm.aspx’)>0) {
return arr[i].parentNode.childNodes[1];
}else{
if(arr[i].childNodes[1].nodeType==1) {
// Assumes it is IE
return arr[i].childNodes[1].childNodes[0];
}else if(arr[i].childNodes[1].nodeType==8) {
// Assumes it is Firefox
return arr[i].childNodes[3].childNodes[0];
}
}
}
}
}
</script>
[/javascript]

How to add webPart to NewForm, DispForm or EditForm? Click here.

One possible use of this script is to hide a single field, or a field array:
[sourcecode language=”jscript”]
function hideFieldsArray() {
var array = [‘Field1’, ‘Field2’];
for (x in array)
{
xField = findacontrolCrossBrowser(array[x]);
if(xField!=null)
{
if(window.location.href.indexOf(‘DispForm.aspx’)>0)
{
xField.parentNode.parentNode.style.display="none";
}else{
xField.parentNode.parentNode.parentNode.style.display="none";
}
}
}
}
</script>
[/javascript]

A fully functional setup of this script would be to add a CEWP below the form in for instance NewForm.aspx, and add the following script to it – of course change ‘Field1’ and ‘Field2’ with your FieldInternalName:
[javascript]
<script type="text/javascript">
hideFieldsArray();

function hideFieldsArray() {
var array = [‘Field1’, ‘Field2’];
for (x in array)
{
xField = findacontrolCrossBrowser(array[x]);
if(xField!=null)
{
if(window.location.href.indexOf(‘DispForm.aspx’)>0)
{
xField.parentNode.parentNode.style.display="none";
}else{
xField.parentNode.parentNode.parentNode.style.display="none";
}
}
}
}

function findacontrolCrossBrowser(FieldInternalName) {
var arr = document.getElementsByTagName(‘td’);
for (var i=0;i < arr.length; i++ ) {
if (arr[i].innerHTML.match(‘FieldInternalName="’ + FieldInternalName + ‘"’) && arr[i].className == ‘ms-formbody’) {
if(window.location.href.indexOf(‘DispForm.aspx’)>0) {
return arr[i].parentNode.childNodes[1];
}else{
if(arr[i].childNodes[1].nodeType==1) {
// Assumes it is IE
return arr[i].childNodes[1].childNodes[0];
}else if(arr[i].childNodes[1].nodeType==8) {
// Assumes it is Firefox
return arr[i].childNodes[3].childNodes[0];
}
}
}
}
}
</script>
[/javascript]
You can also call scripts on pageLoad with:
[sourcecode language=”jscript”]
<script type="text/javascript">
_spBodyOnLoadFunctionNames.push("functionName");
</script>
[/javascript]
but then the hiding of the fields will happen after the page has been presented to the use, and will result in a seconds flash of all your “hidden fields” – not good.

I will return with more on how to return the value from almost all field types (Single line of text, Multiple lines of text (Plain text), Choice (dropdown, radio and multi choice), Date and Time, Lookup, Yes/No, Person or Group), how to use and validate the input, and how to dynamically collapse or expand fields based on selections in other fields.

Stay tuned!

Alexander