Hyperlink in the form created by uisng SolutionModel

Hi,
I have a question regarding the hyperlink in the form field.
I ran a query and used the returned dataset to create the data source; then used solutionModel to create the form. In one field in this form I need show a hyperlink by using dataset.setValue(1, 3, ‘<a href="javascript:globals.showDetail(’ + " ’ " + name + " ’ " + ‘)">’ + name + ‘’).
In the global.showDetail() I used another query to create a new form and tried to show it. But the hyperlink doesn’t work. When I created the field that holds the hyperlink, I did:

var newArea = form.newHtmlArea(fieldName, form.getFields().length + 1, 1, width, 22); 
 newArea.text = label; 
 newArea.editable = false;

Everything was done in a global.js file, including creating forms and the method “showDetail()”. But when I click the hyperlink it does nothing and no error reported.

Does anybody know what’s wrong with my code?

Thanks,

I think that Servoy needs the “” tags to understand that it needs to parse the text as html.

I haven’t done it but I would try:

dataset.setValue(1, 3, '<html><body><a href="javascript:globals.showDetail(' + " ' " + name + " ' " + ')">' + name + '</a></body></html>');

ptalbot:
I think that Servoy needs the “” tags to understand that it needs to parse the text as html.

I haven’t done it but I would try:

dataset.setValue(1, 3, '<html><body><a href="javascript:globals.showDetail(' + " ' " + name + " ' " + ')">' + name + '</a></body></html>');

Thank you for replying. I tried it but it doesn’t work. I got error: Could not eval the string ‘globals.showDetail()’; then I removed “globals” and it still reported the similar error: Could not eval the string ‘showDetail()’.

How to get this working?

I did a basic test with a new form and a basic dataset as a source and it worked fine for me, the code I used (in a global.js) was:

function showDetail()
{
	// the debug call back function
	var what = arguments[0];
	application.output(what);
}

function testSolutionModelHtmlArea()
{
	// retrieve a dataset:
	var dataset =  databaseManager.getDataSetByQuery(forms.membres_recview.controller.getServerName(),"SELECT ID, created_by FROM membres;",null,2);
	// set the html for the second field for all rows:
	for (var i = 1; i <= dataset.getMaxRowIndex(); i++) {
		var name = dataset.getValue(i, 2);
		var js = '<html><body><a href="javascript:globals.showDetail(' + "'" + name + "'" + ')">' + name + '</a></body></html>';
		dataset.setValue(i, 2, js);
	}
	
	// form in memory management:
	if (history.removeForm("jsForm") && solutionModel.getForm("jsForm")) {
		solutionModel.removeForm("jsForm");
	}
	
	// create a datasource form the dataset:
	var dataSource = dataset.createDataSource("jsModel",[DM_COLUMNTYPE.NUMBER,DM_COLUMNTYPE.TEXT]);

	// create a new form using the solution model, on the datasource
	var jsForm = solutionModel.newForm('jsForm', dataSource, null, false, 240, 140);

	// put an HtmlArea on it, bound to the previously formatted field:
	var newArea = jsForm.newHtmlArea('created_by', 100, 50, 100, 22);

	// needed to make the link "clickable":
	newArea.editable = false;

	// show the form:
	application.showFormInDialog('jsForm',10,10,350,200,"test",true,false);
}

The only problem I encountered was because the field I chose to put my Html in was too short, so the value was truncated. I altered the column in the database, refreshed the model in Servoy, and it worked fine after that…

Can you explain when exacly you get the “Could not eval the string” error? When you set the value in the dataset or when you click on the link?

Also, is your “showDetail()” function created at runtime or does it already exists in the global.js?

ptalbot:
Can you explain when exacly you get the “Could not eval the string” error? When you set the value in the dataset or when you click on the link?

Also, is your “showDetail()” function created at runtime or does it already exists in the global.js?

