Link to home
Start Free TrialLog in
Avatar of stuartbw
stuartbw

asked on

Dynamically setting a drop down data window

I am using PowerBuilder 6.5.  My question has 2 parts. The goal is to create a dropdowndatawindow at run time for one of the columns in a datawindow.

Part 1:
How can I set the dddw for a particular row within the column, while leaving the rest of the rows in that column alone?

Part 2:
The dddw, itself, takes a retrieval argument.  How can I get the code to populate the dddw without it prompting me to enter the retrieval argument?

Notes:
I have come up with the below code which does not work completely.  It is within the rowfocuschanged event of my datawindow.
It doesn't meet the requirement for part 1 because it sets all rows in the column to the dddw.  
It doesn't meet the requirement for part 2 because as soon as the dddw.name property is set, I am prompted for the retrieval argument.  I don't think that an InsertRow(0) will work to suppress the prompt for the retrieval argument, because that window pops up immediately upon setting the dddw.name property.
In order of priority, I would like to get Part 2 to work before getting Part 1 to work.
Thanks!

//CODE BEGINS HERE

int li_thetype, li_theid, li_row
long ll_rtn
DataWindowChild dwc

li_thetype = this.object.datatype[currentrow]
li_theid = this.object.itemid[currentrow]

IF li_thetype = 0 THEN
      this.object.StringValue.dddw.name = "d_list_port_info_ddw"
      this.object.StringValue.dddw.displaycolumn = "listitem"
      this.object.StringValue.dddw.datacolumn = "itemid"
      this.object.StringValue.dddw.useasborder = "yes"
      
      ll_rtn = dw_edit.getChild( "StringValue", dwc)
      dwc.SetTransObject( SQLCA )
      IF ll_rtn = -1 THEN
            MessageBox("Error Data Window Message", "Not a valid child Data Window ")
      ELSE
            dwc.Retrieve( li_theid )
      END IF
ELSE
      this.object.StringValue.dddw.name = ""
      this.object.StringValue.dddw.displaycolumn = ""
      this.object.StringValue.dddw.useasborder = "no"
END IF

//CODE ENDS HERE
Avatar of Vikas_Dixit
Vikas_Dixit
Flag of United States of America image

Hi,

1. for that you may need to have a overlapping computed column over the dropdown. in the visible expression of this computed col, put  (if getRow() = currentrow(), 0, 1) and For the visible property of column with dddw style, set (if getRow() = currentrow(), 1, 0) This way, the dropdown will be visible only for the current row. For rest of the rows, computed field will be visible.

2. By this approach, you code in rowfocus changed will work for case 2, just remove the 4 lines before getChild, and the else! part !

Hope this works,

Regards,
Vikas Dixit
Avatar of stuartbw
stuartbw

ASKER


Thanks very much Vikas!  This works but gives me the following trouble:

1. (2 parts)
A. I don't always want the column I am currently on to be a dddw.  This is determined by the value of another column (also a dddw called itemid).  
B. If the StringValue DDDW column is hidden, the alternate column needs to allow the user to enter a value, so it can't be a computed column.  

So, I need to use the regular column object and change the settings for the visible expression.  When datatype = 0, I want to use the dddw.  I have changed the visible expression in the following way ("datatype" is a hidden column linked to the itemid column):
For DDDW:
IF( datatype > 0, 0, 1)
For Other Column:
IF( datatype > 0, 1, 0)

2. The structure of my window is that of two datawindows (dw_list and dw_edit).  dw_list provides general info about each record, while dw_edit provides the detail (it is the dw_detail datawindow that has the problem).  A rowfocuschanged event in dw_list will cause the dw_edit datawindow to load for the selected record.

The problem I am having is that I am now prompted for the retrieval argument when the dw_edit datawindow first loads.  I can solve this by calling dwc.Retrieve(itemid) in the rowfocuschanged event of dw_list, but I would need to loop through each record in dw_edit and call the retrieve there.  The retrieval argument will be different depending on what is in that itemid column.  How can I do that?

