Field with placeholder/hint text

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Field with placeholder/hint text

Post by stam » Mon Nov 20, 2023 4:21 pm

Hi all,

I've needed a field for a project that shows hint text and have pretty much got there but there are a couple of very minor snags.
The snags are minor and this works very well, but would be nice to make it perfect ;)

Screenshot 2023-11-20 at 14.04.19.png

Project available here: https://github.com/stam66/skPlaceholderField
This includes a small UI as a control panel to modify the field's custom props. The stack is set up as a palette and can be used as a plugin (recommended) - you can adjust the 'prototype' field and copy it to your stack - or if you already have an skPlaceholderField in your stack you want to edit, select it in the IDE and click the arrow button top left.


The functionality I required
  • If field is 'empty' it shows the hint text in a different style to 'normal' text entry (eg italic and light grey)
  • On entering field nothing changes but on typing or pasting text, the hint text disappears and the text style changes (eg black, plain)
  • If text is deleted the placeholder text reappears before exiting the field
  • For fields/texts that are within the size of the field it enters the text vertically - but if the formatted text exceeds the height of the field, the text should be vertically aligned to top instead.
  • Option to resize text as a function of field height (i.e. as a percentage of field height)
  • Placeholder and normal text style changes based on whether the field background is light or dark
  • Configurable properties - not hardcoded in handlers

The 2 minor issues
1. The way my code handles entering text is if the he placeholder text is showing, it removes it when the user types so that only the user's text (in normal text style) shows. To do this, I need to be able to check for presence of the placeholder text and remove it - which works well. But if the user clicks in the middle of the placeholder text that inserted text there which makes it very difficult to do this, so I set the selection to the start of the field which then works seamlessly.

Weirdly, putting code in openField did not help, the best I can do is with

Code: Select all

on selectionChanged
    if fieldIsEmpty() then select before me
end selectionChanged
where fieldIsEmpty() is a function that returns true if the field is empty or if the field is only showing the placeholder text.
This works - but while the mouse is down, the cursor is inserted at the mouseLoc and on mouseUp jumps to the start of field.
On click this is isn't that noticeable but on persistent mouseDown it really is... it's a cosmetic issue but it's bugging me ;)

Question: How can I immediately move the selection to the start of the text on mouseDown (mouseDown and openField don't work...)


2. Setting the text programmatically: Because it isn't possible to create a setProp-style handler for the field's text I can't trigger a textStyle change when setting text programmatically, but since this is triggered on field events this works:

Code: Select all

set the text of field "skPlaceholderField" to "some text here"
send "exitField" to field "skPlaceholderField" -- triggers text formatting
Question: is any way for the field to be made aware that its text has been set programmatically to simplify this?

Not sure if there is a way around these minor snags, but very grateful for any suggestions...
I'll post the code in a separate post to make this more readable
Stam
Last edited by stam on Mon Nov 20, 2023 5:00 pm, edited 7 times in total.

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Mon Nov 20, 2023 4:22 pm

Other than the 2 minor issues mentioned above this works very well.


CODE
The field's main code is below - the custom property getters and setters (also part of the field's script of course) is separated below that for readability.

Code: Select all

///////////////  ACTIONS  ////////////////
command setTextStyle
    if fieldIsEmpty() then
        set the textStyle of me to the uPlaceholderTextStyle of me
        set the textColor of me to textColorForBackground(the backgroundColor of me, true)
    else
        set the textStyle of me to the uNormalTextStyle of me
        set the textColor of me to textColorForBackground(the backgroundColor of me, false)
    end if
end setTextStyle

command setFieldProps
    set the borderColor of me to the uBorderColor of me
    set the topColor of me to the uBorderColor of me
    set the bottomColor of me to the uBorderColor of me
    set the backgroundColor of me to the uBackgroundColor of me
    set the textSize of me to the height of me * the uScaleFactor of me
    set the borderwidth of me to the uBorderWidth of me
    centerTextVertically
end setFieldProps

