tags:

views:

401

answers:

3

Is there a way to handle the dynamic change of a dropdown for a single row in a grid-based datawindow?

Example:

NAME    LIKABILITY         PURCHASED IN  COLOUR
(Text)  (DropDown*)        (Text)        (Text)
Bananas [Good]             Hands         Yellow
        [Bad]
        [Bananas are good]

Apples  [Good]             Bags          Red
        [Bad]

Given the above is a grid-based datawindow, where the fields 'NAME','PURCHASED IN' and 'COLOUR' are text fields, where as the 'LIKABILITY' field is a dropdown*.

I say dropdown* because the same visual representation can be created by using a DropDownList (hardcoded within the datawindow element at design time), or a DropDownDW (or DDDW, a select statement that can be based on other elements in the datawindow).

However, there is no way I can get 'Bananas' having it's 3 dropdowns, while Apples has only 2.

If I enter multiple rows of 'Bananas', then all rows have 3 dropdowns, but as soon as I add an Apples row, all dropdowns revert to 2 selections.

To attempt to achieve this functionality, I have tried the following options:

--

1) dw_1.Object.likability.values("Good~tG/Bad~tB/Bananas are good~tDRWHO") on ue_itemchange when editing NAME.

FAILS: edits all instances of LIKABILITY instead of the current row.

--

2) Duplicate Dropdowns, having one filtered, one unfiltered selection list per row, visible based on NAME selection.

FAILS: can't set visibility/overlapping columns on grid-based datawindow. (Source)

--

3) Hard-code display value as Database value, or Vice Versa. Have 'GOOD','BAD','BANANASAREGOOD' as the display and database values, and change handling of options from G, B, DRWHO to these new values.

FAILS: 3rd option appears for all rows, still selectable on Apple rows, which is wrong.

--

4) DDDW retrieve list of options for dropdown. Create a DDDW that uses the value of NAME to determine what selections it should have for the dropdown.

FAILS: edits all instances of the dropdown, not just the current row.

--

5) DDDW retrieve counter of options available (if B then 3 else 2), then have duplicate dropdown columns that protect/unprotect based on DDDW counter.

FAILS: Can't autoselect dddw value to populate column to cause protect on other two columns, ugly solution in any case.

--

There is now a bounty on this question for anyone who can give me a solution that will enable me to edit a dropdown column for a single row on a grid-based datawindow in PB 10.5

+1  A: 

You can edit the contents of the code table on the rowfocuschanged event. Since you can only have one dropdown expanded at once, this should provide the user experience you require.

You can't alter the code table based on expression like you can with e.g. font size unfortunately.

If you need more control over the dropdown, you could make it a DropDownDW. You could re-retrieve it on RowFocusChanged, passing the value from your second column.

Colin Pickard
This one is the answer closest to the solution I went with. I was able to maniputate the rowchange event to change the dropdown to be specific to whatever row the user was currently selecting. Trying to click another row's dropdown is a rowchange event, changing the dropdown back to another solution.I did this by way of a static dropdown, changing it with the dwcontrol.object.column.values syntax on the rowchange method.
glasnt
Interesting. Does it perform well on a large datawindow?
Colin Pickard
+2  A: 

So, the answer to your question is no, you can't have unique contents in DropDownListBoxes (or DropDownDataWindows for that matter) on a row-by-row basis.

The solution to your problem is more complex. You can change the contents of the drop down on RowFocusChanged, but what happens to the presentation on rows where the code value is no longer in the list of values? Only the code value is displayed. It's not great when you're not on a particular row if R is shown instead of Red. So, a common solution is to have two controls, directly on top of one another, to represent that data: one that is visible when the row has focus (the drop down whatever) and the one that is visible when some other row has focus, that shows the display value of the code. In the past I've done this with static text or a dummy edit-style column as the second control, and set the value on the ItemChanged of the first column. However, this morning I'm speculating that you could do this without scripting if the second control was a drop-down column, pointing to the same column in the data set, that always contained the full set of values. I'll leave the experiment (and the few other pieces needed to make this work, like what happens when the user clicks on the second control from another row) up to you.

Good luck,

Terry.


Addendum

You asked about how things are done row by row. This is going to be like Christmas for you (or some other culturally appropriate massive gift-receiving holiday). See in the Properties pane in the DataWindow painter all the elements that have a button to the right with an equals sign? That lets you enter an expression that will evaluate on a row-by-row basis to determine the value of the attribute. To enter an expression so that a field is only visible when it is the current row?

if (getrow() = currentrow(), 1, 0)

You can also Modify() these expressions at run time. I'll leave you to the help to dig that up. The help also gives you a list of attributes for each DataWindow control element, which includes in the table whether or not each attribute takes an expression. (The equals buttons are not 100% of the story; not all expressionable attributes can be expressioned through the IDE.)

Side note: If you get expressions and learn how to master them, you'll get the power of the DataWindow.

As for grids, my second suggestion of column over column won't work in grids, obviously enough. That's the time to fall back to using a column and a static text, for instance, with an ItemChanged script.

T.

Terry
There's a good writeup of the second method Terry mentioned at http://pbbraindump.wordpress.com/category/2-datawindows/drop-down-data-window-dddw/
Hugh Brackett
Off the top of my head I have 2 issues: 1: are you saying that I can set the visibiliy of a DropDown on a row by row basis, but I can't set the codetable values on the same basis? 2: This multi-row datawindow is a Grid formation, which means I'm going to have to do some hardcoding of column locations to get two columns to be one under each other (I've accidently done it before, but otherwise, it requires underlying code changes to get anything overlapping/spaces between columns in the grid mode)
glasnt
See my addendum.
Terry
Your addendum isn't Timmy's best Christmas ever, seeing as though the orphanage is grid-based. I have tried the `if (getrow() = currentrow(), 1, 0)` gleamed from http://pbbraindump.wordpress.com/2008/11/16/the-ol%E2%80%99-hidden-items-in-the-dddw-problem-part-ii/, it didn't work. I've tried hardcoding the dispaly values into the database values, doesn't work (my disclude case appears always). I've tried a DDDW retrieve, I keep getting R0006 errors, I'll keep at the DDDW-retrieve option for now, but if that fails, I'm stuck. PB is making an April Fool out of me :(
glasnt
DDDW Retrieve (having the dropdown based on a select statement) doesn't work as it still updates all instances, not just the row I'm currently working on :(
glasnt
I also tried a DDDW that returns a number that I can use to determine what instance of dropdown I want to have enable/disabled. That was a horrid mess, and didn't work.
glasnt
A: 

Create a dummy column in the select that is large enough to hold the display value. Use a DropDownDataWindow on this column using the display value column for both the display value and the data value. When you retrieve the DataWindow, populate this column by looking up the correct values (hint: use a DDDW on the real, hidden column and call LookUpDisplay(), make sure filter is cleared when you do this); then call ResetUpdate(). Filter the values in the drop-down as desired according to the values on the current row. In the ItemChanged event, when the dummy column value changes, get the code from the DDDW (the DDDW will be on the correct row when the column has focus) and change the value in the hidden column, then change the dummy column status to NotModified. Because the dummy column contains the display value, filtering the DDDW won't cause it to display a code. New rows and update will take care of themselves.

Hugh Brackett
Sorry for the late reply, I have taken a bit to try and work out how to get this advice into a workable solution. This put me on the right track, but I'll post the full answer anyway.
glasnt