Pop Up Button Cell in Table View Question

Hi All,
I’m trying to expand my table skills. I’ve set up a table view to display the properties from a list of script object instances using the Shane’s instructions from his book. I’ve also been able to figure out how to add a pop up button in each row that is populated from a list strings in my code. With this, every pop up is populated with the same text items.

What I’d like to do now is be able to add a pop up button for each row that is populated with items that depend on the row in which it is found. My thinking was to create a list property within the table’s script object that can be dynamically changed in code for each instance, and then bind it to the pop up button cell. It sounds like it should work, but I can’t get the mechanics right. The closest I’ve come to success is to bind the cell’s content value to the table’s array controller and then set the model key path to the created list property. The problem is that instead of using the list as an array of text items, it coerces the list to a single text item, and then displays it a multiple of times in the pop up, one for each row in the table. Also, each pop up is identical with this approach.

I hope the above makes sense. Any help would be appreciated.

Never mind. Of course right after I post my question I figure it out. Changing the controller key to selection did the trick.

Never mind on the never mind. I thought it was working but closer inspection it appears that when I initially click on the pop up I get the right items, but then when I click on a second pop up, regardless of which row, the same exact list of items shows up. The next pop up then shows the list from the previous pop up, and so on. Any hints? Thanks.

What you want to do, it seems to me, is not really the job of a single table – this seems like something you would do with a master-detail interface with two tables. The first would have the different script objects in the rows, and the second would show the details of the selected script object.

Ric

Hi Ric,
Thanks for the response. I actually had something like what you suggested, but it was a little cumbersome to use. The table is both informational, and users also need to input information for each row item before all the data is processed. My use is kind of complicated, but a simplified example would be a table that lists ingredients for a recipe and the user needs to select the quantity of each ingredient from a preset list of options. The problem is for liquid ingredients, the list of user choices are volumes, but for solids, the choices are weights. In the old version, the user would have to select each row, and then make selections from radio buttons that would change depending on what is in the selected row. Which is kind of what you’re suggesting. That works, but it seemed like it would be streamlined if the user could make the selection directly from a pop up in each row. So continuing my example, rows with liquids would have a pop up with volume choices, and rows with solids would have a pop up with weight choices. It’s partially an academic question, but I was hoping that there is a solution out there.

Yes. The problem is that the NSPopupButton is clicked before the array controller is informed of the currently selected row, so you can’t query the array controller for its selected objects because it might be from the previously selected row. Instead, ask for the clicked row of the table and explicitly set the selection:

[i]tell <your array controller> to setSelectionIndex_(theTable's clickedRow())[/i]

(Note: you have to bind the variable theTable in IB to the actual table.)

Thanks heb! I’ll give it a try.

It looks like I’m going to need a little bit more help with this. It seems that no matter what I’ve tried, the pop up opens before I can:

tell myArrayController to setSelectionIndex_(theTable’s clickedRow())

I guess where I’m stuck with is where to put this. When the row is clicked is too late. When I mouse down on a row, the row is highlighted, which seems to me to be the event that I want to use for my code, but I’m not sure how to do that.

Following your ingredients example you posted above, this app worked to populate the popups in the 2 rows with different values:

script IngredientsAppDelegate
	property parent : class "NSObject"
	property measurementList : missing value
	property dryList : {"tsp", "Tblsp", "cup", "pinch"}
	property wetList : {"ml", "dl", "oz", "pint", "quart"}
	property theData : missing value
	property arrayController : missing value
	property theTable : missing value
	
	on applicationWillFinishLaunching_(aNotification)
		setTheData_(current application's NSMutableArray's arrayWithArray_({{amounts:missing value, ingred:"Flour"}, {amounts:missing value, ingred:"Milk"}}))
		theTable's deselectAll_(me)
	end applicationWillFinishLaunching_
	
	on tableViewSelectionIsChanging_(aNote)
		set sel to aNote's object's selectedRow()
		if theData's objectAtIndex_(sel)'s valueForKey_("ingred") as string is "Milk" then
			setMeasurementList_(wetList)
		else if theData's objectAtIndex_(sel)'s valueForKey_("ingred") as string is "Flour" then
			setMeasurementList_(dryList)
		end if
	end tableViewSelectionIsChanging_
	
	on click_(sender)
		log arrayController's arrangedObjects()
	end click_
	
	(* The script is set as the delegate for the NSTableView, theTable
       The array controller's content array is bound to IngredientsAppDelegate.theData
       The column titled "Ingredients" has its *value* bound to Array Controller.arrangedObjects.ingred
       The column titled "Amount" has its *Selected Value* bound to Array Controller.arrangedObjects.amounts
       The popUpCell button cell has its *Content Values* bound to IngredientsAppDelegate.measurementList
	*)
end script

Hope this helps,

Ric

That did it. Thank you very much.