"Static" properties in javascript. Kinda.

by Peter Tyrrell Tuesday, August 05, 2008 10:55 PM

The following gives me the ability to access javascript properties in a static kind of way. Not really, since the object has been instantiated, but at least I don't have to define a specific object, then call its constructor all the time to new it up and get at its properties.

   1: // declare globally
   2: var Artist = {
   3:     Fields: {
   4:         Id: "ID",
   5:         FullName: "Term",
   6:         FirstName: "First Name",
   7:         LastName: "Last Name",
   8:         Birth: "Date of Birth",
   9:         Death: "Date of Death"
  10:     }
  11: };


I like to store DB/Text field names in this way, as they become (pseudo) strongly-typed and the magic strings are stored in one place only, instead of scattered across my code like dandelion seeds.

It can be difficult to work in javascript after C# and other full-featured languages. This is the closest I could come to static properties or a struct. If I weren't scripting in DB/Text, a proprietary closed system, I would be using jQuery or mootools, which put the joy back in joyvascript.


Now I can access field names statically as follows. Look ma, no constructors!

   1: function SomeMethod()
   2: {
   3:     var idFieldName = Artist.Fields.Id;
   4: }

A highly reusable recordset script for DB/Text

by Peter Tyrrell Tuesday, August 05, 2008 10:26 PM

This javascript function performs a search against a DB/Text database and returns a sorted array of dictionary objects with fieldnames as keys.


Search(commandQuery, textbase, password, fieldsToReturn, sortFields)

commandQuery (string): A query in command syntax.
textbase (string): The name of the textbase to query.
password (string): A textbase password that allows querying.
fieldsToReturn (array): An array of field names whose values the query will retrieve from result records.
sortFields (array): An array of field names to sort the recordset by.


SortByField(recordset, sortFields): A method that sorts a recordset by the fields provided.

   1: // returns array of dictionaries with fieldsToReturn as keys
   2: function Search(commandQuery, textbase, password, fieldsToReturn, sortFields)
   3: {
   4:     var rs;
   5:     var output = [];
   7:     rs = Application.newRecordset(textbase, Application.activeTextbase.path, password);
   8:     if (rs != null)
   9:     {
  10:         try {
  11:             rs.Open(commandQuery);
  12:             if (rs.Errors.Count > 0)
  13:             {
  14:                     // log error
  15:             }
  16:             else if (rs.RecordCount > 0)
  17:             {
  18:                 // sort the recordset
  19:                 rs = SortByField(rs, sortFields);
  21:                 rs.MoveFirst();
  22:                 while (!rs.EOF)
  23:                 {                    
  24:                     // create dictionary of field values, add to output list
  25:                     var record = new Object();
  26:                     for (var i = 0;i < fieldsToReturn.length;i++)
  27:                     {
  28:                         record[fieldsToReturn[i]] = rs.Fields(fieldsToReturn[i]).Value;
  29:                     }
  30:                     output[output.length] = record;
  32:                     rs.MoveNext();                    
  33:                 }
  34:             }    
  35:         }
  36:         catch (e) {
  37:             // log exception
  38:         }
  39:         finally 
  40:         {
  41:             rs.Close();    
  42:         }
  43:     }
  44:     return output;
  45: }
  47: // returns recordset sorted by fields provided
  48: function SortByField(recordset, sortFields)
  49: {
  50:     var sort = recordset.NewSortDescriptor();
  51:     for (var i = 0;i < sortFields.length;i++)
  52:     {
  53:         if (i >= (sort.MaxSORTFIELDS - 1))
  54:         {
  55:             break;    
  56:         }
  57:         sort.sortFieldName(i) = sortFields[i];
  58:     }
  59:     recordset.Sort(sort);    
  60:     return recordset;
  61: }


The main advantage of this function is its agnosticism towards the fields it is to retrieve. It relies on the fact that objects in javascript inherently behave as associative arrays, e.g.

var myObject = new Object();
myObject["myKey"] = "some value";

