Page 1 of 1

Custom Widget Response Value and Grids

Posted: Mon Jun 10, 2019 9:05 am
by JacobPreston
I created a custom widget, but my issue is I am having trouble retrieving the response value when the widget is in a subfile for my RPGLE program.

To demonstrate this, i've made a very simple, but useless, textbox widget for the demo and a program that just has a subfile with 3 records each containing a custom textbox widget. When enter is pressed, the values should be pulled from each of the textbox widgets and printed into the message box next to the subfile.

If I don't use a subfile, the value for the custom widget seems to update without any issue. However, with the subfile, there seems to be something that I am missing.

Custom widget js:

Code: Select all

function JMP_Textbox_Initialize(parms)
{
    var id = parms.dom.id;
    parms.dom.setAttribute("jmp_customtextbox","true");
    var value = parms.evalProperty("value");
    if (!value)
    {
        value = "";
    }
    parms.dom.innerHTML = '<input id="'+id+'_txt" type="text" value="'+value+'" style="width: 100%; height: 100%;">';
}

window.JMP_Textbox_OnSubmit = function(response)
{
    var widgets = document.querySelectorAll("div[jmp_customtextbox]");

    for( var i=0; i < widgets.length; i++)
    {
        var idVar = widgets[i].pui.formatName+ "." + widgets[i].pui.fieldName;
        var element = document.getElementById(widgets[i].id + '_txt');
        if (element)
        {
            var value = element.value;
            if (value == null)
            {
                value = "";
            }
            response[idVar] = value;
        }
    }
    return true;
}

// Add the base widget
pui.widgets.add(
{
    name: "custom textbox",
    newId: "Customtextbox",
    menuName: "Custom textbox",
    defaults: 
    {
        "width": "250px",
        "height": "25px",
    },
   
    propertySetters: 
    {
        "field type": function(parms) 
        {
            JMP_Textbox_Initialize(parms);
        },
        "value": function(parms)
        {
            JMP_Textbox_Initialize(parms);
        },
    }
});

pui.toolbox.add(
{
    category: "Custom Widgets",

    widget: "custom textbox",
    text: "Custom textbox",
    icon: "/profoundui/proddata/images/icons/google_maps.png",

    proxyHeight: 25,
    proxyWidth: 250,
    proxyHTML: '<input type="text" value="Custom Textbox" style="width: 100%; height: 100%;">',
    
    defaults: 
    {
    }

});
DSPF:

