How To Create Field Placeholder Text Using Behaviors

This lesson will demonstrate how to create a field that displays placeholder text when the field is a) empty and b) does not have focus.

If you are not familiar with how to assign behaviors then please see How to Assign a Behavior.

Sample stack url: https://tinyurl.com/y7347bpu

What I Will Create

What I Will Create

The behavior I will show you will display placeholder text in a field when the field is empty and does not have focus. The field will be light gray.

When the field has focus the placeholder text will disappear and the text color will be inherited (usually black).

Setting the Placeholder Text

Setting the Placeholder Text

You assign the placeholder text by setting the uPlaceholderText custom property (1) of the field (2). The behavior (3) will display this text when appropriate.

You must get and set the text of the field using the uText or uUTF8Text custom properties that are defined in the behavior. These custom properties only return a value if the user has entered some text. They won't return the text if the placeholder is being displayed.

set the uText of field "Field" to "Some Text"
put the uText of field "Field"

The Behavior Script

This is the script of the behavior. In the example stack it is stored in the Placeholder Text Behavior button.

==========

COPY & PASTE

==========

--> Script Locals
constant kPlaceholderTextColor = "125,125,125"
local sDefaultTextIsDisplayed ## Keeps track of whether or not default text is being displayed
--> Accessors
getprop uText
	if sDefaultTextIsDisplayed then
		return empty
	else
		return the text of me
	end if
end uText

setprop uText pText
	lock screen
	_ClearDefaultText
	set the text of me to pText
	_DisplayDefaultText
	unlock screen
end uText
getprop uUTF8Text
	if sDefaultTextIsDisplayed then
		return empty
	else
		return unidecode(the unicodetext of me, "utf8")
	end if
end uUTF8Text
setprop uUTF8Text pText
	lock screen
	_ClearDefaultText
	set the unicodetext of me to uniencode(pText, "UTF8")
	_DisplayDefaultText
	unlock screen
end uUTF8Text
--> Engine messages
on openField
	## If default text is displayed then clear it out
	_ClearDefaultText
	pass openField
end openField

on closeField
	_DisplayDefaultText
	pass closeField
end closeField
on exitField
	_DisplayDefaultText
	pass exitField
end exitField

private command _ClearDefaultText
	if sDefaultTextIsDisplayed then
		lock screen
		set the text of me to empty
		set the textcolor of me to empty ## inherit default color
		unlock screen
	end if
	
	## Reset
	put false into sDefaultTextIsDisplayed
end _ClearDefaultText
private command _DisplayDefaultText
	## Reset
	put false into sDefaultTextIsDisplayed
	
	## Is text empty?
	if the text of me is empty then
		## Am I focused? If so then don't do anything.
		if the focusedobject is not the long id of me then
			lock screen
			set the text of me to the uPlaceholderText of me
			set the textcolor of me to 125,125,125
			put true into sDefaultTextIsDisplayed
			unlock screen
		end if
	end if
end _DisplayDefaultText

14 Comments

Scott

Maybe it's because this is old but I simple created a field and added:

on openField
if the text of me is "Enter Keyword (s)" then
set the text of me to ""
end if
end openField

Trevor DeVore

@Scott - But what happens if the user doesn't type any text and then leaves the field? You're prompt is gone. Also, the text color of the prompt text is usually lighter than the text the user types in.

Jan Riemersma

I use the following code and works well for me.

on openField
if the text of me is "Search" then
set the text of me to empty
set the foregroundColor of me to black
end if
end openField

on exitField
if the text of me is empty then
set the text of me to "Search"
set the foregroundColor of me to "125,125,125"
end if
end exitField

Trevor DeVore

@Jan - you would also want to handle the closeField message. In addition, the behavior adds a property (uText) which will return empty if the user hasn't typed any text but the placeholder text is visible. With your solution you would need to make a decision when getting the text of the field as to whether or not the text entered was by the user or your prompt.

Jan Riemersma

Dear Trevor,
perhaps I don't understand you [I'm Dutch;-)], but when the user enters the field the placeholder text disappears. When the user types some text in the field the color of the text is black (in my case) and only that text is visible. Which means the user typed in some text. I agree that you need a closeField message as well, for example when the user typed in some text and then deleted it and tabbed to another field. But as far as I know there is no misunderstanding whether the text was entered by the user or it was the prompt.

