Link to home
Start Free TrialLog in
Avatar of msgl
msgl

asked on

Check if people picker field is empty with jQuery?

Hi,

I have the following HTML

    <tr>
<td>
<div id="ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_upLevelDiv" TabIndex="0" onFocusIn="this._fFocus=1;saveOldEntities('ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_upLevelDiv')" onClick="onClickRw(true, true);" onChange="updateControlValue('ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField')" onFocusOut="this._fFocus=0;" onPaste="dopaste();" AutoPostBack="0" class="ms-inputuserfield" onDragStart="canEvt(event);" onKeyup="return onKeyUpRw('ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField');" onCopy="docopy();" onBlur="updateControlValue('ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField')" Title="People Picker" onKeyDown="return onKeyDownRw(this, 'ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField', 3, true, event);" contentEditable="true" style="width: 100%; word-wrap: break-work;overflow-x: hidden; background-color: window; color: windowtext;" name="upLevelDiv">
</div>
<textarea name="ctl00$m$g_c6ae303a_6013_4adb_8057_63a214bcfd24$ctl00$ctl04$ctl08$ctl00$ctl00$ctl04$ctl00$ctl00$UserField$downlevelTextBox" rows="1" cols="20" id="ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField_downlevelTextBox" class="ms-input" onKeyDown="return onKeyDownRw(this, 'ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField', 3, true, event);" onKeyUp="onKeyUpRw('ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_ctl04_ctl08_ctl00_ctl00_ctl04_ctl00_ctl00_UserField');" Title="People Picker" AutoPostBack="0" style="width:100%;display: none;position: absolute; ">
</textarea></td>
                            </tr>

and I am trying to check whether the people picker field has any value at all but I don't get it to work (can't use the ID attribute to find element), I am not sure which element to check.

The current code I have is:

$("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").change(function(){
        checkControls()
});

and here I want to add something like ,select[title=Strategic Priority],textarea.ms-input") but it doesn't work, any ideas?

Thanks in advance.
Avatar of leakim971
leakim971
Flag of Guadeloupe image

You may use find : http://api.jquery.com/find/
$("body").find("select[title='Strategic Priority']").change(function() {
  alert("changed !");
})

Open in new window

Avatar of msgl
msgl

ASKER

the current code I have works:

//bind a change event to all controls to validate
      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").change(function(){
            checkControls()
      });

      //the change event function - check the status of each control
      function checkControls(){

      //set a variable to count the number of valid controls
      var controlsPassed = 0;

      //set up a selector to pick .each() of the target controls
      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").each(function(){

            //if the control value is not zero AND is not zero-length
            var val = $(this).val();
            if($(this).is(':hidden') || (val != 0 && val.length != 0)) {

                  //add one to the counter
                  controlsPassed += 1;
            }

            });

      //call the showHide function and pass the true/false statement of 5 valid controls
      return (controlsPassed == 4);
      }

          function PreSaveItem() {
                return checkControls()
         }

bu when I try to validate the poeple picker field as well it doesn't do it. I change return (controlsPassed
== 4); to (controlsPassed == 5); and then on:
      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority],textarea.ms-input").each(function()

and

      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority],textarea.ms-input").change(function()

but it doesn't validate the people picker. I also try with the ID even though I don't want to use it later but it still doesn't work.




//bind a change event to all controls to validate
	$("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").change(function(){
		checkControls()
	});

	//the change event function - check the status of each control
	function checkControls(){

	//set a variable to count the number of valid controls
	var controlsPassed = 0;

	//set up a selector to pick .each() of the target controls
	$("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").each(function(){

		//if the control value is not zero AND is not zero-length
		var val = $(this).val();
		if($(this).is(':hidden') || (val != 0 && val.length != 0)) { 

			//add one to the counter
			controlsPassed += 1;
		}

		});

	//call the showHide function and pass the true/false statement of 5 valid controls
	return (controlsPassed == 4);
	}

    	function PreSaveItem() {
    		return checkControls()
   	}

Open in new window

Avatar of msgl

ASKER

I guess it doesn't work because the other controls have a value attribute. If I insert something in the date fields they get the attribute value="18/08/2010" for example. But with the textarea the html looks like (simplified)<textarea>value here</textarea> so how can I check if this is empty or not?
$("textarea").html().length return the length of the text inside
Avatar of msgl

ASKER

Thanks,

So what is the best way to check if it's empty or not with the other controls?
something like
if ($(this).is(':hidden') || (val != 0 && val.length != 0) || (textarea[title=People Picker].html().text() != '')){
?
Use :
($("textarea[title='People Picker']").text().length!= 0)
or :
($("textarea[title='People Picker']").html().length != 0)

not both : (textarea[title=People Picker].html().text() != '')

don't forget the $, put attribute value in quote 'People Picker' and close the parenthesis ;-)
Avatar of msgl

ASKER

thanks for that,

yeah I saw that I forgot the $. THis is my code now but  the page still reloads if I hit the submit button:
How do I edit the lines with .change and each. when I look up the other names by title and not check the lenght there?

      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],textarea[title=People Picker],select[title=Strategic Priority]").change

