I hope I am not too late in “chipping” in. I read the thread. However, I am not sure if I have fully understood what you are trying to achieve in your “Financial Manager App”. I have made one working app (code below), roughly following what I think you want to do, and making a few assumptions. The assumptions and considerations are,
- The “income” scene is used to receive repeat data entry of “income”.
- You can use the “done” or “enter” or “go” button on the Windows keyboard or virtual Android keyboard or,
- You can also use the “done” button to complete the entry. Hence, there are two event listeners, to cater for each. Please see insertIncome() and textListener().
- It is more efficient for this nature of app to open and close the db once. Please see initDB() and closeDB() and their placement.
- I also use an external program to open the db and double-check the integrity of the data entered in sqlite. The program I am using on my Windows is “db browser”. Here is the URL,
https://sqlitebrowser.org/
The code below may not be 100% exactly what you want to do. But please feel free to modify it and update it for your exact usage.
Here is the working code,
display.setDefault( "background", 0.8 )
local composer = require( "composer" )
local sqlite3 = require( "sqlite3" )
local scene = composer.newScene()
-- Forward declare display objects, functions and etc
local db, text, numericField, textEntered
local initDB, closeDB
-- Forward declare dimensions and other "constants"
local width = display.contentWidth
local height = display.contentHeight
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local headerHeight = height * 0.2
local labelWidth = width * 0.2
-- ------------------------------------------------------------------------------
function initDB()
local path = system.pathForFile( "data.db", system.DocumentsDirectory )
if ( not db or not db:isopen() ) then
db = sqlite3.open( path )
end
-- Creates the table for income, 'income' is the table name, 'IncomeValue' is the column
local incomeTableSetup = [[CREATE TABLE IF NOT EXISTS income ( IncomeValue INTEGER PRIMARY KEY autoincrement );]]
db:exec( incomeTableSetup )
end
function closeDB()
if ( db and db:isopen() ) then
db:close()
db = nil
end
end
function insertRecord( text )
if text ~= nil and text ~= "" then
local integer = tonumber( text )
-- More check on input value can be performed here, if integer is equal to 0
local insertQuery = [[INSERT INTO income VALUES ( ']] .. integer .. [[' );]]
db:exec( insertQuery )
-- Show the entry
enteredText.text = text
-- clear the text field for next input
numericField.text = ""
text = nil
end
end
-- When the value is written in the text box, then the done button is pressed, this function runs
local function insertIncome( event )
if event.phase == "ended" or event.phase == "submitted" then
print( event.name, event.phase, "insert income done:", tostring( text ) )
insertRecord( text )
end
end
-- When user editing or submitted the input via native text field
local function textListener( event )
if ( event.phase == "began" ) then
event.target.text = ""
elseif ( event.phase == "ended" or event.phase == "submitted" ) then
-- Output resulting text from "defaultField"
print( event.name, event.phase, "input from native text field:", event.target.text )
text = event.target.text
insertRecord( text )
elseif ( event.phase == "editing" ) then
text = event.newCharacters
end
end
-- If the menu button is pressed
local function gotoMenu()
composer.gotoScene( "menu" )
end
-- create()
function scene:create( event )
local sceneGroup = self.view
initDB()
local banner = display.newRect( sceneGroup, centerX, headerHeight * 0.5, width, headerHeight )
banner:setFillColor( 0, 0, 1 )
local incomeBanner = display.newText( sceneGroup, "Income: Data Entry", centerX, headerHeight * 0.5, native.systemFont, headerHeight * 0.2 )
incomeBanner:setFillColor( 1, 1, 1 )
local menuButton = display.newRect( sceneGroup, width * 0.2, height * 0.8, labelWidth, headerHeight * 0.5 )
menuButton:setFillColor( 0, 1, 0 )
menuButton:addEventListener( "tap", gotoMenu )
local menuText = display.newText( sceneGroup, "Menu", width * 0.2, height * 0.8, native.systemFont, headerHeight * 0.2 )
menuText:setFillColor( 0, 0, 0 )
local amountText = display.newText( sceneGroup, "Add Amount:", centerX, height * 0.3, native.systemFont, headerHeight * 0.2 )
amountText:setFillColor( 0, 0, 0 )
local doneButton = display.newRect( sceneGroup, centerX, height * 0.5, labelWidth, headerHeight * 0.5 )
doneButton:setFillColor( 0, 1, 0 )
doneButton:addEventListener( "touch", insertIncome )
local doneText = display.newText( sceneGroup, "Done", centerX, height * 0.5, native.systemFont, headerHeight * 0.2 )
doneText:setFillColor( 0, 0, 0 )
enteredText = display.newText( sceneGroup, "Entered Text", centerX, height * 0.8, native.systemFont, headerHeight * 0.2 )
enteredText:setFillColor( 0, 0, 0 )
numericField = native.newTextField( centerX, height * 0.4, labelWidth * 4, headerHeight * 0.4 )
numericField.inputType = "number"
numericField.placeholder = "enter income here"
numericField:addEventListener( "userInput", textListener )
sceneGroup:insert( numericField )
end
-- show()
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
elseif ( phase == "did" ) then
end
end
-- hide()
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
elseif( phase == "did" ) then
display.remove( numericField )
closeDB()
composer.removeScene( "income" )
end
end
scene:addEventListener( "create", scene)
scene:addEventListener( "show", scene)
scene:addEventListener( "hide", scene)
scene:addEventListener( "destroy", scene)
return scene