How to Get TableView Record that User Clicked On

I have created a dataset from a query and generated a tableview of that data using the solution model.

I have added a onRecordSelection method that correctly triggers when the user clicks on a record on the form. So far so good. :)

However once inside my onRecordSelection method, I can see no Solution Model method or property that gives me an indication of which record the user clicked. :?

Since the form is not based on a table, the table value is null, the usual controller-based functions will not return valid values. So how does one get the

user selected record when the form is generated by the SM, the datasource is generated by the createEmptyDataSet method and the dataset loaded with data gleamed from

an external source such as a dynamic query to non-Servoy application or dataservice? Am I missing something obvious? Any help would be greatly appreciated. TYIA!

When you come to think of it, yes, it is obvious ;-)

Even when you attach a dataSource that you have created yourself from any source, you can refer to its foundset and the dataProvider of this foundset.
For example, foundset.getSelectedIndex will give you the index of the foundset, and in the function attached to the onRecordSelection, you can access the data of the currentRecord (read or write), directly.

For example let say that you have created a dataSource with 3 columns: ID, valueA and valueB.
In your function you can access ID, valueA and valueB directly, since the record is already selected:

var pk = ID;
var valueBSelected = valueB;
valueA = 1; 
//etc...

So your ID, valueA and valueB are already populated with the value of the row the user selected.

Easy, isn’t it?

Hi Ron,

Patrick is right.

Just one gotcha though (and it does make sense too). You can’t search in your datasource when it’s not based on a table.
So controller.find()/controller.search() won’t work, in fact will give you errors.
But all the rest pretty much works the same.

Unfortunately not so obvious to me :oops:

My onRecordSelection method is a global method. I have a method that tell me what form I am on regardless of how deeply nested.

So inside my onRecordSelection method:

application.output('onRecordSelection_myResults - getSelectedIndex:  ' + forms['formName'].foundset.getSelectedIndex());

In the above code, the value output is always 1 regardless of the row on that I click.

I tried accessing the form’s fields directly but may be running into some scope issues because the onRecordSelection method is global.

ROCLASI:
Hi Ron,

Patrick is right.

Just one gotcha though (and it does make sense too). You can’t search in your datasource when it’s not based on a table.
So controller.find()/controller.search() won’t work, in fact will give you errors.
But all the rest pretty much works the same.

Still foundset.find() and foundset.search() does work.

ronm:
Unfortunately not so obvious to me :oops:

My onRecordSelection method is a global method. I have a method that tell me what form I am on regardless of how deeply nested.

So inside my onRecordSelection method:

application.output('onRecordSelection_myResults - getSelectedIndex:  ' + forms['formName'].foundset.getSelectedIndex());

In the above code, the value output is always 1 regardless of the row on that I click.

I tried accessing the form’s fields directly but may be running into some scope issues because the onRecordSelection method is global.

Hum, can’t you put an onRecordSelection at the form level, get the values, then call a global method then?
It seems to me that you want to global method to handle everything, this is not object oriented at all IMHO.

You should have global methods only for global things. Global methods that depend on context and full of if…else is a bad idea.
Use form method for event, and call global methods with the values that are in the context, it will be easier to maintain in the long run.

My two cents.

ptalbot:

ROCLASI:
Hi Ron,

Patrick is right.

Just one gotcha though (and it does make sense too). You can’t search in your datasource when it’s not based on a table.
So controller.find()/controller.search() won’t work, in fact will give you errors.
But all the rest pretty much works the same.

Still foundset.find() and foundset.search() does work.

Well it seems Servoy made it so that the controller.find() will not go into findmode but the foundset.find() does.
And when you use foundset.find() you get the following error:

[attachment=0]search_in_foundset_without_table.png[/attachment]

So I guess they forgot to ‘fix’ the foundset.find() like they ‘fixed’ the controller.find().

Servoy 5.1 - build 956

Edit: filed case #275857

ROCLASI:
So I guess they forgot to ‘fix’ the foundset.find() like they ‘fixed’ the controller.find().

Really? I was convinced I was using it somewhere!
But you must be right, I have iterated on a foundset using an inmem dataSource, maybe not performed searches…
Cheers,

The issue related to retrieving the current record was scope. It is necessary to attach a method to the newly created form.

For the uninitiated, evt_onShow and evt_onHide code samples are included. The onHide method is required since I

