Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested answer

Form datasource re-trigger displayOption method in MS D365

(0) ShareShare
ReportReport
Posted on by 11

Hello!

I'm pretty new in all of this, so sorry if I ask some dumb questions.

My assignment is to change colors for the records of employee calendar, based on some criteria. Color codes I store in the Map and using debugger I can see that displayOption() method is getting correct color codes.

My problem is when I open employee calendar form, and for the current period calendar isn't generated, then even for the rest of the periods displayOption haven't been triggered, but if I generate the calendar for the current period and reopen the calendar form, then colors are displayed for every period correctly. What can be the problem here?

I hope someone can understand what I wrote here!

My displayOptions method:

public void displayOption(Common _p1, FormRowDisplayOption _options)
{
int textColor = 0;
int backColor = 0;

[textColor, backColor] = PRMEmpWorkDaysColor.getForEmpWorkDays(_p1);

if (textColor != 0)
_options.textColor(textColor);

if (backColor != 0 )
_options.backColor(backColor);


super(_p1, _options);

}

And my period modified() method:

[Control("String")]
class PeriodIdFilter
{
public boolean modified()
{
boolean ret;

ret = super();

PRMPeriodId = PeriodIdFilter.valueStr();
PRMPeriod = PRMPeriod::find(PRMPeriodId);
filterStart = PRMPeriod.Start;

PRMEmpWorkDays_ds.executeQuery();
element.updateParts();

return ret;
}

}

  • Maris Sausins Profile Picture
    11 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    I tried it already before, but okay I tried once more now, hard coded colors and removed the if statements, but still it have the same problem:

    Employee who has calendar generated for default period:

    pastedimage1609832723121v1.png

    Employee who hasn't calendar generated for default period:

    pastedimage1609832817859v2.png

  • Suggested answer
    Pete Alberts Profile Picture
    3,542 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    The issue must be in the displayOption() method. I know you mentioned that you debugged it and it seems to be working. But just check again. Maybe hard code the colors and remove the if statements for fault finding purposes.

  • Maris Sausins Profile Picture
    11 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    Here is the form init:

    public void init()
        {
            Common record;
            PRMEmpDisability prmEmpDisability;
            PRMEmpWork prmEmpWork;
            boolean showDisabilityId;
        
            prmEmpWorkDaysColor = PRMEmpWorkDaysColor::construct();
        
            super();
        
            showDisabilityId = true;
            lastEmpDisabilityId = '';
            lastEmpNonAttendaceId = '';
        
            PRMEmpWorkDays_ds.allowCreate(false);
        
            if (element.args() && element.args().record())
            {
    			record = element.args().record();
    
                switch (record.TableId)
                {
                    case tablenum(PRMEmployee):
                        employeeId = record.(fieldNum(PRMEmployee, EmployeeId));
                        break;
        
                    case tablenum(PRMEmpWork):
                        PRMEmpWork = record;
                        employeeId = PRMEmpWork.EmployeeId;
                        break;
        
                    case tablenum(PRMEmpDisability):
                        PRMEmpDisability = record;
                        showDisabilityId = false;
                        employeeId = PRMEmpDisability.EmployeeId;
                        PRMPeriodId = PRMPeriod::findOrCreatePeriod(PRMEmpDisability.Start).PeriodId;
                        break;
    
                    default:
                        break;
                }
            }
        
            if (!PRMPeriodId)
            {
                PRMPeriodId = PRMPeriod::CurrentPeriod().PeriodId;
            }
        
            PeriodIdFilter.text(PRMPeriodId);
    
            element.design().controlName(identifierStr(PRMEmpWorkDays_DisabilityId)).visible(showDisabilityId); 
        
            periodIdFilter.modified();
        
            partList = new PartList(element);
        }

    run:

    public void run()
        {
            super();
        
            element.updateParts();
        }

    modified:

    [Control("String")]
        class PeriodIdFilter
        {
            public boolean modified()
            {
                boolean ret;
            
                ret = super();
            
                PRMPeriodId = PeriodIdFilter.valueStr();
                PRMPeriod   = PRMPeriod::find(PRMPeriodId);
                filterStart = PRMPeriod.Start;
                      
                PRMEmpWorkDays_ds.executeQuery();
                element.updateParts();
            
                return ret;
            }
        }

  • Pete Alberts Profile Picture
    3,542 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    If that is the case - please send the code you have in init() and run() on the form. Or any other initialisations.

  • Pete Alberts Profile Picture
    3,542 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    "I will try to get it done by myself, but if I won't be able to do it I will get back to you, if that's okay?" You are welcome, I'll help when I get the time though.

    On your second reply. I find it difficult to keep track as I am not familiar with the functional side. If I put it as simple as possible: "If the calendar is generated and you open the form then it works, otherwise not." Correct?

  • Maris Sausins Profile Picture
    11 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    About the problem:

    In system parameters I can set default period, for example 2020-10, then if I open the form and there is no calendar generated for the employee, then there are no colors displayed in any period, but if I change system default period, to some period where employees calendar is generated, then colors appear on every period if I change the period. If I generate the calendar for employee in that period and reopen the form, then everything is working fine.

    I hope you understood something

  • Maris Sausins Profile Picture
    11 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    Thanks Pete for your work! Really appreciated.

    Thanks for Your recommendations!

    Now I'm gonna go through everything you wrote and try to understand it.

    About the code:

    1. PRMEmpWorkDaysColor is a class.

    2. Yes, the range is using QueryFilter. 

    public void executeQuery()
            {
                RecId           recId;
                PRMEmployeeId   localEmployeeId;
                TransDate       filterEnd;
            
                if (PRMEmpWorkDays)
                {
                    recId = PRMEmpWorkDays.RecId;
                    localEmployeeId = PRMEmpWorkDays.EmployeeId;
                }
            
                if (filterStart)
                {
                    filterEnd = endmth(filterStart);
                    qfPeriod.value(queryRange(filterStart, filterEnd));
                }
                else
                {
                    qfPeriod.value(queryRange(datenull(), datemax()));
                }
            
                if (employeeId)
                {
                    findOrCreateRange_W(this.queryBuildDataSource(), fieldnum(PRMEmpWorkDays, EmployeeId), queryValue(employeeId));
                }
            
                super();
            
                if (RecId)
                {
                    if (!PRMEmpWorkDays_ds.positionToRecordByValue(fieldnum(PRMEmpWorkDays, RecId), int642str(RecId)))
                    {
                        PRMEmpWorkDays_ds.positionToRecordByValue(fieldnum(PRMEmpWorkDays, EmployeeId), localEmployeeId);
                    }
                }
    
                element.updateParts(); 
            }

    3. For my understanding, there is nothing, but the accesRight check, before updating form part. (I still don't understand it much yet)

    public void updateParts()
        {
            Object partFormRun;
    
            AccessRight accessRight = AccessRight::NoAccess;
            accessRight = SecurityRights::construct().menuItemAccessRight(SecurableType::MenuItemDisplay, menuitemDisplayStr(PrmEmpWorkDaysNewPart));
        
            // Check access right level before attempting to update form part data
            if (accessRight == AccessRight::Delete)
            {
    			partFormRun = PRMGlobal::getFormPartByName(element, identifierStr(PrmEmpWorkDaysNewPart));
    			if (partFormRun)
    			{
    				partFormRun.updateData(PRMEmpWorkDays.EmployeeId, dateStartMth(PRMEmpWorkDays.DayDate), endmth(PRMEmpWorkDays.DayDate));
    			}
            }
    
            accessRight = SecurityRights::construct().menuItemAccessRight(SecurableType::MenuItemDisplay, menuitemDisplayStr(PrmEmpWorkDaysDisabilityPart));
        
            // Check access right level before attempting to update form part data
            if (accessRight == AccessRight::Delete)
            {
    			partFormRun = PRMGlobal::getFormPartByName(element, identifierStr(PrmEmpWorkDaysDisabilityPart));
    			if (partFormRun)
    			{
    				partFormRun.updateData(PRMEmpWorkDays.EmpDisabilityId, dateStartMth(PRMEmpWorkDays.DayDate), endmth(PRMEmpWorkDays.DayDate));
    			}
            }
    
            accessRight = SecurityRights::construct().menuItemAccessRight(SecurableType::MenuItemDisplay, menuitemDisplayStr(PrmEmpWorkDaysNonAttendancePart));
        
            // Check access right level before attempting to update form part data
            if (accessRight == AccessRight::Delete)
            {
                partFormRun = PRMGlobal::getFormPartByName(element, identifierStr(PrmEmpWorkDaysNonAttendancePart));
                if (partFormRun)
                {
                    partFormRun.updateData(PRMEmpWorkDays.EmpNonAttendanceId, dateStartMth(PRMEmpWorkDays.DayDate), endmth(PRMEmpWorkDays.DayDate));
                }
            }
        
        }

    I will try to get it done by myself, but if I won't be able to do it I will get back to you, if that's okay?

    Best regards,

    Maris

  • Pete Alberts Profile Picture
    3,542 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    From the code that Will Wu formatted:

    1. What type of object is PRMEmpWorkDaysColor?
    2. I assume you set the range in PRMEmpWorkDays_ds.executeQuery() method?
    3. I'd start by looking at what happens in the updateParts() form method.

    As you mentioned being new, a few comments:

    1. We always need to add curly brackets around an if-statement even if it only contains a single line of code (also while, for, etc). It really sucks. But that is how it is. It's best practice and you'll notice the code editor struggles with the indentation if you do not add brackets.
    2. Methods in x++ are implicitly public, so I tend to remove the public. But that is my preference.
    3. X++ primitives do not need to be initialised. Int will be 0, boolean false, string will be "", etc
  • Suggested answer
    Pete Alberts Profile Picture
    3,542 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    So if I try to simplify the problem. The displayOption works correctly initially, but when you refresh the data (executeQuery), then it appears to magically have disappeared. Please let me know if I missed something there.

    That comes down to a displayOption and a filter. To test I created a SimpleList form for the CustTable table.

    The code to achieve a display option with a filter will look like this:

    [Form]
    class XYZDisplayOptionTest extends FormRun
    {
        private QueryBuildRange custGroupRange;
    
        [DataSource]
        class Customer
        {
            void init()
            {
                super();
    
                custGroupRange = this.queryBuildDataSource().addRange(fieldNum(CustTable,CustGroup));
            }
    
            void displayOption(Common _p1, FormRowDisplayOption _options)
            {
                _options.textColor(65408);
                _options.backColor(20000);
    
                super(_p1, _options);
            }
    
        }
    
        [Control("String")]
        class CustGroupFilter
        {
            boolean modified()
            {
                boolean modified;
    
                modified = super();
    
                custGroupRange.value(this.text());
                Customer_ds.executeQuery();
    
                return modified;
            }
    
        }
    
    }

    The form design looks like this:

    Screenshot-2021_2D00_01_2D00_04-at-11.56.10.png

    Which works as expected:

    Screenshot-2021_2D00_01_2D00_04-at-11.57.31.pngScreenshot-2021_2D00_01_2D00_04-at-11.57.45.png

    Which means some of your own code somewhere someplace is causing trouble. Exactly what code that is will be difficult from my side. If I were you I'd comment out everything and start with just the display option and the filter. Then it must work. When you get there you can start gradually adding back your logic.

    If you paste all your code I can try and look with you for the problem. But I don't know if you are comfortable with that.

  • Pete Alberts Profile Picture
    3,542 on at
    RE: Form datasource re-trigger displayOption method in MS D365

    Hi Maris

    I deleted my comment because it is clear that the form is indeed your own.

    I will get back to you soon.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

🌸 Community Spring Festival 2025 Challenge 🌸

WIN Power Platform Community Conference 2025 tickets!

Jonas ”Jones” Melgaard – Community Spotlight

We are honored to recognize Jonas "Jones" Melgaard as our April 2025…

Kudos to the March Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 294,000 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 232,850 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,158 Moderator

Leaderboard

Product updates

Dynamics 365 release plans