Thursday, October 17, 2019

#1 2019-10-02 12:39:57 pm

AoRaToS
Member
From:: Greece
Registered: 2019-09-01
Posts: 8
Website

Populating TableView with database data

Hello all,

I'm looking for some help setting a table view to show data that I have in an sql database. I have created the database and can get data from it with no problem. I have created a TableView item in a window and I'm trying to set the data to it. The TableView doesn't seem to accept a list, it needs an array, however I get errors when I create an array.

My goal is to have 2 TableView items, one that populates from the database, and the second that populates the ID of 10 of my own selections from the first one.

the first TableView has: ID|First Name|Last Name|Email

the second TableView has: ID

If I get how to add simple data to the tableView item I'm sure I'll figure out the rest, can anyone point me in the right direction? I guess my issue is with bindings, I would prefer binding with code.

Data I'm trying to parse to it is:

set my questionArray to {cqcID:"0", cqcFName:"Nick", cqcLName:"Smith", cqcMail:"nsmith@test.com"}

also tried:
set my cqcData to current application's NSMutableArray's arrayWithArray:questionArray
tell theFirstArrayController to addObject:cqcData

The error messages I'm getting are:

Illegal NSTableView data source (<NSArrayController: 0x600003d04a50>[object class: NSMutableDictionary, number of selected objects: 1]).  Must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:

or

*** -[AppDelegate applicationWillFinishLaunching:]: *** -[NSArray initWithArray:range:copyItems:]: array argument is not an NSArray (error -10000)

Thank you,
AoRaToS

Last edited by AoRaToS (2019-10-02 01:57:28 pm)

Offline

 

#2 2019-10-03 11:46:22 pm

technomorph
Member
Registered: 2017-12-14
Posts: 124

Re: Populating TableView with database data

Tell 1stArrayController to setContent:theArray

In the tableView each column in the bindings inspector

Bind to 1stArrayConntroller
Arranged Objects
CqcID

Repeat and just change the key of according to the key in the Array or dictionary

Also in your example you created an array of dictionary objects
You want to create multiple dictionaries and add each dictionary to the array.

The arrayController’s content is an Array of items (objects) (dictionaries)
The tableView column controller is looking to the ArrayControllers
“Arranged Objects”  (the order that the  controller has arranged them in (using
Some sort method))............

Each object in the TableView will be represent by a row.
And each column will show the value for the Key that you have provided

cqcName etc

Offline

 

#3 2019-10-04 12:16:27 am

technomorph
Member
Registered: 2017-12-14
Posts: 124

Re: Populating TableView with database data

For your second question:

My goal is to have 2 TableView items, one that populates from the database, and the second that populates the ID of 10 of my own selections from the first one.



You'll Need:
- another mutableArray
mySelectionsArray
- another arrayController
mySelectionsController
- another TableView
mySelTableView
- a "add" button
addToMySelButton
while your at it may as well add a remove as well
- a "remove" button
removeFromMySelButton


-drag new ArrayController Object to sidebar in IB
-drag new TableView to where you want it
-drag 2 new buttons to your view

