Friday, May 25, 2012

Filtering multi select dialog based on another multi select dialog


Hello,

We have already done filtering a dialog based on another dialog. We are doing it again but with one difference which is now we are using multi select drop down.

In this post I am taking the same example which I used in my previous post. However, I've now made the 2 dialogs as multi-select which I already discussed in my first post. you can check it here.



After changing the single select dialog box to multi select, I first declared a List variable in the class declaration method. i.e.,

    List selectedGroup;





This selectedGroup variable holds the values of customer groups which were selected by the user.



I also created a method custGroupModified in my custReportUIBuilder class. Since the modified event do not work with multi select dialogs, so I am changing it to leave event. So first I changed the custGroupMidified method to custGroupLeave and put the following code in it

public boolean custGroupLeave(FormStringControl _control)

{

    if (_control.valueStr() != '')

    {

        selectedGroup = strSplit(_control.valueStr(), ';');

        dialogCustGroup.value(selectedGroup);

    }

    return true;

}



Now in the custLookup method we will use the selectedGroup list variable to filter the customers. So, adding the following code in the method:

    if (selectedGroup)

    {

        enum = selectedGroup.getEnumerator();

        while (enum.moveNext())

        {

            query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, CustGroup)).value(enum.current());

        }

    }



Where the variable enum is the list enumerator and which is defined in the method as:

    ListEnumerator enum;



The whole method will look like this:

public void lookupCust(FormStringControl _control)

{

    Query query = new Query();

    container cnt;

    ListEnumerator enum;

   

    query.addDataSource(tableNum(CustTable));

    query.dataSourceTable(tableNum(CustTable)).fields().addField(fieldNum(CustTable, AccountNum));

    query.dataSourceTable(tableNum(CustTable)).fields().addField(fieldNum(CustTable, Party));

   

    if (selectedGroup)

    {

        enum = selectedGroup.getEnumerator();

        while (enum.moveNext())

        {

            query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, CustGroup)).value(enum.current());

        }

    }

    SysLookupMultiSelectGrid::lookup(query, _control, _control, cnt);

}



One last thing is to change the override method of dialogCustGroup’s leave method. I’ll do it in the postBuild method:

    dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, leave), methodStr(custReportUIBuilder, custGroupLeave), this);



and the whole method will look like this:

public void postBuild()

{

    super();

    // From binding info, get the dialog field for racecode attribute and add button

    dialogCustGroup = this.bindInfo().getDialogField(

                         this.dataContractObject(),

                         methodStr(custReportContract,parmCustGroup));

    // register override method for lookup cust Group

    dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(custReportUIBuilder, lookupCustGroup), this);

    // register override method for modified

    dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, leave), methodStr(custReportUIBuilder, custGroupLeave), this);

   

    if (dialogCustGroup)

    {

     dialogCustGroup.lookupButton(2);

    }



    //binding info for customer drop down

    dialogCust = this.bindInfo().getDialogField(

                         this.dataContractObject(),

                         methodStr(custReportContract,parmCust));

   

    // register override method for lookup customer

    dialogCust.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(custReportUIBuilder, lookupCust), this);

   

    if (dialogCust)

    {

        dialogCust.lookupButton(2);

    }



}



That’s it, we are now done. Thank you all


Thursday, May 24, 2012

Filtering drop down list based on anothre drop down

Hello All,
I've come across a scenario where I have to select a value from a drop down and based on that value I have to fill another drop down. After I did it, I though it will be usefull for others as well. So, I am posting it here.
So, Here is what we need to do.
First create a contract class as (I am hoping) we already know. Here I am using an example of Customer which will be filtered by Customer group. The code of class declaration will be:

[
DataContractAttribute
]
public class custReportContract

{
    CustGroupId custGroup;
    AccountNum cust;

}

Now creating 2 new methods for getting and setting these parameters. 1 for cust group
[
DataMemberAttribute('CustGroup'),
SysOperationLabelAttribute(literalstr("@SYS11904"))
]
public CustGroupId parmCustGroup(CustGroupId _custGroup= custGroup)
{
    custGroup = _custGroup;
    return custGroup;
}
And the other one for customer
[
DataMemberAttribute('Cust'),
SysOperationLabelAttribute(literalstr("@SYS313797"))
]
public AccountNum parmCust(AccountNum _cust= cust)
{
    cust = _cust;
    return cust;
}

Your screen will look like this:



Nothing new in it. We all know it (I guess). Moving forward and now we are creating another class for UI builder.
Create this new class and on the class declaration method, type the following code
public class custReportUIBuilder extends SysOperationAutomaticUIBuilder
{
}

your screen will look like this
Now we have to create 2 dialog boxes. 1 for customer group and customer each. To do this type the following code.
    DialogField dialogCustGroup;
    DialogField dialogCust;

We also have to define our contract class here, so declare the contract class
    custReportContract contract;

so, the class declaration method will look like this:
public class custReportUIBuilder extends SysOperationAutomaticUIBuilder
{
    DialogField dialogCustGroup;
    DialogField dialogCust;

    custReportContract contract;
}
Now, we have to draw the dialog boxes. For this reason, we will create another method of build and type the following code In it.
public void build()
{
    Dialog      dialogLocal = this.dialog();
    custReportContract contract = this.dataContractObject();
   
    dialogLocal.addGroup("Customer");
    this.addDialogField(methodStr(custReportContract,parmCustGroup), contract);
    this.addDialogField(methodStr(custReportContract,parmCust), contract);

}

