Can't retrieve loginName / AccountName of person field

Discussions about Forms Designer for SharePoint 2013 / 2016 and Office 365.
Locked
Leslie
Posts: 32
Joined: Thu Dec 05, 2019

28 Feb 2020

Hello !

I have an issue form, with a "Demandeur" single person field, and of course the AssignedTo field.
I need to do 3 comparisons / actions with the current user :
1 _ If the "Demandeur" field is empty, I fill it with the current user.
_ Else (if the "Demandeur" field isn't empty) then ...
2 _ if the "Demandeur" field is different from the current user, I hide a table of the form (it's a table with fields for the Demandeur).
3 _ If the AssignedTo field is empty, then do nothing.
_ Else (if the AssignedTo field isn't empty) then ...
4.1 _ if the AssignedTo field is different from the current user, I hide a table of the form (it's a table with fields for the AssignedTo person).

There is the code that does it :

Code: Select all

SP.SOD.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 () {
			console.log("0");
			var currentuser = user.get_loginName();
			console.log("CurrentUser = " + currentuser + " .");
			// si demandeur est vide, alors remplir avec current user
			if (fd.field('Demandeur').value() == '') {
				console.log("1");
			    fd.field('Demandeur').value(user.get_loginName());
			} 
			else {
				console.log("2");
				var demandeur = fd.field('Demandeur').value().dictionaryEntries.AccountName; 
				console.log("Demandeur = " + demandeurTXT + " .");
				//si demandeur n'est pas egal à currentuser alors masquer les boutonsUser
				if (demandeur != currentuser) {
					console.log("3");
					$('.boutonsUser').hide();
				}
			}
			console.log("4");
			if (fd.field('AssignedTo').value == '') {
				console.log("5");
			}
			else {
				console.log("6");
				var assignedTo = fd.field('AssignedTo').value().dictionaryEntries[0].AccountName;
				console.log("AssignedTo = " + assignedTo + " .");
				//si currentuser == assigné à, alors masquer le boutonPEC
				if (assignedTo == currentuser) {
					console.log("7");
					$('.boutonPEC').hide();
				}
			}
		}
	);		
}), "SP.js");
The firts comparison works well and I succeed to fill the "Demandeur" field with the current user.

2 issues detected by several tests :
_ For the "Demandeur" field , it's like this field was impossible to read: "Unable to get property '0' of undefined or null reference"
>> How can I retrieve the login name of that field ??
_ For the AssignedTo field, it's like this field was full when empty : When I am on item where the AssignedTo field is empty, the "if" react like this field was full (I see the console.log("6");), and I got the error : "Unable to get property '0' of undefined or null reference"
>> How can I do to detect if my AssignedTo field is empty or not ??

If I can't do that, my list of issues will never work as expected, and it's a highly expected list for my company. :cry:

Thank you very much in advanace for your help ! :D

User avatar
mnikitina
Posts: 264
Joined: Wed Jun 05, 2019

02 Mar 2020

Hello Leslie,

There are some incorrect lines and typos in your code.

1. It is better to use 'ready' event to set/check the people picker field value to make sure that the field has fully loaded.

Code: Select all

fd.field('PeoplePicker').control('ready', function() {

//your code here

});
2. It is better to check if the people picker field is empty using this code:

Code: Select all

if(fd.field('PeoplePicker').value().length == 0)
3. To get the LoginName of the user that is selected in the PeoplePicker field, please use this code:

Code: Select all

fd.field('PeoplePicker').value()[0].Key
4. You need to make sure that you are using the correct variable name:
console.log("Demandeur = " + demandeurTXT + " .");

I've updated your code, please see below.

Code: Select all

SP.SOD.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 () {
			console.log("0");
			var currentuser = user.get_loginName();
			console.log("CurrentUser = " + currentuser + " .");
			
            //make sure the field has fully loaded
			fd.field('Demandeur').control('ready', function() {
			
			// si demandeur est vide, alors remplir avec current user
				if (fd.field('Demandeur').value().length == 0) {
					console.log("1");
					fd.field('Demandeur').value(user.get_loginName());
				} 
				else {
					console.log("2");
					var demandeur = fd.field('Demandeur').value()[0].Key; 
					console.log("Demandeur = " + demandeur + " .");
					//si demandeur n'est pas egal à currentuser alors masquer les boutonsUser
					if (demandeur != currentuser) {
						console.log("3");
						$('.boutonsUser').hide();
					}
				}
			});
			console.log("4");
			//make sure the field has fully loaded
			fd.field('AssignedTo').control('ready', function() {
				if (fd.field('AssignedTo').value().length == 0) {
					console.log("5");
				}
				else {
					console.log("6");
					var assignedTo = fd.field('AssignedTo').value()[0].Key;
					console.log("AssignedTo = " + assignedTo + " .");
					//si currentuser == assigné à, alors masquer le boutonPEC
					if (assignedTo == currentuser) {
						console.log("7");
						$('.boutonPEC').hide();
					}
				}
			});
		}
	);		
}), "SP.js");