(function(){
            checkControls()
      });

and


      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],textarea[title=People Picker],select[title=Strategic Priority]").each

(function(){
//bind a change event to all controls to validate
	$("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],textarea[title=People Picker],select[title=Strategic Priority]").change

(function(){
		checkControls()
	});

	//the change event function - check the status of each control
	function checkControls(){

	//set a variable to count the number of valid controls
	var controlsPassed = 0;

	//set up a selector to pick .each() of the target controls
	$("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],textarea[title=People Picker],select[title=Strategic Priority]").each

(function(){

		//if the control value is not zero AND is not zero-length
		var val = $(this).val();
	
		if ($(this).is(':hidden') || (val != 0 && val.length != 0) || ($("textarea[title='People Picker']").text().length!= 0)){ 

			//add one to the counter
			controlsPassed += 1;
		
		}

		});

	//call the PreSaveItem function and pass the true/false statement of 5 valid controls
	return (controlsPassed == 5);

	}

    	function PreSaveItem() {
    		return checkControls()
   	}

Open in new window

>but  the page still reloads if I hit the submit button

Use event.preventDefault : http://api.jquery.com/event.preventDefault/

>How do I edit the lines with .change and each. when I look up the other names by title and not check the lenght there?

You may use three statement, one for input, one for select and one for textarea
Avatar of msgl

ASKER

with sharepoint I have to send a false statement to the PreSaveItem function (a default function to all submit buttons) to not reload the page.
check this :


//the change event function - check the status of each control
	function checkControls(){
		return ( $("input[title='Target Date'][value!=''],input[title='Start Date'][value!=''],select[title='Strategic Objective'][value!=''],select[title='Strategic Priority'][value!=''],textarea[title='People Picker'][value!='']").length == 5 );
	}

Open in new window

Avatar of msgl

ASKER

//bind a change event to all controls to validate
      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],textarea[title=People Picker],select[title=Strategic Priority]").change

(function(){
            checkControls()
      });
      //the change event function - check the status of each control
            function checkControls(){
            return ( $("input[title='Target Date'][value!=''],input[title='Start Date'][value!=''],select[title='Strategic Objective'][value!=''],select[title='Strategic Priority'][value!=''],textarea[title='People Picker'][value!='']").length == 5 );
      }
}
          function PreSaveItem() {
                return checkControls()
         }


Or

//bind a change event to all controls to validate
      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").change(function(){
            checkControls()
      });
      //the change event function - check the status of each control
      function checkControls(){

      //set a variable to count the number of valid controls
      var controlsPassed = 0;

      //set up a selector to pick .each() of the target controls
      $("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],select[title=Strategic Priority]").each(function(){
            //if the control value is not zero AND is not zero-length
            var val = $(this).val();
            if($(this).is(':hidden') || (val != 0 && val.length != 0)) {

                  //add one to the counter
                  controlsPassed += 1;
            }
            });
      //call the showHide function and pass the true/false statement of 5 valid controls
            return ( $("input[title='Target Date'][value!=''],input[title='Start Date'][value!=''],select[title='Strategic Objective'][value!=''],select[title='Strategic Priority'][value!=''],textarea[title='People Picker'][value!='']").length == 5 );
      }
          function PreSaveItem() {
                return checkControls()
         }

Both of the examples above causes the script to break.
You set a flag and not return

So when it's time to send true or false to PreSaveItem you use the flag
$(document).ready(function() {
		//bind a change event to all controls to validate
		$("input[title=Target Date],input[title=Start Date],select[title=Strategic Objective],textarea[title=People Picker],select[title=Strategic Priority]").change(function() {
			flag = (  $("input[title='Target Date'][value!=''],input[title='Start Date'][value!=''],select[title='Strategic Objective'][value!=''],select[title='Strategic Priority'][value!=''],textarea[title='People Picker'][value!='']").length == 5 );
		});
	});

	var flag = false;
	function PreSaveItem() {
		return flag;
	}

Open in new window

Or why not :



$(document).ready(function() {
	});

	function PreSaveItem() {
		return (  $("input[title='Target Date'][value!=''],input[title='Start Date'][value!=''],select[title='Strategic Objective'][value!=''],select[title='Strategic Priority'][value!=''],textarea[title='People Picker'][value!='']").length == 5 );
	}

Open in new window

Avatar of msgl

ASKER