connect the controller, tableViews, 2 buttons to your outlets in your
appleScript class (appleScript Delegate I'm guessing)

Applescript:

set mySelectionsArray to current application's NSMutableArray's new()

you can either set the content of the mySelectionsController via IB
in the ArrayController's binding section. bind to "Delegate" with key path of "mySelections"
or programatically set the content.

Applescript:

mySelectionsController's setContent:mySelectionsArray

bind the AddToMySelButton's action in IB to this function:

Applescript:

on addSelToMySelection:sender
set aSelectedObject to 1stArrayConntroller's selection
--(it's good practice to check to make sure that there is a selection before continuing)
if aSelectedObject is not missing value then
mySelectionsController's addObject:aSelectedObject
end if

bind the removeFromMySelButton's action in IB to this function:

Applescript:

on removeSelFromMySelection:sender
set aRemoveSelectedObject to mySelectionsController's selection
--(it's good practice to check to make sure that there is a selection before continuing)
if aRemoveSelectedObject is not missing value then
mySelectionsController's removeObject: aRemoveSelectedObject
end if

actually I think on the remove you can just drag the action from the removeButton to
the mySelectionsController object in IB and a menu will appear and your can select remove

Offline

 

#4 2019-10-06 06:17:11 am

AoRaToS
Member
From:: Greece
Registered: 2019-09-01
Posts: 8
Website

Re: Populating TableView with database data

Hello technomorph,

Thank you for your valuable support. I think my array is not created correctly...
What is the correct format that I can pass over to the array controller?

Also in your example you created an array of dictionary objects
You want to create multiple dictionaries and add each dictionary to the array.



let's say my first row needs to be:
cqcID:"0", cqcFName:"Nick", cqcLName:"Smith", cqcMail:"nsmith@test.com"

and the second line:
cqcID:"1", cqcFName:"Ben", cqcLName:"Doe", cqcMail:"jdoe@test.com"

my actual code looks like this:

Applescript:

repeat with qCount from 1 to maxQuestionNum
set currentData to convertStringToList(sqlQuery("select ID, Product, Question, Category from " & qTableName & " where ID = '" & qCount & "'"), "|")
set questionArray to {{QuestionID:item 1 of currentData}, {Product:item 2 of currentData}, {Question:item 3 of currentData}, {Category:item 4 of currentData}}
---???
end repeat

where I put ---??? is where I'm trying to add data to the array controller which ends up in adding empty lines or errors

I've also tried:
set my questionArray to recordFromLabelsAndValues(currentLabels, currentData)

using:

Applescript:

on recordFromLabelsAndValues(theseLabels, theseValues)
   set theResult to ¬
       current application's NSDictionary's dictionaryWithObjects:theseValues forKeys:theseLabels
   return theResult as record
end recordFromLabelsAndValues

which returns records but my results are the same. I think I need to start a quick simple code example and get it to work and then adjust it for the database data

Last edited by AoRaToS (2019-10-06 06:18:33 am)

Offline

 

#5 2019-10-06 10:02:23 pm

technomorph
Member
Registered: 2017-12-14
Posts: 124

Re: Populating TableView with database data

let's say my first row needs to be:
cqcID:"0", cqcFName:"Nick", cqcLName:"Smith", cqcMail:"nsmith@test.com"

and the second line:
cqcID:"1", cqcFName:"Ben", cqcLName:"Doe", cqcMail:"jdoe@test.com"



so basically those are each a dictionary that you need to create.
And add each of those dictionary to your array.  Your code below is a bit off
as your nesting each KeyValue item in its own array.

my actual code looks like this:

Applescript:

repeat with qCount from 1 to maxQuestionNum
set currentData to convertStringToList(sqlQuery("select ID, Product, Question, Category from " & qTableName & " where ID = '" & qCount & "'"), "|")
set questionArray to {{QuestionID:item 1 of currentData}, {Product:item 2 of currentData}, {Question:item 3 of currentData}, {Category:item 4 of currentData}}
---???
end repeat



try something more like this:

Applescript:



set theArray to {}

repeat with qCount from 1 to maxQuestionNum
set currentData to convertStringToList(sqlQuery("select ID, Product, Question, Category from " & qTableName & " where ID = '" & qCount & "'"), "|")
set questionDict to {QuestionID:item 1 of currentData, Product:item 2 of currentData, Question:item 3 of currentData, Category:item 4 of currentData}
-- if that doesn't work try this instead
-- set questionDict to {QuestionID:(item 1 of currentData), Product:(item 2 of currentData), Question:(item 3 of currentData), (Category:item 4 of currentData)}

set the end of theArray to questionDict

end repeat

arrayController's setContent:theArray

^^^ you are then creating a dictionary of each one, and addicting each dictionary to the array
I always find it's easier to create the whole array 1st.   Then set the arrayController content
to theArray.

If you want to use the controller to do it: 

Applescript:



set theArray to {}
arrayController's setContent:theArray

repeat with qCount from 1 to maxQuestionNum
set currentData to convertStringToList(sqlQuery("select ID, Product, Question, Category from " & qTableName & " where ID = '" & qCount & "'"), "|")
set questionDict to {QuestionID:item 1 of currentData, Product:item 2 of currentData, Question:item 3 of currentData, Category:item 4 of currentData}
-- if that doesn't work try this instead
-- set questionDict to {QuestionID:(item 1 of currentData), Product:(item 2 of currentData), Question:(item 3 of currentData), (Category:item 4 of currentData)}

arrayController's addObject:questionDict

end repeat

I've also tried:
set my questionArray to recordFromLabelsAndValues(currentLabels, currentData)

using:

Applescript:

on recordFromLabelsAndValues(theseLabels, theseValues)
   set theResult to ¬
       current application's NSDictionary's dictionaryWithObjects:theseValues forKeys:theseLabels
   return theResult as record
end recordFromLabelsAndValues

using the above like this:

Applescript:



set currentLables to {"QuestionID", "Product", "Question", "Category"}
set theArray to {}

repeat with qCount from 1 to maxQuestionNum
set currentData to convertStringToList(sqlQuery("select ID, Product, Question, Category from " & qTableName & " where ID = '" & qCount & "'"), "|")
set questionDict to my recordFromLabelsAndValues(currentLabels, currentData)

set the end of theArray to questionDict

end repeat
arrayController's setContent:theArray

or to use the controller to add like this:

Applescript:



set currentLables to {"QuestionID", "Product", "Question", "Category"}
set theArray to {}
arrayController's setContent:theArray

repeat with qCount from 1 to maxQuestionNum
set currentData to convertStringToList(sqlQuery("select ID, Product, Question, Category from " & qTableName & " where ID = '" & qCount & "'"), "|")
set questionDict to my recordFromLabelsAndValues(currentLabels, currentData)
arrayController's addObject:questionDict

end repeat

Offline

 

#6 2019-10-09 03:19:43 pm

AoRaToS
Member
From:: Greece
Registered: 2019-09-01
Posts: 8
Website

Re: Populating TableView with database data

Hello technomorph,

thank you very much for all your help. I managed to sort everything out and got it all to work. I also removed that loop through the database and replaced it with 4 calls (1 for each column), I could replace it with 1 but the data would need more editing before being passed to the array controller.
Anyway, I really enjoyed working on this and learning at the same time. Once again thank you for your input! smile

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)