I am trying to create dynamically a group of buttons, using this code:
DEFINE VAR temp-hand AS WIDGET-HANDLE.
DEFINE INPUT PARAMETER ipc AS CHARACTER NO-UNDO.
&global-define X VALUE(v + ipc )
CREATE BUTTON temp-hand
ASSIGN
FRAME = FRAME btn-frame:HANDLE
ROW = vdeInicio
COLUMN = 10
WIDTH = 19
LABEL = ipc
SENSITIVE = TRUE
VISIBLE = TRUE
TRIGGERS:
ON CHOOSE PERSISTENT RUN btn-mess IN THIS-PROCEDURE.
END TRIGGERS.
temp-hand:LOAD-IMAGE("imagenes/Entradas").
vdeInicio = vdeInicio + 3.57.
This works when I address a single button widget, also if a write a loop and call a procedure with this code in it, it creates multiple buttons but points to one handle, some told me than creating a temp table and saving there the widget handle may work, but I donĀ“t know how to populate the table with the widget-handle, can you help me with this,
Something like this:
define temp-table tt_buttonList no-undo
field buttonId as integer
field buttonHandle as widget-handle
.
define variable i as integer no-undo.
do i = i to 5:
create tt_buttonList.
tt_buttonList.buttonId = i.
CREATE BUTTON tt_buttonList.buttonHandle
ASSIGN FRAME = FRAME btn-frame:HANDLE /* this is undefined in your example -- I have no idea where it came from */
ROW = i * 4
COLUMN = 10
WIDTH = 19
LABEL = string( i )
SENSITIVE = TRUE
VISIBLE = TRUE
.
end.
I've no idea why you would run code like this from a trigger procedure. While it might "work", mixing UI into db access code like that is really asking for serious trouble.
Related
I have just created a window, containing a fill-in field (TestField) and a checkbox (chk_TestField):
DEFINE VARIABLE TestField AS INTEGER VIEW-AS FILL-IN.
DEFINE VARIABLE chk_TestField AS LOGICAL VIEW_AS TOGGLE-BOX.
It is very simple to change the value of the fill-in field, based on the checking of the checkbox, something like:
ON VALUE-CHANGED OF chk_TestField IN FRAME DEFAULT-FRAME
DO:
TestField = 5.
END.
However, I'm interested in changing an attribute of the Fill-in field itself, not the integer it represents (I would like to make the fill-in field read-only), how to I do this?
I've tried:
ON VALUE-CHANGED OF chk_TestField IN FRAME DEFAULT-FRAME
DO:
TestField.Read-Only = NOT(chk_TestField).
END.
This, obviously, does not work.
ASSIGN TestField:READ-ONLY IN FRAME {&FRAME-NAME} = TRUE.
or
ASSIGN Table.TestField:READ-ONLY IN FRAME {&FRAME-NAME} = TRUE.
A client needs the application to have colour inserted into the application for specific instances, so the fields will only be populated with colour when necessary, I'm doing this with a right-click context menu.
I created an example application that uses this code and pulls the widget names from a JSON file.
DEFINE VARIABLE hHandle AS HANDLE NO-UNDO.
DEFINE VARIABLE widgetName AS CHARACTER NO-UNDO.
DEFINE VARIABLE colourNumber AS INTEGER NO-UNDO.
FOR EACH Results-WidgetList:
ASSIGN
widgetName = Results-WidgetList.tt-widName /* these assignments are just getting the info */
colourNumber = INT(Results-WidgetList.tt-colour)
.
hHandle = SESSION:FIRST-CHILD.
DO WHILE VALID-HANDLE(hHandle):
IF hHandle:TYPE = "FIELD-GROUP" THEN LEAVE.
hHandle = hHandle:FIRST-CHILD.
END.
hHandle = hHandle:FIRST-CHILD.
DO WHILE VALID-HANDLE(hHandle):
IF hHandle:TYPE = "FILL-IN" AND hHandle:NAME = widgetName THEN LEAVE.
hHandle = hHandle:NEXT-SIBLING.
END.
ASSIGN
hHandle:BGCOLOR = colourNumber.
END.
This worked perfectly fine in my example application, but once I try implement it in the main application it can't see the specific widgets because it is looping through the topmost parent container and going no further.
Is there a way to get to the elements that are contained within?
I'm not sure why you are loading stuff from a JSON file and you don't show that so I can't really comment on it. But, in general, you need to "Walk the widget tree". The following snippet might be helpful:
/* walk the widget tree so that we can update the dcolor for the named field
*/
procedure tweakTree:
define input parameter w as handle no-undo.
define input parameter wName as character no-undo.
define input parameter dClr as integer no-undo.
define variable n as handle no-undo.
n = w:first-child no-error.
if valid-handle( n ) then
run tweakTree( n, wName, dClr ).
n = w:next-sibling no-error.
if valid-handle( n ) then
run tweakTree( n, wName, dClr ).
if w:type = "fill-in" and w:name = wName then
do:
if session:window-system = "tty" then
w:dcolor = dClr.
else
w:fgcolor = dClr.
end.
return.
end.
define variable c1 as character no-undo.
define variable c2 as character no-undo.
form c1 with frame f1.
form c2 with frame f2.
assign
c1 = "abc"
c2 = "123"
.
display c1 with frame f1.
display c2 with frame f2.
pause.
run tweakTree( current-window, "c1", 2 ).
run tweaktree( current-window, "c2", 1 ).
pause.
I need to create a report that displays an empty ALV with 4 columns and that is editable (the user can input on the fields of the ALV).
The ALV is going to be used as an input for the user and the data is then going to be read from the ALV.
What would be the best approach for this?
When youre setting the fieldcatalog, you need to declare "editable". For example
wa_fieldcat-fieldname = 'REMARKS'.
wa_fieldcat-scrtext_m = 'Purchase Order'.
wa_fieldcat-col_pos = 1.
wa_fieldcat-outputlen = 10.
wa_fieldcat-editable = 'X'.
wa_fieldcat-key = 'X'.
APPEND wa_fieldcat TO it_fieldcat.
CLEAR wa_fieldcat.
Then you need to declare in your process after input(PAI) the check changed data of the alv.
alv->checked_changed_data
Which event should be applied to the combo-box in prorgress 10.2b, so that it drop down. By default, this is the cursor down, but I need it to open by a space, and I just can not figure out how to do it.
I've managed to do it by creating a selection list that's a copy of the list-items in your combo-box.
Here's some code. Assume the combo is called c and the frame is called f. This works even if you have a widget directly under your combo.
def var hSL as handle no-undo. /* Mandatory variable definition in your program */
on ' ' of c do:
create selection-list hSL
assign frame = frame f:handle
col = c:col in frame f
row = c:row in frame f + 1
list-items = c:list-items in frame f
visible = yes
sensitive = true
triggers:
on return persistent run piChoose.
on leave persistent run piLeave.
end triggers.
apply 'entry' to hSL.
end.
procedure piChoose:
assign c:screen-value in frame f = hSL:Screen-value.
assign c.
apply 'leave' to self.
end procedure.
procedure piLeave:
delete object hSL no-error.
end procedure.
Note if you're using list-item-pairs, then the LIST-ITEM-PAIRS attribute should be used where I'm using list-items.
Hope that helps!
I'm creating a table that displays information from a MySQL database, I'm using foreignkeys all over the place to cross-reference data.
Basically I have a datagrid with a column named 'system.' The system is an int that represents the id of an object in another table. I've used lableFunction to cross-reference the two and rename the column. But now sorting doesn't work, I understand that you have to create a custom sorting function. I have tried cross-referencing the two tables again, but that takes ~30sec to sort 1200 rows. Now I'm just clueless as to what I should try next.
Is there any way to access the columns field label inside the sort function?
public function order(a:Object,b:Object):int
{
var v1:String = a.sys;
var v2:String = b.sys;
if ( v1 < v2 ){
trace(-1);
return -1;
}else if ( v1 > v2 ){
trace(1);
return 1;
}else {
trace(0);
return 0;
}
}
One way to handle this is to go through the objects you received and add the label as a property on each of them based on the cross-referenced id. Then you can specify your label property to display in your data grid column instead of using a label function. That way you would get sorting as you'd expect rather than having to create your own sort function.
The way that DataGrids, and other list based classes work is by using itemRenderers. Renderers are only created for the data that is shown on screen. In most cases there is a lot more data in your dataProvider than what is seen on screen.
Trying to sort your data based on something displayed by the dataGrid will most likely not give you the results you want.
But, there is no reason you can't call the same label function on your data objects in the sortFunction.
One way is to use the itemToLabel function of the dataGrid:
var v1:String = dataGrid.itemToLabel(a);
var v2:String = dataGrid.itemToLabel(b);
A second way is to just call the labelFunction explicitly:
var v1:String = labelFunction(a);
var v2:String = = labelFunction(b);
In my experience I have found sorting to be extremely quick, however you're recordset is slightly larger than what I usually load in memory at a single time.