I got "Could not eval the string ‘globals.showDetail()’ " error when it called databaseManager.getDataSetByQuery() in showDetail().
The “showDetail()” function exists in global.js. But why databaseManager.getDataSetByQuery() throws the error? It has nothing to do with ‘globals.showDetail()’. databaseManager.getDataSetByQuery() just runs query and the argument passed in looks correct.

I think the error "Could not eval the string ‘globals.showDetail()’ " was caused by setting value into the dataset. But if I removed <html just leave then ite doesn’t call the global method at all.

happytigger:
I got "Could not eval the string ‘globals.showDetail()’ " error when it called databaseManager.getDataSetByQuery() in showDetail().

Are you saying that you call the getDataSetByQuery that set the field to the html calling showDetail() from the showDetail() function?
I’m sorry but it doesn’t make sense to me. Could you send a test solution or at least the showDetail() function and the calling code in its entirety?

As I said, setting the html worked in my example, so I cannot understand what you are trying to achieve that doesn’t work.
Please elaborate.

Thanks

I have a function to create the form:

function createForm()
{
   var fname = "newForm";
   var dataSet = databaseManager.getDataSetByQuery('my_db', sql, null, -1);

   for (var i = 1; i < dataSet.getMaxRowIndex(); i++)
    { 
            var number = dataSet.getValue(i, 2);
            var name = dataSet.getValue(i, 1); 
             var js = '<html><body><a href="javascript:globals.showDetail(' + "'" + name + "'" + ')">' +
                       + number + '</a></body></html>'; 
             dataSet.setValue(i, 2, js); 
    }

    var uri = dataSet.createDataSource(
      'mydata', [DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.INTEGER,
                 DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.TEXT,     
                 DM_COLUMNTYPE.TEXT]);
    var jsform = solutionModel.newForm(fname, uri, null, true, 400, 700);
    var fieldn = buildField(jsform, "name", "Name", 120);
    fieldn = buildField(jsform, "media_num", "Tapes", 70, true);
    fieldn = buildField(jsform, "ready", "Ready", 70);
          ................//Create fields
    forms[fname].controller.show(); 
}

function buildField()
{
   var form = arguments[0];
   var fieldName = arguments[1];
   var label = arguments[2];
   var width = typeof(arguments[3]) == 'undefined' ? 100 : arguments[3];
   var htmlArea = arguments[4] == true ? true : false;
 
   var newArea;
   if (htmlArea)
   {
      newArea = form.newHtmlArea(fieldName, form.getFields().length, 31, width, 22);
   }
   else
   {
      newArea = form.newTextField(fieldName, form.getFields().length, 31, width, 22);
   }
   newArea.text = label;
   newArea.editable = false;
   return newArea;
}

function showDetail() //Create a new form
{
    var args = new Array();
    args[0] = arguments[0];
    var dataSet = databaseManager.getDataSetByQuery('my_db', sql, args, -1);
    var fname = "detailForm";
    var uri = dataSet.createDataSource(
      'mydata', [DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.TEXT]);
    var fieldn = buildField(jsform, "code", "Barcode", 100); 
           ...... //Create fields
    forms[fname].controller.show(); 
}

I already tested that it did call showDetail() but it threw the exception “Could not eval the string ‘globals.showDetail()’” when calling “var dataSet = databaseManager.getDataSetByQuery(‘my_db’, sql, args, -1)” in showDetail(). I can do anything else in showDetail() but calling databaseManager.getDataSetByQuery().

Thanks,

happytigger:
I have a function to create the form:

function createForm()

