1. James Medick
  2. PowerBuilder
  3. Friday, 7 February 2020 19:19 PM UTC

I've run into a situation which seems to have been around for years.  When filtering a dddw in a datawindow that has multiple rows, I lose the display value and get the key value in the non-current rows using the GetChild and SetFilter.  I found some posted code from years back that seems rather complex. 

Is there a way around this?

This webpage describes the exact problem in detail: https://www.pbdr.com/pbtips/dw/fltrdddw.htm

James Medick Accepted Answer Pending Moderation
  1. Saturday, 8 February 2020 18:58 PM UTC
  2. PowerBuilder
  3. # 1

Thanks to everyone who responded.  After many hours (many) I finally got it working using the advice I received.  These corner cases really eat my lunch.

Thanks again

Comment
There are no comments made yet.
Michael Kramer Accepted Answer Pending Moderation
  1. Saturday, 8 February 2020 12:12 PM UTC
  2. PowerBuilder
  3. # 2

Hi James,

You are right: Filtering of dropdown when multiple rows visible is NOT straightforward.

For argument's sake I will name like this:
Main-DW: DW displayed on screen having a DDDW column.
Child-DW: DW displayed as dropdown for the DDDW column.

Child-DW's primary buffer acts as a lookup table: Data displays with display value when data available in primary buffer.

Now, filtering moves all rows failing the filter-expression into the filter buffer. So such data-display rows are unavailable for the Main-DW.

There are several ways to circumvent this issue and still display the "display" value instead of "data" value for all non-current rows in Main-DW.

  1. No filtering of Child-DW, instead have rows display or hide in dropdown using other techniques.
    Techniques:
    1. Each of my techniques in this case use extra column in Child-DW:
      Column Name=IsActive, Type=long, Initial=1.
      Custom filtering function: Rows passing filter => IsActive=1,   Rows failing filter => IsActive=0

    2. OPTION A: Hide rows based on IsActive.
      Detail band has AutoSizeHeight=true and Height=0.
      Visible attribute on all objects in the detail band: if(IsActive=1, 1, 0)

    3. OPTION B: "Disable" rows based on IsActive.
      Set Font.Strikethrough expression = if(IsActive=1, 0, 1) <= Normal or stricken out
      Set Font.Color expression = if(IsActive=1, 0, ‭8421504‬ ) <= Black or grey(128, 128, 128)

    4. For both options: ItemChanged must fail any selection where IsActive = 0.

  2. Filter but use other technique to display "display" values for all non-current rows despite no row in Child-DW's primary buffer.
    Techniques:
    1. OPTION C: Two DDDW columns display on top of each other.
      Column having filtered DDDW > Visible = if( GetRow( ) = CurrentRow( ),  1, 0 )
      Column having unfiltered DDDW > Visible = if( GetRow( ) = CurrentRow( ),  0, 1 )
      This has resource consumption impact because you allocate an extra DDDW displaying all rows 
      Little performance impact though because you could do RowsCopy from one DDDW to the other instead of retrieving same data into both DDDW.

    2. OPTION D: Filter on/off like your link describes in detail.
      This has performance impact because filter is being turned on and off every so often

 

I have used option B successfully because it works similar to having set of options where some are enabled, others are disabled, but all options appear in place just displaying differently. No surprise to the user like "why is my presumed 'option' gone?" Instead: "Ah! Disabled, so right now I can't choose this specific value.

HTH /Michael

Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Saturday, 8 February 2020 02:47 AM UTC
  2. PowerBuilder
  3. # 3

Now that I think of it, there might be another way of doing this:

- use only one field with the dddw

- instead of filtering the data, somehow set the columns in the dddw to invisible. It's visibility expression would be depending on the value(s) you assign in a hidden field of the dddw. 

- if we're lucky, using the "shift to above" functionality would make the rows appear correctly above each other, without leaving empty white space.

 

It's 02:45 here, so maybe somewhere this weekend, I'll try to make a sample to illustrate what I mean (and see if it's possible).

Comment
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Saturday, 8 February 2020 02:22 AM UTC
  2. PowerBuilder
  3. # 4

"Edit: I realize this is exactly what John has answered before" embarassed

One 'ugly' way of doing this, would be by using a second column, below the first one, with the same dddw assigned (and which you do not filter). That one is only visible if the currently selected/active row is NOT the row it's shown on. For the current row it would have to be invisible and instead you'd show the filtered first dddw.

In other words both fields need an expression in their visible attribute to show when current row or not.

This won't be possible/easy with a grid dw though as you cannot position 2 fields on top of each other.

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Saturday, 8 February 2020 00:33 AM UTC
  2. PowerBuilder
  3. # 5

Hi, James -

Some years ago I figured out a technique that accomplishes what you're requesting. If I recall, it involved one or more computed fields, one of which occupies the same space as the data column utilizing the DDDW edit style and expressions on the Visible property on the column and computed field. I believe it also required the "always show drop-down arrow" property was NOT enabled on the data column object for best usability/appearance. It's not ù rocket science, but it's not a trivial solution to your issue, either.

Unfortunately, my notes on the subject are at the office and I'm unable to access them until Monday. If no one else is able to assist you this weekend, I will follow up early next week.

Regards, John

Comment
There are no comments made yet.
James Medick Accepted Answer Pending Moderation
  1. Friday, 7 February 2020 21:10 PM UTC
  2. PowerBuilder
  3. # 6

Not sure how I would do that.  It is already a dddw.  How would formatting work?

Comment
  1. mike S
  2. Saturday, 8 February 2020 02:31 AM UTC
format is used / displayed when the column doesn't have focus. so use an expression - you can use a case statement to decode the values.
  1. Helpful
  1. mike S
  2. Saturday, 8 February 2020 15:20 PM UTC
at runtime, get all the values in the dddw child and create a case statement out of it. then do a modify to set that as the format. so if your dddw has just 2 rows of Y/N, then it would look something like the following:



string ls_format

ls_format = "CASE column WHEN 'Y' THEN 'Yes' WHEN 'N' then 'No' END"

dw_1.modify( 'column.format="~t ' + ls_format +'"')



for a real dddw, you would need to read each row of the retrieved dddw and build the format from those values



another option that may work, is you could create a 2nd copy of the column , put the same dddw on that field and make the field invisible. then use lookupdisplay as the format expression for the visible copy of that column.
  1. Helpful
There are no comments made yet.
mike S Accepted Answer Pending Moderation
  1. Friday, 7 February 2020 20:19 PM UTC
  2. PowerBuilder
  3. # 7

you would use a format expression

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.