command initField -- populates custom props if empty, so visible in IDE
    if the uPlaceholderText of me is empty then \
          set the uPlaceholderText of me to the uPlaceholderText of me
    if the uNormalTextStyle of me is empty then \
          set the uNormalTextStyle of me to the uNormalTextStyle of me
    if the uPlaceholderTextForDarkBackground of me is empty then \
          set the uPlaceholderTextForDarkBackground of me to the uPlaceholderTextForDarkBackground of me
    if the uPlaceholderTextForLightBackground of me is empty then \
          set the uPlaceholderTextForLightBackground of me to the uPlaceholderTextForLightBackground of me
    if the uPlaceholderTextStyle of me is empty then \
          set the uPlaceholderTextStyle of me to the uPlaceholderTextStyle of me
    if the uTextForDarkBackground of me is empty then \
          set the uTextForDarkBackground of me to the uTextForDarkBackground of me
    if the uTextForLightBackground of me is empty then \
          set the uTextForLightBackground of me to the uTextForLightBackground of me
end initField

command resetProps
    set the uTextForDarkBackground of me to empty
    set the uTextForLightBackground of me to empty
    set the uPlaceholderTextForDarkBackground of me to empty
    set the uPlaceholderTextForLightBackground of me to empty
    set the uBorderColor of me to empty
    set the uBackgroundColor of me to empty
    set the uNormalTextStyle of me to empty
    set the uPlaceholderTextStyle of me to empty
    set the uScaleFactor of me to empty
    set the uPlaceholderText of me to empty
    set the uBorderWidth of me to empty
    ####  use the default values from the getter functions:
    set the uTextForDarkBackground of me to the uTextForDarkBackground of me
    set the uTextForLightBackground of me to the uTextForLightBackground of me
    set the uPlaceholderTextForDarkBackground of me to the uPlaceholderTextForDarkBackground of me
    set the uPlaceholderTextForLightBackground of me to the uPlaceholderTextForLightBackground of me
    set the uBorderColor of me to the uBorderColor of me
    set the uBackgroundColor of me to the uBackgroundColor of me
    set the uNormalTextStyle of me to the uNormalTextStyle of me
    set the uPlaceholderTextStyle of me to the uPlaceholderTextStyle of me
    set the uScaleFactor of me to the uScaleFactor of me
    set the uPlaceholderText of me to the uPlaceholderText of me
    set the uBorderWidth of me to the uBorderWidth of me
end resetProps
///////////////  /ACTIONS  ///////////////

///////////////  EVENTS /////////////// 
on keyDown pKeyName
    if the text of me = the uPlaceholderText of me then set the text of me to empty
    pass keydown
end keyDown

on textChanged
    if fieldIsEmpty() then
        set the text of me to the uPlaceholderText of me
        select before me
    end if
    setTextStyle
end textChanged

on selectionChanged
    lock screen
    if fieldIsEmpty() then select before me
end selectionChanged

on openField
    initField
    setTextStyle
end openField

on exitField
    setTextStyle
    if fieldIsEmpty() then set the text of me to the uPlaceholderText of me
end exitField

on closeField
    setTextStyle
    if fieldIsEmpty() then set the text of me to the uPlaceholderText of me
end closeField

on resizeControl
    setFieldProps
end resizeControl

on pasteKey // SUSPEND DEV TOOLS IF TESTING IN IDE - works in standalone
    if fieldIsEmpty() then set the text of me to empty
    pass pasteKey
end pasteKey
///////////////  /EVENTS /////////////// 


/////////////// HELPERS ///////////////
function fieldIsEmpty
    return (the text of me is empty or the text of me is the uPlaceholderText of me)
end fieldIsEmpty