Leslie
Posts: 32
Joined: Thu Dec 05, 2019

02 Mar 2020

Nikita Kurguzov replied in an email of the support team ! :)
3/2/2020 3:18:01 AM

Dear Leslie,

I can see that you struggle with the Person field and how to check it. That's because Person fields do not store their value as text, but instead as an array of JS objects, where each object is a user, and it has a list of properties (such as Display Text, Key, etc.):
<image with different properties you can ask>

If you want to check if it's empty, try it like this:
if(fd.field('Person').value().length == 0)

If you try to check for specific person, try like this:
if(fd.field('Person').value()[0].DisplayText == "John Smith")

---
Kind regards,
Nikita Kurguzov
Plumsail
http://plumsail.com

Leslie
Posts: 32
Joined: Thu Dec 05, 2019

02 Mar 2020

I replied by an email to Nikita today :

Dear Nikita,

I've tested that and I found 3 conclusions :

•To check if a person field is empty, it works very well with fd.field('AssignedTo').value() == '' .
◦This didn't work with my AssignedTo field because I forgot the () after value !! :lol:
◦So, fd.field('AssignedTo').value() == '' , it works fine.

•I've tried with var demandeur = fd.field('Demandeur').value()[0].AccountName; but I still have the same error :
Unable to get property '0' of undefined or null reference
◦It's like if the Demandeur field was empty, but it's not !

•I've also tried with .Key, in place of .AccountName, but same error :
Unable to get property '0' of undefined or null reference
◦Always like if the person field was empty.


So my question is : What is the syntax for retrieving the account name of a person field ? (to compare it to current user account name) :shock:

There is my code now :

Code: Select all

SP.SOD.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 () {
			console.log("0");
			var currentuser = user.get_loginName();
			console.log("CurrentUser = " + currentuser + " .");
			// si demandeur est vide, alors remplir avec current user
			if (fd.field('Demandeur').value() == '') {
				console.log("1");
			    fd.field('Demandeur').value(user.get_loginName());
			} 
			else {
				console.log("2");
				var demandeur = fd.field('Demandeur').value()[0].Key; //doesn't work :(
				console.log("Demandeur = " + demandeurTXT + " .");
				//si demandeur n'est pas egal à currentuser alors masquer les boutonsUser
				if (demandeur != currentuser) {
					console.log("3");
					$('.boutonsUser').hide();
				}
			}
			console.log("4");
			if (fd.field('AssignedTo').value() == '') {
				console.log("5");
			}
			else {
				console.log("6");
				var assignedTo = fd.field('AssignedTo').value()[0].AccountName; // doesn't work too :(
				console.log("AssignedTo = " + assignedTo + " .");
				//si currentuser == assigné à, alors masquer le boutonPEC
				if (assignedTo == currentuser) {
					console.log("7");
					$('.boutonPEC').hide();
				}
			}
		}
	);		
}), "SP.js");
Thank you again and have a nice day !

Leslie
Posts: 32
Joined: Thu Dec 05, 2019

02 Mar 2020

Mnikitina, I just saw your post, looks like we wrote at the same time ! :lol:

To answer you, point by point:

1. It is better to use 'ready' event to set/check the people picker field value to make sure that the field has fully loaded.
>> Interesting, I'll check that out!

2. It is better to check if the people picker field is empty using this code: if(fd.field('PeoplePicker').value().length == 0)
>> As replied to Nikita, I don't know why but fd.field('PeoplePicker').value()== '' works well.
>> I'll try your technique, just in case.

3. To get the LoginName of the user that is selected in the PeoplePicker field, please use this code: fd.field('PeoplePicker').value()[0].Key
>> As replied to Nikita, that always sends me the same error "Unable to get property '0' of undefined or null reference"
>> Maybe if I use the ready event, that will change, I'll tell you!

4. You need to make sure that you are using the correct variable name: console.log("Demandeur = " + demandeurTXT + " .");
>> Yes, sorry, that was a previous variable that I don't use anymore. :mrgreen:

I check with the ready event and I tell you the result ! :D

Leslie
Posts: 32
Joined: Thu Dec 05, 2019

02 Mar 2020

I'm back !

The ready event has worked well, and it has solved all the problems mentioned before. :D

BUT there is a last issue : (I hope this is the last one :P )

