The Semi-Rookie Rides again - using HTML in a form

Hi all,

This is my first time trying to use HTML in a form (aside from some simple formatting things). I’d like to build a table and populate it with information from a foundset. I can build the table, but I haven’t been able to figure out the correct syntax for getting the data elements into the table. Basically, I run a search, and the resulting foundset has data that I’d like to put into the table, mostly images from the database with some descriptive text, also from the database. I haven’t round anything in the wiki about this (although I may have missed it). I’ve found one or two examples in the forum of using datasets to populate a table, but so far, nothing on foundsets (a search on HTML yielded 234 pages, and I’m about 40 into it :-).

Is there a “best practice” on this that you might point me to?

As always, thanks for any guidance you can provide.

Thanks and have a good day.

Ron

For me the best practice to deal with HTML building is to use VelocityReport.

Put your foundset/dataset/whatever in a context object:

var context = {};
context.fs = yourFoundset;

then you can loop on it inside your html like this:

<html>
....
<table>
#foreach($record in $fs)
<tr>
<td>$record.aField</td>
<td>$record.anotherField</td>
</tr>
#end
...

That html can be a template file in the VelocityReports folder or a String that you feed directly to the plugin, using either:

plugins.VelocityReport.renderTemplate('aTemplate.html', context);

or

plugins.VelocityReport.evaluateWithContext(yourHtml, context);

Try it. It’s very easy! And there’s millions more things you can do with it once you’ve started using it.
https://www.servoyforge.net/projects/velocity-report

Hi Patrick,

Thanks for that information. Certainly something worth exploring.

I hope that you’re having a good day up there in Montreal. I’ve only been there once, long ago, but I remember it being a beautiful city.

Ron

Any alternatives to using Velocity Reports?

Is there anything in the Servoy doc that might cover this? I’ve looked in the wiki, and also at the Servoy University videos, and so far haven’t found anything. I didn’t notice anything in the sample solutions, either.

HTML seemed to be the way to go about building a form that contains a grid, with each box in the grid holding information from one record (and related data). I wasn’t able to figure out a way to do this with standard forms, using tabpanels and the like. Might there be another way to approach this in a way that will work in both the smart client and the web client?

As always, thanks for any guidance you can provide.

Have a good day.

Ron

The first idea that pops in my head about standard way of showing records is building a form through solution model.

Second idea maybe easier is getting the data in a dataset , use the getAsHTML method and show it in a form with a big HTML field… Not sure what will happen to images though… and the CSS handling is limited

Oh… And you can generate your own HTML…record by record…

Hi Joao,

Thanks for the response. Appreciate your thoughts.

It’s interesting that you mention putting the data into a dataset. In the two examples I’ve seen of building the HTML in a regular form within an HTML-area field, both used datasets rather than foundset. One thing I was wondering is if it has has to be in a dataset to do something like populating an HTML table within a form, or whether syntax exists to allow usage of a foundset, and looping through that rather than a dataset. Research continues. :)

Thanks again and have a good day.

Ron

Hi Ron,

It is a beautiful day here in Montreal :)

In the end, HTML is nothing but text… So nothing prevents you to loop through a foundset (or a dataset, or an array, or an object, for that instance) to build HTML text.
You can do it the hard way, like this:

// oversimplified HTML for the sake of the example:
var html = '<html><head></head><body>';
if (theFoundset && theFoundset.getSize() > 0) {
    var dataSource = fs.getDataSource();
    var serverName = databaseManager.getDataSourceServerName(dataSource);
    var tableName = databaseManager.getDataSourceTableName(dataSource);
    html += '<table>';
    for (var i = 1; i <= theFoundset.getSize(); i++) {
        var rec = fs.getRecord(i);
        if (rec) {
            html += '<tr>';
            html += '<td>' + rec.atextField + '</td>';
            if (rec.imageField) {
            	// url could come from a calculation as well:
            	var url = 'media:///servoy_blobloader?servername=' + serverName;
            	url += '&tablename=' + tableName;
            	url += '&dataprovider=imageField';
            	url += '&rowid1=' + rec.id;
                html += '<td><img src="'+ URL + '"/></td>';
            }
            html += '</tr>';
        }
    }
    html += '</table>';
}
html += '</body></html>';

Or you can do it the Velocity way, as I’ve outlined before:

var template = '<html><head></head><body>\
#if($fs) <table>\
    #foreach($rec in $fs)\
        <tr>\
            <td>$!rec.aTextField</td>\
            <td>$!rec.imageField</td>\
        </tr>\
    #end\
#end\
</body></html>';

var context = {fs: theFoundset};
var html = plugins.VelocityReport.evaluateWithContext(template,context);

Both method will give you the same kind of HTML result, but note how much more readable (and maintable) the Velocity version is.
Especially note that you cannot use blob images in HTML apart from using the servoy_blobloader.
VelocityReport does the wrapping automatically for you when it detects an image byte field.

  • my 2 (Canadian) cents ;)

Hi Patrick,

Thanks so much for that information and for taking the time to send the examples. Very helpful. I can see what you’re talking about now.

Obviously, your 2 cents (CAD) is worth more than my 2 cents (USD) :D

Ron