# return dark textColor for light backgrounds & vice versa
private function textColorForBackground pColor, pPlaceholder
    local hsp, r, g, b
    if pColor is empty then put the backgroundColor of the owner of me into pColor
    if pColor is empty then put 255,255,255 into pColor // assume white background if color can't be found for field or it's owner
    if char 1 of pColor is "#" and length(pColor) = 7 then  // hex in format #xxxxxx
        put baseConvert(char 2 to 3 of pColor, 16, 10) into r
        put baseConvert(char 4 to 5 of pColor, 16, 10) into g
        put baseConvert(char 6 to 7 of pColor, 16, 10) into b
    else if length(pColor) = 6 then                         // hex in format xxxxxx
        put baseConvert(char 1 to 2 of pColor, 16, 10) into r
        put baseConvert(char 3 to 4 of pColor, 16, 10) into g
        put baseConvert(char 5 to 6 of pColor, 16, 10) into b
    else if pColor contains ","  then                       // rbg triplet
        put item 1 of pColor into r
        put item 2 of pColor into g
        put item 3 of pColor into b
    else                                                    // colorName
        put RGBFromColorName (pColor) into pColor
        if pColor = "Error: not a color" then return "red"  // red text signifies error(s)...
        put item 1 of pColor into r
        put item 2 of pColor into g
        put item 3 of pColor into b
    end if
    put (0.299 * r + 0.587 * g + 0.114 * b)/255 into hsp
    if hsp >  0.5 then
        if pPlaceholder then
            return the uPlaceholderTextForLightBackground of me
        else
            return the uTextForLightBackground of me
        end if
    else
        if pPlaceholder then
            return the uPlaceholderTextForDarkBackground of me
        else
            return the uTextForDarkBackground of me
        end if
    end if
end textColorForBackground

function RGBFromColorName pColorName
    local tRGBColor
    if pColorName is not a color then return "Error: not a color"    
    create invisible button
    set the backgroundColor of last button to pColorName
    set the backgroundPixel of last button to the backgroundPixel of last button
    put the backgroundColor of last button into tRGBColor
    delete last button
    send "choose browse tool" to me in 10 milliseconds
    return tRGBColor
end RGBFromColorName

# CENTER VERTICALLY
private command centerTextVertically
    local tTextHeight, tFieldY, tFormatRect, tFormatheight, tFormatHalfHeight, tCurrFormatTop, tCenterField_To_TopTextDiff
    
    put the effective textHeight of me into tTextHeight
    put item 2 of the loc of me into tfieldY
    put the formattedRect of line 1 to - 1 of me into tFormatRect
    put item 4 of tFormatRect - item 2 of tFormatRect into tFormatHeight
    put tFormatHeight div 2 into tFormatHalfHeight
    put item 2 of tFormatRect into tCurrFormatTop
    put tfieldY - tCurrFormatTop into tCenterField_To_TopTextDiff
    set the topMargin of me to the topMargin of me + tCenterField_To_TopTextDiff - tFormatHalfHeight
    if the formattedHeight of me > the height of me then 
        set the topMargin of me to 8
    end if 
    exitfield
end centerTextVertically


CUSTOM PROPERTIES
To manage this functionality I've used a number of custom properties:

TEXT
uPlaceholderText -- the hint/placeholder text to show
uScaleFactor. -- how to scale the text in proportion to field height
uPlaceholderTextStyle -- the textStyle for the placeholder text
uNormalTextStyle -- the textStyle for the normal text
COLORS
uPlaceholderTextForLightBackground -- the placeholder/hint textColor when the field has a light background
uPlaceholderTextForDarkBackground -- the placeholder/hint textColor when the field has a dark background
uTextForLightBackground -- the normal textColor when the field has a light background
uTextForDarkBackground -- the normal textColor when the field has a dark background
OTHER - self explanatory
uBorderColor
uBorderWidth -- needed because with width = 2 (the default), LC does the funky to imitate the OS, at least on MacOS
uBackgroundColor



GETTERS (WITH DEFAULT VALUES) AND SETTERS

Code: Select all

// uPlaceholderText
getProp uPlaceholderText
    local tText
    put the uPlaceholderText of me into tText
    if tText is empty then put "Placeholder text" into tText
    return tText
end uPlaceholderText

setProp uPlaceholderText tText
    set the uPlaceholderText of me to tText
    send "exitField" to me
end uPlaceholderText

// uScaleFactor
getProp uScaleFactor
    local tFactor
    put the uScaleFactor of me into tFactor
    if tFactor is empty then put 0.4 into tFactor
    return tFactor
end uScaleFactor

setProp uScaleFactor pFactor
    set the uScaleFactor of me to pFactor
    setFieldProps
end uScaleFactor