The value of the variable currentuser is of the type "i:0#.w|domain\leslie.roze". (with .get_loginName())
The value of variables demandeur or assignedTo is of the type "domain\leslie.roze". (with .Key )
So it doesn't work when I want to compare currentuser and demandeur, or currentuser and assignedTo.

I've tried other properties to replace .Key, but none worked : AutoFillKey, LocalSearchTerm.
So, How can I obtain demandeur and assignedTo with the same syntax than i:0#.w|domain\leslie.roze ? :?

There is my code now :

Code: Select all

SP.SOD.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 () {
			console.log("0");
			var currentuser = user.get_loginName();
			console.log("CurrentUser = " + currentuser + " .");
			// si demandeur est vide, alors remplir avec current user
			//Une fois que le control Demandeur est prêt...
			fd.field('Demandeur').control('ready', function () {
				if (fd.field('Demandeur').value() == '') {
					console.log("1");
				    fd.field('Demandeur').value(user.get_loginName());
				} 
				else {
					console.log("2");
					var demandeur = fd.field('Demandeur').value()[0].Key; 
					console.log("Demandeur = " + demandeur + " .");
					//si demandeur n'est pas egal à currentuser alors masquer les boutonsUser
					if (demandeur != currentuser) {
						console.log("3");
						$('.boutonsUser').hide();
					}
				}
			});
			console.log("4");
			//Une fois que le control AssignedTo est prêt...
			fd.field('AssignedTo').control('ready', function () {
				if (fd.field('AssignedTo').value() == '') {
					console.log("5");
				}
				else {
					console.log("6");
					var assignedTo = fd.field('AssignedTo').value()[0].Key;
					console.log("AssignedTo = " + assignedTo + " .");
					//si currentuser == assigné à, alors masquer le boutonPEC
					if (assignedTo == currentuser) {
						console.log("7");
						$('.boutonPEC').hide();
					}
				}
			});
		}
	);		
}), "SP.js");
I feel that I am close to the goal! Thank you in advance!

Leslie
Posts: 32
Joined: Thu Dec 05, 2019

03 Mar 2020

I found it on my own ! :D

I didn't know this function but it exists a substring function !
I found that in another post of this forum (viewtopic.php?f=1&t=844&p=3463&hilit=va ... ring#p3463), thank you Satyrical !

So I create a variable named pipe = currentuser.indexOf('|'); to give me the index of the | symbol, and after that, I create another variable named currentuserTXT = currentuser.substring(pipe + 1);
And I compare demandeur and assignedTo to currentuserTXT and it's works fine ! :D

So, this is my final code :

Code: Select all

SP.SOD.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 () {
			console.log("0");
			var currentuser = user.get_loginName();
			console.log("CurrentUser = " + currentuser + " .");
			// récupérer le login du current user au format domain\prenom.nom, pour comparaison avec demandeur et assignedto
			var pipe = currentuser.indexOf('|');
			var currentuserTXT = currentuser.substring(pipe + 1);
			console.log("CurrentUserTXT = " + currentuserTXT + " .");
			// si demandeur est vide, alors remplir avec current user
			//Une fois que le control Demandeur est prêt...
			fd.field('Demandeur').control('ready', function () {
				if (fd.field('Demandeur').value() == '') {
					console.log("1");
				    fd.field('Demandeur').value(user.get_loginName());
				} 
				else {
					console.log("2");
					var demandeur = fd.field('Demandeur').value()[0].Key; 
					console.log("Demandeur = " + demandeur + " .");
					//si demandeur n'est pas egal à currentuser alors masquer les boutonsUser
					if (demandeur != currentuserTXT) {
						console.log("3");
						$('.boutonsUser').hide();
					}
				}
			});
			console.log("4");
			//Une fois que le control AssignedTo est prêt...
			fd.field('AssignedTo').control('ready', function () {
				if (fd.field('AssignedTo').value() == '') {
					console.log("5");
				}
				else {
					console.log("6");
					var assignedTo = fd.field('AssignedTo').value()[0].Key;
					console.log("AssignedTo = " + assignedTo + " .");
					//si currentuser == assigné à, alors masquer le boutonPEC
					if (assignedTo == currentuserTXT) {
						console.log("7");
						$('.boutonPEC').hide();
					}
				}
			});
		}
	);		
}), "SP.js");
I can now move on to the final part of developing my form! :mrgreen:

Thank you very much and have a nice day !

User avatar
mnikitina
Posts: 264
Joined: Wed Jun 05, 2019

03 Mar 2020

Leslie,

I'm glad this is working!

You can do this either with a split, or try to use Description instead of Key:

Code: Select all

var assignedTo = fd.field('AssignedTo').value()[0].Description;

Locked
  • Information
  • Who is online

    Users browsing this forum: No registered users and 8 guests