Datasource in a tab - No access when tab is not selected?

I am having a problem where a datasource works perfectly when the tab it resides in is visible. When I have selected any other tab it throws an error. The code and error follow.

set theWindow to window of theObject
set theTabView to tab view item "contactInfoTab" of tab view "ContactTabData" of theWindow
set theTableView to table view "contact_info_table" of scroll view "contact_info_table" of theTabView
set theDataSource to data source of theTableView
--perform work here...

Error: NSCannotCreateScriptCommandError (10)

When I comment out the last line “set theDataSource to data source of theTableView” the code does not throw an error when executed while the other tabs are selected.

Has anyone had this error? And does anyone know how to fix it?

Thanks for your help!
jON bEEBE

Tab views can be frustrating. :rolleyes:

That said, you have few options when it comes to manipulating object data and values for tab view items that are not the current one. The key I’ve found is to be very selective about how and when you reference the objects. Truthfully, you should only try to set data when you want to display it, which will eliminate some of your problem right there. The trick is finding a way to display the information after first making sure the tab view is selected.

Another thing that many people forget (largely due to the lack of decent documentation) is that the data source is an object NOT AT ALL dependent on the the object displaying it. A data source is an application-level object that can be managed regardless of the whether the object you want to display it in is visible… or even loaded from it’s nib. Rather than using a “set theDataSource to data source of theObject” to reference your data source, get in the habit of managing the data source directly (by name). Then, when you want something to display the data source you can simply tell it to use that data source.

For example, set up your data source in the application ‘launched’ handler…

on launched theObject
	set theDataSource to make new data source at end of data sources with properties {name:"MyDataSource"}
	tell theDataSource
		make new data column at end of data columns with properties {name:"column1"}
		set theRow to make new data row at the end of the data rows
		set contents of data cell "column1" of theRow to "Test"
	end tell
end launched

Then use handlers that only set the data source of your table view when you are certain that the object is in view. You can use the ‘selected tab view item’ handler of the tab view…

on selected tab view item theObject tab view item tabViewItem
	if ((name of tabViewItem) as string) is "tab2" then
		set theTableView to table view "tableView" of scroll view "scrollView" of tab view item "tab2" of tab view "tabs1" of window "window"
		set data source of theTableView to data source "MyDataSource"
	end if
end selected tab view item

Or you could use a control to manually set the current tab view item and THEN update the data source of the object…

on clicked theObject
	if name of theObject is "tab2Button" then
		tell tab view "tabs1" of window "window"
			set the current tab view item to tab view item "tab2"
			set theTableView to table view "tableView" of scroll view "scrollView" of tab view item "tab2"
		end tell

		set data source of theTableView to data source "MyDataSource"
	end if
end clicked

There are lots of ways to provide workarounds to this tab view problem. Just make sure that you provide some ‘error-checking’ before asking an object known to be in a tab view to do something… and making it’s tab view item current if it’s not already.

Hope that helps (and is not too confusing ;))…
j

As usual, when I have a problem and consult this site I find jobu’s name behind very useful bits of knowledge. Thanks for the tip!

By referencing the datasource directly via its name all my problems were solved. In this particular case I needed to click a button and have a few text fields update via data in the next/previous row of the datasource while it was hidden, and this did the trick perfectly.

Now I want to get picky and ask if there exists a way to tell the datasource to visually select the next row without the mouse actually clicking it. I would like to press a button telling the data source to pull data from the next row (which I already have working) and ALSO have it reflect this visually by highlighting the next row. Is this possible? Maybe there is a “set highlighted to true” type of command someone knows of? I have thus far been unsuccessful.

Once again, thanks for your help - there are many of us scripters who are very grateful for your efforts jobu.

jON bEEBE

Remember to separate the data source from the object. Are you trying to go down the table view… or to the next item in the actual data source? To simply make the next item down on the table view highlighted, use something like…

tell tab view "tabs1" of window "window"
	tell table view "tableView" of scroll view "scrollView" of tab view item "tab2"
		set currentRow to selected row
		if currentRow > 0 then
			try
				set selected row to (currentRow + 1)
			end try
		end if
	end tell
end tell

If you’re using a datasource and you are sorting the columns, you may run into problems as the table view may not always reflect the hierarchy of the data source in a linear fashion. You could also read the data source using the ‘selected data row’ property of the table view, and then make the table view change the selected data row, but I think what you’re looking for is in the code above. Check out apple’s table view documentation for more info.

Thanks for the appreciation, that’s why I’m here. :smiley:
j