added the newly created form to an existing tabpanel. The tab must be removed before the remove form method will

function correctly.

The evt_onShow method:

	elements.tabs_extlData.readOnly = true
	
	var fname = "testform"
	var mname = 'myRecordSelection'
	if (forms[fname])
	{
		var success = history.removeForm(fname)
		if(success)
		{
			solutionModel.removeForm(fname)
		}
	}
	if (!forms[fname])
	{
	       //Create dataset
	       ds = databaseManager.createEmptyDataSet()
	       ds.addColumn("Degrees")
	       ds.addColumn("Direction")
	       ds.addRow([0,  'North'])
	       ds.addRow([45, 'Northeast'])
	       ds.addRow([90, 'East'])
	       ds.addRow([135,'Southeast'])
	       ds.addRow([180,'South'])
	       ds.addRow([225,'Southwest'])
	       ds.addRow([270,'West'])
	       ds.addRow([315,'Northwest'])
	
	      //Create a new data source, returns an uri that can be used to build forms on
	      var uri = ds.createDataSource('mydata', [DM_COLUMNTYPE.INTEGER, DM_COLUMNTYPE.TEXT]);
	
	      //Create form
	      var jsform = solutionModel.newForm(fname, uri, null, true, 760, 480);
	      jsform.navigator = SM_DEFAULTS.NONE 
	   	  jsform.view = JSForm.LOCKED_TABLE_VIEW
	   	  jsform.newLabel("Degrees",0,0,100,19)
	      jsform.newLabel("Direction",100,0,200,19);
	   	  jsform.newHeaderPart(20)
	      var myField = jsform.newTextField("Degrees",0,20,100,20);
	   	  myField.editable = false;
	      var myField = jsform.newTextField("Direction",100,20,200,20);
	   	  myField.editable = false;
	   	  
	   	  var myMethodString = 'function ' + mname+ '()'
	   	  	myMethodString += ' {' 
	   		myMethodString += '   application.output("A direction of " + direction + " has a heading of " + degrees + " degrees.");'
	   		myMethodString += ' }'
		  var myMethod = jsform.newFormMethod(myMethodString);
	   	  myMethod.showInMenu = false;
		  jsform.onRecordSelection = myMethod
	}

  //Add newly created form to existing tab panel
  elements.tabs_extlData.addTab(forms[fname],'CompassTab','Compass',null,null,'#000000','#BBCCEE');

The evt_onHide method:

	elements.tabs_extlData.removeAllTabs()

ronm:
Unfortunately not so obvious to me :oops:

My onRecordSelection method is a global method. I have a method that tell me what form I am on regardless of how deeply nested.

So inside my onRecordSelection method:

application.output('onRecordSelection_myResults - getSelectedIndex:  ' + forms['formName'].foundset.getSelectedIndex());

that ‘formname’ is that a string? That should be a variable that is filled by the JSEvent.getFormName()

so a global onrecordsection method:

function onRecordSelection(event)
{
application.output('onRecordSelection_myResults - getSelectedIndex:  ' + forms[event.getFormName()].foundset.getSelectedIndex());
}

that should work fine.

ROCLASI:
Well it seems Servoy made it so that the controller.find() will not go into findmode but the foundset.find() does.
And when you use foundset.find() you get the following error:

controller.find/search should work, also on forms based on a dataset.
I just did a small test and it worked fine.

Rob

Johan’s solution works in Servoy version 5.xx. My production system is version 4.1.5.

in 4 you can use the application.getMethodTriggerFormName() to get the form that triggered your method.

ROCLASI:
So I guess they forgot to ‘fix’ the foundset.find() like they ‘fixed’ the controller.find().

Servoy 5.1 - build 956

Edit: filed case #275857

We cannot reproduce this, if you have a sample solution that shows this issue, please send it to us.

Rob

Will do that today.

Ack!
I did my test on a form without any table or dataset attached. So that error makes sense.
However foundset.find() does go into findmode while controller.find() doesn’t (when no datasource is attached). So I guess it should use the same check there as well. So this is (a different) bug anyway.

As for forms with a dataset as datasource. Indeed this works.
Sorry for the (wrong) noise. I should have tested this better. Just didn’t had the time at that moment.

ROCLASI:
However foundset.find() does go into findmode while controller.find() doesn’t (when no datasource is attached).

This has already been corrected for next release.

Rob