For each record in the query's result set, an object is created with fieldsToReturn as keys, and the function's return type is simply an array of these objects. The fact that I am using these objects solely for their key/value behaviour leads me to refer to them as dictionaries. They are not dictionaries in the sense of specialized collections as with other languages outside of javascript.


The following is a simplified method that I would never use in production code. It grabs search text from a box, creates a command query, then searches the Catalog. The result set will be sorted by Title, and will contain values from Title and Author fields. It then shows an alert message with the title from the first result in the set.

Note that field values are retrieved by using field names as keys on the objects in the results array.

   1: function btnSearch_onClick()
   2: {
   3:     var searchText = Form.boxes("boxSearchText").content;
   4:     var query = "find (Title ct {0}) or (Author ct {0})".replace("{0}", searchText);
   5:     var results = Search(query, "Catalog", "password", ["Title", "Author"], ["Title"]);
   7:     var msg = "First result Title is '{0}'".replace("{0}", results[0]["Title"];
   8:     Application.message(msg);
   9: }

Updated Andornot Utility scripts for Webpublisher 11

by Peter Tyrrell Friday, June 13, 2008 11:34 PM

As reported in my last post, Inmagic Webpublisher 11 broke some of our utility scripts. This release is compatible with WPP 11, and is still backwards-compatible with earlier versions.

Download them from our demo site at ask.andornot.com:

Andornot Search Utilities 1.9

Andornot Result Utilities 1.11


CSS absolute positioning while using ASK

by Peter Tyrrell Friday, June 13, 2008 10:22 AM

is NOT recommended.

Usually not added when you first install WPP, check your DBTWPUB.ini file in your WPP installation folder on your web server. Make sure that you do not have the line of code "WebCSSOpt=2" as our ASK web forms will not display properly.

You can edit the DBTWPUB.ini file in Notepad and either change it to WebCSSOpt=0 or delete that line entirely.

Below is the DB/TextWorks Help file article for more information....

WebPublisher PRO: Form layout

By default, WebPublisher version 4.1 and later uses Cascading Style Sheets (CSS) and absolute positioning, so that report, display, and edit forms look as much as possible as they would look in DB/TextWorks.

WebPublisher detects whether the browser supports Cascading Style Sheets. If not, WebPublisher uses simple HTML (boxes will be left-justified, box labels will appear on top rather than to the left, and so forth).

Forms that contain Raw HTML or inline images are incompatible with absolute positioning. Forms containing these elements will have overlapping text unless very carefully designed. Therefore, simple HTML is used for this type of form unless you explicitly set WebCSSOpt=2 in your DBTWPUB.INI file (see below).

Note: DB/TextWorks tabular forms do not use absolute positioning, so this issue does not affect them.

You can use picture boxes in place of inline images to retain CSS formatting. The Image size option specified using Box Properties>Position in the Form Designer is used. In order for the image sizing to work properly, the images must reside either in the textbase folder (for example, C:\CATALOG\) or the folder specified in the Image field in the record (for example, C:\IMAGES\COYOTE.JPG).

To control whether the site uses CSS, set the WebCSSOpt= parameter in the [WebPublisher] section of your DBTWPUB.INI file equal to one of the following:

0 = do not use CSS 1 = the default behavior 2 = use CSS regardless of whether forms contain Raw HTML or inline images


[WebPublisher] WebCSSOpt=0

Note: The WebCSSOpt= parameter affects all forms and all textbases, unless you override it using the CS= parameter in an individual query screen.

Webpublisher 11 breaks some Andornot scripts

by Peter Tyrrell Tuesday, June 10, 2008 10:51 AM

Inmagic Webpublisher 11, just released, breaks some Andornot Utility scripts that rely on the dbtw_params variable: Rewind, Next/Previous, and Change Form On Dropdown Value are affected. Possibly others.

A fix will be released as soon as possible, and I will update this post and provide download links to the script files at that time.

UPDATE Jun 13 2008: Fix released.

More Info

dbtw_params is a javascript variable injected into the page by Webpublisher that holds a query string representation of the current result page. As with all query strings, Key/value pairs are separated by the & character, except that in WPP 11, this character is HTML-encoded as &amp;.

Webpublisher 10


Webpublisher 11


Month List