I am trying to auto populate some cells based on the initial key strokes the user makes in that cell. I’ve got most of this working except the part that would write the new contents of the cell.
In my ide I have a two column table, the cell that is being edited is the second col of the first row. Here’s the code I have so far (if this can be written more efficiently let me know - at some point I might stick the photographers list into a MySQL db and use a shell script to call it as AS-S’s lack of application wide globals is annoyingly restrictive but that’s another thread:
property photographers : {"Joe Photographer", "Jane Photographer", "Ralph Photographer", "Charlie Photographer", "Freelancer", "Other Staff"}
property theKeystrokes : 0
property theKeyHit : {}
on keyboard up theObject event theEvent
set thisTable to table view "table1" of scroll view "tableScroll" of window "mainWin"
set thisRow to selected row of thisTable as string
set theKeystrokes to theKeystrokes + 1
copy (character of theEvent as string) to end of theKeyHit
if theKeystrokes > 1 then
set thisNameBlurb to ""
--build out name blurb
try
repeat with thisLetter in theKeyHit
set thisLetter to thisLetter as string
set thisNameBlurb to thisNameBlurb & thisLetter
end repeat
on error errMsg
display dialog errMsg
end try
--check photographer list
repeat with thisPhotographer in photographers
if thisPhotographer begins with thisNameBlurb then
--THIS IS WHERE I GET STUCK. THE APP DOESN'T BREAK BUT IT ALSO DOESN'T WORK, ANY HELP
--WOULD BE APPRECIATED
set (content of data cell 2 of data row 1 of data source of theObject) to thisPhotographer as string
--display dialog thisPhotographer
end if
end repeat
set theKeystrokes to 0
set theKeyHit to {}
end if
end keyboard up
maybe you could use an NSComboBoxCell for this column? It hast a built-in autocompleting feature which can be setup and enabled with only a few ‘call methods’:
property photographers : {"Joe Photographer", "Jane Photographer", "Ralph Photographer", "Charlie Photographer", "Freelancer", "Other Staff"}
on awake from nib theObject
set thisTable to table view "table1" of scroll view "tableScroll" of window "mainWin"
tell data cell "comboBoxCell" of table column "column" of thisTable
call method "setUsesDataSource:" of it with parameter no
call method "setCompletes:" of it with parameter yes
call method "addItemsWithObjectValues:" of it with parameter photographers
end tell
end awake from nib
Now every cell autocompletes when typing one of the first characters from the photographers list and additionally has a pulldown menu with these items.
We had thought about that but some of the entries that we want to auto complete have hundreds of listings (photo locations). As I flesh this out more it’ll make a call to a MySQL db to see if the photographer or location is listed there and autocomplete if it is, if not, it’ll offer the option to add this to the database.
Anyway, I figured out a solution. If someone has a better way, please share. What I had to do was reset the focus on something other than the cell I was trying to write into. For this example I just dumped a hidden text field in the IDE and reset the focus of the window to that.
property photographers : {"Joe Photographer", "Jane Photographer", "Ralph Photographer", "Charlie Photographer", "Freelancer", "Other Staff"}
property theKeystrokes : 0
property theKeyHit : {}
on keyboard up theObject event theEvent
set thisTable to table view "table1" of scroll view "tableScroll" of window "mainWin"
set thisRow to selected row of thisTable as string
set thisCol to selected column of thisTable as string
set theKeystrokes to theKeystrokes + 1
copy (character of theEvent as string) to end of theKeyHit
if theKeystrokes > 1 then
set thisNameBlurb to ""
--build out name blurb
try
repeat with thisLetter in theKeyHit
set thisLetter to thisLetter as string
set thisNameBlurb to thisNameBlurb & thisLetter
end repeat
on error errMsg
display dialog errMsg
end try
--check photographer list
repeat with thisPhotographer in photographers
if thisPhotographer begins with thisNameBlurb then
set first responder of window "mainWin" to text field "hiddenText" of window "mainWin"
set contents of data cell 2 of selected data row of theObject to (thisPhotographer as string)
end if
end repeat
set theKeystrokes to 0
set theKeyHit to {}
end if
end keyboard up
Just to add to the pool of knowledge and stuff - here’s my expanded code. Feel free to comment and let me know if it could be streamlined.
property theKeystrokes : 0
property theKeyHit : {}
on keyboard up theObject event theEvent
set thisTable to table view "table1" of scroll view "tableScroll" of window "mainWin"
set thisRow to selected row of thisTable as string
set thisCol to selected column of thisTable as string
set theKeystrokes to theKeystrokes + 1
copy (character of theEvent as string) to end of theKeyHit
if theKeystrokes > 1 then
set thisNameBlurb to ""
--making sure we are using MySQL
try
set mySQLList to {"/usr/local/mysql/bin/", "/Library/MySQL/bin/"}
repeat with i from 1 to the count of mySQLList
try
set theResult to do shell script (item i of mySQLList) & "mysql -V"
set gPathToMySQL to (item i of mySQLList)
set haveFound to true
exit repeat
end try
end repeat
set gmySQLCommand to gPathToMySQL & "mysql"
on error errMsg
display dialog "Oops! - Error connecting to database" & return & return & errMsg
end try
--set which db and table
set theDatabase to "photoarchive"
set theTable to "photographers"
--build out name blurb
try
repeat with thisLetter in theKeyHit
set thisLetter to thisLetter as string
set thisNameBlurb to thisNameBlurb & thisLetter
end repeat
on error errMsg
display dialog errMsg
end try
--make the query
set queryString to "SELECT photoName FROM " & theTable & " WHERE photoName LIKE '" & thisNameBlurb & "%'"
set theResults to my runQuery(queryString, theDatabase, gmySQLCommand)
--parse results
set AppleScript's text item delimiters to ASCII character 13
if (count of every text item of theResults) > 1 then
set thisPhotographer to text item 2 of theResults
else
--if db does not contain record match
display dialog "I cannot find a record with this Photographer's name. Would you like to add it to the database?" buttons {"Yes", "No"} default button "Yes"
set thisAnswer to button returned of result
if (thisAnswer as string) = "Yes" then
display dialog "Enter new listing here." default answer ""
set thisPhotographer to text returned of result
try
--add new name to db
set queryString to "INSERT INTO " & theTable & "(photoName) VALUES " & "('" & thisPhotographer & "')"
set theResults to my runQuery(queryString, theDatabase, gmySQLCommand)
on error errMsg
display dialog "Oops! Error uploading data to database" & return & return & errMsg
end try
else
return
end if
end if
set first responder of window "mainWin" to text field "hiddenText" of window "mainWin"
set contents of data cell 2 of selected data row of theObject to (thisPhotographer)
set theKeystrokes to 0
set theKeyHit to {}
end if
end keyboard up
(*S U B R O U T I N E S*)
--do mySQL queries
on runQuery(queryString, theDatabase, gmySQLCommand)
set theHost to "10.1.*.***"
set theUser to "mysqladmin"
set thePassword to "******"
set thePort to "3306"
set theLoginString to " -h " & theHost & " -u " & theUser & " --password=" & thePassword
set dataBaseString to " -D " & "'" & theDatabase & "'"
set theCommand to gmySQLCommand & theLoginString & dataBaseString & " -e \"" & queryString & "\""
set theResult to ""
--display dialog theCommand
try
set theResult to do shell script theCommand
on error errMsg
display dialog errMsg
end try
return theResult
end runQuery