Now that we created the build method, let’s move into filling the cust group drop down with the table CustGroup. We’ll create another method for lookup and type the following code in it.
public void lookupCustGroup(FormStringControl _control)
{
    Query query = new Query();
    SysTableLookup sysTablelookup;

    sysTablelookup =SysTableLookup::newParameters(tableNum(CustGroup),_control);
    sysTablelookup.addLookupfield(fieldNum(CustGroup,CustGroup));
    sysTablelookup.addLookupfield(fieldnum(CustGroup,Name));

    query.addDataSource(tableNum(CustGroup));

    sysTablelookup.parmQuery(query);
    sysTablelookup.performFormLookup();
}
We need to create another method so that when user selects any record from cust group drop down, the customer drop down will be filtered with that value, for this reason we will select the modified event of cust group and then type the code:
public boolean custGroupModified(FormStringControl _control)
{
    dialogCustGroup.value(_control.valueStr());
    dialogCust.value('');
    return true
}

Ok now we will create the lookup method for customer. Here is the code
public void lookupCust(FormStringControl _control)
{
    Query query = new Query();
    SysTableLookup sysTablelookup;

    sysTablelookup =SysTableLookup::newParameters(tableNum(CustTable),_control);
    sysTablelookup.addLookupfield(fieldNum(CustTable,AccountNum));
    sysTablelookup.addLookupfield(fieldnum(CustTable,Party));

    query.addDataSource(tableNum(CustTable));
    query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, CustGroup)).value(dialogCustGroup.value());
   
    sysTablelookup.parmQuery(query);
    sysTablelookup.performFormLookup();
}

Note that I filtered the cust query with the value selected in cust group drop down
    query.dataSourceTable(tableNum(CustTable)).addRange(fieldNum(CustTable, CustGroup)).value(dialogCustGroup.value());

we have almost completed our code for lookups and their filters. Now we will bind our dialog boxes with the contract class params and also override the modified method of cust group with the method we just wrote. To do this we will create another method for postBuild. Here we go
public void postBuild()
{
    super();
    // From binding info, get the dialog field for racecode attribute and add button
    dialogCustGroup = this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(custReportContract,parmCustGroup));
    if (dialogCustGroup)
    {
     dialogCustGroup.lookupButton(2);
    }

    // register override method for lookup cust Group
    dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(custReportUIBuilder, lookupCustGroup), this);
    // register override method for modified
    dialogCustGroup.registerOverrideMethod(methodStr(FormStringControl, modified), methodStr(custReportUIBuilder, custGroupModified), this);
   
    //binding info for customer drop down
    dialogCust = this.bindInfo().getDialogField(
                         this.dataContractObject(),
                         methodStr(custReportContract,parmCust));
   
    // register override method for lookup customer
    dialogCust.registerOverrideMethod(methodStr(FormStringControl, lookup), methodStr(custReportUIBuilder, lookupCust), this);
   
    if (dialogCust)
    {
        dialogCust.lookupButton(2);
    }

}

We may have to create some other methods as well in order to functioning your code properly. They are getFromDialog, initializeFields and postRun. Create three new methods each for getFromDialog, initializeFields and postRun and copy the following code to them
public void getFromDialog()
{
    contract = this.dataContractObject();
    super();
}

public void initializeFields()
{
    contract = this.dataContractObject();
}

public void postRun()
{
    super();
}

We are done. But wait one last thing, open your contract class and in the class declaration method, reference your UI builder class just below the DataContractAttribute. Your code will become:
[
    DataContractAttribute,
    SysOperationContractProcessingAttribute(classStr(custReportUIBuilder))
]
public class custReportContract

{
    CustGroupId custGroup;
    AccountNum cust;

}
 We are now done. In this post we have tried to filter our single value drop down based on another drop down. In the next post we will try to repeat the same process for multi value drop down list.
Thank you all
Here is the screen shot of what we just did


Thursday, May 3, 2012

Creating multi-select lookup dialog for SSRS report parameter in MS Dynamics AX 2012

Hello All,
I just recently found a way to create a multi select lookup
dialog for SSRS report parameter using SysLookupMultiSelectGrid
class. I thought it might be helpfull for other developers
as well since I couldn't find any other Blog or Post answering this issue.

I am just assuming that you know how to create a simple dialog
for reporting parameter. However, if you don't know this link might be helpfull to you. http://www.artofcreation.be/2011/08/22/ax2012-sysoperation-part-1-data-contracts-and-service-operations/

I will just write those methods which will create a multi select
dialog. So, here we go.

Step 1:
In your data contract class declaration method, define your
parameter with 'List'. For example I want to create a multi select dialog for
customers in which I need Customer account to be selected when a user selects
any customer. SO, I will write

List accountNum;
In your DataMemberAttribue method type
the following code

[
DataMemberAttribute('AccuontNum'),
AifCollectionTypeAttribute('AccountNum', Types::String),
SysOperationLabelAttribute(literalstr("@SYS302"))
]
public List parmAccountNum(List _accountNum = accountNum)
{
accountNum = _accountNum;
return accountNum;
}
Your screen will look like this

Step 2:
Now that you have completed the contract class, let’s move on to
the UI Builder class. In your main lookup method write the following code.

public void
lookup(FormStringControl _control)
{
Query query = new Query(queryStr(CustTableSRS));
container cnt;
SysLookupMultiSelectGrid::lookup(query, _control, _control, cnt);
}
you may have to create 3 more methods to run your code without any
error. They are getFromDialog, initializeFields
and postRun. Here is the code for these methods. you have to change the contract class name with your
contract class

First create a new mothod for initializeFields and paste the following code
public void
initializeFields()
{
custMultiSelectContract contract = this.dataContractObject();
}
Then create another method for getFromDialog
public void getFromDialog()
{
custMultiSelectContract contract = this.dataContractObject();
super();
}
and then another method for postRun
public void postRun()
{
custMultiSelectContract contract = this.dataContractObject();
}
That's it. You are now done. Run your report and enjoy.
Thanks.