Code: Select all

     A          R ZT1002                    SFL                                 
     A            QPUI000001     1A  O  2  2                                    
     A            @TEST         10A  H                                          
     A          R QSFLCTL001                SFLCTL(ZT1002)                      
     A                                      SFLSIZ(0001)                        
     A                                      SFLPAG(0001)                        
     A                                      SFLDSP                              
     A                                  1  2HTML('QPUISFLZT1001')               
     A          R ZT1001                                                        
     A  31 32 30                            CA01                                
     A                                  1  2HTML('QPUICTL1    ZT1002    5    RS-
     A                                      FLDSP    0    E1    3    N30RSFLDSP-
     A                                      CTL 0    E1    3    N31RSFLCLR    0-
     A                                          E1    3     31RSFLPAG    1    C-
     A                                      1    5 RSFLSIZ    1    C4    9999 0-
     A                                          0    ')                         
     A                                  1  2HTML('{"screen":{"record format nam-
     A                                      e":"ZT1001","description":"Main Rec-
     A                                       Format","document title":"Title","-
     A                                      onsubmit":"JMP_Textbox_OnSubmit;"},-
     A                                      "items":[{"id":"Exit","field type":-
     A                                      "button","css class":"button","valu-
     A                                      e":"Exit","left":"770px","top":"400-
     A                                      px","width":"255px","shortcut key":-
     A                                      "F3","height":"65px"},{"id":"TextAr-
     A                                      ea1","field type":"text area","valu-
     A                                      e":{"fieldName":"MYMSG","dataLength-
     A                                      ":"2000","trimLeading":"false","tri-
     A                                      mTrailing":"true","blankFill":"fals-
     A                                      e","rjZeroFill":"false","dataType":-
     A                                      "char","formatting":"Text","textTra-
     A                                      nsform":"none","designValue":"[MYMS-
     A                                      G]"},"left":"770px","top":"180px","-
     A                                      height":"210px","width":"250px","vi-
     A                                      sibility":"visible"},{"id":"Menu1",-
     A                                      "field type":"menu","color":"#66000-
     A                                      0","font family":"Arial","font size-
     A                                      ":"14px","font weight":"bold","hove-
     A                                      r background color":"#ffffff","hove-
     A                                      r text color":"#FFFFFF","animate":"-
     A                                      false","border color":"#EEEEEE","me-
     A                                      nu option indent":"9px","option hov-
     A                                      er image":"/profoundui/proddata/ima-
     A                                      ges/menus/harvest/menu_image4.png",-
     A                                      "background color":"#ffffff","left"-
     A                                      :"1190px","top":"330px","height":"6-
     A                                      0px","width":"120px","visibility":"-
     A                                      hidden","onoptionclick":"var rowCli-
     A                                      cked = this.pui.properties[\"user d-
     A                                      efined data\"];\npui.set(\"TextBox2-
     A                                      \" + \".\" + rowClicked, value);\np-
     A                                      ui.click();\n"},{"id":"Grid1","fiel-
     A                                      d type":"grid","css class":"bluepri-
     A                                      nt-grid","left":"210px","top":"180p-
     A                                      x","border color":"transparent","co-
     A                                      lumn headings":"Header 1,Header 2,H-
     A                                      eader 3","column widths":"530","css-
     A                                       class 2":"blueprint-defaults","hea-
     A                                      der height":"38","height":"288px","-
     A                                      number of columns":"1","number of r-
     A                                      ows":"6","row height":"50","visibil-
     A                                      ity":"visible","width":"531px","dis-
     A                                      play subfile":{"fieldName":"N30","c-
     A                                      ustomTrue":"","customFalse":"","dat-
     A                                      aType":"expression","formatting":"I-
     A                                      ndicator","indFormat":"true / false-
     A                                      "},"display control record":{"field-
     A                                      Name":"N31","customTrue":"","custom-
     A                                      False":"","dataType":"expression","-
     A                                      formatting":"Indicator","indFormat"-
     A                                      :"true / false"},"clear subfile":{"-
     A                                      fieldName":"31","customTrue":"","cu-
     A                                      stomFalse":"","dataType":"expressio-
     A                                      n","formatting":"Indicator","indFor-
     A                                      mat":"true / false"},"subfile size"-
     A                                      :"9999","subfile record number":{"f-
     A                                      ieldName":"@rrn","dataLength":"5","-
     A                                      decPos":"0","numSep":"false","zeroB-
     A                                      alance":"false","numBlankFill":"fal-
     A                                      se","zeroFill":"false","noExtraSpac-
     A                                      es":"false","curSym":"","dataType":-
     A                                      "zoned","formatting":"Number","negN-
     A                                      um":"-999.00","units":""},"subfile -
     A                                      end":{"fieldName":"32","customTrue"-
     A                                      :"","customFalse":"","dataType":"ex-
     A                                      pression","formatting":"Indicator",-
     A                                      "indFormat":"true / false"},"record-
     A                                       format name":"ZT1002')             
     A                                  1  2HTML('","description":"Subfile"},{"-
     A                                      id":"Customtextbox1","field type":"-
     A                                      custom textbox","value":{"fieldName-
     A                                      ":"@test","dataLength":"10","trimLe-
     A                                      ading":"false","trimTrailing":"true-
     A                                      ","blankFill":"false","rjZeroFill":-
     A                                      "false","dataType":"char","formatti-
     A                                      ng":"Text","textTransform":"none","-
     A                                      designValue":"[@test]"},"left":"5px-
     A                                      ","top":"5px","width":"465px","heig-
     A                                      ht":"30px","grid":"Grid1","column":-
     A                                      "0"}]}')                            
     A            @RRN           5S 0H                                          
     A            MYMSG       2000A  H                                          
 
RPGLE Code:

Code: Select all

HDATFMT(*iso)                                                        
HTIMFMT(*HMS)                                                        
H DFTACTGRP(*NO)                                                     
 /DEFINE PROFOUNDUI                                                  
h option(*nodebugio:*srcstmt:*noexpdds)                              
H**********************************************************          
H* Version..: 1.00                                                   
H* Author...: Jacob Preston                                          
H* Date.....: 06/10/2019                                             
H*                                                                   
H* Description:                                                      
H* Widget Development Test Program                                   
f**********************************************************          
fZT100S    cf   e             workstn HANDLER('PROFOUNDUI(HANDLER)') 
f                                     sfile(ZT1002:@rrn)             
f                                     extfile('ZT100S')              
f                                     infds(info)                    
d**********************************************************          
d*Variable Declarations                                              
d i               s              4  0 inz                  
d reccount        s              4  0 inz                  
d*Constant Declarations                                    
d crlf            C                   CONST(X'0d25')       
d*Exit Hotkey                         F3                   
dexit             c                   const(X'33')         
d*Enter Hotkey                        Enter                
denter            c                   const(X'F1')         
d                                                          
dinfo             ds                                       
d  screenrec        *record                                
d  cfkey                369    369                         
                                                           
d pgmsts         sds                                       
d  pgmnam           *proc                                  
d  userid               358    367A                        
d  MsgTxt                91    170A                        
c**********************************************************
 /FREE                                                     
   exsr Main;                                                                                   
  *inlr=*on;                                                                                   
                                                                                               
  /////////////////////////////////////////////////////////////////////////////////////////////
  //LoadSFL - Load subfile                                                                  
  /////////////////////////////////////////////////////////////////////////////////////////////
  begsr LoadSFL;                                                                               
    @rrn=0;                                                                                    
    *in31 = *on; //Clear subfile                                                               
    write ZT1001; //Write to screen record holding subfile                                     
    *in30 = *off; //Display subfile                                                            
    *in31 = *off; //Display Control Record                                                     
                                                                                               
    @test='Option 1';                                                                          
    @rrn += 1;                                                                                 
    write ZT1002;                                                                              
                                                                                               
    @test='Option 2';                                                                          
    @rrn += 1;                                                                                 
        write ZT1002;                                                                              
                                                                                               
    @test='Option 3';                                                                          
    @rrn += 1;                                                                                 
    write ZT1002;                                                                              
                                                                                               
    reccount = @rrn; //Store record count for iterating through/chaining/printing values later                                                                         
    *in32 = *on; //End of File                                                                   
  endsr;                                                                                       
  /////////////////////////////////////////////////////////////////////////////////////////////
  //Main - main control loop                                                                 
  /////////////////////////////////////////////////////////////////////////////////////////////
  begsr Main;                                                                                  
    exsr LoadSFL;                                                                              
    DOW *inlr=*off;                                                                            
      exfmt ZT1001;                                                                            
                                                                                               
      select;                                                                                  
        when cfkey=exit;                                                                       
         leave;                                  
                                                 
       when cfkey=enter;                         
         for i = 1 to reccount;                  
           chain(e) i ZT1002;                    
           if not %error;                        
             mymsg = %trim(mymsg) + crlf + @TEST;
           endif;                                
         endfor;                                 
                                                 
     endsl;                                      
                                                 
   enddo;                                        
 endsr;                                          
                                                 
/END-FREE                                        

Re: Custom Widget Response Value and Grids

Posted: Mon Jun 10, 2019 5:23 pm
by Scott Klement
Hi Jacob,

I wonder why you want to create your own textbox when we provide one with the product. Wouldn't it be easier to just use ours?

If you're just trying to change the defaults, there are much easier ways to do that vs. creating a whole new one.

Re: Custom Widget Response Value and Grids

Posted: Mon Jun 10, 2019 5:42 pm
by Scott Klement
If you did want to do this with a custom widget (and, again, I really don't recommend it unless you're going to do something special) and you want it to work with rows in the grid, you must:

1. Add the row number to the field name. So instead of ZS1002.@TEST you'd need to have ZS1002.@TEST.1 for row 1, ZS1002.TEST.2 for row 2, etc.
2. Mark the row as modified by setting the 'rrn' variable for the row. So ZS1002.rrn=1 for row 1, ZS1002.rrn=2 for row 2, etc.

I modified your JMP_Textbox_OnSubmit function to do that, though I can't promise it's 100% bug free.

This is the modified code:

Code: Select all

window.JMP_Textbox_OnSubmit = function(response)
{
    var widgets = document.querySelectorAll("div[jmp_customtextbox]");

    for( var i=0; i < widgets.length; i++)
    {
        var idVar = widgets[i].pui.formatName+ "." + widgets[i].pui.fieldName;
        var element = document.getElementById(widgets[i].id + '_txt');
        if (element)
        {
            var value = element.value;
            if (value == null)
            {
                value = "";
            }
            
            // Check if the widget id ends in a row number like .1, .2, etc.
            // if so, assume it is in a subfile, and mark it accordingly.
            
            var tempId = widgets[i].id.split(".");
            if (tempId instanceof Array && tempId.length >= 2) {
              var rowno = parseInt(tempId[tempId.length - 1], 10);
              if (!isNaN(rowno)) {
                idVar += "." + rowno;
                var rrnVar = widgets[i].pui.formatName + ".rrn";
                if (!response[rrnVar]) response[rrnVar] = [];
                response[rrnVar][rowno - 1] = rowno;
              }
            }
            
            response[idVar] = value;
        }
    }
    return true;
}
That would fix that one error, but there are a lot of other details you can get wrong, which is why I'm asking what the purpose is, here. If you just need a working textbox, use the one that comes with PUI, it'll be a lot easier that way.

Re: Custom Widget Response Value and Grids

Posted: Mon Jun 10, 2019 6:24 pm
by JacobPreston
Scott Klement wrote:If you did want to do this with a custom widget (and, again, I really don't recommend it unless you're going to do something special) and you want it to work with rows in the grid, you must:

1. Add the row number to the field name. So instead of ZS1002.@TEST you'd need to have ZS1002.@TEST.1 for row 1, ZS1002.TEST.2 for row 2, etc.
2. Mark the row as modified by setting the 'rrn' variable for the row. So ZS1002.rrn=1 for row 1, ZS1002.rrn=2 for row 2, etc.

I modified your JMP_Textbox_OnSubmit function to do that, though I can't promise it's 100% bug free.

This is the modified code:

Code: Select all

window.JMP_Textbox_OnSubmit = function(response)
{
    var widgets = document.querySelectorAll("div[jmp_customtextbox]");

    for( var i=0; i < widgets.length; i++)
    {
        var idVar = widgets[i].pui.formatName+ "." + widgets[i].pui.fieldName;
        var element = document.getElementById(widgets[i].id + '_txt');
        if (element)
        {
            var value = element.value;
            if (value == null)
            {
                value = "";
            }
            
            // Check if the widget id ends in a row number like .1, .2, etc.
            // if so, assume it is in a subfile, and mark it accordingly.
            
            var tempId = widgets[i].id.split(".");
            if (tempId instanceof Array && tempId.length >= 2) {
              var rowno = parseInt(tempId[tempId.length - 1], 10);
              if (!isNaN(rowno)) {
                idVar += "." + rowno;
                var rrnVar = widgets[i].pui.formatName + ".rrn";
                if (!response[rrnVar]) response[rrnVar] = [];
                response[rrnVar][rowno - 1] = rowno;
              }
            }
            
            response[idVar] = value;
        }
    }
    return true;
}
That would fix that one error, but there are a lot of other details you can get wrong, which is why I'm asking what the purpose is, here. If you just need a working textbox, use the one that comes with PUI, it'll be a lot easier that way.
Thank you so much this makes perfect sense. The actual widget I was working on was a lot more involved which is why I opted to make this example to demonstrate the issue I was having. I was working on a more user friendly multiple selection dropdown instead of the default multiple selection select box.