// uNormalTextStyle
getProp uNormalTextStyle
    local tStyle
    put the uNormalTextStyle of me into tStyle
    if tStyle is empty then put "Plain" into tStyle
    return tStyle
end uNormalTextStyle

setProp uNormalTextStyle tStyle
    set the uNormalTextStyle of me to tStyle
    send "exitField" to me
end uNormalTextStyle

// uPlaceholderTextStyle
getProp uPlaceholderTextStyle
    local tStyle
    put the uPlaceholderTextStyle of me into tStyle
    if tStyle is empty then put "Italic" into tStyle
    return tStyle
end uPlaceholderTextStyle

setProp uPlaceholderTextStyle tStyle
    set the uPlaceholderTextStyle of me to tStyle
    send "exitField" to me
end uPlaceholderTextStyle

// uPlaceholderTextForDarkBackground
getProp uPlaceholderTextForDarkBackground
    local tColor
    put the uPlaceholderTextForDarkBackground of me into tColor
    if tColor is empty then put "200,200,200" into tColor
    return tColor
end uPlaceholderTextForDarkBackground

setProp uPlaceholderTextForDarkBackground pColor
    set the uPlaceholderTextForDarkBackground of me to pColor
    send "exitField" to me
end uPlaceholderTextForDarkBackground

// uPlaceholderTextForLightBackground
getProp uPlaceholderTextForLightBackground
    local tColor
    put the uPlaceholderTextForLightBackground of me into tColor
    if tColor is empty then put "170,170,170" into tColor
    return tColor
end uPlaceholderTextForLightBackground

setProp uPlaceholderTextForLightBackground pColor
    set the uPlaceholderTextForLightBackground of me to pColor
    send "exitField" to me
end uPlaceholderTextForLightBackground

// uTextForDarkBackground
getProp uTextForDarkBackground
    local tColor
    put the uTextForDarkBackground of me into tColor
    if tColor is empty then put "240,240,240" into tColor
    return tColor
end uTextForDarkBackground

setProp uTextForDarkBackground pColor
    set the uTextForDarkBackground of me to pColor
    send "exitField" to me
end uTextForDarkBackground

// uTextForLightBackground
getProp uTextForLightBackground
    local tColor
    put the uTextForLightBackground of me into tColor
    if tColor is empty then put "66,66,66" into tColor
    return tColor
end uTextForLightBackground

setProp uTextForLightBackground pColor
    set the uTextForLightBackground of me to pColor
    send "exitField" to me
end uTextForLightBackground

// uBorderColor
getProp uBorderColor
    local tColor
    put the uBorderColor of me into tColor
    if tColor is empty then put "66,66,66" into tColor
    return tColor
end uBorderColor

setProp uBorderColor pColor
    set the uBorderColor of me to pColor
    setFieldProps
end uBorderColor

// uBackgroundColor
getProp uBackgroundColor
    local tColor
    put the uBackgroundColor of me into tColor
    if tColor is empty then put "255,255,255" into tColor
    return tColor
end uBackgroundColor

setProp uBackgroundColor pColor
    set the uBackgroundColor of me to pColor
    setFieldProps
end uBackgroundColor

// uBorderWidth
getProp uBorderWidth
    local tSize
    put the uBorderWidth of me into tSize
    if tSize is empty then put 2 into tSize
    return tSize
end uBorderWidth

setProp uBorderWidth pSize
    set the uBorderWidth of me to pSize
    setFieldProps
end uBorderWidth

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7239
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Field with placeholder/hint text

Post by jacque » Tue Nov 21, 2023 10:44 pm

I didn't parse through your entire script but I can offer a simpler one I use. I think it's typical for the field prompt to go away when the user clicks in the field, that is, on openField. At least, that's how most of the ones I've seen on mobile work. At any rate, here's what I use in the script of a field. I use a custom property "cDefaultPrompt" but it could just as well be a constant.

Code: Select all

constant kDisabledColor = "138,138,138"

function textFldEmpty
  get the text of me
  return (it = "" or it = the cDefaultPrompt of me)
end textFldEmpty

on openField
  if textFldEmpty() then
    put "" into me
    if the backcolor of me = "255,255,255" or the backcolor of me = "" then
      set the textcolor of me to empty
    else
      set the textcolor of me to "255,255,255" -- color bg
    end if
  else -- scripted text entry
    set the textcolor of me to empty
  end if
