This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
sample_code:visitor_log [2014/10/18 21:49] stevegarman created |
sample_code:visitor_log [2014/12/07 05:05] (current) |
||
---|---|---|---|
Line 2: | Line 2: | ||
This is the first working draft of a visitor sign-in log for my workplace. | This is the first working draft of a visitor sign-in log for my workplace. | ||
- | The final copy includes more error-checking for signing out, extra code to deal with the possibility that the app is left running over midnight and a fair bit of prettying up. | + | The live version |
===== The code ===== | ===== The code ===== | ||
<code javascript visitors.js> | <code javascript visitors.js> | ||
//Visitor sign-in app by Steve Garman | //Visitor sign-in app by Steve Garman | ||
//saves one day's data as a JSON string in a file | //saves one day's data as a JSON string in a file | ||
- | |||
//Global variables | //Global variables | ||
- | var recArray = [], fileFolder = "/ | + | var recArray = [], |
+ | | ||
+ | | ||
//Global layouts and controls | //Global layouts and controls | ||
- | var scrollr, layScroll, edtName, edtOrg, edtVehicle, | + | var scrollr, layScroll, edtName, edtOrg, edtVehicle, edtReason; |
//Called when application is started. | //Called when application is started. | ||
- | function OnStart(){ | + | function OnStart() |
- | //file variables | + | |
- | var d = new Date(); | + | if (!app.IsTablet()) app.SetOrientation(" |
- | jsonPath = fileFolder + " | + | |
- | | + | var d = new Date(); |
- | + " | + | jsonPath = fileFolder + " |
- | app.MakeFolder(fileFolder) | + | d.toISOString().slice(0, |
- | //Create main layout. | + | app.MakeFolder(fileFolder) |
- | var lay = app.CreateLayout( " | + | //Create main layout. |
- | //Create a scroller and add it to main layout | + | var lay = app.CreateLayout(" |
- | scrollr = app.CreateScroller( 1.0, 0.8 ); | + | //Create a scroller and add it to main layout |
- | lay.AddChild( scrollr ); | + | scrollr = app.CreateScroller(1.0, |
- | //Create a layout inside scroller. | + | lay.AddChild(scrollr); |
- | layScroll = app.CreateLayout( " | + | //Create a layout inside scroller. |
- | scrollr.AddChild( layScroll | + | layScroll = app.CreateLayout(" |
- | + | scrollr.AddChild(layScroll); | |
- | //Create a sign-in layout | + | |
- | var layNew = app.CreateLayout( " | + | |
- | edtName = app.CreateTextEdit("", | + | |
- | edtName.SetHint(" | + | |
- | layNew.AddChild(edtName); | + | |
- | edtOrg = app.CreateTextEdit("", | + | |
- | edtOrg.SetHint(" | + | |
- | layNew.AddChild(edtOrg); | + | |
- | edtVehicle = app.CreateTextEdit("", | + | |
- | edtVehicle.SetHint(" | + | |
- | layNew.AddChild(edtVehicle); | + | |
- | edtReason = app.CreateTextEdit("", | + | |
- | edtReason.SetHint(" | + | |
- | layNew.AddChild(edtReason); | + | |
- | var btnCreate = app.CreateButton(" | + | |
- | btnCreate.SetOnTouch(btnCreate_OnClick); | + | |
- | layNew.AddChild(btnCreate); | + | |
- | + | ||
- | //Add sign-in layout to main layout | + | |
- | lay.AddChild(layNew); | + | |
- | | + | |
- | app.AddLayout( lay ); | + | var layNew = app.CreateLayout(" |
- | // | + | edtName = app.CreateTextEdit("", |
- | if(app.FileExists(jsonPath)){ | + | |
- | | + | layNew.AddChild(edtName); |
- | } | + | edtOrg = app.CreateTextEdit("", |
- | }//OnStart | + | |
+ | | ||
+ | edtVehicle = app.CreateTextEdit("", | ||
+ | edtVehicle.SetHint(" | ||
+ | | ||
+ | | ||
+ | | ||
+ | layNew.AddChild(edtReason); | ||
+ | var btnCreate = app.CreateButton(" | ||
+ | btnCreate.SetOnTouch(btnCreate_OnClick); | ||
+ | layNew.AddChild(btnCreate); | ||
- | function btnCreate_OnClick( ){ | + | |
- | app.HideKeyboard(); | + | lay.AddChild(layNew); |
- | var name = edtName.GetText(); | + | |
- | var org = edtOrg.GetText(); | + | |
- | var reg = edtVehicle.GetText(); | + | |
- | var reason = edtReason.GetText(); | + | |
- | | + | |
- | var errs = ""; | + | |
- | if ( name == "" | + | |
- | if ( reason == "" | + | |
- | if ( errs != "" | + | |
- | //bail out | + | |
- | app.Alert( errs + " | + | |
- | return; | + | |
- | } | + | |
- | // clear sign-in | + | |
- | edtName.SetText("" | + | |
- | edtOrg.SetText("" | + | |
- | edtVehicle.SetText("" | + | |
- | edtReason.SetText("" | + | |
- | // create a record | + | |
- | var obj = {}; | + | |
- | obj.name = name; | + | |
- | obj.org = org; | + | |
- | obj.reg = reg; | + | |
- | obj.reason = reason; | + | |
- | var d = new Date(); | + | |
- | obj.timeIn = d.toTimeString().slice(0, | + | |
- | obj.timeOut = " | + | |
- | // add this record | + | |
- | | + | |
- | saveJSONfile(); | + | |
- | // display record on scroller | + | |
- | layScroll.AddChild( | + | |
- | scrollr.ScrollTo(0, | + | |
- | }// | + | |
- | function btnOut_OnClick( ){ | + | |
- | | + | app.AddLayout(lay); |
- | if (this.GetText() != " | + | //check if today' |
- | //not yet, so record time out | + | |
- | var d = new Date(); | + | { |
- | this.obj.timeOut = d.toTimeString().slice(0,5); | + | loadJSONfile(); |
- | | + | } |
- | // | + | } //OnStart |
- | | + | |
- | }//btnOut_OnClick | + | |
- | function | + | function |
- | | + | |
- | var newlay = app.CreateLayout( " | + | app.HideKeyboard(); |
- | var txt = app.CreateText(obj.name, 0.15); | + | var name = edtName.GetText(); |
- | | + | var org = edtOrg.GetText(); |
- | | + | var reg = edtVehicle.GetText(); |
- | | + | var reason = edtReason.GetText(); |
- | | + | // |
- | | + | var errs = ""; |
- | | + | if (name == "" |
- | | + | |
- | txt = app.CreateText(obj.timeIn, 0.15); | + | if (errs != "" |
- | | + | { |
- | var btn = app.CreateButton(obj.timeOut, | + | //bail out |
- | btn.obj = obj; | + | |
- | btn.SetOnTouch(btnOut_OnClick); | + | return; |
- | | + | } |
- | | + | // clear sign-in form for next visitor |
- | }//recordLayout | + | edtName.SetText("" |
+ | edtOrg.SetText("" | ||
+ | | ||
+ | | ||
+ | // create a record | ||
+ | var obj = {}; | ||
+ | | ||
+ | obj.org = org; | ||
+ | obj.reg = reg; | ||
+ | obj.reason = reason; | ||
+ | var d = new Date(); | ||
+ | | ||
+ | obj.timeOut | ||
+ | // add this record to the array | ||
+ | recArray.push(obj); | ||
+ | | ||
+ | // display record on scroller | ||
+ | layScroll.AddChild(recordLayout(obj)); | ||
+ | | ||
+ | } //btnCreate_OnClick | ||
- | function | + | function |
- | //update copy of recArray on file | + | |
- | var s = JSON.stringify(recArray); | + | |
- | app.WriteFile(jsonPath, s ) | + | if (this.GetText() != " |
- | }// | + | //not yet, so record time out |
+ | | ||
+ | this.obj.timeOut = d.toTimeString().slice(0, 5); | ||
+ | | ||
+ | | ||
+ | | ||
+ | } // | ||
- | function | + | function |
- | //read copy of recArray from file | + | |
- | var s = app.ReadFile(jsonPath) | + | //create a new horizontal layout to display this record |
- | recArray = JSON.parse(s) | + | var newlay = app.CreateLayout(" |
- | var len = recArray.length; | + | var txt = app.CreateText(obj.name, |
- | for (var i=0; i< | + | newlay.AddChild(txt); |
- | var obj = recArray[i]; | + | txt = app.CreateText(obj.org, |
- | layScroll.AddChild( recordLayout(obj) ); | + | newlay.AddChild(txt); |
- | } | + | txt = app.CreateText(obj.reg, |
- | scrollr.ScrollTo(0, | + | newlay.AddChild(txt); |
- | }// | + | txt = app.CreateText(obj.reason, |
+ | newlay.AddChild(txt); | ||
+ | txt = app.CreateText(obj.timeIn, | ||
+ | newlay.AddChild(txt); | ||
+ | var btn = app.CreateButton(obj.timeOut, | ||
+ | btn.obj = obj; | ||
+ | btn.SetOnTouch(btnOut_OnClick); | ||
+ | newlay.AddChild(btn); | ||
+ | return newlay; | ||
+ | | ||
+ | |||
+ | function saveJSONfile() | ||
+ | { | ||
+ | //update copy of recArray on file | ||
+ | var s = JSON.stringify(recArray); | ||
+ | app.WriteFile(jsonPath, | ||
+ | } // | ||
+ | |||
+ | function loadJSONfile() | ||
+ | { | ||
+ | | ||
+ | var s = app.ReadFile(jsonPath) | ||
+ | recArray = JSON.parse(s) | ||
+ | var len = recArray.length; | ||
+ | for (var i = 0; i < len; i++) | ||
+ | | ||
+ | | ||
+ | layScroll.AddChild(recordLayout(obj)); | ||
+ | } | ||
+ | scrollr.ScrollTo(0, | ||
+ | } // | ||
</ | </ | ||
+ | ===== Notes ===== | ||
+ | This app was designed for a tablet. It is a replacement for an old paper form and is designed to be similar. | ||
+ | |||
+ | The final version is in use on a 7-inch tablet, which is mainly kept in landscape mode, though sometimes they rotate the tablet to make it easier to log-out a visitor who is way back the list. | ||
+ | |||
+ | At the suggestion of Jorge Ramirez, I have set the orientation to Landscape if it is being used on a phone. | ||
+ | |||
+ | The final version includes code to save previous files to a network server and the internal code to deal with date/time is significantly more robust, so that visitors who have not been logged out can be copied across to the live list as part of the backup process. | ||
+ | |||
+ | Please note. If this code is used with large numbers of records, the slow bit is displaying them all. For sizeable databases, the method of creating hundreds of layouts will need to be avoided. |