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