Sciter. Working with persistent data (database)

Here is an example of minimalistic application working with DB (persistent data) in Sciter.

Screenshot of DB form.

This sample is using three files:

  1. simple-db-form.htm – main file of our application;
  2. db.tis – open or create database;
  3. form.tis – behavior that handles showing/saving data from list of input elements on the form.

db.tis – open or create database

This file contains single procedure that will open or create new storage if does not exist:

function openDatabase(pathname = "records.db")
{
  var ndb = Storage.open(pathname);
  if(!ndb.root)
  { 
    // new db, initialize structure
    ndb.root = 
      { // root of our db is an object having single field 'records'
        records: ndb.createIndex(#integer) // main index, int -> item
      };
  }
  return ndb;
}

Structure of our storage is simple – its root node contains single field records of type Index. In our example this index maps integer – number of the record to the record itself – object that may have arbitrary structure.

form.tis – showing/saving data from input elements on a form

// Form handler class
type Form: Behavior
{
  function show(rec)
  {
    if(this.shown) this.save(); // save previously shown record.
    this.shown = rec;
    function load_value(el)
    {
      var name = el.attributes#name;
      el.value = rec[symbol(name)];
    }
    this.select(load_value, "[name]"); 
    // call load_value for each element having "name" defined.
    // De facto this means that form content defines structure of the record.
  }
  function save()
  {
    var shown = this.shown;
    function store_value(el)
    {
      var name = el.attributes#name;
      shown[symbol(name)] = el.value;
    }
    this.select(store_value, "[name]"); 
    // call store_value for each element having "name" defined.
  }
}

This behavior class has two methods:

  • show(rec) – show fields of object rec in fields of the form and
  • save() – stores content of input elements of the form in fields of last shown rec object

simple-db-form.htm – main file of our application

And last part is our main file that defines UI layout and assembles all parts together:

<html>
<head>
  <style>
    form#record 
    { 
      prototype:Form; 
    }
    ...
  </style>  
  <script type="text/tiscript">
    include "form.tis";
    include "db.tis";
    
    var form = self.select("form#record");
    var rec_no = self.select("#rec-no");
    
    var db = openDatabase();
    var no = 0;
    
    function gotoRecNo( n )
    {
      no = n;
      if( no < 0 ) no = 0;
      else if( no >= db.root.records.length ) no = db.root.records.length - 1;
      form.show( db.root.records[no] );
      rec_no.text = String.printf("%d of %d", no, db.root.records.length); rec_no.update();
    }

    function gotoNewRecord() 
    { 
      // create new record 
      var newidx = db.root.records.length;
      db.root.records[ newidx ] = { first:0, second:"", third:"<html><\/html>" };
      gotoRecNo(newidx); 
    }

    // handlers of navigatonal buttons
    function self #first .onClick() { gotoRecNo(0); }
    function self #prev  .onClick() { gotoRecNo(no - 1); }
    function self #next  .onClick() { gotoRecNo(no + 1); }
    function self #last  .onClick() { gotoRecNo(db.root.records.length - 1); }
    function self #new   .onClick() { gotoNewRecord(); }
    
    function view.onLoad()   { if(db.root.records.length) gotoRecNo(0); 
                                        else gotoNewRecord(); }
    function view.onUnload() { form.save(); db.close(); }
    
  </script>  
<head>
<body>
  <h1>Simple DB form</h1>
  <form #record>
    <table>  
      <tr><td>First (number)</td><td><input name="first" type="number"/></td></tr>
      <tr><td>Second (text)</td><td><input name="second" type="text"/></td></tr>
      <tr><td>Third (richtext(html))</td><td><richtext name="third" /></td></tr>
    </table>
  </form>
  <div #nav>
    <button #first title="to first record">|<</button>
    <button #prev title="to prev record"><</button>
    <button #next title="to next record">></button>
    <button #last title="to last record">>|</button>
    <button #new title="create new record">new</button>
    record: <span #rec-no>?</span>
  </div>
</body>
</html>

Done. We have simple form that allows us to create records with text, numeric and richtext (html) fields.


Code above is not the best one from architectural point of view – its goal is to show basic principles, not more.
You can find this sample in [Sciter SDK]/samples/ideas/db/ folder.