end openField

on closeField
  resetDefaultText
end closeField

on exitField
  resetDefaultText
end exitField

on resetDefaultText
  if textFldEmpty() then
    put the cDefaultPrompt of me into me
    if the backcolor of me = "255,255,255" or the backcolor of me = "" then
      set the textcolor of me to kDisabledColor
    else
      set the textcolor of me to "255,255,255" -- color bg
    end if
  end if
  centerTextVertical
end resetDefaultText

on centerTextVertical
  put round(the effective textheight of me * .66) into tUnderHang
  set the topmargin of me to (the height of me - (the formattedheight of line 1 to -1 of me) + tUnderHang) div 2.5
end centerTextVertical
You'll probably want to add more specific text styling and flesh out some other properties, but I think using openField would manage the 2 issues you mention. I'm not sure why openField doesn't work for you, it seems okay in my stack. But like I said, I didn't go through your entire script.
Attachments
Prompt field.livecode.zip
Sample prompt field with vertical text centering.
(1.74 KiB) Downloaded 45 times
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7239
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Field with placeholder/hint text

Post by jacque » Tue Nov 21, 2023 11:22 pm

Playing with this, for scripted text:

Code: Select all

on scriptedText pText
  put pText into me
  openField
  resetDefaultText
end scriptedText
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Wed Nov 22, 2023 2:37 am

Thank Jacque

Using openField was my initial approach - but it doesn't conform to what I normally see in software, ie deleting all the text so the field is empty I expect/hope to see the hint text again but with openField, you have to exit the field to show the hint text.
My current implantation shows/hides the hint text as needed while typing.

The only issue is that you can select the hint text and click in it, which is visually unappealing.
Functionally this can't cause any issues because typing in the field will only show what the user typed (I realised the below fixed the risk of typing in the middle of the field)

Code: Select all

on keyDown pKeyName
    if the text of me = the uPlaceholderText of me then set the text of me to empty
    pass keydown
end keyDown
It is a cosmetic issue as the user can still see the cursor/selection until they release the mouse. This mitigates it a bit but the cursor/selection is visible until the user releases the mouse:

Code: Select all

on selectionChanged
    if fieldIsEmpty() then select before me
end selectionChanged

What I don't understand is why the following doesn't work, as it would completely addressed this issue:

Code: Select all

on openField
    select before me
end openField

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7239
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Field with placeholder/hint text

Post by jacque » Wed Nov 22, 2023 6:42 am

Does this do what you want?

Code: Select all

constant kDisabledColor = "138,138,138"

function textFldEmpty
  get the text of me
  return (it = "" or it = the cDefaultPrompt of me)
end textFldEmpty

on openField
  if textFldEmpty() then
    put "" into me
    if the backcolor of me = "255,255,255" or the backcolor of me = "" then
      set the textcolor of me to empty
    else
      set the textcolor of me to "255,255,255" -- color bg
    end if
  else -- scripted text entry
    set the textcolor of me to empty
  end if
end openField

on closeField
  resetDefaultText
end closeField

on exitField
  resetDefaultText
end exitField

on rawKeyDown pKey
  if me = the cDefaultPrompt of me then
    openField
  end if
  pass rawKeyDown
end rawKeyDown

on rawKeyUp pKey
    resetDefaultText
end rawKeyUp

on textChanged
  resetDefaultText
end textChanged

on resetDefaultText
  if textFldEmpty() then
    put the cDefaultPrompt of me into me
    if the backcolor of me = "255,255,255" or the backcolor of me = "" then
      set the textcolor of me to kDisabledColor
    else
      set the textcolor of me to "255,255,255" -- color bg
    end if
  end if
  centerTextVertical
end resetDefaultText

on centerTextVertical
  put round(the effective textheight of me * .66) into tUnderHang
  set the topmargin of me to (the height of me - (the formattedheight of line 1 to -1 of me) + tUnderHang) div 2.5
end centerTextVertical

on scriptedText pText
  put pText into me
  openField
  resetDefaultText
