
NextDB.net Database Form Utilities
Introduction
NextDB.net is a JavaScript API for database programming that enables web
developers to build data driven web applications without
any server side coding.
To further simplify things, we have built an abstraction layer on top of the
JavaScript API to enable faster development by automatically creating HTML
forms that connect to your NextDB.net account and takes care of many of the
time consuming issues in web development. With one line of code you
can add a database enabled HTML form to your page to execute inserts, updates
or queries. This new library is based
on the Builder Design Pattern and it uses reflection to inspect the database
to automatically populate the form with all of the appropriate fields.
The form builder library offers three distinct database operations: inserts, updates
and queries. The library also offers a variety of simple convenience features
including automatic form validation or custom regex preferences for form validation,
layout control, date pickers, file uploaders, custom default values, dropdown lists,
captcha protection, and callback function registries for responses.
This article will go over the various options available through the
form builder library. If you want to see these code examples live,
you can import the data model used by the examples and plug these into your
account directly. Just copy this URL into the 'Import Database' option under
the databases tab on the
www.nextdb.net/admin
admin pages. If you don't have an account, you can sign up at
www.nextdb.net. This is the database
data model for these simple examples:
http://www.nextdb.net/nextdb/service/brenthamby/FORM_EXAMPLE/EXPORT
Basics
The main new class in the NextDB.net JavaScript API is the super class Form:
net.nextdb.html.Form
There three new subclasses that inherit from the super class:
net.nextdb.html.InsertForm
net.nextdb.html.QueryForm
net.nextdb.html.UpdateForm
The functions common to all of the forms are in the super class, while the operation
specific functions are all defined in the subclasses.
The naming convention between the database and these functions is simple,
use underscores when you name your table columns
and query parameters on the admin pages. For example, if you have a column
named 'first_name', it will appear as the label on the form as 'first name'.
It simply creates the form labels based on the column/parameter name, replacing
underscores with spaces.
Inserts
The constructor for the InsertForm requires two parameters, the connection
object to specify your account and database name, and the name of the table
for the insert. Once constructed, you can optionally add a variety of
additional configurations to the form.
Once it is ready, the final call is
.render(div) which will
render the form into a div (or any HTML node) on the web page.
In the most basic form, the code for adding an insert form to your web page
looks like this:
var conn = new net.nextdb.Connection("MY_ACCOUNT","MY_DATABASE");
new net.nextdb.html.InsertForm(conn,"USER").render(myDiv);
This simple line of code will inspect the USER table in your account and build
a form that will represent input fields for all of the columns in the table.
The default behavior is to make all of the columns mandatory, enforced by
client side form validation. When submit, if all the fields are valid, then
an insert will be executed. This is what the form will look like in the
above example:
In most cases you will probably want a bit more control over the insert.
You might want to make the user enter their password twice to confirm
against typos, and obscure the password fields as HTML password types. You
might also want to provide a drop down list for the users sex to constrain
the data entered. You can also enforce that the email is a valid email
either by using our email regular expression checker, or provide your own
regular expression. You might want to omitt the creation date since
you want it to default to 'now' which is set as the default value, and
omitt the user pic as they can always update that later.
Finally, you can register callback functions to receive notification when
the insert is executed and when the cancel button is clicked.
This new code would look like this:
var conn = new net.nextdb.Connection("MY_ACCOUNT","MY_DATABASE");
new net.nextdb.html.InsertForm(conn,"USER")
.confirmFields(["password"])
.obscureFields(["password"])
.options({sex:{M:"Male",F:"Female",O:"Other"}})
.omitFields(["creation_date","pic"])
.validation({email:net.nextdb.validate.EMAIL})
.captchaColors({fg:"#880000",bg:"#ffffff"})
.insertCallback(function(rowId,error){ /* your code */ })
.cancelCallback(function(){ /* your code */ })
.render(myDiv);
The form from the above code will look like this:
Another additional function special to InsertForm is the
insertAndLink(<String> rowId, <String> relationshipName)
which is used to relate the inserted row to another row in the database.
For example, a user inserts a blog entry and the blog entry gets 'related'
to the user based on a one-to-many relationship that you defined on the
admin pages.
Queries
Queries are a bit different than inserts and updates because the fields are
not necessarily related to columns, rather they are the parameters that you
defined for the query when compiling the query on the admin pages. You will
identify the query name in the constructor, and define a callback function
to capture the 'results set' of rows that are returned from the query.
This is a simple example building a form for a LOGIN query:
var qForm = new net.nextdb.html.QueryForm(conn,"LOGIN");
qForm.queryCallback(myCallback)
.obscureFields(["password"])
.render(document.getElementById("myDiv"));
function myCallback(rows,error){
if(error){
qForm.message(error.getMessage(),"#990000");
}else if(rows.length==0){
qForm.message("You have entered an invalid login/password","#990000");
}else{
qForm.message("Welcome!","#009900");
/* your code goes here to handle the successful login */
}
}
This query will produce a query form whose results you can handle in your
own callback function. In this case you check that the LOGIN query returns
a row, and if not let the user know that the login and password they entered
failed to authenticate.
Updates
Updates work the same as Inserts in that you specify the name of the table in
the constructor, then apply your preferences. The one parameter to updates
that is unique and required is
setRowId(<SURID> rowId)
which identifies the row you want to update. The rowId is a SURID/PK that must
have been returned from a query that was configured as "FOR UPDATE".
This is an example of using the update form to update a users password:
new net.nextdb.html.UpdateForm(conn,"USER")
.omitFields(["first_name","last_name","login","sex","pic","creation_date","email"])
.obscureFields(["password"])
.setRowId(rowId) /* retrieved from a query */
.confirmFields(["password"])
.render(document.getElementById("myDiv"));
This update code produces a form with just the password field, and forces the
user to enter the new password twice. If the input is valid then the update
is sent to the database to update the identified row. Here is a snapshot of the
form:
Layouts
Since the layout of the page is a huge part of web design, we offer three
layout options for the form builder. Setting the layout is the same for
inserts, queries and updates. For example:
// (default)
new net.nextdb.html.InsertForm(conn,"USER")
.layout(net.nextdb.html.Form.BOX_LAYOUT)
.render(myDiv);
Box layout produces a column of the field names and a column of the inputs:
new net.nextdb.html.InsertForm(conn,"USER")
.layout(net.nextdb.html.Form.HORIZONTAL_LAYOUT)
.render(myDiv);
Horizontal layout produces a single row:
.layout(net.nextdb.html.Form.VERTICAL_LAYOUT)
.render(myDiv);
Vertical layout produces a single column:
Chaining and Nesting Operations
These examples cover very basic usages of the form builder library. In more
sophisticated usage, you will probably want to chain operations together.
For example, first you have a user register. When they register you will remove
the register form and render a login form. When they login, you will remove
the login form and render out whatever other operations are available to users
on your system. You can accomplish this either by nesting the form builders
within the callback functions, or just calling out from the callback function
to some other controller function. The important point is that because of the
asynchronous nature of the library you have great flexibility to build
very dynamic user interfaces.
Feedback
Please give us any feedback you might have on this library on our Google Group at:
http://groups.google.com/group/nextdb-user