Character limitation not working

Please someone feed me with some light!

local function onNickTap( event ) if event.phase == "began" then event.text = "" if event.phase == "editing" then if (string.len(event.text) \> 8) then event.text = event.text:sub(1, 8) end end end end usernameField = native.newTextField( centerX, centerY - 14, 150, 36, onNickTap ) usernameField.font = native.newFont( "Gotham", 25 ) usernameField.text = "Nickname..." usernameField:setTextColor( 0, 0, 0) usernameField.inputType = "default" usernameField.hasBackground = false usernameField.isEditable = true

Hello,

At a quick glance, it looks like you’ve wrapped the “editing” phase inside the “began” phase. Those two phases should be separate conditional blocks.

See the examples here about what I mean:

https://docs.coronalabs.com/api/library/native/newTextField.html

Also, you should not be specifying the “onNickTap” listener function inline with “native.newTextField()”. The listener should be specified separately like this:

[lua]

usernameField:addEventListener( “userInput”, onNickTap )

[/lua]

Best regards,

Brent

Thank you for your interest in my problem! I have followed your tips and looked at the link. Sorry to say that it didnt solve tough.

Here is what I got 

local function onNickTap( event ) if event.phase == "began" then event.text = "" elseif event.phase == "editing" then if (string.len(event.text) \> 8) then event.text = event.text:sub(1, 8) end end end usernameField = native.newTextField( centerX, centerY - 14, 150, 36) usernameField.font = native.newFont( "Gotham", 25 ) usernameField.text = "Nickname..." usernameField:setTextColor( 0, 0, 0) usernameField.inputType = "default" usernameField.hasBackground = false usernameField.isEditable = true usernameField:addEventListener( "userInput", onNickTap )

Hi David,

Almost, but not exactly. You should use the same listener function, but inside that, each “phase” should be a distinct conditional block:

[lua]

local function onNickEditing( event )

   – “began” phase

   if event.phase == “began” then

      event.text = “” – note that this will clear the field every time, so maybe don’t do this

   – “editing” phase

   elseif event.phase == “editing” then

      if (string.len(event.text) > 8) then

         event.text = event.text:sub(1, 8)

      end

   end

end

– your other code

usernameField:addEventListener( “userInput”, onNickEditing )

[/lua]

Thank you again for the quick answer. This didn’t work either. When I click, it doesn’t clear the field, and when it passes over 8 char it doesnt work too. I made a build to test on my device and it didnt work as well. Also when I click outside the textbox the keyboard doesnt go away. Sorry for troubling with simple questions, I spent big time trying to solve myself before posting it here,  :unsure: but it seems impossible somehow . 

*PS, running a dayle build, dont know if this changes anything.

Replace every instance of

event.text

with

event.target.text

in your snippet above and you should be good to go.

Hi David,

A couple follow-up points:

  1. Do you really want it to clear the entire field every time the user initially clicks in it? That seems like a slightly odd UI design.

  2. The keyboard won’t automatically hide when you click somewhere outside of the box. One common solution is to detect a touch on the screen and, if the keyboard is showing, make the API call to hide it.

  3. The contents of the field are referred to as “event.text” during the “began” and “editing” phases, but “event.target.text” during the “ended” or “submitted” phases. I don’t know why engineering made this differentiation, but that’s how it works.

Best regards,

Brent

Thank you both for the answers. Since I am a beginner I was trying to do this in parts.

Actually what I wanted it to do is :

When the user clicks on the field it goes blank,

when it touchs outside the field the text would be what he had put.

but if the chars were > 8 or < 4 or blank , the field would be “Nickname…” again.

I was a Gamesalad user and moved to corona a few weeks ago, it’s been difficult to me to learn all this but I am sure I will get there.

Any help is welcome! Appreciate your attention, have a good week.

This is was the closest I could get :

local function onNickEditing( event ) if event.phase == "began" then if event.target.text == "Nickname..." then event.target.text = "" if event.phase == "editing" then if (string.len(event.target.text) \> 8) then event.target.text = event.target.text:sub(1, 8) if event.phase == "ended" then if (string.len(event.text) \< 4) then event.target.text = "Nickname..." end end end end end end end usernameField = native.newTextField( centerX, centerY - 14, 150, 36) usernameField.font = native.newFont( "Gotham", 25 ) usernameField.text = "Nickname..." usernameField:setTextColor( 0, 0, 0) usernameField.inputType = "default" usernameField.hasBackground = false usernameField.isEditable = true usernameField:addEventListener( "userInput", onNickEditing )

Before I take a crack at answering your question, I want to point out something.  See all those “end” statements all lined up nice and neat?  Well it makes your code very… very… hard to read.  Each end needs to be indented to the same level as the statement that needs ended.  For instance:

local function doSomething() &nbsp;&nbsp;&nbsp; if someCondition then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- do stuff &nbsp;&nbsp;&nbsp; end end

See how the ends match up with the statement they are ending?  Please see this tutorial:  https://coronalabs.com/blog/2015/06/09/tutorial-the-value-of-well-formatted-code/

Now here is your code properly formatted:

local function onNickEditing( event ) &nbsp;&nbsp; &nbsp;if event.phase == "began" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.target.text == "Nickname..." then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.phase == "editing" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.target.text) \> 8) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = event.target.text:sub(1, 8) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.phase == "ended" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.text) \< 4) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "Nickname..." &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;end end

Once you see the code properly formatted, you should be able to trace through it. Your first if statement tests the event phase == “began”  Inside that if block you test event.phase again to see the phase is editing. But that condition will never be true because you’re in the middle of a conditions where phase is “began”.

This is likely the code you are looking for:

local function onNickEditing( event ) &nbsp;&nbsp; &nbsp;if event.phase == "began" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.target.text == "Nickname..." then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;elseif event.phase == "editing" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.target.text) \> 8) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = event.target.text:sub(1, 8) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;elseif event.phase == "ended" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.text) \< 4) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "Nickname..." &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;end end

That should get you on track, but you can simplify this even more. It looks like “Nickname…” is intended to be what’s called a Placeholder, which is text that goes away once the user starts typing in the field.  If you do:

usernameField.placeholder = “Nickname…”

The field will show that text for you and automatically show it until there are typed characters. I think this does what you want:

local function onNickEditing( event ) &nbsp;&nbsp; &nbsp;if event.phase == "editing" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.target.text) \> 8) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = event.target.text:sub(1, 8) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;elseif event.phase == "ended" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.text) \< 4) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;end end

Rob

I would never imagine an answer so detailed like yours. Let me start saying a big thank you for all the tips and knowledge shown in your post.

I loved to see that placeholder feature but it gets in the way in my alpha interpolation from 0 to 0.65. ( it doesn’t disappear when alpha = 0 ). With your post, I was able to do everything I was imagining and went beyond. check this out :slight_smile: Thank your for being part of my learning journey !

local function onNickEditing( event ) if event.phase == "began" then if event.target.text == "Nickname..." then event.target.text = "" end if event.target.text ~= "Nickname..." then event.target.text = event.target.text end elseif event.phase == "editing" then if (string.len(event.target.text) \> 8) then event.target.text = event.target.text:sub(1, 8) end elseif event.phase == "ended" then if (string.len(event.target.text) \< 4) then event.target.text = "Nickname..." end end end usernameField = native.newTextField( centerX, centerY - 14, 150, 36) usernameField.font = native.newFont( "Gotham", 25 ) usernameField.text = "Nickname..." --usernameField.placeholder = "Nickname..." -- didn't use but it's good for future reference! usernameField:setTextColor( 0, 0, 0, 0) usernameField.inputType = "default" usernameField.hasBackground = false usernameField.isEditable = true usernameField:addEventListener( "userInput", onNickEditing ) local function showNickAlpha () usernameField:setTextColor( 0, 0, 0, 0.65 ) end timer.performWithDelay( 3700, showNickAlpha )

Hello,

At a quick glance, it looks like you’ve wrapped the “editing” phase inside the “began” phase. Those two phases should be separate conditional blocks.

See the examples here about what I mean:

https://docs.coronalabs.com/api/library/native/newTextField.html

Also, you should not be specifying the “onNickTap” listener function inline with “native.newTextField()”. The listener should be specified separately like this:

[lua]

usernameField:addEventListener( “userInput”, onNickTap )

[/lua]

Best regards,

Brent

Thank you for your interest in my problem! I have followed your tips and looked at the link. Sorry to say that it didnt solve tough.

Here is what I got 

local function onNickTap( event ) if event.phase == "began" then event.text = "" elseif event.phase == "editing" then if (string.len(event.text) \> 8) then event.text = event.text:sub(1, 8) end end end usernameField = native.newTextField( centerX, centerY - 14, 150, 36) usernameField.font = native.newFont( "Gotham", 25 ) usernameField.text = "Nickname..." usernameField:setTextColor( 0, 0, 0) usernameField.inputType = "default" usernameField.hasBackground = false usernameField.isEditable = true usernameField:addEventListener( "userInput", onNickTap )

Hi David,

Almost, but not exactly. You should use the same listener function, but inside that, each “phase” should be a distinct conditional block:

[lua]