the page still gets reloaded if I haven't filled out any fields and hit the submit button.
The reason why I have
if($(this).is(':hidden') || (val != 0 && val.length != 0)) {
is because depending on what I select in a dropdown list some elements gets hidden and I don't want to validate these.
hidden ? visibility ? or input type ?
Avatar of msgl

ASKER

If I select a certain item in the Strategic Objective dropdown list I hide for example the Start Date and Target Date fields. If I select anoter item I set them to be visible (.show())

If they are hidden I don't want to validate them, if they are visible I want to validate them.

It all works fine it's just that I can't get it to validate the people picker field. So in the code I posted I need to check if the textarea with title People Picker has lenght > 0 between <textarea> and </textarea>.
ASKER CERTIFIED SOLUTION
Avatar of leakim971
leakim971
Flag of Guadeloupe image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
if People Picker can be hidden :


return (controlsPassed == 4) && ( ($("textarea[title='People Picker'][value!='']").length==1) || $("textarea[title='People Picker'][value!='']").is(":hidden") );

Open in new window

Avatar of msgl

ASKER

That works, sort of, if I type my name and fill out the other fields nothing happens when I click the submit button. However, If I type my name and click the "Check Name" icon next to the field my name gets an underline in the textarea and then I can click the submit button.

It'll do for now but if you have any idea on how to change the code so it checks for any changes in the textarea please let me know. I should be able to type my name correctly and then hit Submit, without having to click the Check Name button.

Thanks anyway.
Avatar of msgl

ASKER

hmm maybe I was to fast there
If I use
return (controlsPassed == 4) && ( ($("textarea[title='People Picker'][value!='']").length==1) || $("textarea[title='People Picker'][value!='']").is(":hidden") );
and the poeple picker field is hidden I can't submit the form :(
to know if the code update(change) the textarea you need to save its value at page load :

< script language="javascript">
var oldTextAreaValue;
$(document).ready(function() {
        oldTextAreaValue = $("textarea[title='People Picker']").val();

then you can check :

function PreSaveItem() {
    return (controlsPassed == 4) && ($("textarea[title='People Picker'][value!='']").length==1) && ($("textarea[title='People Picker']").val() != oldTextAreaValue);

Another method is to attach keyup to the field : http://api.jquery.com/keyup/

$("textarea[title='People Picker']").keyup(function() { flagTextAreaValueModified = true; });
>and the poeple picker field is hidden I can't submit the form :(

Read this : http://api.jquery.com/hidden-selector/

Could you confirm the textarea is hidden (css visibility) or not displayed (css display)

Sorry, I'm going to sleep, see you later for sure!
Avatar of msgl

ASKER

I hide it with
$('nobr:contains("Assigned To")').closest('tr').hide();

thanks & good night
Avatar of msgl

ASKER

thought I could do something like
if ($("textarea[title='People Picker'][value!='']").is(":hidden")) {
      return (controlsPassed == 4)
}
else {
return (controlsPassed == 4) && ( ($("textarea[title='People Picker'][value!='']").length==1);
}

but no
Avatar of msgl

ASKER

The people picker is not hidden (.hide()) by default so probably that's the problem, when I hid it the function still thinks it's visible.
Perhaps it's because you hide the closest tr and not itslef so try :


if ($("textarea[title='People Picker'][value!='']").parents("tr").is(":hidden")) {
      return (controlsPassed == 4)
}
else {
      return (controlsPassed == 4) && ( ($("textarea[title='People Picker'][value!='']").length==1);
}

Open in new window

Avatar of msgl

ASKER

Hi leakim,

I posted a question about the people picker on microsoft's msdn forum and got this reply:
"Just to clarify, the textarea that is rendered by the people picker control will always be hidden, regardless of the visibility of the people picker on the page.

When you type into the people picker (On IE anyway), you are typing into a div with contentEditable="true", not into the textarea itself.

The textarea is just a control that is used by the people picker to store the data (and send it back to the server). Some fancy javascript behind the scenes works to keep the textarea updated when users are added to the picker.

Therefore, if you are basing your validation on hidden/visible controls, then you might want to check the visibility of the div for the people picker, not the textarea."

So I check the div instead:
return (controlsPassed == 4) && ( ($("textarea[title='People Picker'][value!='']").length==1) || $('#ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_UserField_upLevelDiv').is(":hidden") );

and it works apart form the issue with having to click the Check Name button.

<TD valign="top" class="ms-formbody" width="400px">
            <!-- FieldName="Assigned To"
                   FieldInternalName="AssignedTo"
                   FieldType="SPFieldUser"
              -->
                  <span dir="none">
            <input name="ctl00$m$g_$ctl00$HiddenUserFieldValue" type="hidden" id="ctl00_m_g____HiddenUserFieldValue" />
            <span id="ctl00_m_g____UserField" class="ms-usereditor" NoMatchesText="<No Matching Names>" MoreItemsText="More Names..." RemoveText="Remove" value="" allowEmpty="1" ShowEntityDisplayTextInTextBox="0" EEAfterCallbackClientScript=""><input name="ctl00$m$g_$ctl00$UserField$hiddenSpanData" type="hidden" id="ctl00_m_g____UserField_hiddenSpanData" /><input name="ctl00$m$g_$ctl00$UserField$OriginalEntities" type="hidden" id="ctl00_m_g____UserField_OriginalEntities" value="<Entities />" /><input name="ctl00$m$g_$ctl00$UserField$HiddenEntityKey" type="hidden" id="ctl00_m_g____UserField_HiddenEntityKey" /><input name="ctl00$m$g_$ctl00$UserField$HiddenEntityDisplayText" type="hidden" id="ctl00_m_g____UserField_HiddenEntityDisplayText" /><table id="ctl00_m_g____UserField_OuterTable" class="ms-usereditor" cellspacing="0" cellpadding="0" border="0" style="border-collapse:collapse;">
                              <tr valign="bottom">

                                    <td valign="top" style="width:90%;"><table cellpadding="0" cellspacing="0" border="0" style="width:100%;table-layout:fixed;">
                                          <tr>
                                                <td><div id="ctl00_m_g____UserField_upLevelDiv" name="upLevelDiv" class="ms-inputuserfield" TabIndex="0" style="display: none;position: absolute; " AutoPostBack="0"></div><textarea name="ctl00$m$g_$ctl00$UserField$downlevelTextBox" rows="1" cols="20" id="ctl00_m_g____UserField_downlevelTextBox" class="ms-input" onKeyDown="return onKeyDownRw(this, 'ctl00_m_g____UserField', 3, true, event);" onKeyUp="onKeyUpRw('ctl00_m_g____UserField');" Title="People Picker" AutoPostBack="0" style="width:100%;wordwrap: break-word;"></textarea></td>
                                          </tr>
                                    </table></td><td align="right" valign="top" nowrap="true" style="padding-left:5px;"><a id="ctl00_m_g____UserField_checkNames" title="Check Names" onclick="var arg=getUplevel('ctl00_m_g____UserField');var ctx='ctl00_m_g____UserField';EntityEditorSetWaitCursor(ctx);WebForm_DoCallback('ctl00$m$g_$ctl00$UserField',arg,EntityEditorHandleCheckNameResult,ctx,EntityEditorHandleCheckNameError,true);return false;" href="javascript:"><img title="Check Names" src="/_layouts/images/checknames.gif" alt="Check Names" style="border-width:0px;" /></a>&nbsp;<a id="ctl00_m_g____UserField_browse" accesskey="B" title="Browse" onclick="__Dialog__ctl00_m_g____UserField(); return false;" href="javascript:"><img title="Browse" src="/_layouts/images/addressbook.gif" alt="Browse" style="border-width:0px;" /></a></td>
                              </tr>


Anyway, I have already accepted your answer as  the solution so I'll try on my own and then post a new qustion if I need more help.
lol I understand now. What we see is not a textarea... lol because similar for CKEditor : https://www.experts-exchange.com/questions/26408514/using-onChange-or-OnKeyDown-with-CKEditor.html

to test if the div is hidden :

$("textarea[title='People Picker'][value!='']").parents("div:hidden")
Avatar of msgl

ASKER

yeah so I check if the div is hidden instead and it works. I still have the problem with having to click the Check Name button though. If I enter something in the field and check the generated source I can see that the value is stored in "<input value="the name here" name="ctl00$m$g_c6ae303a_6013_4adb_8057_$ctl00$UserField$hiddenSpanData" id="ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_UserField_hiddenSpanData" type="hidden">"

So i check if that element has a value or not but it's always hidden and if I select one of the items in a dropdown list it shouldn't check this value.


I tried to start over with something like:
            $("select[title='Item Level']").change(function() {
            var itemLevel = $(this).val();            
            if (itemLevel == "Strategic Objective") {
            alert("objective");
                  $("input[id$=UserField_hiddenSpanData]").change(function(){
                  checkControls();
                  alert("checkcontrols");
                  });

                  function checkControls(){
                  $("input[id$=UserField_hiddenSpanData]").each(function(){
                  var txt = $('#ctl00_m_g_c6ae303a_6013_4adb_8057_63a214bcfd24_ctl00_UserField_hiddenSpanData').val();
                  alert(txt);      
                  });
            

            function PreSaveItem() {
                  return checkControls();
            }


            }

            }
            if (itemLevel == "Strategic Priority") {
alert("priority");
            }
            if (itemLevel == "Milestone Action") {
alert("action");
            }
            if (itemLevel == "Performance Measure") {
alert("measure");
            }

            });


I get the alerts with the value for the selected item in the drop down but the rest doesn't work.