Hi, I’ve almost completed my business app but can’t make contact form to work. I’ve used the corona sdk sample “Native Keyboard” to build the form but now I have no idea how to send data from the form to an email address. Every help is appreciated. Thanks in advance
If you are using their email account it is a simple matter of just opening the native email dialog like a so…
http://docs.coronalabs.com/api/library/native/showPopup.html
If you want to send it in the background you will need to use lua sockets and/or just send the message to your server directly via http post.
you can use lua sockets like this:
local socket = require 'socket' local smtp = require 'socket.smtp' local ssl = require 'ssl' local https = require 'ssl.https' local ltn12 = require 'ltn12' function sslCreate() local sock = socket.tcp() return setmetatable({ connect = function(\_, host, port) local r, e = sock:connect(host, port) if not r then return r, e end sock = ssl.wrap(sock, {mode='client', protocol='tlsv1'}) return sock:dohandshake() end }, { \_\_index = function(t,n) return function(\_, ...) return sock[n](sock, ...) end end }) end function sendMessage(subject, body) local msg = { headers = { to = 'Your Target \<target email\>', subject = subject }, body = body } local ok, err = smtp.send { from = '\<your email\>', rcpt = '\<target email\>', source = smtp.message(msg), user = 'username', password = 'password', server = 'smtp.gmail.com', port = 465, create = sslCreate } if not ok then print("Mail send failed", err) -- better error handling required end end
That’s great! Just a question: how I can set the email content ( subject and message ) from the data form? What i want to do is: app user fill the form and taps a button that sends data from form to my email address. What I currently done is:
local function fieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard print( textField().text ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end -- Predefine local objects for use later local defaultField, numberField, phoneField, urlField, emailField, passwordField local fields = display.newGroup() ------------------------------------------- -- \*\*\* Buttons Presses \*\*\* ------------------------------------------- -- Default Button Pressed local defaultButtonPress = function( event ) -- Make sure display object still exists before removing it if defaultField then print("Default button pressed ... removing textField") fields:remove( defaultField ) defaultButton:setLabel( "Add Default textField" ) defaultField = nil -- do this so we don't remove it a second time else -- Add the text field back again defaultField = native.newTextField( 10, 30, 180, tHeight ) defaultField.font = native.newFont( native.systemFontBold, 18 ) defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) fields:insert(defaultField) defaultButton:setLabel( "Remove Default textField" ) end end -- Number Button Pressed local numberButtonPress = function( event ) print("Number button pressed ... removing textField") -- Make sure display object still exists before removing it if numberField then numberField:removeSelf() numberButton:setLabel( "Add Number textField" ) numberField = nil -- do this so we don't remove it a second time else -- Add the text field back again numberField = native.newTextField( 10, 70, 180, tHeight ) numberField.font = native.newFont( native.systemFontBold, 18 ) numberField.inputType = "number" numberField:addEventListener( "userInput", fieldHandler( function() return numberField end ) ) fields:insert(numberField) numberButton:setLabel( "Remove Number textField" ) end end ------------------------------------------- -- \*\*\* Create native input textfields \*\*\* ------------------------------------------- display.setDefault( "anchorX", 0.0 ) -- default to TopLeft anchor point for new objects display.setDefault( "anchorY", 0.0 ) -- Note: currently this feature works in device builds or Xcode simulator builds only (also works on Corona Mac Simulator) local isAndroid = "Android" == system.getInfo("platformName") local inputFontSize = 18 local inputFontHeight = 30 tHeight = 30 if isAndroid then -- Android text fields have more chrome. It's either make them bigger, or make the font smaller. -- We'll do both inputFontSize = 14 inputFontHeight = 42 tHeight = 40 end defaultField = native.newTextField( 10, 30, 180, tHeight ) defaultField.font = native.newFont( native.systemFontBold, inputFontSize ) defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) numberField = native.newTextField( 10, 70, 180, tHeight ) numberField.font = native.newFont( native.systemFontBold, inputFontSize ) numberField.inputType = "number" numberField:addEventListener( "userInput", fieldHandler( function() return numberField end ) ) phoneField = native.newTextField( 10, 110, 180, tHeight ) phoneField.font = native.newFont( native.systemFontBold, inputFontSize ) phoneField.inputType = "phone" phoneField:addEventListener( "userInput", fieldHandler( function() return phoneField end ) ) urlField = native.newTextField( 10, 150, 180, tHeight ) urlField.font = native.newFont( native.systemFontBold, inputFontSize ) urlField.inputType = "url" urlField:addEventListener( "userInput", fieldHandler( function() return urlField end ) ) -- Add fields to our new group fields:insert(defaultField) fields:insert(numberField) ------------------------------------------- -- \*\*\* Add field labels \*\*\* ------------------------------------------- local defaultLabel = display.newText( "Nome e Cognome", 200, 35, native.systemFont, 18 ) defaultLabel:setFillColor( 170/255, 170/255, 1 ) local defaultLabel = display.newText( "Telefono", 200, 75, native.systemFont, 18 ) defaultLabel:setFillColor( 1, 150/255, 180/255 ) local defaultLabel = display.newText( "Email", 200, 115, native.systemFont, 18 ) defaultLabel:setFillColor( 1, 220/255, 120/255 ) local defaultLabel = display.newText( "Messaggio", 200, 155, native.systemFont, 18 ) defaultLabel:setFillColor( 170/255, 1, 170/255 ) --display.setDefault( "anchorX", 0.5 ) -- restore anchor points for new objects to center anchor point --display.setDefault( "anchorY", 0.5 ) ------------------------------------------- -- \*\*\* Create Buttons \*\*\* ------------------------------------------- -- "Remove Default" Button defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Remove Default textField", labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onPress = defaultButtonPress, } -- "Remove Number" Button numberButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Remove Number textField", labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onPress = numberButtonPress, } -- Position the buttons on screen defaultButton.x = display.contentCenterX - defaultButton.contentWidth/2; defaultButton.y = 325 numberButton.x = display.contentCenterX - numberButton.contentWidth/2; numberButton.y = 400
Well first and foremost you need to name your fields so you can get access to them, for example lblSubject, lblMessage etc. as defaultLabel is a little hard to get access to unless you are putting them in a table and giving them an “id” to scan through.
so once you change your vars around then just do following:
if using “their” native email client then do this.
local options = { to = "youremailaddress@yourdomain.com", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
else if using luaSockets do this
sendMessage(lblSubject.text, lblMessage.text)
You will have to test it as above is just an example
AWESOME!!! Thanks a lot cbishop0! The only problem is that now the popup comes out immediately when I go to the contact screen, and I want to show that after form is compiled. I tried to set up the send mail button but it doesn’t worked… any ideas? I’m SO newbie!! -.-
defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onPress = native.showPopup, }
No problem
Try this you just need to hookup the onEvent and check for ended.
defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then native.showPopup() end end, }
btw you need to pass in params to the native.showPopup like a so…
local options = { to = "youremailaddress@yourdomain.com", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
Otherwise it doesn’t know what it needs to do.
Why it doesn’t work??? I’m going mad, I’ve done exactly what you said but still the popup appears when go to contact scene. And the button doesn’t even work… here is my code:
-- "Send email" Button defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then native.showPopup() end end, } -- Position the buttons on screen defaultButton.x = 160 ; defaultButton.y = 250 local options = { to = "info@icityapp.it", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
And after i tried with this but still nothing…
-- Create the widget local button1 = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = handleButtonEvent } -- Position the buttons on screen button1.x = 160 ; button1.y = 250 local options = { to = "info@icityapp.it", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
Itsd because your local options/show popUp is not in your handleButtonEvent code use below:
defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then local options = { to = "info@icityapp.it", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options) end end, } -- Position the buttons on screen defaultButton.x = 160 ; defaultButton.y = 250
Thanks a lot! Now works like a charme!! Still can’t automatically fill the email with the data from the fields, but I will not take advantage of your kindness, I will try to solve in some way. Thank you very much!
Thanks a LOT to Christopher Bishop, now the form works really really good. I post the code as sample code if anyone need it.
local widget = require( "widget" ) local tHeight -- forward reference display.setDefault( "background", 80/255 ) ------------------------------------------- -- General event handler for fields ------------------------------------------- -- You could also assign different handlers for each textfield local function fieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard print( textField().text ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end display.setDefault( "anchorX", 0.0 ) -- default to TopLeft anchor point for new objects display.setDefault( "anchorY", 0.0 ) -- Note: currently this feature works in device builds or Xcode simulator builds only (also works on Corona Mac Simulator) local isAndroid = "Android" == system.getInfo("platformName") local inputFontSize = 18 local inputFontHeight = 30 tHeight = 30 if isAndroid then -- Android text fields have more chrome. It's either make them bigger, or make the font smaller. -- We'll do both inputFontSize = 14 inputFontHeight = 42 tHeight = 40 end subjectField = native.newTextField( 10, 210, 180, tHeight ) subjectField.font = native.newFont( native.systemFontBold, inputFontSize ) subjectField.inputType = "subject" subjectField:addEventListener( "userInput", fieldHandler( function() return emailField end ) ) group:insert(subjectField) messageField = native.newTextField( 10, 250, 180, 80 ) messageField.font = native.newFont( native.systemFontBold, inputFontSize ) messageField.inputType = "message" messageField:addEventListener( "userInput", fieldHandler( function() return passwordField end ) ) group:insert(messageField) ------------------------------------------- -- \*\*\* Add field labels \*\*\* ------------------------------------------- local lblSubject = display.newText( "Subject", 200, 210, native.systemFont, 18 ) lblSubject:setFillColor( 106, 106, 106 ) group:insert(lblSubject) local lblMessage = display.newText( "Message", 200, 250, native.systemFont, 18 ) lblMessage:setFillColor( 106, 106, 106 ) group:insert(lblMessage) --display.setDefault( "anchorX", 0.5 ) -- restore anchor points for new objects to center anchor point --display.setDefault( "anchorY", 0.5 ) ------------------------------------------- -- \*\*\* Create Buttons \*\*\* ------------------------------------------- -- "Send email" Button defaultButton = widget.newButton { defaultFile = "button.png", overFile = "buttonOver.png", labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then local options = { to = "info@yourdomain.it", -- insert here your email contact subject = subjectField.text, body = messageField.text, } native.showPopup("mail", options) end end, } group:insert(defaultButton) -- Position the buttons on screen defaultButton.x = 235 ; defaultButton.y = 370
If you are using their email account it is a simple matter of just opening the native email dialog like a so…
http://docs.coronalabs.com/api/library/native/showPopup.html
If you want to send it in the background you will need to use lua sockets and/or just send the message to your server directly via http post.
you can use lua sockets like this:
local socket = require 'socket' local smtp = require 'socket.smtp' local ssl = require 'ssl' local https = require 'ssl.https' local ltn12 = require 'ltn12' function sslCreate() local sock = socket.tcp() return setmetatable({ connect = function(\_, host, port) local r, e = sock:connect(host, port) if not r then return r, e end sock = ssl.wrap(sock, {mode='client', protocol='tlsv1'}) return sock:dohandshake() end }, { \_\_index = function(t,n) return function(\_, ...) return sock[n](sock, ...) end end }) end function sendMessage(subject, body) local msg = { headers = { to = 'Your Target \<target email\>', subject = subject }, body = body } local ok, err = smtp.send { from = '\<your email\>', rcpt = '\<target email\>', source = smtp.message(msg), user = 'username', password = 'password', server = 'smtp.gmail.com', port = 465, create = sslCreate } if not ok then print("Mail send failed", err) -- better error handling required end end
That’s great! Just a question: how I can set the email content ( subject and message ) from the data form? What i want to do is: app user fill the form and taps a button that sends data from form to my email address. What I currently done is:
local function fieldHandler( textField ) return function( event ) if ( "began" == event.phase ) then -- This is the "keyboard has appeared" event -- In some cases you may want to adjust the interface when the keyboard appears. elseif ( "ended" == event.phase ) then -- This event is called when the user stops editing a field: for example, when they touch a different field elseif ( "editing" == event.phase ) then elseif ( "submitted" == event.phase ) then -- This event occurs when the user presses the "return" key (if available) on the onscreen keyboard print( textField().text ) -- Hide keyboard native.setKeyboardFocus( nil ) end end end -- Predefine local objects for use later local defaultField, numberField, phoneField, urlField, emailField, passwordField local fields = display.newGroup() ------------------------------------------- -- \*\*\* Buttons Presses \*\*\* ------------------------------------------- -- Default Button Pressed local defaultButtonPress = function( event ) -- Make sure display object still exists before removing it if defaultField then print("Default button pressed ... removing textField") fields:remove( defaultField ) defaultButton:setLabel( "Add Default textField" ) defaultField = nil -- do this so we don't remove it a second time else -- Add the text field back again defaultField = native.newTextField( 10, 30, 180, tHeight ) defaultField.font = native.newFont( native.systemFontBold, 18 ) defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) fields:insert(defaultField) defaultButton:setLabel( "Remove Default textField" ) end end -- Number Button Pressed local numberButtonPress = function( event ) print("Number button pressed ... removing textField") -- Make sure display object still exists before removing it if numberField then numberField:removeSelf() numberButton:setLabel( "Add Number textField" ) numberField = nil -- do this so we don't remove it a second time else -- Add the text field back again numberField = native.newTextField( 10, 70, 180, tHeight ) numberField.font = native.newFont( native.systemFontBold, 18 ) numberField.inputType = "number" numberField:addEventListener( "userInput", fieldHandler( function() return numberField end ) ) fields:insert(numberField) numberButton:setLabel( "Remove Number textField" ) end end ------------------------------------------- -- \*\*\* Create native input textfields \*\*\* ------------------------------------------- display.setDefault( "anchorX", 0.0 ) -- default to TopLeft anchor point for new objects display.setDefault( "anchorY", 0.0 ) -- Note: currently this feature works in device builds or Xcode simulator builds only (also works on Corona Mac Simulator) local isAndroid = "Android" == system.getInfo("platformName") local inputFontSize = 18 local inputFontHeight = 30 tHeight = 30 if isAndroid then -- Android text fields have more chrome. It's either make them bigger, or make the font smaller. -- We'll do both inputFontSize = 14 inputFontHeight = 42 tHeight = 40 end defaultField = native.newTextField( 10, 30, 180, tHeight ) defaultField.font = native.newFont( native.systemFontBold, inputFontSize ) defaultField:addEventListener( "userInput", fieldHandler( function() return defaultField end ) ) numberField = native.newTextField( 10, 70, 180, tHeight ) numberField.font = native.newFont( native.systemFontBold, inputFontSize ) numberField.inputType = "number" numberField:addEventListener( "userInput", fieldHandler( function() return numberField end ) ) phoneField = native.newTextField( 10, 110, 180, tHeight ) phoneField.font = native.newFont( native.systemFontBold, inputFontSize ) phoneField.inputType = "phone" phoneField:addEventListener( "userInput", fieldHandler( function() return phoneField end ) ) urlField = native.newTextField( 10, 150, 180, tHeight ) urlField.font = native.newFont( native.systemFontBold, inputFontSize ) urlField.inputType = "url" urlField:addEventListener( "userInput", fieldHandler( function() return urlField end ) ) -- Add fields to our new group fields:insert(defaultField) fields:insert(numberField) ------------------------------------------- -- \*\*\* Add field labels \*\*\* ------------------------------------------- local defaultLabel = display.newText( "Nome e Cognome", 200, 35, native.systemFont, 18 ) defaultLabel:setFillColor( 170/255, 170/255, 1 ) local defaultLabel = display.newText( "Telefono", 200, 75, native.systemFont, 18 ) defaultLabel:setFillColor( 1, 150/255, 180/255 ) local defaultLabel = display.newText( "Email", 200, 115, native.systemFont, 18 ) defaultLabel:setFillColor( 1, 220/255, 120/255 ) local defaultLabel = display.newText( "Messaggio", 200, 155, native.systemFont, 18 ) defaultLabel:setFillColor( 170/255, 1, 170/255 ) --display.setDefault( "anchorX", 0.5 ) -- restore anchor points for new objects to center anchor point --display.setDefault( "anchorY", 0.5 ) ------------------------------------------- -- \*\*\* Create Buttons \*\*\* ------------------------------------------- -- "Remove Default" Button defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Remove Default textField", labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onPress = defaultButtonPress, } -- "Remove Number" Button numberButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Remove Number textField", labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onPress = numberButtonPress, } -- Position the buttons on screen defaultButton.x = display.contentCenterX - defaultButton.contentWidth/2; defaultButton.y = 325 numberButton.x = display.contentCenterX - numberButton.contentWidth/2; numberButton.y = 400
Well first and foremost you need to name your fields so you can get access to them, for example lblSubject, lblMessage etc. as defaultLabel is a little hard to get access to unless you are putting them in a table and giving them an “id” to scan through.
so once you change your vars around then just do following:
if using “their” native email client then do this.
local options = { to = "youremailaddress@yourdomain.com", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
else if using luaSockets do this
sendMessage(lblSubject.text, lblMessage.text)
You will have to test it as above is just an example
AWESOME!!! Thanks a lot cbishop0! The only problem is that now the popup comes out immediately when I go to the contact screen, and I want to show that after form is compiled. I tried to set up the send mail button but it doesn’t worked… any ideas? I’m SO newbie!! -.-
defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onPress = native.showPopup, }
No problem
Try this you just need to hookup the onEvent and check for ended.
defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then native.showPopup() end end, }
btw you need to pass in params to the native.showPopup like a so…
local options = { to = "youremailaddress@yourdomain.com", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
Otherwise it doesn’t know what it needs to do.
Why it doesn’t work??? I’m going mad, I’ve done exactly what you said but still the popup appears when go to contact scene. And the button doesn’t even work… here is my code:
-- "Send email" Button defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then native.showPopup() end end, } -- Position the buttons on screen defaultButton.x = 160 ; defaultButton.y = 250 local options = { to = "info@icityapp.it", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
And after i tried with this but still nothing…
-- Create the widget local button1 = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = handleButtonEvent } -- Position the buttons on screen button1.x = 160 ; button1.y = 250 local options = { to = "info@icityapp.it", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options)
Itsd because your local options/show popUp is not in your handleButtonEvent code use below:
defaultButton = widget.newButton { defaultFile = "buttonBlue.png", overFile = "buttonBlueOver.png", label = "Invia Segnalazione", --that's Send Mail in italian labelColor = { default = { 1, 1, 1 }, }, fontSize = 18, emboss = true, onEvent = function(event) if (event.phase == "ended") then local options = { to = "info@icityapp.it", subject = lblSubject.text, body = lblMessage.text } native.showPopup("mail", options) end end, } -- Position the buttons on screen defaultButton.x = 160 ; defaultButton.y = 250
Thanks a lot! Now works like a charme!! Still can’t automatically fill the email with the data from the fields, but I will not take advantage of your kindness, I will try to solve in some way. Thank you very much!