end scriptedText
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Wed Nov 22, 2023 10:15 am

Thanks Jacque

No - as I mentioned this was my initial approach.

The reason I don’t prefer this is that I still want the placeholder text to show when the user enters the field but hasn’t typed anything.
And if the user deletes all inputted text, the placeholder text should reappear even if the user has not exited the field.

With your (and my initial approach) the hint text disappears on entering the field and before typing anything, if I understood your code correctly.

I also don’t understand why I can’t set the selection on openfield…
I’ve been thinking of trying “before openfield” in a behaviour script, but as usual been to busy with my day job…

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7239
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Field with placeholder/hint text

Post by jacque » Wed Nov 22, 2023 9:50 pm

My version does insert the prompt when the user deletes any existing content. If you want the prompt to disappear on the first keystroke rather than when the field opens, then you could remove my openField handler and adjust rawKeyDown:

Code: Select all

on rawKeyDown pKey
  if me = the cDefaultPrompt of me then
    put "" into me
  end if
  pass rawKeyDown
end rawKeyDown
I think this covers all instances while the user is typing. You mentioned you noticed a visible change/glitch but I don't see that on my Mac. If you do see it, you could lock the screen briefly.

I'm not sure why you can't use openField to do your setup, but if that's important I suppose you could use a send-in-time to effect the selection. The above rawKeyDown handler doesn't need a selection; the first key press removes the prompt.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Thu Nov 23, 2023 10:49 am

jacque wrote:
Wed Nov 22, 2023 9:50 pm
I think this covers all instances while the user is typing.
Yeah, I mentioned above that I did exactly that, so there is no functional problem, only the issue that the cursor/selection is visible until the mouse is released. I used keyDown instead (works just fine)
stam wrote:
Wed Nov 22, 2023 2:37 am
Functionally this can't cause any issues because typing in the field will only show what the user typed (I realised the below fixed the risk of typing in the middle of the field)

Code: Select all

on keyDown pKeyName
    if the text of me = the uPlaceholderText of me then set the text of me to empty
    pass keydown
end keyDown

jacque wrote:
Wed Nov 22, 2023 9:50 pm
I suppose you could use a send-in-time to effect the selection. The above rawKeyDown handler doesn't need a selection; the first key press removes the prompt.
That's a great suggestion, thank you - will test it out

Many thanks
Stam

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Thu Nov 23, 2023 11:12 am

Alas, further testing does not resolve this minor cosmetic issue (cursor/selection showing until mouse is released)

Trying to affect mouseDown in either openField or mouseDown directly does nothing until the mouse is released.
Sending in time to affect selection does not work while the mouse is down (when sent from openField or mouseDown)
Changing the script to a behaviour and using before|after openField|mouseDown has no effect until the mouse is released.

Seems like openField itself stops all processing until the mouse is released (tabbing into the field was never an issue, only clicking in the default prompt text).

I'm not sure there is a way around this to keep the prompt text showing after entering the field but before the user types, without using a 2nd field/label.

On the other hand, using a label field I could do something like this: https://www.youtube.com/watch?app=desktop&v=PTGnpXbMU1U
Hmmmm....

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4003
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Field with placeholder/hint text

Post by bn » Thu Nov 23, 2023 12:47 pm

stam wrote:
Thu Nov 23, 2023 11:12 am
Alas, further testing does not resolve this minor cosmetic issue (cursor/selection showing until mouse is released)
I'm not sure there is a way around this to keep the prompt text showing after entering the field but before the user types, without using a 2nd field/label.
On the other hand, using a label field I could do something like this: https://www.youtube.com/watch?app=desktop&v=PTGnpXbMU1U
Hmmmm....
Stam,

In Livecode Create there is a "widget.materialfield" which behaves like the field in the link you posted. It is pretty neat and I guess it should show up in the next iteration of LC 10 DP.

materialField before mouseDown.png
materialField before mouseDown.png (22.94 KiB) Viewed 34003 times
materialField after mouseDown.png
materialField after mouseDown.png (8.69 KiB) Viewed 34003 times

The widget is extremely configurable. It is not blocked by the mouse being down in the field.

Of course that does not solve your current problem.