3. If the user changes the value in the itemid column, the StringValue column/dddw_column need to be adjusted.  It would have to determine which column is visible and rerun the retrieve for the new itemid.  This would be done within the itemchanged event in dw_edit for the particular row that has been changed.  How can this be coded?

I think I have solved part 1, but need help with parts 2 and 3.  Thanks again.
Hi,

For 2). In the constructor of dw_edit, do a getchild and InsertRow().

And for 3).  You don't need to determine which column is visible... You don't need two columns ( in the column specifications ), You can paste the same column (insert->control->column) multiple times on a data window ( the name changes to colname_1 etc.). and when you do a setitem on "colname", the value in "colname_1" etc also changes.

regards,
Vikas Dixit
Comment:
Thanks Vikas.
For #2, your suggestion will successfully suppress the application from asking for the retrieval argument (I can do the same thing in the rowfocuschanged event of dw_list).  However, I still want to call the retrieve for each row to initialize them such that the displaycolumn is shown instead of the datacolumn.

The itemid will determine the contents of the dddw for the StringValue column.  So, the additional complication is that if I set the dddw for one row, it will then also affect the rest of the rows with visible dddw's, causing their dddw displaycolumns to be incorrect if their rows have different itemids.  Do you have any suggestions?

For #3, I am doing what you say in regards to pasting the same column twice (so when one column is updated, the other will update also).  However, what I was really getting at for that part was a way to call the retrieve again on the dddw when a different itemid is selected for that row by the user.  I think that once I can find a solution to #2, that can be applied to solve #3.
Hi,

In that case, you need to retrieve (and Keep in the dropdown)  the values for all the itemids and then filter them-out when your id changes for the current row.
You can have one more dddw column, that will not be filtered, and will always have all the values for all the item ids, and the other dddw that will have values filtered  on the basis of the item id. For the currentrow, make the dddw with filtering visible, and for rest of the rows(where the dddw is needed) make the dddw without filtering visible.

Vikas
Sorry it took so long to post, away for the weekend.

Thanks for this interesting suggestion Vikas.  Sorry I have not had a change to reply sooner.

This technique has raised some issues for me:
When the user changes focus from one row to another by clicking on or tabbing to the ItemID column, there is no problem.  The DDDW-NoFilter (DDDW-NF) gets hidden and the DDDW-WithFilter (DDDW-WF) becomes visible for that row.  

However, if the user clicks directly on the StringValue column DDDW, it prevents the DDDW-NF from getting hidden because that is the currently selected object. Even though the DDDW-WF become visible, by the time the user clicks on that column, it already shows me the contents of the DDDW-NF.  I have tried various things in the rowfocuschanged and rowfocuschanging events to set the focus to the DDDW-WF if the user clicks directly on the DDDW-NF, but to no avail.  Do you have any suggestions?
You can make the taborder of DDDW-NoFilter zero. so this will prevent showing the contents of the DDDW-NF.
Vikas Dixit
I thought that would work, but unfortunately it does not because it does not bring focus to the DDDW-WF and I am left with being unable to expand the list in the DDDW.  Is there a way to force the code to set focus to the DDDW-WF column when I click on the DDDW-NF while they are both sitting on top of each other?
you can probably use SetColumn().. May be in clicked event you can put. Keep the taborder zero..

if dwo.name = 'DDDW-NF' then
    SetColumn(''DDDW-WF' )
    SetRow(row)
end if
Hi Vikas - Your suggestion did not work well until I added after SetRow:
      ScrollToRow(row)
      SetFocus()

That has brought me closer, but it is still not optimal because it requires that I click on the DDDW-WF twice before I can get the list to expand.  I think that is because when I call SetFocus it put the initial focus on the ItemID column

I tried using the dddw properties showlist and useasborder to force the list to appear when I click on the DDDW, but that was giving me even more trouble.  What do you think?
ASKER CERTIFIED SOLUTION
Avatar of Vikas_Dixit
Vikas_Dixit
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This works perfectly!  Thanks for all of your help Vikas.  It is much appreciated.