NS BASIC TUTORIAL: Learn Mobile Development - the easiest way to create apps For iPhone, iPad, Android, and mobile web
By: Nick Antonaccio Updated: 11-29-2011 This tutorial is best viewed with Chrome, Safari, or mobile Webkit based browsers. Linked app examples in this tutorial will run directly on screen if you are using one of those browsers. NOTE: This tutorial is written by a third party enthusiast, NOT by the company that created NS-Basic. Go to http://tech.groups.yahoo.com/group/nsbasic-app/ to ask questions in the community forum. Check out re-bol.com for a matching in depth REBOL programming tutorial,
and freeconsignmentsoftware.com to see a project written in it.
Contents:
1. Introducing NS Basic/App Studio
2. How This Tutorial Is Organized
3. Getting Started: Downloading and Installing NS Basic, Hello World
4. Several Simple Examples
5. Some Perspective for Absolute Beginners
6. A Quick Intro to the NS Basic Language
6.1 Built-In Functions and Basic Syntax
6.2 Concatenation
6.3 White Space and Comments
6.4 More Fundamentals
6.5 Basic Text Formatting
6.6 Saving Data
6.7 Times, Dates, and Common Data Types
7. Conditions
7.1 If
7.2 If/Else
7.3 If/ElseIf/Else
7.4 Multiple Conditions: "and", "or"
7.5 Select Case
8. GUIs (Program Windows)
8.1 Basics
8.2 A Little Sliding Puzzle Game
8.3 Adding More Features to the Sliding Puzzle Game
9. Arrays
9.1 Array()
9.2 Adding Items to an Array
9.3 Array Techniques
10. Loops
10.1 While/Wend and Do/Until
10.2 Looping Through Arrays: FOR and FOR EACH
10.3 Joining, Splitting, and Saving Arrays to localStorage
10.4 Displaying Items in an Array With a ComboBox - a Useful Simple Data Storage App
10.5 Using the Grid Widget to Display Array Data
11. SQLite Databases
11.1 Tables
11.2 SQL
11.3 A Complete Example - Database Info in a Grid
12. Strings
13. Global and Local Variables: Dim
14. Sending and Retrieving Data To/From Internet Servers
14.1 Form1.submit()
14.2 A Second Way to Submit Data
14.3 Receiving Data Back from a Server Application
14.4 A Complete NS Basic/Server CGI Application That Sends, Processes, and Returns Data
15. Metaprogramming: Execute and Eval
16. Quick Review and Synopsis
17. Built In Help and Documentation
18. EXAMPLE PROGRAMS - Learning How All The Pieces Fit Together
19. Additional Topics
20. REAL WORLD CASE STUDIES - Learning To Think In Code
20.1 A Generalized Approach Using Outlines and Pseudo Code
21. Other Scripts
1. Introducing NS Basic/App Studio
What is NS Basic/App Studio? Why use it?
- NS Basic/App Studio is a uniquely simple and productive development tool that can be used to create powerful apps for iPhone, iPad, Android, and other mobile web devices. The App Studio version of NS Basic is one of a family of products, all based on familiar Visual Basic language syntax and development patterns, which can be used to create native desktop, mobile (Windows CE, Palm, etc.), and web applications. In this tutorial, "NS Basic" refers to NS Basic/App Studio, used to create apps for iPhone, iPad, Android, Blackberry, and other mobile web devices.
- The NS Basic IDE (Integrated Development Environment) runs on MS Windows. It does not require a Macintosh computer, Objective-C, $99 Apple developer fee, Apple approval process, the 4 gigabyte iPhone SDK download, or any of the other requirements normally associated with iPhone/iPad development. Most other iPhone development environments, including cross-platform tools such as Ansca Corona, Rhodes, MoSync, etc. do require at least a Macintosh computer with the iPhone development kit installed, or commercial server services, to produce an iPhone app. Simple apps created by NS Basic can run just about everywhere, not just on iPhone and Android, but on all other modern mobile devices with a Webkit based browser (Blackberry, Symbian devices, Kindle, etc.) - and on any desktop machine too, as browser based apps. NS Basic can even be used as a tremendously simple web development tool. NS Basic apps can also easily make use of the PhoneGap Api to access additional native hardware and API functionality. The entire NS Basic development system installs quickly on Windows without any external packages required. It uses the simplest programming language available anywhere for mobile development (an extremely easy version of Visual Basic, and/or Javascript - your choice). It sports a fantastically easy and useful IDE, and one-click instant online application deployment to multiple mobile platforms, using a free server hosted by NS Basic, or your own web server. Apps can be downloaded by users instantly, and when installed, they look and operate just like native applications on each platform.
- The NS Basic demo version can be downloaded for free. The single file installation does not require you to install or configure Java, Android SDK, iPhone SDK or any other 3rd party packages. Just run the install program, and you can deploy your first application within seconds. There is no simpler way to create and distribute mobile apps.
- NS Basic includes GUI, graphics, sound, video, database, math, string, network, CGI, geolocation, and other functions built-in. No external libraries, modules, tool kits, SDKs, or IDEs are required for any essential functionality.
- NS Basic is easy enough for absolute beginners and average computer users to operate immediately, but powerful and rich enough for a wide variety of complex professional work.
- NS Basic has useful built-in help for all available functions, controls, properties, and language constructs.
- NS Basic is supported by a friendly and knowledgeable community of active developers around the world.
- NS Basic is made by a company with a long and well established record of success in the mobile development industry. Versions of NS Basic are available for Windows Mobile, Palm, and even the old Newton, as well as desktop Windows. Tens of thousands of developers have used NS Basic products.
- NS Basic can be picked up immediately by anyone who's used any form of Visual Basic. An entire community of developers can leverage their existing skills in this familiar and easy environment, to build useful mobile apps. If you're new to Visual Basic or even to programming in general, don't fret. NS Basic is a very simple subset of modern VB. You can read the entire API and the reference documentation in a single day. This tutorial will provide enough basic understanding, working code examples, and case studies to get you creating apps of all types, completely on your own.
Here are a few screen shots of examples covered in this tutorial:
Executables of these programs are available at the links below. You can run these apps directly on your iPhone, iPad, Android, Blackberry, or other mobile device by surfing to the links in your mobile browser. To turn them into genuine mobile apps, simply bookmark them and add to your mobile device home page. They will then look and act like any other native app, and they will run whether or not your device is connected to the Internet. You can also run these apps on your desktop computer in Chrome, Safari, and other Webkit based browsers:
http://ns-basic.com/puzzle/
http://ns-basic.com/timer/
http://ns-basic.com/notepad/
http://ns-basic.com/combobox/
http://ns-basic.com/grid1/
http://ns-basic.com/grid2_sqlite/
http://ns-basic.com/submit_cgi/
http://ns-basic.com/submit_array/
http://ns-basic.com/retrieve_cgi/
The NS Basic project files for each of the programs above are available at the following links (right click to download):
http://ns-basic.com/puzzle.nsx
http://ns-basic.com/timer.nsx
http://ns-basic.com/notepad.nsx
http://ns-basic.com/combobox.nsx
http://ns-basic.com/grid1.nsx
http://ns-basic.com/grid2_sqlite.nsx
http://ns-basic.com/submit_array.nsx
http://ns-basic.com/submit_cgi.nsx
http://ns-basic.com/retrieve_cgi.nsx
2. How This Tutorial Is Organized
There are several main parts to this text:
- Fundamentals:
The first sections cover how to use the NS Basic IDE (creating projects, building GUI forms visually, typing in code, navigating built-in help, deploying executable apps, etc.), basic language constructs and syntax (variables, functions, data types, conditions, arrays, loops, data storage) and other topics such as using SQLite, graphics, animation, sound, videos, posting info to web site CGI, Phonegap and 3rd party tool kits, parsing text, and more.
- Examples:
Several fully documented programs which demonstrate, line by line, how the above fundamentals are put together to form complete applications.
- Real World Case Studies:
This section of the tutorial is currently under construction. Several full case studies covering how a wide variety of complete applications were conceived and created using NS Basic. This section demonstrates, step by step, how each of the examples grew from concept to final design using outlines, pseudo code, and detailed finished code. Each example demonstrates a variety of practical NS Basic concepts, code patterns, and tools, and helps guide you towards "thinking in NS Basic".
- Additional Scripts and Resources:
More code and resources to help complete your understanding of NS Basic and continue learning (under construction).
This tutorial is less than 50 pages, yet it covers the NS Basic language from the ground up, fully documents the creation of 5 applications, and contains many additional short scripts and useful concepts. Links to other online documentation resources are provided to more fully learn many topics, but no third party reference materials are required to understand any example in this text, even if you've never programmed a line of code before. NS Basic's design provides straightforward solutions to reduce or eliminate the need for many complex coding techniques you may know. Every step of the way through this tutorial, you'll pick up practical approaches to easily achieve computing goals of all types. By learning NS Basic, you'll learn to get many things done more quickly and easily than you can with many other tools. Enjoy!
3. Getting Started: Downloading and Installing NS Basic, Hello World
The NS Basic IDE is a program that runs on your computer. It translates written text in the NS Basic language syntax ("source code") into instructions ("apps", "programs") which other users can run on their device. To get the free NS Basic demo, go to:
http://www.nsbasic.com/app/demo/
A download link will be emailed to you. Save the program to your hard drive, and then run the installation. Once you've got the NS Basic IDE installed and running on your computer, find it in Start -> Programs -> NS Basic App Studio -> NS Basic App Studio, click File -> New Project -> Save "Project1.nsx". Then in the Project Explorer, click Form1 -> Code. In the code area, type:
Print "Hello world!"
To save and run the program, click File -> Save Project, then Run -> Start in Desktop Browser. You can use keyboard shortcuts (CTRL-S and F5), and/or the dedicated toolbar icons to make this process faster. Your browser will open and display the running application.
NOTE: If you have any trouble previewing/running the application in your desktop browser, download and install Chrome, Safari, or another Webkit based browser.
To deploy the working Hello World application to your iPhone, Android, or other mobile device, click Run -> Deploy (or press the F6 key on your keyboard). The application will be uploaded to a free web server, and a web link to the app will be displayed. Surf to that link in your mobile device browser (Safari, or any Webkit based mobile browser), and your application will run. Save the bookmark to your mobile home screen, and the application will look and operate just like any native application written for your device. To see a visual guide of this entire process, go to http://www.nsbasic.com/app/tour/
Before going any further, give it a try. Download NS Basic and type in the code above to see how it works. It's extraordinarily simple and literally takes just a few seconds. To benefit from this tutorial, type or paste each code example into the NS Basic interpreter to see what happens.
4. Several Simple Examples
NS Basic apps are created by dragging "Widgets" (buttons, labels, text fields, drop down boxes, image containers and other clickable program controls), onto "Forms" in the NS Basic IDE. These items make up the "GUI" (Graphic User Interface) of your program. Forms appear as individual screens, tabs, or windows on the device where your app will run.
When you drag a widget onto your GUI form, you can adjust how it looks and acts by editing items in the PROPERTIES box of the NS Basic IDE. The following example program form simply contains a text area widget and a button. The "value" property of the button has been edited to "Save". Open a new project now by clicking File -> New Project -> (save it with any name you want), and re-create the following screen as closely as you can:
Now copy the following code into the form's "Code" editor, in NS Basic's PROJECT EXPLORER:
If localStorage.notepad = undefined Then localStorage.notepad = ""
Textarea1.value = localStorage.notepad
Function Button1_onclick()
localStorage.notepad = Textarea1.value
MsgBox "Saved"
End Function
Save the project and run the program in your local browser (be sure to set Chrome or Safari as your default browser). If you have any trouble, you can download the complete project file at http://www.ns-basic.com/notepad.nsx. You can try a working version of this app at http://www.ns-basic.com/notepad/ (if you are using Chrome, Safari, or a mobile Webkit based browser to view this page, you can view and run the live app directly from that link). This tiny program is a useful little notepad app that you can use to jot down and save important text information of any kind. You can use this app on iPhone, iPad, Andoid, and Blackberry devices, as well as in Chrome and Safari browsers on any desktop operating system. Up to 5 megabytes of text data can be saved. To permanently erase any saved data, simply delete your browser's cache.
Now open a new project and create the following screen. It contains two buttons and three Textbox widgets:
Add the following code to the form (click "Code" in the PROPERTIES area, then paste this text into the code editor):
currenttime = Now
Function Button1_onclick()
currenttime = Now
Text1.value = currenttime
End Function
Function Button2_onclick()
Text3.value = Now
timediff = DateDiff("s", currenttime, Now)
If timediff > 60 Then
minutes = Fix(timediff / 60)
seconds = timediff Mod 60
Text2.value = minutes + " minutes, " + seconds + " seconds"
Else
Text2.value = timediff + " seconds"
End If
End Function
If you have any trouble creating the form or adding the code, download and run the completed project from http://www.ns-basic.com/timer.nsx. You can try a working version of this app at http://www.ns-basic.com/timer/. This program is a useful timer that allows you to click start and end times, and tells the elapsed difference in minutes and seconds.
As you can see, NS Basic programs can be very fast and simple to create.
5. Some Perspective for Absolute Beginners
This tutorial moves at a pace quick enough to satisfy experienced developers, but it can also be understood clearly by beginners. If you're reading this text as a novice programmer, it can be helpful to understand a few basic concepts that provide perspective about learning to program. First:
Essentially, all computers do is let users input, store, retrieve, organize, share/transfer, manipulate, alter, view and otherwise deal with data in useful ways.
So, everything you'll do when writing code basically involves manipulating text, numbers, and/or binary data (photos, music, etc.). The fundamental components used to deal with data haven't changed too dramatically in the past few decades. They've simply improved in speed, capacity, and interface. In the current state of modern computing, data is typically input, manipulated, and returned via graphical user interfaces such as program windows, web forms displayed in browsers, and other keyboard/mouse/finger driven GUIs. Data is saved on local hard drives and storage devices (CDs, thumb drives, flash memory, etc.) and on remote web servers, and is typically transferred via local networks and Internet connections. Images, sounds, video, and other types of multimedia data are contained in standardized file formats, and graphic data is displayed using standard mathematical techniques. Knowing how to control those familiar computing elements to allow users to manipulate data, is the goal of learning to program. It doesn't matter whether you're interested in writing business applications to work with inventory and scheduling (text and number data), programs to alter web pages (text and image data), programs to play/edit music (binary data), programs to broadcast video across the Internet (rapidly transferred sequential frames of binary data), programs to control robotic equipment, compute scientific equations, play games, etc... They all require learning to input, manipulate, and return data of some sort. You can do all those things with NS Basic, and once you've done it in one language, it's easier to do with other programming tools.
NS Basic allows programmers to quickly build graphic interfaces to input and return all common types of data. It can easily display and manipulate text, graphics, and sounds in useful ways, and it provides simple methods to save, retrieve, and share data across networks and the Internet. That makes it a great way to begin learning how to program. By learning NS Basic, you'll learn about all the fundamental structures and concepts in programming: variables, functions, data types, conditional operations, loops, objects, etc. You'll also learn about important topics such as user interface design, algorithmic thinking, working with databases, 3rd party APIs, CGI, and more. Those topics all share conceptual and technical similarities, regardless of language, and you'll need to learn to think in those terms to write computer programs, even in a language that's as easy to learn as NS Basic. Despite its ease of use, NS Basic is a very powerful tool. You may never need to learn another programming language.
If you've never done any real "programming" before, the first part of this text may seem a bit technical. Don't be put off. There is no other mobile development language with a faster learning curve than NS Basic - you'll begin to see the big picture within a few days. Working through this tutorial, you'll gradually build recognition of NS Basic language idioms and practical code patterns, by example. The first part of the tutorial will be a whirlwind introduction to many of the fundamental language elements. Just take it all in, and if you really want to learn, be sure to type in, or at least copy/paste, each example into the NS Basic IDE. Reading through the code isn't enough.
6. A Quick Intro to the NS Basic Language
6.1 Built-In Functions and Basic Syntax
NOTE: Be sure to create a new NS Basic project and type (or copy/paste) these examples into the code window to see how they run:
As with any modern programming language, to use NS Basic, you need to learn how to use "functions" (also called "commands" or "methods"). Functions are words that perform actions. Function words are followed by data "parameters" (also called "arguments"). In NS Basic, parameters are typically enclosed in parentheses. Paste these functions into the NS Basic IDE to see how they work:
MsgBox ("MsgBox is a function. THIS TEXT IS ITS PARAMETER.")
MsgBox (LCase ("THE 'LCASE' FUNCTION CONVERTS TEXT TO LOWERCASE."))
Print ("That last line of code contains 2 functions: 'MsgBox' and 'LCase'")
The MsgBox and Print functions do not require parentheses around their text parameters:
MsgBox "MsgBox is a function. THIS TEXT IS ITS PARAMETER."
Print "This line of code contains 1 text parameter."
Some functions don't require any data parameters, but do produce "return" values. Try typing the following functions into the NS Basic code window. They each return a value selected by the user. The data entered by the user is stored in a variable - a word followed by an "=" sign. The variable can be used later in the program to represent the stored data. You can choose any combination of letters and numbers to use as variable words, as long as the variable starts with a letter. The variable words below are "loca", "name", and "currenttime" - their values are displayed in a message box, immediately after they are set:
loca = GetLocale()
MsgBox loca
currenttime = Time()
MsgBox currenttime
name = InputBox()
Print name
The return values output by the above functions can be used in your programs to accomplish useful goals. Text input by the user, for example, could be used to determine what operation the program should perform next, or it could potentially contain a value which is plugged into a mathematical formula, etc.
Many functions have optional or limited parameters/return values. Try these variations of the InputBox()function to see how they each perform differently:
name1 = InputBox ()
name2 = InputBox ("What is your name?")
name3 = InputBox ("What is your name?", "Question:", "John")
6.2 Concatenation
Concatenation is the joining together of pieces of text. In NS Basic, you can concatenate text using either the "+" or "&" symbols:
MsgBox ("Hello " + "World" + "!")
MsgBox ("Hello " & "World" & "!")
Concatenation is particularly useful when combining static text with data stored in variables or returned by functions. You will use code similar to the following in virtually every program you write:
MsgBox ("The current time is: " + Time())
name = InputBox ("What is your name?")
MsgBox ("Good to meed you " + name + "!")
6.3 White Space and Comments
NS Basic does not require line terminators at the ends of code lines, and you can insert empty white space (tabs, spaces, etc.) as desired into code. Text after a single quote (') and before a new line is treated as a comment (ignored entirely by the compiler). The code below works exactly the same as the previous similar example:
MsgBox ("The current time is " + Time()) ' joined data
6.4 More Fundamentals
As you've seen, In NS Basic the equal symbol ("=") is used to assign variables to values:
person = "John"
Along with functions, variables are perhaps the most fundamental, useful, and pervasive concepts in all programming, regardles of language. After the code above, the label "person" can be used anywhere (without the equal sign), to represent the text "John". Notice that the variable "person" has been rejoined with some other text below:
MsgBox ("The person's name is " + person)
Variable values can be changed at any point in a program - that is one of the main reasons for their use:
person = "Dave"
MsgBox ("The new person's name is " + person)
In NS Basic, variables are case sensitive (functions are not):
MsgBox person
MsgBox PERSON
MsgBox PeRsOn
' to the NS Basic compiler, the three lines above are NOT the same
In this next example, the variable label "username" is assigned to the value returned by the InputBox function (a username entered by the user):
username = InputBox ("Enter a User Name")
Now, the label "username" can be used to represent the username entered above:
MsgBox ("You entered: " + username)
Here's another similar example:
result = MsgBox("Really perform this action?", 1)
MsgBox ("You entered: " + result)
6.5 Basic Text Formatting
Multi-line formatted text is prepared by attaching an underscore character ("_") to the end of any line that continues on:
MsgBox "_
Line 1_
Line 2_
Line 3_
"
You can print a carriage return using the variable "vbCRLF":
MsgBox "Line 1" + vbCRLF + "Line 2" + vbCRLF + vbCRLF + "Line 3"
You can include quotes inside strings by tripling the quote character:
MsgBox """quoted text"""
6.6 Saving Data
In NS Basic, the "localStorage" object is used to save persistant data between usage sessions, in the same way that desktop data is typically saved to files. Use localStorage.yourVariableName to save and retrieve data. Try refreshing the following example to run it several times, then close your browser and run it again. You will see that all the data you entered has been saved. This is a tremendously important concept. To erase the data, clear your browser's cache:
result = InputBox("Enter some text:")
localStorage.somedata = localStorage.somedata + vbCRLF + result
MsgBox localStorage.somedata
6.7 Times, Dates, and Common Data Types
Time and date operations are simple in NS Basic. The following functions help to put date and time data into correct formats, and perform calculations upon them:
MsgBox Now ' display current Date and Time
MsgBox Date ' display current Date
MsgBox Time ' display current Time
MsgBox Month(Now)
MsgBox MonthName(Month(Now))
MsgBox Day(Date)
MsgBox WeekdayName(Day(Date))
MsgBox Minute(Now)
MsgBox "Now -45 seconds: " + DateAdd("s", -45, NOW)
MsgBox "Now +5 years: " + DateAdd("yyyy", 5, NOW)
birthday = InputBox("What date were you born?", "", "5/27/72")
birthday = CDate(birthday)
MsgBox "That was " + DateDiff("d", birthday, Now) + " days ago!"
MsgBox "Or " + DateDiff("n", birthday, Now) + " minutes ago!"
Interval values for the DateAdd and DateDiff functions are: yyyy (Year), q (Quarter), m (Month), y (Day of year), d (Day), w (Weekday), ww (Week of year), h (Hour), n (Minute), s (Second).
Data types can be specifically "cast" (assigned to different types) using the following "Cxxx" functions:
MsgBox CByte(99.44)
MsgBox CCur(9283.066) ' convert to money
MsgBox CDate("8/18/98") ' convert to date
MsgBox CDbl("3.141593") ' ...
MsgBox CInt("3.141593")
MsgBox CSng(10)
MsgBox CStr(TRUE)
A complete searchable list of functions built into NS Basic, along with examples of each function's use, is available by clicking Help -> Language Reference in the IDE. You can find a duplicate listing of the functions in the NS Basic Handbook (Help -> NS Basic/App Studio Handbook). Learning those built-in functions (the "API" of the language), is fundamental to becoming a capable NS Basic programmer. Read through the Language Reference now to familiarize yourself with the entire set of functions available in NS Basic - you can read it in a single sitting.
7. Conditions
Conditions are used to manage program flow ... to make "decisions" in your program. They are among the most important concepts in all types of programming.
7.1 If
The most basic conditional evaluation is "if":
If (this expression is true) Then
do this block of code
End If
' parentheses are NOT required
Math operators are typically used to perform conditional evaluations: = < > <> (equal, less-than, greater-than, not-equal):
If Hour(Now) > 12 Then
MsgBox "It's after noon."
End If
7.2 If/Else
If/Else chooses between two blocks of code to evaluate, based on whether the given condition is true or false. Its syntax is:
If (condition) Then
perform this code if the condition is true
Else
perform this code if the condition is false
End If
For example:
If Hour(Now) > 8 Then
MsgBox "It's time to get up!"
Else
MsgBox "You can keep on sleeping."
End If
These types of evaluations are found in just about every type of computer program:
username = InputBox ("Username:")
If username = "validuser" Then
MsgBox "Welcome back!"
Else
MsgBox "You are not a registered user."
End If
7.3 If/ElseIf/Else
You can choose between multiple evaluations of any complexity using the "If/ElseIf/Else" structure. If none of the cases evaluate to true, you can use "Else" to run some default code:
name = InputBox("What is your name?")
If InStr(name, "a") <> 0 Then
MsgBox "Your name contains the letter 'a'"
ElseIf InStr(name, "e") <> 0 Then
MsgBox "Your name contains the letter 'e'"
ElseIf InStr(name, "i") <> 0 Then
MsgBox "Your name contains the letter 'i'"
ElseIf InStr(name, "o") <> 0 Then
MsgBox "Your name contains the letter 'o'"
ElseIf InStr(name, "u") <> 0 Then
MsgBox "Your name contains the letter 'u'"
Else
MsgBox "Your name doesn't contain any vowels!"
End If
7.4 Multiple Conditions: "and", "or"
You can check for more than one condition to be true, using the "and" and "or" evaluations. Here's an example that gets a username and password from the user, tests that data using an "if" evaluation, and alerts the user if both responses are correct:
username = InputBox ("Username:")
password = InputBox ("Password:")
If username = "validuser" And password = "validpass" Then
MsgBox "Welcome back!"
Else
MsgBox "You are not registered!"
End If
This example reponds if the user chooses any one of three favorite colors:
color = InputBox ("What is your favorite color?")
If color = "blue" Or color = "red" Or color = "orange" Then
MsgBox "That's one of my favorite colors too!"
Else
MsgBox "We don't like any of the same colors :("
End If
7.5 Select Case
This evaluation allows you to compare as many values as you want against a main value, and run a selected block of code for any matching value, with an optional default block of code to be run if no matches are found:
favoriteDay = InputBox ("What's your favorite day of the week?")
Select Case favoriteDay
Case "Monday"
MsgBox "Monday is the worst! The work week begins..."
Case "Tuesday"
MsgBox "Tuesdays and Thursdays are both ok, I guess..."
Case "Wednesday"
MsgBox "The hump day - the week is halfway over!"
Case "Thursday"
MsgBox "Tuesdays and Thursdays are both ok, I guess..."
Case "Friday"
MsgBox "Yay! TGIF!"
Case "Saturday"
MsgBox "Of course, the weekend!"
Case "Sunday"
MsgBox "Of course, the weekend!"
Case Else
MsgBox "You didn't type in the name of a day!"
End Select
The conditional structures you've seen here will help your programs perform appropriate actions basic on user input, data content, and other potentially changing situations.
8. GUIs (Program Windows)
8.1 Basics
Program windows, also called "GUI"s (Graphic user interfaces), are incredibly easy to create in NS Basic. Simply drag the widgets (controls) you want onto a form, and adjust their properties to make them look and perform the way you want:
The "left", "top", "width", and "height" properties control the position and size of elements in a GUI layout. The "Value" property ("textContent" on some widgets) controls the text displayed on the widget. Try creating a new project now, drag a button onto a new form, as in the image above, and adjust the various properties to see how changing the values changes the look of the widget.
VERY IMPORTANT: You can have widgets perform functions when clicked, or when otherwise activated. The on____ properties of a widget control what action(s) the widget perform(s) when the user interacts with the widget. This is how you get your NS Basic programs to do something. Onclick() is the most common method:
Clicking this property will bring up the code editor with the function to perform when the widget is clicked by the user:
Function Button1_onclick()
End Function
You can put any code you want inside this function, and it will be performed any time the user clicks the widget:
Function Button1_onclick()
MsgBox "You clicked the button!"
End Function
You can also set various properties of a widget by referring to those properties in code. To see how this works, create a new project and make a form like the one below, with 1 button and 2 Textbox widgets. Edit the "Value" property of the button to read "Switch":
Now, select the onclick() property of the button, and add the following 3 lines to the onclick() function:
Function Button1_onclick()
temp = Text1.value
Text1.value = Text2.value
Text2.value = temp
End Function
The first line in the code above creates a "temp" variable to hold the text that's in Textbox 1 (referred to in code as "Text1.value"). The second line sets the text of the first Textbox (Text1.value) to be equal to the text that's in the second Textbox (Text2.value) - i.e., it copies Text2 to Text1. The third line sets the text in the second Textbox (Text2.value) to the value previously stored in the "temp" variable. This code, therefor, has the effect of swapping the 2 lines of text. Getting and setting text values from fields, text areas, and other widgets is a fundamentally important part of learning to create functional GUI program windows.
When writing code, you can use the "WidgetName.offsetLeft" and "WidgetName.offsetTop" properties to refer to the coordinate position of any widget. To move a widget with code, just set the "Widget.style.left" and "Widget.style.top" properties to new values. This technique is especially important in GUIs which involve movement, such as games. To see how it works, create a new project with two buttons:
Add the following code to the onclick() property of the second button:
Function Button1_onclick()
MsgBox "Start position, top: " + Button2.offsetTop
MsgBox "Start position, left: " + Button2.offsetLeft
Button2.style.left = "0px"
Button2.style.top = "30px"
MsgBox "New position, top: " + Button2.offsetTop
MsgBox "New position, left: " + Button2.offsetLeft
End Function
Notice that when moving the button, the Button2.style.left property is enclosed in quotes, and contains the characters "px" (it refers to a pixel location). The downloadable project file for this app is available at http://www.ns-basic.com/move_button.nsx, and the working example is at http://www.ns-basic.com/move_button/.
8.2 A Little Sliding Puzzle Game
This next example form simply contains 9 button widgets. The "height", "left", "top", and "width" properties have all been edited to size and position each widget into the tight grid you see. The "value" property of each button has also been edited to set the text on each button to a different number (1 to 8, on each individual button):
Open a new project now, and recreate the button arrangement above, as closely as you can. The width and height of each button should be 50 pixels, and the top and left positions of each button should be 50 pixels apart.
Now copy the following code into the form's "Code" editor, in NS Basic's PROJECT EXPLORER:
Function movebtn (currentbtn)
tempLeft = currentbtn.offsetLeft
tempTop = currentbtn.offsetTop
If ((Abs (tempLeft - Button9.offsetLeft) = 50) And _
(Abs (tempTop - Button9.offsetTop) = 0)) Or _
((Abs (tempLeft - Button9.offsetLeft) = 0) And _
(Abs (tempTop - Button9.offsetTop) = 50)) Then
currentbtn.style.left = Button9.offsetLeft + "px"
currentbtn.style.top = Button9.offsetTop + "px"
Button9.style.left = tempLeft + "px"
Button9.style.top = tempTop + "px"
End If
End Function
Function Button1_onclick()
movebtn (this)
End Function
Function Button2_onclick()
movebtn (this)
End Function
Function Button3_onclick()
movebtn (this)
End Function
Function Button4_onclick()
movebtn (this)
End Function
Function Button5_onclick()
movebtn (this)
End Function
Function Button6_onclick()
movebtn (this)
End Function
Function Button7_onclick()
movebtn (this)
End Function
Function Button8_onclick()
movebtn (this)
End Function
Notice a few things about this example code:
- A movebtn function is created in the beginning of the program. This function takes 1 parameter - the name of a button. This function is then executed in the onclick() method of each button, using the parameter "this". The word "this" is a way for an object to refer to itself. So, that function simply provides a way to write the code one time, and then run whenever any individual button is clicked, instead of having to copy the exact same code into each button's onclick() function.
- The 4 lines starting with "If" and ending with "Then" simply perform some math calculations to ensure that when a button is clicked, it is next to the empty space. The math computations evaluate whether or not a button's top and left coordinates are within 50 pixels of the blank button's (Button9's) coordinates. If that is the case, then the button's positions are swapped (the code that makes the swap occur should be familiar from the previous example). Math functions such as Abs() will be covered in depth in separate sections of this tutorial.
Save the project and run the program in your local browser. If you have any trouble, you can download the complete project file at http://www.ns-basic.com/puzzle_simplest.nsx. You can try a working version of this app at http://www.ns-basic.com/puzzle_simplest/. Run the program and play the game by sliding the pieces around the screen. Arrange them in descending numerical order in the fewest moves possible.
That's just the tip of the iceberg. With NS Basic, even absolute beginners can create nice looking, powerful graphic interfaces in minutes. A complete searchable list of GUI widgets built into NS Basic, along with examples of each widget's use and available properties and methods, is available by clicking Help -> Language Reference in the IDE. You can find a duplicate listing of the widgets, along with images of each, in the NS Basic Handbook. Learning how to use and control those widgets is fundamental to becoming a capable NS Basic programmer. Read through the Language Reference now to familiarize yourself with the entire set of widgets available in NS Basic - you can read it in a single sitting.
8.3 Adding More Features to the Sliding Puzzle Game
Now that we've got a fully working app, let's add a few features. Save your existing project with a new file name (click the File menu -> Save As -> (come up with a new name to save the project)). Add the following GUI widgets and make the changes shown below (the project file is available at http://ns-basic.com/puzzle.nsx):
To create the screen above:
- Move the existing button widgets to the middle of the screen.
- Add a Titlebar widget with the "rightButtonNames" property set to "Help" and the "rightButtonStyle" property set to "rightnav". The leftButtonNames and leftButtonStyle properties should both be erased (so that there is nothing in the property fields).
- Add a Label widget with the "textContent" property set to "Moves", color set to "blue", and the height, left, top, and width properties set to 20, 117, 225, and 165 (the size and position are not critical).
- Add another Label widget with the "textContent" property set to "0", color set to "black", and the height, left, top, and width properties set to 20, 183, 225, and 38 (again the size and position are not critical).
- Add a Textbox widget in approximately the position shown.
Next, click Project -> Add Form, and add the following widgets to the new GUI window form:
To create the screen above:
- Add a Titlebar widget with the "leftButtonNames" property set to "Play" and the "leftButtonStyle" property set to "leftnav". The rightButtonNames and rightButtonStyle properties should both be erased (so that there is nothing in the property fields).
- Add a Label widget with the "textContent" property set to "Instructions:", positioned approximately as shown.
- Add a Text Area widget with the approximate size and position shown, and the "value" property set to nothing (erased).
- Add a Button widget in approximately the position shown, with the "value" property set to "About".
Your app now has 2 totally separate GUI screens. To make the screens work together, click the "Code" link under the second form (in the Project Explorer), and add the following code. Be sure the following code gets added to the code area for the second GUI form (the help screen):
Function Button10_onclick()
MsgBox "NS Basic Sliding Puzzle Copyright (C) 2011, Nick Antonaccio"
End Function
Function TitleBar2_onclick(choice)
Form1.style.display="none"
Puzzle.style.display="block"
End Function
Now take a look at this code for the help screen. The first function should be familiar and easy to understand. When the user clicks the "About" button on that screen, a message box is displayed, showing copyright information about the program.
The onlick() function for the Titlebar demonstrates what needs to be done to switch displays between the first and second GUI screens. In our example, the first screen was labeled "Puzzle", and the second screen was left with the default label "Form1". Setting the help screen's "Form1.style.display" to "none" erases it from the screen (makes it invisible), and setting the first screen's "Form1.style.display" to "block" makes it visible. So, when the title bar icon labeled "Play" is clicked by the user, the game play screen is shown, and the game can be played. Very simple!
Next, click the "Code" icon under the first form (in the Project Explorer), and add the following code. Be sure the following code gets added in the code area for the first form (the game play screen) - separate from the code above:
counter = 0
If localStorage.lowscore = undefined Then localStorage.lowscore = "1000"
Text1.value = "Low Score: " + localStorage.lowscore
Function TitleBar1_onclick(choice)
If choice="Help" Then
Puzzle.style.display="none"
Form1.style.display="block"
Textarea1.value = "Click the numbers to slide the buttons_
into reverse order, 8 To 1._
Complete the Puzzle in as few moves as possible!_
To play again, refresh the page."
End If
End Function
Function movebtn (currentbtn)
tempLeft = currentbtn.offsetLeft
tempTop = currentbtn.offsetTop
If ((Abs (tempLeft - Button9.offsetLeft) = 50) And _
(Abs (tempTop - Button9.offsetTop) = 0)) Or _
((Abs (tempLeft - Button9.offsetLeft) = 0) And _
(Abs (tempTop - Button9.offsetTop) = 50)) Then
currentbtn.style.left = Button9.offsetLeft + "px"
currentbtn.style.top = Button9.offsetTop + "px"
Button9.style.left = tempLeft + "px"
Button9.style.top = tempTop + "px"
counter = counter + 1
Label2.textContent = counter
If counter > 999 Then
MsgBox "Too many moves - Game Over!"
Print "*** GAME OVER ***"
End If
End If
Checkend ()
End Function
Function Checkend ()
If Button8.offsetLeft = 75 And _
Button8.offsetTop = 50 And _
Button7.offsetLeft = 125 And _
Button7.offsetTop = 50 And _
Button6.offsetLeft = 175 And _
Button6.offsetTop = 50 And _
Button5.offsetLeft = 75 And _
Button5.offsetTop = 100 And _
Button4.offsetLeft = 125 And _
Button4.offsetTop = 100 And _
Button3.offsetLeft = 175 And _
Button3.offsetTop = 100 And _
Button2.offsetLeft = 75 And _
Button2.offsetTop = 150 And _
Button1.offsetLeft = 125 And _
Button1.offsetTop = 150 Then
msg = "Complete!"
If CInt(Label2.textContent) < CInt(localStorage.lowscore) Then
Text1.value = "Low Score: " + Label2.textContent
localStorage.lowscore = Label2.textContent
msg = msg + "You just achieved a new low score!"
End If
MsgBox msg
End If
End Function
Function Button1_onclick()
movebtn (this)
End Function
Function Button2_onclick()
movebtn (this)
End Function
Function Button3_onclick()
movebtn (this)
End Function
Function Button4_onclick()
movebtn (this)
End Function
Function Button5_onclick()
movebtn (this)
End Function
Function Button6_onclick()
movebtn (this)
End Function
Function Button7_onclick()
movebtn (this)
End Function
Function Button8_onclick()
movebtn (this)
End Function
Much of this code is taken directly from our existing simple game. Each button has an onclick() function which runs the "movebtn" function on itself, when clicked by the user - exactly as in our original simple game.
The following line sets a starting "counter" variable, which we'll use to count the number of moves the player makes before solving the puzzle:
counter = 0
These lines set the "localStorage.lowscore" object to a value of 1000, if it's never been set in previous games (if the stored value is "undefined"). The text of Textbox widget is then set to display the stored value (joined together with the text "Low Score:"):
If localStorage.lowscore = undefined Then localStorage.lowscore = "1000"
Text1.value = "Low Score: " + localStorage.lowscore
The onclick() function of the TitleBar1 widget hides the game play screen, shows the help screen, and then displays the help text in the TextArea widget (remember that the underscore simple simply allows you to enter single line text on multiple lines):
Puzzle.style.display="none"
Form1.style.display="block"
Textarea1.value = "Click the numbers to slide the buttons_
into reverse order, 8 To 1._
Complete the Puzzle in as few moves as possible!_
To play again, refresh the page."
The surrounding If choice="Help" Then... condition demonstrates how to select between different choices in the titlebar are clicked. In this case, the titlebar only has one option showing ("Help"), but if more options were available, you could use an If/ElseIf construct in the format above to react appropriately to the choice the user selects in the titlebar.
The movebtn() function starts out the same as in our original simple program, but adds a bit more new code. The following lines increment the "counter" variable every time a button is clicked, and then displays the number of moves in the Label2 text widget:
counter = counter + 1
Label2.textContent = counter
The following lines check if a given number of moves have been performed by the user (999, in this case). If so, a game over message is displayed, and the game is ended:
If counter > 999 Then
MsgBox "Too many moves - Game Over!"
Print "*** GAME OVER ***"
End If
Finally, every time a button is clicked, the Checkend() function is run.
The following lines of the Checkend() function check to see if the buttons are aligned as needed to end the game:
If Button8.offsetLeft = 75 And _
Button8.offsetTop = 50 And _
Button7.offsetLeft = 125 And _
Button7.offsetTop = 50 And _
Button6.offsetLeft = 175 And _
Button6.offsetTop = 50 And _
Button5.offsetLeft = 75 And _
Button5.offsetTop = 100 And _
Button4.offsetLeft = 125 And _
Button4.offsetTop = 100 And _
Button3.offsetLeft = 175 And _
Button3.offsetTop = 100 And _
Button2.offsetLeft = 75 And _
Button2.offsetTop = 150 And _
Button1.offsetLeft = 125 And _
Button1.offsetTop = 150 Then
If so (the buttons are arranged in reversed numerical order), then the following code is run:
msg = "Complete!"
If CInt(Label2.textContent) < CInt(localStorage.lowscore) Then
Text1.value = "Low Score: " + Label2.textContent
localStorage.lowscore = Label2.textContent
msg = msg + "You just achieved a new low score!"
End If
MsgBox msg
The If conditon in the code above checks to see if the current low score (the text in Label2 - set above), is lower than the value stored previously in localStorage.lowscore. If so, the Textbox is set to display the new low score, the value in localStorage.lowscore is set to the new low score, and the winning message is set to contain the text "You just achieved a new low score!".
That's it - a complete game with a familiar user interface, multiple screens, help info, about info, error checking, game state checking, saved high scores, and typical required logic, all in just a few minutes. You're well on your way to understanding how to create useful apps in NS Basic!
9. Arrays
In NS Basic, multiple pieces of grouped data items are stored in "arrays". Arrays are basically used to store lists of data.
9.1 Array()
There are several ways to create arrays in NS Basic. The first is to assign a variable label to the output of the "Array" function. The parameters of the array function are a list of strings, separated by commas:
MyList = Array("Monday", "Tuesday", "Wednesday", "Thursday", _
"Friday", "Saturday", "Sunday")
You can access the elements of an array by using incremental number indeces, starting with the number 0
MsgBox MyList(0)
MsgBox MyList(1)
MsgBox MyList(2)
MsgBox MyList(3)
MsgBox MyList(4)
MsgBox MyList(5)
MsgBox MyList(6)
MsgBox MyList(7) ' There is no 8th element here ('undefined')
9.2 Adding Items to an Array
You can also create arrays by first defining an empty array, and then adding indexed items, as follows:
months = []
months[0] = "January"
months[1] = "February"
months[2] = "March"
months[3] = "April"
months[4] = "May"
months[5] = "June"
months[6] = "July"
months[7] = "August"
months[8] = "September"
months[9] = "October"
months[10] = "November"
months[11] = "December"
MsgBox "The first month, at index [0], is: " + months[0]
MsgBox "The last month, at index [11], is: " + months[11]
9.3 Array Techniques
The "UBound" function can be used to count the number of items in an array:
lastMonth = UBound (months)
MsgBox "The last month, at index [" + lastMonth + "], is: " + months[lastMonth]
This is useful, for example, when adding new items to the end of a list, when you don't know how many items are in the array:
' add a new item to the end of the list:
months[lastMonth + 1] = "Not a month"
lastMonth = UBound (months)
MsgBox "The last month, at index [" + lastMonth + "], is: " + months[lastMonth]
10. Loops
"Loop" structures provide ways to methodically repeat actions, manage program flow, and automate lengthy data processing activities. They can also be used to step through lists of data in an array.
10.1 While/Wend and Do/Until
The "while" function repeatedly evaluates a block of code while the given condition is true. While loops are formatted as follows:
While (condition)
block of functions to be executed while the condition is true
Wend
This example counts to 5:
x = 1 'create an initial counter value
While x <= 5
MsgBox x
x = x + 1
Wend
In English, that code reads:
"x" initially equals 1
While x is less than or equal to 5:
display the value of x
then add 1 to the value of x
Repeat
You can use While/Wend to create forever repeating loops. Simply use an evaluation that is always true, and use the "Exit" function to end the loop. Notice how the While loop and If evaluations are indented to clearly separate the logic:
MsgBox "Please wait 5 seconds ..."
alarmtime = Second(Now) + 5
While 1 = 1 ' this is always true
Sleep 1000 ' wait 1 second
If Second(Now) = alarmtime Then
MsgBox "5 seconds have passed"
Exit While
End If
Wend
Here's a more interactive version using some info provided by the user:
eventname = InputBox ("What do you want to be reminded of?")
seconds = InputBox ("Seconds to wait:")
endtime = DateAdd ("s", seconds, Now)
MsgBox "It's now " + Now + ", and you'll be alerted in "_
+ seconds + " seconds."
While 1 = 1 ' this is always true
Sleep 1000 ' wait 1 second
If Now = endtime Then
MsgBox ("It's now " + endtime + ", and " + seconds_
+ " seconds have passed. It's time for: " + eventname)
Exit While
End If
Wend
10.2 Looping Through Arrays: FOR and FOR EACH
"FOR EACH" loops are used to do something to/with each item in an array:
counter = 0
For Each myMonth IN months
counter = counter + 1
MsgBox "Month " + counter + ": " + myMonth
Next
"FOR/Next" loops are another way to step through each item in an array, with some additional control. FOR loops simply count through a range of numbers:
For i = 0 To 6
MsgBox i
Next
You can use conditional tests within a For loop, to perform different operations on each item:
For i = 1 To 100
If (0 = i Mod 3) And (0 = i Mod 5) Then ' Mod checks the remainder
Print "fizzbuzz" ' of a division operation
ElseIf 0 = i Mod 3 Then
Print "fizz"
ElseIf 0 = i Mod 5 Then
Print "buzz"
Else
Print i
End If
Next
You can use this sequential counting ability of For loops to pick sequential items from an array, using numbered indexes:
For i = 0 To UBound(months) ' count from 0 to last index # in the array
MsgBox "Month " + (i + 1) + ": " + months[i]
Next
The "Step" option of a "For" loop allows you to skip a given number of items, each time through the loop:
For i = 0 To 12 Step 3 ' skip to every third number
MsgBox i
Next
And to count backwards:
For i = 5 To 1 Step -1 ' start on 5, end on 1, subtract 1
MsgBox i ' each time through the loop
Next
MsgBox "Blast off!"
"Step" is especially useful because it allows you to skip fields in an array:
For i = 0 To UBound(months) step 3
' count from 0 to the last item in the list, skipping by 3
MsgBox "Month " + (i + 1) + ": " + months[i]
Next
This technique is very useful when creating and using arrays of structured data. For example, the following array contains three fields of data for each person (name, address, and phone), in consecutive order. Pay particular attention to how the For/Next/Step loop is used to pick out blocks of 3 consecutive pieces of data from the array:
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
For i = 0 To UBound(myUsers) Step 3
MsgBox "Name: " + myUsers[i] + vbCRLF + _ ' current index (every 3rd field: name)
"Address: " + myUsers[i + 1] + vbCRLF + _ ' current index + 1 (next field: address)
"Phone: " + myUsers[i + 2] ' current index + 2 (next field: phone)
Next
The code pattern above is very useful when creating data management apps. Little data arrays such as the one above can hold all sorts of useful related blocks of data (phone books, recipes, etc.).
You can also use FOR loops to alter data in an array. The following example checks each phone number field in the myUsers array (every third item in the list, starting with the third item (index #2)). If any phone field is empty, it changes that field to "000-000-0000":
For i = 2 To UBound(myUsers) Step 3
If myUsers[i] = "" Then
myUsers[i] = "000-000-0000"
End If
Next
Print myUsers
10.3 Joining, Splitting, and Saving Arrays to localStorage
You can convert an array of data items to a single block of text (a "string"), using the "Join" function. The parameters required by the Join function are the array to be converted, and a character to be used to separate each item (the "delimiter"):
myText = Join (myUsers, "|") ' separate each item using the "pipe" symbol
MsgBox myText
You can save data in the joined string to localStorage.yourVariable as follows:
localStorage.myUsers = myText
Once you save the text to localStorage, you can close the app, and the data will remain stored on your device. You can then reopen the app at a later time, and convert the saved data back to an array by using the "Split" function to split the stored string at the given delimiter character:
myArray = Split(localStorage.myUsers, "|") ' split at the pipe symbol
For i = 0 To UBound(myArray) Step 3
MsgBox "Name: " + myArray[i] + vbCRLF + _
"Address: " + myArray[i + 1] + vbCRLF + _
"Phone: " + myArray[i + 2]
Next
This allows you to create simple apps which help users save all sorts of useful information collections: contact information, recipes, account information, web site passwords, etc.
10.4 Displaying Items in an Array With a ComboBox - a Useful Simple Data Storage App
Combo boxes (drop-down lists) are useful for allowing users to select items from a list. To see how they work, create a new project and add a ComboBox widget to the GUI form:
Now add the following code to the form, and run the program:
ComboBox1.children[0].options[0] = new Option("Item 1", "Item 1")
ComboBox1.children[0].options[1] = new Option("Item 2", "Item 2")
ComboBox1.children[0].options[2] = new Option("Item 3", "Item 3")
Next, add the following code to check which item has been selected by the user, and run the program again (try picking an item from the drop down list to see how the code below reacts):
Function ComboBox1_onchange()
a = ComboBox1.childNodes[0]
MsgBox a.value + " (index " + a.selectedIndex + ")"
End Function
To make comboboxes more useful, a "For" loop can be used to display a selectable list of data contained in an array. Try replacing the code above with the following code. Notice how the For loop is used to pick names from the myUsers array (every third item), which are then displayed in the ComboBox. When an item is selected from the list, the name, address, and phone of the selected person are picked out of the myUsers array:
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
counter = 0
For i = 0 To UBound(myUsers) Step 3
ComboBox1.children[0].options[counter] = new Option(myUsers[i], myUsers[i])
counter = counter + 1
Next
Function ComboBox1_onchange()
a = ComboBox1.childNodes[0]
MsgBox a.value + vbCRLF + myUsers[a.selectedIndex * 3 + 1] + vbCRLF + _
myUsers[a.selectedIndex * 3 + 2]
End Function
Now add 3 Labels and 3 TextBoxes to the form above:
And change the code for the program, as follows:
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
counter = 0
For i = 0 To UBound(myUsers) Step 3
ComboBox1.children[0].options[counter] = new Option(myUsers[i], myUsers[i])
counter = counter + 1
Next
Function ComboBox1_onchange()
a = ComboBox1.childNodes[0]
Text1.value = a.value
Text2.value = myUsers[a.selectedIndex * 3 + 1]
Text3.value = myUsers[a.selectedIndex * 3 + 2]
End Function
The onchange() function for the ComboBox above now picks out the appropriate items from the array, and displays them in the correct name, address, and phone number text fields.
To see how useful these array and looping techniques can be when combined with a ComboBox, add the following 3 buttons to the above form:
And change the form's code to the following:
If localStorage.myUsers = undefined Then
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
Else
myUsers = Split(localStorage.myUsers, "|")
End If
Function refreshComboBox()
counter = 0
For i = 0 To UBound(myUsers) Step 3
ComboBox1.children[0].options[counter] = new Option(myUsers[i], myUsers[i])
counter = counter + 1
Next
End Function
refreshComboBox()
Function ComboBox1_onchange()
a = ComboBox1.childNodes[0]
Text1.value = a.value
Text2.value = myUsers[a.selectedIndex * 3 + 1]
Text3.value = myUsers[a.selectedIndex * 3 + 2]
End Function
Function Button1_onclick()
tail = UBound(myUsers)
myUsers[tail + 1] = Text1.value
myUsers[tail + 2] = Text2.value
myUsers[tail + 3] = Text3.value
refreshComboBox()
MsgBox "Added"
End Function
Function Button2_onclick()
localStorage.myUsers = Join(myUsers, "|")
MsgBox "Saved"
End Function
Function Button3_onclick()
For i = 0 To UBound(myUsers) Step 3
If myUsers[i] = Text1.value Then
If vbYes = MsgBox("Really erase?", 1) Then
myUsers[i] = ""
myUsers[i + 1] = ""
myUsers[i + 2] = ""
End If
End If
Next
refreshComboBox()
End Function
There's quite a bit going on in that code, and each of the functions demonstrates a code pattern that you'll likely be able to use elsewhere. Let's take a look through it in depth to see how everything works.
The program starts out with an "If" evaluation to check if any data has previously been saved by the program. If not (if the localStorage variable is "undefined"), it creates a new array. Otherwise, it loads the saved array:
If localStorage.myUsers = undefined Then
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
Else
myUsers = Split(localStorage.myUsers, "|")
End If
Next, a function is created to refresh the GUI ComboBox. A counter is used, along with a For/Step loop, to pick out only the names (every 3rd item) from the myUsers array, and display them in the ComboBox:
Function refreshComboBox()
counter = 0
For i = 0 To UBound(myUsers) Step 3
ComboBox1.children[0].options[counter] = new Option(myUsers[i], myUsers[i])
counter = counter + 1
Next
End Function
Then, the above function is executed, so that the ComboBox displays the current user data:
refreshComboBox()
Whenever an item from the ComboBox is selected by the user, the following function chooses the selected data (the name), plus the address and the phone number, and displays each in a separate TextBox. The index is multiplied by 3, because the name fields are found every third item in the list, then 1 and 2 are added to the current index position, to display the next and the next next pieces of data in the array (the address and phone):
Function ComboBox1_onchange()
a = ComboBox1.childNodes[0]
Text1.value = a.value
Text2.value = myUsers[a.selectedIndex * 3 + 1]
Text3.value = myUsers[a.selectedIndex * 3 + 2]
End Function
Whenever the user clicks the "Add" button, the following function first determines the number of items in the user array (UBound(myUsers)), and assigns the variable "tail" to that number. Then it adds the name, address, and phone text strings to the index positions 1, 2, and 3 positions past the tail position in the array (i.e., to the end of the list, in the tail+1, tail+2, and tail+3 positions). The ComboBox is refreshed to display the new data, and a confirmation message is displayed to the user:
Function Button1_onclick()
tail = UBound(myUsers)
myUsers[tail + 1] = Text1.value
myUsers[tail + 2] = Text2.value
myUsers[tail + 3] = Text3.value
refreshComboBox()
MsgBox "Added"
End Function
When the user clicks the "Save" button, the array is converted to a string of text separated by the pipe symbol ("|"). That string is then saved to localStorage, so that the application can be closed without losing data (remember how the application began, with this data being loaded, if it exists), and then a confirmation message is displayed to the user:
Function Button2_onclick()
localStorage.myUsers = Join(myUsers, "|")
MsgBox "Saved"
End Function
When the "Clear" button is clicked by the user, the following function executes a "For" loop to compare all the names in the array against the current name in TextBox 1. If a match is found, the user is asked to confirm the erase process, using a MsgBox question. If the user confirms, three sequential items in the array, at indexes i, i+1, and i+2 (the items at the current index, the next, and the next one after that) are all set to blank, and the ComboBox is refreshed to display the change:
Function Button3_onclick()
For i = 0 To UBound(myUsers) Step 3
If myUsers[i] = Text1.value Then
If vbYes = MsgBox("Really erase?", 1) Then
myUsers[i] = ""
myUsers[i + 1] = ""
myUsers[i + 2] = ""
End If
End If
Next
refreshComboBox()
End Function
You can extend the techniques in this example to build interfaces for saving and retrieving all sorts of useful information in address, recipe, account info, and other simple data storage apps.
10.5 Using the Grid Widget to Display Array Data
The Grid ("table") widget enable simple display and manipulation of columns and rows of data. To see how a grid widget works, create a new project and drag the widget onto a blank form. Edit the grid's properties as follows: cols 3; colWidths 110,120,90; height 300; rows 14; titles name,address,phone; width 320:
We'll fill the grid with the same array of data that we used in the previous section:
If localStorage.myUsers = undefined Then
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
Else
myUsers = Split(localStorage.myUsers, "|")
End If
To fill the grid with data, add the following For loop to the form's code. Notice that the Grid1.setValue() function is what does the actual work of filling the grid with values:
count = 1
For row = 0 To UBound(myUsers) step 3
Grid1.setValue(count,0,myUsers[row])
Grid1.setValue(count,1,myUsers[row+1])
Grid1.setValue(count,2,myUsers[row+2])
count = count + 1
Next
To make the grid respond to user clicks, the grid's onclick() function can make use of the Grid1.getValue() function. The event.target.id holds the information about which grid, row, and column were clicked:
Function Grid1_onclick()
s = Split(event.target.id, "_")
MsgBox "row " + s(1) + ", column " + s(2) + ", " + Grid1.getValue(s(1),s(2))
End Function
Here's the whole program. Keep this code close at hand - it's really useful for displaying and manipulating any type of tabular data:
If localStorage.myUsers = undefined Then
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
Else
myUsers = Split(localStorage.myUsers, "|")
End If
count = 1
For row = 0 To UBound(myUsers) step 3
' MsgBox(myUsers[row] + ", " + myUsers[row+1] + ", " + myUsers[row+2])
Grid1.setValue(count,0,myUsers[row])
Grid1.setValue(count,1,myUsers[row+1])
Grid1.setValue(count,2,myUsers[row+2])
count = count + 1
Next
Function Grid1_onclick()
s = Split(event.target.id, "_")
MsgBox "row " + s(1) + ", column " + s(2) + ", " + Grid1.getValue(s(1),s(2))
End Function
You can find this working application at http://ns-basic.com/grid1/ and the project file at http://ns-basic.com/grid1.nsx.
11. SQLite Databases
One of the most powerful features of NS Basic is its built-in support for SQLite. SQLite is a small, self contained relational database system that allows you to store, retrieve, search, sort, compare, and otherwise manipulate large stores of data, very quickly and easily. SQLite is used as the main data storage system in the iPhone, Android, and other portable devices, and is supported on all platforms for which NS Basic can deploy applications (including desktop Webkit based browsers such as Chrome and Safari). Users of apps built with NS Basic do not need to install SQLite - it's already there by default on all the platforms which NS Basic supports.
Keep in mind that programming, and the use of computing devices in general, is ultimately about managing data, so learning to use SQLite is fundamentally useful in becoming a capable NS Basic programmer.
11.1 Tables
In SQLite and other databases, data is stored in "tables". Tables are made up of columns of related information. A "Contacts" table, for example, may contain name, address, phone, and birthday columns. Each entry in the database can be thought of as a row containing info in each of those column fields:
name address phone birthday
---- ------- -------- --------
John Smith 123 Toleen Lane 555-1234 1972-02-01
Paul Thompson 234 Georgetown Place 555-2345 1972-02-01
Jim Persee 345 Portman Pike 555-3456 1929-07-02
George Jones 456 Topforge Court 1989-12-23
Tim Paulson 555-5678 2001-05-16
11.2 SQL
"SQL" statements let you work with data stored in database tables. Some SQL statements are used to create, destroy, and fill columns with data:
CREATE TABLE table_name ' create a new table of information
DROP TABLE table_name ' delete a table
INSERT INTO table_name VALUES (value1, value2,....) ' add data
INSERT INTO Contacts
VALUES ('Billy Powell', '5 Binlow Dr.', '555-6789', '1968-04-19')
INSERT INTO Contacts (name, phone)
VALUES ('Robert Ingram', '555-7890')
The following SQL code will create the Contacts table illustrated above:
INSERT into Contacts VALUES
('John Doe', '1 Street Lane', '555-9876', '1967-10-10'),
('John Smith', '123 Toleen Lane', '555-1234', '1972-02-01'),
('Paul Thompson', '234 Georgetown Pl.', '555-2345', '1972-02-01'),
('Jim Persee', '345 Portman Pike', '555-3456', '1929-07-02'),
('George Jones', '456 Topforge Court', '', '1989-12-23'),
('Tim Paulson', '', '555-5678', '2001-05-16')
The SELECT statement is used to retrieve information from columns in a given table:
SELECT column_name(s) FROM table_name
SELECT * FROM Contacts
SELECT name,address FROM Contacts
SELECT DISTINCT birthday FROM Contacts ' returns no duplicate entries
To perform searches, use WHERE. Enclose search text in single quotes and use the following operators: ; =, <>, >, <, >=, <=, BETWEEN, LIKE (use "%" for wildcards):
SELECT * FROM Contacts WHERE name='John Smith'
SELECT * FROM Contacts WHERE name LIKE 'J%' ' any name starting with "J"
SELECT * FROM Contacts WHERE birthday LIKE '%72%' OR phone LIKE '%34'
SELECT * FROM Contacts
WHERE birthday NOT BETWEEN '1900-01-01' AND '2010-01-01'
IN lets you specify a list of data to match within a column:
SELECT * FROM Contacts WHERE phone IN ('555-1234','555-2345')
SELECT * FROM Contacts ORDER BY name ' sort results alphabetically
SELECT name, birthday FROM Contacts ORDER BY birthday, name DESC
Other SQL statements:
UPDATE Contacts SET address = '643 Pine Valley Rd.'
WHERE name = 'Robert Ingram' ' alter or add to existing data
DELETE FROM Contacts WHERE name = 'John Smith'
DELETE * FROM Contacts
ALTER TABLE ' change the column structure of a table
CREATE INDEX ' create a search key
DROP INDEX ' delete a search key
There are many tutorials available online to help learn the SQL language, and SQLite, in greater depth. Take a look at http://zetcode.com/databases/sqlitetutorial for more information.
To open an SQLite database, use the following code. The file name can be anything you choose, and all the other parameters are optional. If the database file does not exist, it will be created:
db = SqlOpenDatabase("myData.db", "1.0", "My Data")
If db = 0 Then MsgBox "Error opening database"
SQL commands should be formatted into an array. You can define your own functions to handle successful and failed SQL commands. The dbSuccess function below is very important. It demonstrates how to use a For loop to retreive and display data from an SQL SELECT command:
sqlList = Array()
sqlList(0) = "CREATE TABLE IF NOT EXISTS myData('name', 'address', 'phone', PRIMARY KEY('name'));"
sqlList(1) = "INSERT INTO myData (name, address, phone) VALUES ('Steve Thomas', '14 Ty Lane', '442-2351');"
sqlList(2) = "INSERT INTO myData (name, address, phone) VALUES ('Ryan Pengo', '3 Surf Dr.', '536-3214');"
sqlList(3) = ["SELECT * from myData;", dbSuccess, dbFail]
Function dbSuccess (transaction, results)
For i = 0 To (results.rows.length - 1)
Print results.rows.item(i)["name"]
Print results.rows.item(i)["address"]
Print results.rows.item(i)["phone"]
Next
End Function
Function dbFail (transaction, results)
MsgBox "Error - SQL Failed: " + transaction
End Function
To execute the SQL commands, use the Sql function, with the database ID and SQL command array as parameters:
Sql(db, sqlList)
Here's a complete example that opens a database, creates a new "myData" table, inserts data into the table, and then retrieves and prints all the contents of the table:
db = SqlOpenDatabase("data.db", "1.0", "My Data")
If db = 0 Then
MsgBox "Error opening db"
End If
sqlList = Array()
sqlList(0) = "CREATE TABLE IF NOT EXISTS myData('name', 'address', 'phone', PRIMARY KEY('name'));"
sqlList(1) = "INSERT INTO myData (name, address, phone) VALUES ('Steve Thomas', '14 Ty Lane', '442-2351');"
sqlList(2) = "INSERT INTO myData (name, address, phone) VALUES ('Ryan Pengo', '3 Surf Dr.', '536-3214');"
sqlList(3) = ["SELECT * from myData;", dbSuccess, dbFail]
Sql (db, sqlList)
Function dbSuccess (transaction, results)
For i = 0 To (results.rows.length - 1) ' results.rows.length is like uBound with arrays
Print results.rows.item(i)["name"]
Print results.rows.item(i)["address"]
Print results.rows.item(i)["phone"]
Next
End Function
Function dbFail (transaction, results)
MsgBox "Error - SQL Failed: " + transaction
End Function
11.3 A Complete Example - Database Info in a Grid
You can display and work with data retrieved from a database in the all the same ways that you've already seen with arrays (display it in drop down boxes, tables, etc.). Here's a variation of the previous grid example which creates an SQLite database, and then displays the data in a grid. This is very useful code which can serve as a basic model for creating many types of basic data storage apps:
db = SqlOpenDatabase("data.db", "1.0", "My Data")
If db = 0 Then
MsgBox "Error opening db"
End If
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
sqlList = Array()
' sqlList(0)="drop table mydata"
sqlList(0) = "CREATE TABLE IF NOT EXISTS myData('name', 'address', 'phone', PRIMARY KEY('name'));"
count = 1
For i = 0 To UBound(myUsers) step 3
sqlList(count) = "INSERT into myData (name,address,phone) VALUES " + _
"('" + myUsers[i] + "', '" + myUsers[i+1] + "', '" + myUsers[i+2] + "');"
count = count + 1
Next
sqlList(count) = ["SELECT * from myData;", dbSuccess, dbFail]
' Print Join (sqlList, "|")
Sql (db, sqlList)
Function dbSuccess (transaction, results)
count = 1
For i = 0 To (results.rows.length - 1)
Grid1.setValue(count,0,results.rows.item(i)["name"])
Grid1.setValue(count,1,results.rows.item(i)["address"])
Grid1.setValue(count,2,results.rows.item(i)["phone"])
count = count + 1
Next
End Function
Function dbFail (transaction, results)
MsgBox "Error - SQL Failed: " + transaction
End Function
Function Grid1_onclick()
s = Split(event.target.id, "_")
MsgBox "row " + s(1) + ", column " + s(2) + ", " + Grid1.getValue(s(1),s(2))
End Function
You can find this working application at http://ns-basic.com/grid2_sqlite/ and the project file at http://ns-basic.com/grid2_sqlite.nsx.
For more info about SQLite, be sure to open the example projects "SqlSample1.nsx" and "SqlSample2.nsx", and read Tech Note 15 in the built-in help.
12. Strings
A "string" is simply a series of characters. Take a look at the following examples to see how to do a few common text operations:
theString = "abcdefghijklmnopqrstuvwxyz"
' Left String: (get the left 7 characters of the string):
Left(theString, 7)
' Right String: (Get the right 7 characters of the string):
Right(theString, 7)
' Mid String 1: (get 7 characters from the middle of the string,
' starting with the 12th character):
Mid(theString, 12, 7)
' Mid String 2: (get 7 characters from the middle of the string,
' starting 7 characters back from the letter "m"):
pos = InStr(theString, "m") ' the index position of "m"
MsgBox Mid(theString, pos - 7, 7)
' get just the 7th character:
Mid(theString, 7, 1)
' Change "cde" to "123"
Replace(theString, "cde", "123")
' Compare the alphabetical order of 2 strings:
a = StrComp(theString, "abd")
MsgBox a ' -1 means 1st string is lower
' Determine the number of characters in the string:
Len(theString)
' Change the 7th character to "7"
q = Len(theString)
x = Left(theString, 6)
y = Right(theString, q - 7)
theString = x + "7" + y
MsgBox(theString)
' Remove 15 characters, starting at the 3rd position:
q = Len(theString)
x = Left(theString, 3)
y = Right(theString, q - (3 + 15))
theString = x + y
MsgBox(theString)
' Insert 15 characters, starting at the 3rd position:
q = Len(theString)
x = Left(theString, 3)
y = Right(theString, q - 3)
theString = x + "defghijklmnopqr" + y
MsgBox(theString)
' Create a string of 10 repeating characters:
String(10, "i")
' Get the ASCII value for "c" (ASCII 99):
Asc("C")
' Get the character for ASCII 99 ("c"):
Chr(99)
' Convert a number value to a string:
CStr(99434)
' Convert the string to upper case:
UCase(theString)
' Convert the string to lower case:
LCase(theString)
13. Global and Local Variables: Dim
By default, values used inside functions are treated as global, which means that if any variables are changed inside a function, they will be changed throughout the rest of your program:
x = 10
Function changeXglobally (y, z)
x = y + z
MsgBox "Inside the function, X is: " + x
End Function
changeXglobally (10, 20)
MsgBox "Outside the function, X is: " + x ' x has changed to 30
You can change this default behavior, and specify that any value be treated as local (NOT changed throughout the rest of your program), by using "Dim" inside the function:
x = 10
Function changeXlocally (y, z)
Dim x
x = y + z
MsgBox "Inside the function, X is: " + x
End Function
changeXlocally (10, 20) ' inside the function, x is now 30
' outside the function, x is still 10
MsgBox "Outside the function, X is: " + x
14. Sending and Retrieving Data To/From Internet Servers
NOTE: This section of the tutorial requires some knowledge of server side programming. In order to transfer data between your NS Basic app and an Internet application, you must learn some basics of either PHP, ASP, or CGI with Python, Ruby, Perl, or some other programming language that allows for processing of GET and/or POST data submissions. Several of this author's other tutorials teach that topic: http://re-bol.com/rebol.html#section-9.9 and http://re-bol.com/cgi_tutorial.txt, using the REBOL language. There are plenty of other tutorials online for any programming language of your choice. Just search Google for "CGI tutorial (your favorite programming language)".
14.1 Form1.submit()
NS Basic has a built-in function that submits all data in named text widgets on a given form. To the server, data sent by the following function appears just like data submitted from HTML forms on a web page:
Form1.submit()
In order to see how this works, create a form with a TextArea widget and a button.
Add the following onclick() function to the button:
Function Button1_onclick()
Form1.submit()
End Function
Next, be sure to change the NAME property of the TextArea (give the widget a new name). NS Basic will only submit data from widgets which have had the NAME property changed from the default (i.e., from "Textarea1", in this case):
Now click Form1 in the NS Basic Project Explorer, and change the URL property to "http://ns-basic.com/save.cgi". You can also chose between GET and POST methods of submission by editing the "method" property ("POST" is generally a better way to send data, but handling POSTed data may require more code in your server application):
This project can be found at http://ns-basic.com/submit_cgi/ and http://ns-basic.com/submit_array.nsx
The code for the application referenced above, at http://ns-basic.com/save.cgi, is as follows (this is REBOL CGI server code, but you could use the equivalent PHP, ASP, Python, Ruby, Perl, etc., to process the submitted data):
#!../rebol276 -cs
REBOL []
print {content-type: text/html^/}
print {<HTML><HEAD><TITLE>Data Submitted By NS Basic</TITLE></HEAD><BODY>}
submitted: decode-cgi system/options/cgi/query-string
foreach item submitted [
print rejoin [item {<br>}]
]
print {</BODY></HTML>}
Here's a version of the above server application which saves the submitted data to a text file on the web server:
#!../rebol276 -cs
REBOL []
print {content-type: text/html^/}
print {<HTML><HEAD><TITLE>Data Submitted By NS Basic</TITLE></HEAD><BODY>}
submitted: decode-cgi system/options/cgi/query-string
write/append %saved_cgi.txt rejoin [newline submitted/2]
print {Saved!</BODY></HTML>}
To see how this server application works, try changing the URL property of Form1 in the above NS Basic app to "http://ns-basic.com/save2.cgi". Run the app, type and submit some data, then look at the saved results by surfing to http://ns-basic.com/saved_cgi.txt (this is the file to which data is written, in the above server application code above).
14.2 A Second Way to Submit Data
The following code does essentially the same thing as the Form.submit() function. The difference is, the .submit() function requires data to be entered into a named TextArea. Text areas can have their hidden property set, so the the area does not appear visually, but this technique is a bit more straightforward to use:
src="http://mysite.com/my.cgi?" + myString
Print "<iframe src=" & src & "></iframe>"
The following NS Basic app uses the Join() function to convert an array of data to a string (just as you've seen in the earlier section about arrays). That data is then submitted directly to a server application, to be saved, displayed, or used in any other way on the server. Notice the Escape() function in the following code. It's used to automatically convert spaces and other characters into a format that's usable in GET and POST data submissions:
Sub Main
myUsers = Array("John Smith", "123 Tomline Lane Forest Hills NJ", "555-1234", _
"Paul Thompson", "234 Georgetown Pl. Peanut Grove AL", "555-2345", _
"Jim Persee", "345 Pickles Pike Orange Grove FL", "555-3456", _
"George Jones", "456 Topforge Court Mountain Creek CO", "", _
"Tim Paulson", "", "555-5678")
myUsers = Join(myUsers, "|")
src = "http://ns-basic.com/submit_array.cgi?x=" + Escape(myUsers)
Print "<iframe src=" & src & "></iframe>"
End Sub
Create a new project and copy the above code into a Main() subroutine in the "Project Properties and Global Code" section of NS Basic's Project Explorer. The Main() function runs every time an NS Basic app starts:
This project can be found at http://ns-basic.com/submit_array/ and http://ns-basic.com/submit_array.nsx
Here's some example REBOL CGI code which demonstrates how the submitted data above can be split into an array (a "block" in REBOL), using REBOL's "parse" function (REBOL's parse function does basically the same thing as NS Basic's Split() function). That split data is then displayed by the server, in the user's browser. This server application is found at the link in the above NS Basic code (http://ns-basic.com/submit_array.cgi):
#!../rebol276 -cs
REBOL []
print {content-type: text/html^/}
print {<HTML><HEAD><TITLE>Data Submitted By NS Basic</TITLE></HEAD><BODY>}
submitted: decode-cgi system/options/cgi/query-string
my-users: parse/all submitted/2 "|"
foreach [name address phone] my-users [
print rejoin ["Name: " name "<br>"]
print rejoin ["Address: " address "<br>"]
print rejoin ["Phone: " phone "<br><br>"]
]
print {</BODY></HTML>}
Depending on your needs, you could also choose to save the submitted data to a database, save it to a file, send it in an email, or otherwise process, sort, search, manipulate, display it, etc. in useful ways on your web server. You can see that by learning just a minimal amount about processing HTML forms submitted via GET and POST, you can learn to make valuable use of data collected and submitted via NS Basic applications, on any server platform that supports a web server and your favorite server development language.
14.3 Receiving Data Back from a Server Application
In order for an NS Basic app to receive data from a server application, the NS Basic app must be deployed to a distinct URL location. The server application will run a completely new and restarted instance of your NS Basic app at the given location, with the desired data submitted to that restarted app. The restart that occurs will refresh any data and/or settings saved in the current state of the NS Basic app, so be sure to save any data before sending data from a server application.
There are several ways to redirect the output of a server program back to an NS basic app. The first is to set the redirect location in the HTTP header:
print "HTTP/1.1 303 See Other"
print "Location: http://ns-basic.com/retrieve_cgi?name=Nick%20Antonaccio&address=1%20Lane%20Way")
In the code above, the "Location" is set to the URL of your deployed NS Basic app. The retrieved data follows a question mark ("?") after the URL. Variable names and their data are separated by equal signs ("="), and those variable/value pairs are separated by the ampersand symbol ("&"). Spaces and other characters should be converted using the equivalent of NS Basic's Escape() function (in REBOL, you can use the "to-url" function). So in the example above, 2 variables are sent back to the NS Basic app:
name = "Nick Antonaccio"
address = "1 Lane Way"
To use the data sent by the above server application, use the GetURLParameter() function in NS Basic. Put that function in the Main() subroutine, as follows:
print "Name: " + GetURLParameter("name")
print "Address: " + GetURLParameter("address")
Another way to redirect data back to the
print rejoin [
{<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://ns-basic.com/retrieve_cgi/index.html?name=}
(to-url submitted/2) {&addr=} (to-url submitted/4) {">}
]
14.4 A Complete NS Basic/Server CGI Application That Sends, Processes, and Returns Data
Here's an entire application to demonstrate the process of sending, processing and returning data to/from NS Basic and a server CGI application. First, create a new NS Basic project with 2 labels, 2 TextBoxes, and 1 button. Change the "name" property of the first TextBox to "name", and the name of the second Textbox to "addr":
Change the URL property of Form1 to "http://ns-basic.com/submit_array2.cgi":
Add the following code to the Project Properties and Global Code:
Sub Main
myname = GetURLParameter("name")
If myname <> "" Then
MsgBox "THIS DATA HAS BEEN SAVED TO THE WEB SITE:" + vbCRLF + vbCRLF + _
"Name: " + myname + vbCRLF + "Address: " + GetURLParameter("addr") + _
vbCRLF + vbCRLF + "You can see the saved data at http://ns-basic.com/names.txt"
End If
End Sub
Finally, add the Form1.submit() function to the onclick() event of the button widget:
Function Button1_onclick()
Form1.submit()
End Function
The link to the Server app above (http://ns-basic.com/submit_array2.cgi) contains the following REBOL CGI code to process the submitted data. This code appends the submitted data to a text file on the server, and then returns the text fields back to the NS Basic app, where a message box is displayed to inform the user that the submitted data has been stored on the server. You can see the saved text submissions processed by this code at :
#!../rebol276 -cs
REBOL []
submitted: decode-cgi system/options/cgi/query-string
write/append %names.txt rejoin [newline submitted/2 ", " submitted/4]
print {content-type: text/html^/}
print rejoin [
{<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://ns-basic.com/retrieve_cgi/index.html?name=}
(to-url submitted/2) {&addr=} (to-url submitted/4) {">}
]
This project can be found at http://ns-basic.com/retrieve_cgi/ and http://ns-basic.com/retrieve_cgi.nsx. It should give you a basic understanding of how NS Basic can be integrated with server data and applications, to form the mobile portion of more complex software suites.
15. Metaprogramming: Execute and Eval
(under construction)
16. Quick Review and Synopsis
The list below summarizes some key characteristics of the NS Basic language and IDE. Knowing how to put these elements to use constitutes a fundamental understanding of how NS Basic works:
- To start off, NS Basic has many built-in function words that perform common tasks. As in other languages, function words are typically followed by data parameters. Parameters are placed immediately after the function word and are typically enclosed in parenthesis. To accomplish a desired goal, functions are arranged in succession, one after another. The value returned by one function is often used as the argument input to another function. Line terminators are not required at any point, and all expressions are evaluated in left to right order, then vertically down through the code. Empty white space (spaces, tabs, newlines, etc.) can be inserted as desired to make code more readable. The underscore character is used to continue code onto a new line. Text after a single quote and before a new line is treated as a comment. You can complete significant work by simply knowing the predefined functions in the language, and organizing them into a useful order.
- NS Basic contains a rich set of conditional and looping structures, which can be used to manage program flow and data processing activities. If, while, for, for each, and other typical structures are supported.
- NS Basic can increment, compare, and perform proper computations on many common types of data (numbers, strings, dates, times, etc.). Data of any type can be written to and read from localStorage.yourVariable, to SQLite databases, or sent and retrieved to/from Internet servers.
- Any data or code can be assigned a variable label. The equal sign ("=") is used to assign word labels to values. Once assigned, variable words can be used to represent all of the data and/or actions contained in the given string, array, etc.
- Multiple pieces of data (lists) are stored in "arrays". Item can be added to or picked out of an array by index numbers in brackets ("[]"). The "Split" function can convert strings to arrays, and the "Join" function can convert arrays to strings. Arrays can be saved to database tables, or they can be converted to dilimted text strings and saved to localStorage.
- GUI layouts are created by dragging controls onto GUI forms in the NS Basic IDE. Color, position, spacing, and other properties can be edited in the Properties section of the IDE. On___() functions are executed whenever a widget is clicked with a mouse or otherwise used by the user.
17. Built In Help and Documentation
NS Basic ships with a variety of useful documents, tutorials, and code examples that will help you to fully learn and understand the IDE environment, code syntax, and common NS Basic development patterns. The "Help" menu includes the following resources:
- Handbook - a PDF document which covers much of the primary functionality of the NS Basic IDE. It also includes a language reference which covers all the basic functions, syntax, and constructs used to write NS Basic code. The PDF is filled with images which clarify the look of available GUI widgets and the location of available options in menus of the NS Basic IDE. You can save the PDF to any location, or take it with you on a thumb drive as a readable reference. By default, it's installed to C:\Program Files\NSBasic\AppStudio\lang .
- Language Reference - a Windows help file covering the basic language syntax, functions, and GUI widgets (including properties, methods, and events of each widget). The search facility in this help file make it a bit quicker to use as reference, compared to the handbook. Found by default in C:\Program Files\NSBasic\AppStudio\lang .
- Tech Notes and Tutorials - These HTML documents cover getting started step by step, as well as important topics such as using PhoneGap to create iOS and Android apps, using Chrome to debug programs, using WebSockets, sending form data to CGI server applications, drawing graphics using the picturebox widget, and more. The example code and explanations in these documents are all installed in C:\Program Files\NSBasic\AppStudio\tutorials\ and C:\Program Files\NSBasic\AppStudio\technotes\ . Tech note #2 is especially important because it documents important events, properties, and methods which are not covered in any other documentation.
- Sample Applications - NS Basic installs more than 40 sample applications, with code documented to explain how everything works. These examples are the most useful part of the documentation provided with NS Basic. You should read through the code in these apps line by line to see how it all works, then compile and run each application to see each example in action. These examples demonstrate how to use many of the GUI widgets, as well as built-in functions, properties, events, and other important concepts. The sample project files are located in your My Documents folder -> NSBasic Samples -> App Studio .
- Web Board - http://tech.groups.yahoo.com/group/nsbasic-app/ is the place to go when you have questions. Sign up for a free Yahoo account to use this active forum, search for answers to questions which have already been resolved, download files which have been created by the NS Basic community, communicate with the developers of NS Basic, etc.
18. EXAMPLE PROGRAMS - Learning How All The Pieces Fit Together
(under construction)
19. Additional Topics
(under construction)
20. REAL WORLD CASE STUDIES - Learning To Think In Code
At this point, you've seen most essential bits of NS Basic language syntax, but you're probably still saying to yourself "that's great ... but, how do I write a complete program that does ______". To materialize any working software from an imagined design, it's obviously essential to know which language constructs are available to build pieces of a program, but "thinking in code" is just as much about organizing those bits into larger structures, knowing where to begin, and being able to break down the process into a manageable, repeatable routine. This section is intended to provide some general understanding about how to convert human design concepts into NS Basic code, and how to organize your work process to approach any unique situation. A number of case studies are presented to provide insight as to how specific real life situations were satisfied.
20.1 A Generalized Approach Using Outlines and Pseudo Code
Software virtually never springs to life in any sort of initially finalized form. It typically evolves through multiple revisions, and often develops in directions originally unanticipated. There's no perfect process to achieve final designs from scratch, but certain approaches typically do prove helpful. Having a plan of attack is what gets you started writing line 1 of your code, and it's what eventually delivers a working piece of software to your user's machines. Here's a generalized routine to consider:
- Start with a detailed definition of what the application should do, in human terms. You won't get anywhere in the design process until you can describe some form of imagined final program. Write down your explanation and flesh out the details of the imaginary program as much as possible. Include as much detail as possible: what should the program look like, how will the user interact with it, what sort of data will it take in, process, and return, etc.
- Determine a list of general code and data structures related to each of the 'human-described' program goals above. Take stock of any general code patterns which relate to the operation of each imagined program component. Think about how the user will get data into and out of the program. Will the user work with a desktop GUI window, web forms that connect to a CGI script, or directly via command line interactions in the interpreter console? Consider how the data used in the program can be represented in code, organized, and manipulated. What types of data will be involved (text types such as strings, time values, or URLs, binary types such as images and sounds, etc.). Could the program code potentially make use of variables, block/series structures and functions, or object structures? Will the data be stored in local files, in a remote database, or just in temporary memory? Think of how the program will flow from one operation to another. How will pieces of data need to be sorted, grouped and related to one another, what types of conditional and looping operations need to be performed, what types of repeated functions need to be isolated and codified? Consider everything which is intended to happen in the imagined piece of software, and start thinking, "_this_ is how I could potentially accomplish _that_, in code...".
- Begin writing a code outline. It's often easiest to do this by outlining a user interface, but a flow chart of operations can be helpful too. The idea here is to begin writing a generalized code container for your working program. At this point, the outline can be filled with simple natural language PSEUDO CODE that describes how actual code can be organized. Starting with a user interface outline is especially helpful because it provides a starting point to actually write large code structures, and it forces you to deal with how the program will handle the input, manipulation, and output of data. Simple structures such as "button (which does this when clicked...)", "array: (with labels and sub-arrays organized like this...), "function: (which loops through this block and saves these elements to another variable...)" can be fleshed out later with complete code.
- Finally, move on to replacing pseudo code with actual working code. This isn't nearly as hard once you've completed the previous steps. A language dictionary/guide with cross referenced functions is very helpful at this stage. And once you're really familiar with all the available constructs in the language, all you'll likely need is an occasional syntax reminder from NS Basic's help documents. Eventually, you'll pass through the other design stages much more intuitively, and get to/through this stage very quickly.
- As a last step, debug your working code and add/change functionality as you test and use the program.
The basic plan of attack is to always explain to yourself what the intended program should do, in human terms, and then think through how all required code structures must be organized to accomplish that goal. As an imagined program takes shape, organize your work flow using a top down approach: imagined concept -> general outline -> pseudo code description / thought process -> working code -> finished code.
The majority of code you write will flow from one user input, data definition or internal function to the next. Begin mapping out all the things that need to "happen" in the program, and the info that needs to be manipulated along the way, in order for those things to happen, from beginning to end. The process of writing an outline can be helped by thinking of how the program must begin, and what must be done before the user starts to interact with the application. Think of any data or actions that need to be defined before the program starts. Then think of what must happen to accommodate each possible interaction the user might choose. In some cases, for example, all possible actions may occur as a result of the user clicking various GUI widgets. That should elicit the thought of certain bits of GUI code structure, and you can begin to design a GUI interface.
Whatever your conceived interface, think of all the choices the user can make at any given time, and provide a user interface component to allow for those choices. Then think of all the operations the computer must perform to react to each user choice, and describe what must happen in the code.
As you tackle each line of code, use natural language pseudo code to organize your thoughts. For example, if you imagine a button in a GUI interface doing something for your user, you don't need to immediately write the NS Basic code that the button runs. Initially, just write a description of what you want the button to do. The same is true for functions and other chunks of code. As you flesh out your outline, describe the language elements and coding thought you conceive to perform various actions or to represent various data structures. The point of writing pseudo code is to keep clearly focused on the overall design of the program, at every stage of the development process. Doing that helps you to avoid getting lost in the nitty gritty syntax details of actual code. It's easy to lose sight of the big picture whenever you get involved in writing each line of code.
As you convert you pseudo code thoughts to language syntax, remember that most actions in a program occur as a result of conditional evaluations (if this happens, do this...), loops, or linear flow from one action to the next. If you're going to perform certain actions multiple times or cycle through lists of data, you'll likely need to run through some loops. If you need to work with changeable data, you'll need to define some variable words, and you'll probably need to pass them to functions to process the data. Think in those general terms first. Create a list of data and functions that are required, and put them into an order that makes the program structure build and flow from one definition, condition, loop, GUI element, action, etc., to the next.
(the rest of this section is under construction)
21. Other Scripts
(under construction)
For feedback, bugs reports, suggestions, etc., please email Nick at:
reverse (moc tod etup-moc ta lober)
To hire the author for tutoring, to develop software or web site applications, or for general consultation/computing support, see http://com-pute.com or call 267-352-3625.
Keywords:
software development, learn to program a phone, how to write software, learn mobile programming, easy coding, how to create programs, learn to write code, phone programming tutorial, programming course, learn about programming, coding, easiest way to create apps, simple app programming, best mobile programming language, easiest mobile programming language, get started programming mobile apps
Copyright © Nick Antonaccio 2005-2011, All Rights Reserved
|