local function onNickEditing( event )

   – “began” phase

   if event.phase == “began” then

      event.text = “” – note that this will clear the field every time, so maybe don’t do this

   – “editing” phase

   elseif event.phase == “editing” then

      if (string.len(event.text) > 8) then

         event.text = event.text:sub(1, 8)

      end

   end

end

– your other code

usernameField:addEventListener( “userInput”, onNickEditing )

[/lua]

Thank you again for the quick answer. This didn’t work either. When I click, it doesn’t clear the field, and when it passes over 8 char it doesnt work too. I made a build to test on my device and it didnt work as well. Also when I click outside the textbox the keyboard doesnt go away. Sorry for troubling with simple questions, I spent big time trying to solve myself before posting it here,  :unsure: but it seems impossible somehow . 

*PS, running a dayle build, dont know if this changes anything.

Replace every instance of

event.text

with

event.target.text

in your snippet above and you should be good to go.

Hi David,

A couple follow-up points:

  1. Do you really want it to clear the entire field every time the user initially clicks in it? That seems like a slightly odd UI design.

  2. The keyboard won’t automatically hide when you click somewhere outside of the box. One common solution is to detect a touch on the screen and, if the keyboard is showing, make the API call to hide it.

  3. The contents of the field are referred to as “event.text” during the “began” and “editing” phases, but “event.target.text” during the “ended” or “submitted” phases. I don’t know why engineering made this differentiation, but that’s how it works.

Best regards,

Brent

Thank you both for the answers. Since I am a beginner I was trying to do this in parts.

Actually what I wanted it to do is :

When the user clicks on the field it goes blank,

when it touchs outside the field the text would be what he had put.

but if the chars were > 8 or < 4 or blank , the field would be “Nickname…” again.

I was a Gamesalad user and moved to corona a few weeks ago, it’s been difficult to me to learn all this but I am sure I will get there.

Any help is welcome! Appreciate your attention, have a good week.

This is was the closest I could get :

local function onNickEditing( event ) if event.phase == "began" then if event.target.text == "Nickname..." then event.target.text = "" if event.phase == "editing" then if (string.len(event.target.text) \> 8) then event.target.text = event.target.text:sub(1, 8) if event.phase == "ended" then if (string.len(event.text) \< 4) then event.target.text = "Nickname..." end end end end end end end usernameField = native.newTextField( centerX, centerY - 14, 150, 36) usernameField.font = native.newFont( "Gotham", 25 ) usernameField.text = "Nickname..." usernameField:setTextColor( 0, 0, 0) usernameField.inputType = "default" usernameField.hasBackground = false usernameField.isEditable = true usernameField:addEventListener( "userInput", onNickEditing )

Before I take a crack at answering your question, I want to point out something.  See all those “end” statements all lined up nice and neat?  Well it makes your code very… very… hard to read.  Each end needs to be indented to the same level as the statement that needs ended.  For instance:

local function doSomething() &nbsp;&nbsp;&nbsp; if someCondition then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- do stuff &nbsp;&nbsp;&nbsp; end end

See how the ends match up with the statement they are ending?  Please see this tutorial:  https://coronalabs.com/blog/2015/06/09/tutorial-the-value-of-well-formatted-code/

Now here is your code properly formatted:

local function onNickEditing( event ) &nbsp;&nbsp; &nbsp;if event.phase == "began" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.target.text == "Nickname..." then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.phase == "editing" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.target.text) \> 8) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = event.target.text:sub(1, 8) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.phase == "ended" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.text) \< 4) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "Nickname..." &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;end end

Once you see the code properly formatted, you should be able to trace through it. Your first if statement tests the event phase == “began”  Inside that if block you test event.phase again to see the phase is editing. But that condition will never be true because you’re in the middle of a conditions where phase is “began”.

This is likely the code you are looking for:

local function onNickEditing( event ) &nbsp;&nbsp; &nbsp;if event.phase == "began" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if event.target.text == "Nickname..." then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;elseif event.phase == "editing" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.target.text) \> 8) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = event.target.text:sub(1, 8) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;elseif event.phase == "ended" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.text) \< 4) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "Nickname..." &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;end end

That should get you on track, but you can simplify this even more. It looks like “Nickname…” is intended to be what’s called a Placeholder, which is text that goes away once the user starts typing in the field.  If you do:

usernameField.placeholder = “Nickname…”

The field will show that text for you and automatically show it until there are typed characters. I think this does what you want:

local function onNickEditing( event ) &nbsp;&nbsp; &nbsp;if event.phase == "editing" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.target.text) \> 8) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = event.target.text:sub(1, 8) &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;elseif event.phase == "ended" then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (string.len(event.text) \< 4) then &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;event.target.text = "" &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;end &nbsp;&nbsp; &nbsp;end end

Rob