Kind regards
Bernd

PBH
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 129
Joined: Sun Feb 20, 2011 4:26 pm
Location: Vancouver Island, BC, Canada. ex.UK
Contact:

Re: Field with placeholder/hint text

Post by PBH » Thu Nov 23, 2023 4:23 pm

Stam,

Out of curiosity I played with this for a short while, I made the following changes targeting the field's autoHilite and it seems to work as far as I can tell, but obviously you'll need to test thoroughly as there may be other scenarios where you need to set the autoHilite to true or false.

Hope this helps, at least a little.

Paul


Under ACTIONS;

Code: Select all

command setTextStyle
   if fieldIsEmpty() then
      set the textStyle of me to the uPlaceholderTextStyle of me
      set the textColor of me to textColorForBackground(the backgroundColor of me, true)
      set the autoHilite of me to false -- Blocks the ability to highlight text
   else
      set the textStyle of me to the uNormalTextStyle of me
      set the textColor of me to textColorForBackground(the backgroundColor of me, false)
      set the autoHilite of me to true -- Allows the ability to highlight text
   end if
end setTextStyle
Under EVENTS;

Code: Select all

on exitField
   setTextStyle
   if fieldIsEmpty() then set the text of me to the uPlaceholderText of me
   set the autoHilite of me to true -- Allows the ability to highlight text
end exitField

on closeField
   exitField -- just to save duplicated script 
end closeField
Under HELPERS;

Code: Select all

function fieldIsEmpty
   return (the text of me is empty or the text of me is the uPlaceholderText of me)
   set the autoHilite of me to false -- Blocks the ability to highlight text
end fieldIsEmpty
Last edited by PBH on Thu Nov 23, 2023 9:08 pm, edited 1 time in total.

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4003
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Field with placeholder/hint text

Post by bn » Thu Nov 23, 2023 7:50 pm

Hi Stam,

I also gave this a try, I don't know if it meets all your requirements. The whole thing is a bit tricky...

Kind regards
Bernd
Attachments
fieldPlaceHolderTest.livecode.zip
(1.19 KiB) Downloaded 44 times

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Thu Nov 23, 2023 8:56 pm

Thanks both - I won’t be able to look at your solutions until the weekend now (on-call again), but am eager to test!

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Field with placeholder/hint text

Post by stam » Fri Nov 24, 2023 4:39 pm

bn wrote:
Thu Nov 23, 2023 7:50 pm
Hi Stam,

I also gave this a try, I don't know if it meets all your requirements. The whole thing is a bit tricky...

Kind regards
Bernd
Thanks Bernd, but doesn't quite do what I wanted - which is for the hint text to stay visible after entering the field but disappear if the user types anything.

This solution is quite similar to what Jacque posted, which again is similar to my initial attempts - which is to hide the placeholder text on openField.
I've been using such a field for some time but was more annoying to edit for specific use cases and this was an attempt to generalise (the idea is to eventually make it a script widget).

In truth I've "over-engineered" this a bit and will greatly simplify (too may properties!) - but the requirements I wanted to use (mainly to stay in line with commercial software we use) are:
1. Show the placeholder text with different style/color
2. on openField the placeholder text stays visible until the user types - and 'normal' text appears with different style/colour to the placeholder text.
3. If on typing the field is empty the placeholder text should again become visible and styles should change again.

All of these things work exactly and correctly with my initial posting.

The slight glitch is that while the mouse is down on clicking in the non-hilted field, the cursor remains visible and can be the middle of the placeholder text - but on releasing the mouseButton, everything is correct again. If just clicking the field, you wouldn't even notice it, but it's an annoyance ;)

It's truly a minor cosmetic issue - but one which could be avoided if only the cursor could be moved to the start on clicking the field. There is probably a solution I'm overlooking...

Dear Paul,
thank you for the excellent suggestion - but I'm not sure that will do it. I've not had time to actually test, but if I read this correctly, your code will leave auto-hilite on if exiting the field even if the placeholder text is showing, which then doesn't help. And if autohilite isn't on, you can't enter the field ;)
Or maybe I didn't get it...

Thanks both
Stam

Post Reply

Return to “Talking LiveCode”