This handler filters a data source for an AppleScript Studio project. It should be easy to change what column(s) it searches, and whatever sorting you want to use.
OS version: OS X
-- filter - string to search for
-- theTable - the table view which displays the data source
-- theFullDS - the unfiltered data source
on filterDataSource(filter, theTable, theFullDS)
try
delete data source "filtered"
end try
if filter is not "" then
set theDS to make new data source at end of data sources with properties {name:"filtered"}
repeat with i in every data column of theFullDS
set theCol to make new data column at end of data columns of theDS
tell theCol
set name to name of i
set sort type to sort type of i
set sort case sensitivity to sort case sensitivity of i
set sort order to sort order of i
end tell
end repeat
repeat with i in every data row of theFullDS
--change next line if you want to filter multiple data cells or a different data cell.
if contents of data cell 1 of i contains filter then
set theRow to make new data row at end of data rows of theDS with properties {associated object:(associated object of i) as string}
repeat with j from 1 to count of every data cell of i
set name of data cell j of theRow to name of data cell j of i
try
set contents of data cell j of theRow to contents of data cell j of i
end try
end repeat
end if
end repeat
set sort column of theDS to data column 1 of theDS
set sorted of theDS to true
set data source of theTable to theDS
else
set data source of theTable to theFullDS
end if
update theTable
end filterDataSource
Hello fellow scripters,
First I would like to thank the original author of this script - it helped me immensely. Secondly, I wanted to share my changes/tweeks to this script.
My goal was to create an AppleScript SEARCH-AS-YOU-TYPE kind of search of the contents of a table so the results would quickly be funneled down visually. I put together this test application (built from what was originally Jonathan Nathan’s “get_rows” example - because I also wanted to get data on the selected rows of the found set of data, thanks Jonathan!). The entire XCode project can be downloaded here:
In a nutshell the example will randomly populate the bottom table with data and:
If text is typed in the search field it will display all matches in the top table
The search is performed as you type and the results are updated as you go
Additional buttons exist to show how to programatically:
* Set the selected rows
* get the selected rows (a list of numbers)
* get the selected data rows (a list of references to the data row)
* Scroll to a row - forces the table to show it if it is not visible
The two chunks of code in the XCode project that do the work are:
-- Here is where the user initiates the search by typing in a text field named "searchField"
on action theObject
if name of theObject is "searchField" then
if searchAction is false then -- we are not already performing another search
set searchAction to true -- tell the app we are now performing a search
-- GET THE DATASOURCE TO BE SEARCHED
set theFullTable to table view 1 of scroll view "with_ds" of window "main"
set theFullDS to data source of theFullTable
-- GET THE TABLE USED TO DISPLAY THE FOUND SET
set theFilteredTable to table view 1 of scroll view "without_ds" of window "main"
set theFilteredDS to data source of theFilteredTable
-- GET THE FILTER CRITERIA
set theFilter to contents of text field "searchField" of window "main"
-- COMPARE THIS TO PREVIOUS SEARCH CRITERIA
set a to (count of currentSearchCriteria)
set b to (count of theFilter)
if (a > 0) and (b > a) then
set theTest to (characters 1 thru a of theFilter) as string
if (theTest is currentSearchCriteria) and (searchStatus is true) then
beep
set theFullDS to theFilteredDS
end if
log theTest
end if
set currentSearchCriteria to theFilter
if theFilter is not "" then -- we have something to search for
log "theFilter = " & theFilter
my filterDataSource(theFilter, theFilteredTable, theFullDS)
else
set data source of theFilteredTable to theFullDS
end if
end if
set searchAction to false -- tell the app we are no longer performing a search
end if
end action
-- theFilter - string to search for
-- theTable - the table view which displays the data source
-- theFullDS - the unfiltered data source
on filterDataSource(theFilter, theTable, theFullDS)
tell progress indicator "progressWheel" of window "main" to start
set searchStatus to false -- tell the app we are currently performing a search
--set theCount to count of data sources of me
--log (theCount as string) & " data sources of me"
-- WE NEED TO DELETE DATA SOURCES WE ARE NO LONGER USING
-- WE KEEP X AROUND IN CASE WE NEED TO SEARCH IT AS A SUBSET
try -- Clean Up - delete the filtered datasource x-1 since we no longer need it
delete data source ("filtered" & ((x - 1) as string))
on error
log "could not delete data source named " & ("filtered" & ((x - 1) as string))
end try
set x to x + 1 -- we use x to increment the filtered data source name so we can identify the ones currently in use
if (theFilter) is not "" then -- we have something to search for
-- CREATE THE DATASOURCE TO STORE THE FOUND RESULTS
-- BUILD IT USING THE PROPERTIES OF THE DATABASE WE ARE SEARCHING (DUPLICATE THE STRUCTURE)
set theDS to make new data source at end of data sources with properties {name:"filtered" & x as string}
repeat with i in every data column of theFullDS
set theCol to make new data column at end of data columns of theDS
tell theCol
set name to name of i
set sort type to sort type of i
set sort case sensitivity to sort case sensitivity of i
set sort order to sort order of i
end tell
end repeat
set update views of theDS to false
-- ASSIGN THE NEWLY CREATED DATASOURCE TO THE TABLE VIEW
set sort column of theDS to data column 1 of theDS
set sorted of theDS to true
set data source of theTable to theDS
set localSearchCount to globalSearchCount
try
append theDS with (contents of data cells of (data rows of theFullDS whose ((contents of data cell 2 of it contains theFilter) or (contents of data cell 3 of it contains theFilter))))
on error theError number theNumber
log theError & tab & theNumber
end try
tell progress indicator "progressWheel" of window "main" to stop
end if
update theTable
set searchStatus to true
end filterDataSource
There are a couple of bugs/issues with the above code, and I updated/improved the search functionality even further, providing a much more robust solution than the one mentioned above, in my iTunes remote application (source code found here - http://www.beebeography.com/remoteitunes/index.html). The version I used in the iTunes remote only uses one table - when a search is performed it will replace the table contents with the found set (keeping the original data safe behind the scenes). If the search is canceled the original full set of data is reinstated in the table view. Unfortunately the code is harder to separate from the rest of the application so if you want to see how it works download the source code and scroll to the very bottom of the script named “iTunes Remote.applescript” - there is a section labeled “FILTER_METHODS” that holds the bulk of it.
I hope someone finds this useful, if you have any questions or comments they would be greatly appreciated!
jON bEEBE
I too write an open source iTunes remote control app (TuneConnect, http://www.tuneconnect.net), and if you don’t mind I think I’ll take a look into implementing this in my track browser.
Feel free to download my source code and take a look through it-- see if you can find anything you can use. It’s not modeled after iTunes like so many remote control apps, but instead has two windows: an iTunes-like mini-player to control the music, which features a search box to play a song if you know what you’re looking for, and a track browser that is similar to the iTunes interface.