2008-07-31

SysListSelect

In AX there is an easy tool for creating simple lists with following selection needed items called SysListSelect. In this form we may check/uncheck every item separately or whole list by clicking at Yes to All or No to All buttons.

Some information about SysListSelect we may find in MSDN SysListSelect class, but unfortunately description is very compact and it's hard even for experienced developer to understand how to fully use this tool. Following article is meant to fill this gap in knowledge.

To call SysListSelect form we don't need write any code. In Global class there is corresponding wrapper selectMultiple() method:

/*
Returns container with the status of how the form is closed plus the selected ids.
*/
static client container selectMultiple(
    Caption     caption,
    str         info,                   // An info text displayed in the top of the form
    container   choices,
    container   headers = conNull()     // If null, the list view is used
    )
The first and second parameters are evident. There are form's caption and info respectively. At first glance third parameter is obvious too: choices container contains items we need to select. But be aware that each item consists from three fields:

label - (string) in fact this is an item we are selecting
id - (integer) item's identifier
set - (boolean) determines default state of item (checked\unchecked)

before passing choices into selectMultiple() we need to pack every item into container using sysListSelect::packChoice()

static container packChoice(
    str                 label,
    int                 id,
    boolean             set
    )
{
    return [label,id,set];
}
Here we create our first row.
con+=[sysListSelect::packChoice(label, id, set)];
The fourth parameter headers is used to show headers. That means that we may visualise more than one column. But how to pass these columns?
The answer is simple. If we need to pass some columns we just need to "divide" each label at columns by '\n' symbol:

label = column1+'\n'+column2+'\n'+...+columnN

Thats all. Now we are ready to launch SysListSelect form.

static void sysListSelectSampleJob(Args _args)
{
    container con;
    container ret;
    boolean             ok;

    str                 label;
    int                 id;
    boolean             set;
    ;

    label   = 'label_11'+'\n'+'label_12';
    id      = 1;
    set     = false;
    con+=[sysListSelect::packChoice(label, id, set)];

    label   = 'label_21'+'\n'+'label_22';
    id      = 2;
    set     = true;
    con+=[sysListSelect::packChoice(label, id, set)];

    [ok, ret] = selectMultiple('Caption','Info', con, ['First column', 'Second column']);
    conView(ret);
}


I absolutely forgot to say that selectMultiple() returns container which first parameter is boolean (in our example this is ok) pointing whether was pressed OK button or not and container of selected id's.


Here we selected 2 elements.

And here we try to work with AX breakpoints (something similar with native SysBreakpoints form)

static void sysListSelectBreakpointsJob(Args _args)
{
    container con;
    container ret;
    boolean             ok;

    str                 label;
    int                 id;
    boolean             set;

    container           breakpoints;
    int                 i, bpLen;
    ;

    breakpoints = infolog.breakpoint();
    bpLen = conLen(breakpoints);
    for(i=2; i<=bpLen; i++)
    {
        switch ((i mod 3))
        {
            case 2:
                label   = conpeek(breakpoints, i);
            break;

            case 0:
                id      = conpeek(breakpoints, i);
            break;

            case 1:
                set     = conpeek(breakpoints, i);
            break;
        }
        con+=[sysListSelect::packChoice(label, id, set)];
    }
    [ok, ret] = selectMultiple('Caption','Breakpoints', con, ['Path']);
}



I'd like to point at fact that using SysListSelect is very rare. I've found in AX it in one place only: \Classes\SysDataImport\deleteTablesCheck (AX 3.0) so this tool is still waiting for developers :-)

I've discovered too that there is a small bug in \Classes\SysListSelect\selected() method.
When we launch the form from a wrapper and try to close form (not click at OK or Cancel) AX falls at endless loop(AX 3.0). The matter of fact in this case listView is destroyed already and impossible to get listView items correctly.



To avoid this I dropped a line into selected() method:
container selected()
{
    Counter         i;
    FormListItem    item;
    container       selected;
    ;

    
  if(listView.getCount())// added by GRR
  {
    for (i=listView.getNextItem(FormListNext::ALL); i>=0; i=listView.getNextItem(FormListNext::ALL,i))
    {
        item = listView.getItem(i);
        if (item && item.image() == this.imageOn())
            selected += item.data();
    }
  }
    return selected;
}
Copyright © 2008 Ruslan Goncharov