action on clicking into a text field

Hi,
no doubt this is another example of my ability to miss the obvious, but…

I have a text field that I’m filling with greyed out advice for the user. That works perfectly.

I want to have the field set to “” as soon as anyone clicks into it, i.e. before they start typing.

I’ve been playing with

	on textDidBeginEditing_(sender)
		log "entered"
		set blackColour to current application's NSColor's blackColor
		keywordField's setTextColor_(blackColour)
		keywordField's setStringValue_("")
	end textDidBeginEditing_

with the field’s sent action linked to the delegate in IB.

but it don’t work: even when I change sender to notification (for which I should surely need to register???)

thanks for any help

rhb

Use Interface Builder “Placeholder” for the text field instead. That is what this is for.

Hi,

You don’t need to connect anything or write any code to do this. As, Craig said, use the placeholder field in IB to put in your grayed out text. Depending on what other UI elements you have in your window, and what order they were placed in there, you might have to check “Refuses First Responder”, or your placeholder text might not show up. The text will disappear when you click in the box.

Ric

Thanks for that Craig and rdelmar, but my masters want the text to show up only when the app opens and then go away once the user has entered the field and not reappear until the next time it’s opened.

I haven’t been able to find a hypothetical “onEnterButBeforeEditingTextField”.

Is there anything like that or should I persuade them that what they really wanted was the placeholder behaviour?
again thanks

rhb

Oh yes, and don’t bindings interfere with placeholder?

You don’t want

you want

textDidBeginEditing: is a method you implement to tell the application the text field has begun editing,
controlTextDidBeginEditing: is the notification that your text field automatically sends when it begins editing.

ALSO:
you don’t want

you want the field’s delegate linked to the ASOC class (a blue cube) containing the controlTextDidBeginEditing_ method. When you control-click (or right-click) on the text field there should be a delegate link as well as a sent action selector; use that.

Hi again,

I got it to work by using the placeholder text, and then in the action method for the text field (called textDone_ in my example) have this:

on textDone_(sender)
		log sender's stringValue()
		keywordField's setStringValue_("")
		keywordField's |cell|'s setPlaceholderString_("")
	end textDone_

This will erase what you type in as well as the placeholder text when you press enter or click on another cell.

If you want to use bindings, you can still use a placeholder text but you enter it, not in the attributes pane, but in the bindings pane. When you’re setting up your bindings under Value, if you look below you’ll see a field called Null Placeholder --put your text there. So, with bindings my method was:


property theText:""
on textDone_(sender)
		log theText
		keywordField's setStringValue_("")
		keywordField's |cell|'s setPlaceholderString_("")
	end textDone_

Again thanks to everyone.

However I still can’t get the bloody thing to work.

at the moment my script has ( after elspub):

on controlTextDidBeginEditing_(sender)
	log "entered"
	set blackColour to current application's NSColor's blackColor
	keywordField's setTextColor_(blackColour)
	keywordField's setStringValue_("")
end controlTextDidBeginEditing_

I have the keywordField Text Field linked in IB :

Sent Action
controlTextDidBeginEditing ---- keyword App Delegate (where cTDBE resides)
Referencing Outlet
keywordField ---- keyword App Delegate

It also has a Binding
Value ---- keyword App Delegate (theKeyword)

If I choose the Sent Action (Attributes tab) to Sent on End Editing it works perfectly, but of course only when I leave the field. If I set it to Sent on Enter Only it doesn’t get called and nothing happens.

so any guesses as to what’s the problem

rhb

“Sent on Enter Only” should only send your action message when you press enter (as opposed to Tab, or clicking in another field). The method “controlTextDidBeginEditing_(sender)” should get called as soon as you enter the first character in your text field, regardless of whether you have “sent on end editing” or “sent on enter only”.

So, what behavior is it doing now that you don’t want, I’m unclear on what it’s doing now?

Sorry I’m not making myself clear.
What I want it to do is to clear out the field when it is entered so that the merely informational text that is in the field when the application opens is removed before typing. (Similar to the placeholder behaviour, only I don’t want it to come back if the field is empty.)
What it does now is to clear out the field AFTER it is exited. Although the reference says “This method is invoked when the user begins editing text in a control such as a text field…” nothing happens when I click into the field or when I start to type, but only when I click in another field (or hit return to run other stuff—stuff that runs apparently BEFORE the controlTextDidBeginEditing runs).

You’ll probably need to subclass the text field, and override becomeFirstResponder so that it also set the placeholder text to an empty string.

Remove the placeholder text in IB


on awakeFromNib()
		keywordField's |cell|'s setPlaceholderString_("Placeholder string")
end awakeFromNib
	
on textDone_(sender)
		log sender's stringValue()
		keywordField's setStringValue_("")
		keywordField's |cell|'s setPlaceholderString_("")
end textDone_

I’ll try these suggestions when I get to work on Monday.

Not that it directly effects this problem, but one thing no one has picked up on is why the placeholder text doesn’t show up if the text field has binding.
If I add a binding to a text field the placeholder text doesn’t show up in the app (though it does in IB). It does show up until I add the binding.

Bindings has a Null Placeholder field. Set that and you will have a placeholder when using bindings.

Craig,
just put that down to bad eyesight!

Thanks to everyone for all the help.

rhb