{
var fname = “newForm”;
var dataSet = databaseManager.getDataSetByQuery(‘my_db’, sql, null, -1);

for (var i = 1; i < dataSet.getMaxRowIndex(); i++)
{
var number = dataSet.getValue(i, 2);
var name = dataSet.getValue(i, 1);
var js = ‘<a href="javascript:globals.showDetail(’ + “'” + name + “'” + ‘)">’ +
+ number + ‘’;
dataSet.setValue(i, 2, js);
}

var uri = dataSet.createDataSource(
  'mydata', [DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.INTEGER,
             DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.TEXT,     
             DM_COLUMNTYPE.TEXT]);
var jsform = solutionModel.newForm(fname, uri, null, true, 400, 700);
var fieldn = buildField(jsform, "name", "Name", 120);
fieldn = buildField(jsform, "media_num", "Tapes", 70, true);
fieldn = buildField(jsform, "ready", "Ready", 70);
      ................//Create fields
forms[fname].controller.show(); 

}

function buildField()
{
var form = arguments[0];
var fieldName = arguments[1];
var label = arguments[2];
var width = typeof(arguments[3]) == ‘undefined’ ? 100 : arguments[3];
var htmlArea = arguments[4] == true ? true : false;

var newArea;
if (htmlArea)
{
newArea = form.newHtmlArea(fieldName, form.getFields().length, 31, width, 22);
}
else
{
newArea = form.newTextField(fieldName, form.getFields().length, 31, width, 22);
}
newArea.text = label;
newArea.editable = false;
return newArea;
}

function showDetail() //Create a new form
{
var args = new Array();
args[0] = arguments[0];
var dataSet = databaseManager.getDataSetByQuery(‘my_db’, sql, args, -1);
var fname = “detailForm”;
var uri = dataSet.createDataSource(
‘mydata’, [DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.TEXT, DM_COLUMNTYPE.TEXT]);
var fieldn = buildField(jsform, “code”, “Barcode”, 100);
… //Create fields
forms[fname].controller.show();
}



I already tested that it did call showDetail() but it threw the exception "Could not eval the string 'globals.showDetail()'" when calling "var dataSet = databaseManager.getDataSetByQuery('my_db', sql, args, -1)" in showDetail(). I can do anything else in showDetail() but calling databaseManager.getDataSetByQuery().

Thanks,

Your code seems a bit weird to me (no offense :).

I don’t know really what’s in your ‘sql’ variable but what I understand from the above is that in your createForm() function:

  • first you get a number from your database (in column 2),
  • then you build a string from it and insert into the same column (?)
  • and after that you create a datasource from that dataset, specifying that the second column is of type integer (DM_COLUMNTYPE.INTEGER)

So I would guess that when you are trying to pull the dataset back with the getDataSetByQuery(…) in showDetail(), Servoy chokes because it tries to interpret your string or number or I don’t know what it is after all this!.
I don’t know how sensitive Servoy’s JavaScript is to the database types, but I know that in java, it would never work…

Maybe you intended to do “dataSet.setValue(i, 1, js);” or maybe the type of args in showDetail is not what you think, anyway I would check for the type of variables and maybe the sql variable itself because it seems that it either sql or args in showDetail() contains “'globals.showDetail()”.

That’s only a few ideas. Hope this helps,

ptalbot:

  • and after that you create a datasource from that dataset, specifying that the second column is of type integer (DM_COLUMNTYPE.INTEGER)

I changed that column to be “DM_COLUMNTYPE.TEXT” but that is not the problem as the error still exists. In the showDetail(), databaseManager.getDataSetByQuery() runs a different query and I printed out the argument that was passed in, it was correct and there was no ‘globals.showDetail()’ contained. I also tried removing the argument and just running “select * from table1”, it still threw out the same error.
I found another topic posted by somebody. He asked the similar question and Robert Ivens replied:

You use … for this specific value but when you display the dataset you also wrap it in one. So it seems you should only use the ‘+dataset1.getMaxRowIndex()+’'.

I followed this (remove ) but it still doesn’t work.

Maybe it does this because you are not allowed to use the databaseManager in a callback method on a new form.
I don’t know about Servoy’s internal, but if it’s using Hibernate it might be that the HibernateSession is not opened when you call the showDetail() method… Hibernate can be that picky!

In any case, I would file a case to the support system if I were you, we a stripped down version of your problem and see what they could find out…

Thanks for help.