Trevor DeVore

@Jan - there is no confusion from the user perspective. But how does your code know if the text is the prompt text or what the user entered? You have to check somehow. With the behavior you can simply do this:

put the uText of field "MyFieldWithPrompt" into theUserEnteredText

If the prompt text is still visible (e.g. the user never typed anything or the user typed something but then later deleted what they entered and the prompt text reappeared) then the variable theUserEnteredText will be empty rather than "Search".

What would your code look like that gets the text of the field?

if the foregroundColor of field "MyFieldWithPrompt" is black then
# user entered text
put the text of field "MyFieldWithPrompt" into theUserEnteredText
else
put empty into theUserEnteredText
end if

Also, in your code, what if the user typed in "Search", left the field and then came back to it? The text they typed would disappear.

So while your example works in a very basic sense, it requires more code elsewhere and can break during user interaction.

Make sense?

Jan Riemersma

@Trevor - Oops, I think you're right. Thanks for your explanation. It helps me a lot!

Ebillson GRAND JEAN

@Trevor How would you handle the hint property more elegantly than what jan suggested? This tutorial is interesting but I am looking for the best and simplest approach

Elanor Buchanan

Hi Ebillson

Is there something in the method described in the lesson that is not working for you? Trevor was the original author of the lesson so this is the method he would use, but if it is not working or you are looking for some slightly modified behavior please let us know.

Kind regards.

Elanor

Eric

Has anyone made a placeholder behavior where the placeholder text dims when the field has focus and only goes away when the user enters text or pastes?

Elanor Buchanan

Hi Eric

You could add a new handler, or modify _ClearDefaultText, to check the text in the field. If it is the default text then dim the text, otherwise set the text color to empty(the default color).

private command _ClearDefaultText
if sDefaultTextIsDisplayed then
## Dim text
set the textcolor of me to 180,180,180
else
lock screen
set the textcolor of me to empty ## inherit default color
unlock screen
end if
end _ClearDefaultText

You would also need a textChanged handler which is sent when the content of a field has changed so that you can respond when the user types or pastes into the field

on textChanged
_ClearDefaultText
pass textChanged
end textChanged

The downside of this is that the default text is never automatically cleared.

I hope that helps.

Elanor

Stam

I'm adapting Trevor's elegant code to an interface element. This works well... except on opening the stack AND the field is empty (ie there is no uText assigned).

The placeholder text is displayed as intended, but clicking or tabbing into the field doesn't make the placeholder text go away and inserts itself into whatever you type.

To make it work properly, i have to enter value, delete it, focus on nothing/something else and then enter text again - after that it continues to work as intended until stack is closed, but recurs on re-opening (if the uText is empty).

There's something about openField that doesn't fire?
Any suggestions?

Elanor Buchanan

Hi Stam

I haven't been able to recreate the issue you are seeing. I tried opening the example stack from this lesson, which I think has the same setup you describe above, and it behaves as expected. Does the sample stack work for you?

Kind regards

Elanor

Stam

Hi Elanor,
interestingly the sample stack does work - but i tried implementing this without the ask dialog to set the text.

I copied the text field and the behaviour button into a new default stack (and i re-linked the behaviour as button id changes). I save and close.

What i then see is that opening the stack (my stacks are set to purge on close) and when no text is set in the field, clicking into it doesn't remove the placeholder text; i have to delete the placeholder text manually, exit the field, re-enter the field and then it works. If i delete the text in script (say in openCard) it still doesn't work.

I wonder if this may be linked to the bug Trevor mentions in the comments of his button that asks for text. Or possibly the script variable not registering state correctly.

In the mean time, i've implemented this slightly differently thanks to Jacque's suggestion on the forums:
https://forums.livecode.com/viewtopic.php?f=7&t=35408&start=15#p202045

Slightly less advanced, doesn't include a script variable to monitor state and doesn't keep a separate uText variable (so won't return text that is identical to the placeholder text), but on the other hand simpler, works well and covers my needs...

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.