Skip to content

Input Line Event

Business Portals can trigger an event based on input in a line on the frontend. This input is sent to Business Central, where it can be processed by a custom codeunit to recalculate values or return a specific result.

This section provides an example of how to implement a custom codeunit that is triggered by an event based on user input.

Code Example

In this example, we will use the Sales Order Line table in a scenario where the user can input a quantity for the items listed in a line. The input will update the item price by multiplying the quantity with the unit price.

The user input triggers an event by sending the value to Business Central, where it is processed in a Business Central codeunit.

AL
'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EVENT');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'All lines with the same quantity will be selected.');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // This will get the value of what is entered in the frontend,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // Filter at the exact line which triggers the event, and get the value of other fields for calculation, then return the value to frontend. It is just an example based on Quantity field, it can be any other fields and any calculation based on the requirement. It is recommended to directly get the line which triggers the event and return the value for that line only, then do the calculation on client side, if there are performance concern when there are lots of lines with the same quantity.
                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange("Line No.", LocalRecordSalesLine."Line No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindFirst() then begin
                    // This code block will return the input value to the frontend.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                    LocalInputXmlElement.SetAttribute('VALUE', LocalInputText);

                    // This code block will return other field values, based on the input value, to the frontend for calculation. In this example, it returns Unit Price and does a multiplication on backend, then return the result to frontend, but it can be any other fields and any calculation based on the requirement.
                    LocalInfoXmlElement := XmlElement.Create('INFO');
                    LocalEventXmlElement.Add(LocalInfoXmlElement);
                    LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                    LocalInputXmlElement := XmlElement.Create('INPUT');
                    LocalInfoXmlElement.Add(LocalInputXmlElement);
                    Evaluate(LocalMultiplierDecimal, LocalInputText);

                    LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                    LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                    LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));
                end;
            end;
    end;

Code Example 2

With a similar scenario as the first Code Example, this code example will show how to update all of the lines rather than only the selected line

AL
 'INPUTLINE':
    begin
        LocalEventXmlElement := XmlElement.Create('EVENT');
        LocalRootXmlElement.Add(LocalEventXmlElement);
        LocalRootXmlElement.SetAttribute('EVENTTYPE', ParamRecordSIMDPSOL."Sub Function Event");
        LocalRootXmlElement.SetAttribute('EVENTVALUE', LocalEventValueText);
        LocalRootXmlElement.SetAttribute('EVENTMESSAGE', 'Alle Zeilen mit der gleichen Anzahl wurden abgewählt.');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGETYPE', 'default');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILE', '');
        LocalRootXmlElement.SetAttribute('EVENTMESSAGEMOBILETYPE', 'default');

        if Evaluate(LocalRecordId, LocalEventValueText, 9) then
            if LocalRecordRef.Get(LocalRecordId) then begin
                LocalLineRecordSIMDPSOL.Reset();
                LocalLineRecordSIMDPSOL.SetRange("Entry No.", ParamRecordSIMDPSOL."Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Sub Entry No.", ParamRecordSIMDPSOL."Sub Entry No.");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Code", ParamRecordSIMDPSOL."Dataset Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Code", ParamRecordSIMDPSOL."Dataset Table Code");
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Type", ParamRecordSIMDPSOL."Dataset Table Type"::Line);
                LocalLineRecordSIMDPSOL.SetRange("Dataset Table Record", LocalRecordId);

                // This will get the value of what is entered in the frontend,
                if LocalLineRecordSIMDPSOL.FindSet() then
                    LocalInputText := GlobalCodeunitSIMDPSOrderFunctionLibrary.GetDPSOrderLineInputFieldByCode(LocalLineRecordSIMDPSOL, 'QUANTITY');

                // To loop through all lines with the same quantity, the code can be like below, but it may have performance issue when there are lots of lines, so it is better to directly get the line which triggers the event and return the value for that line only, then do the calculation on client side.

                LocalRecordRef.SetTable(LocalRecordSalesLine);
                Local2RecordSalesLine.SetRange("Document Type", LocalRecordSalesLine."Document Type");
                Local2RecordSalesLine.SetRange("Document No.", LocalRecordSalesLine."Document No.");
                Local2RecordSalesLine.SetRange(Quantity, LocalRecordSalesLine.Quantity);
                if Local2RecordSalesLine.FindSet() then
                    repeat
                        LocalInfoXmlElement := XmlElement.Create('INFO');
                        LocalEventXmlElement.Add(LocalInfoXmlElement);
                        LocalInfoXmlElement.SetAttribute('VALUE', Format(Local2RecordSalesLine.RecordId, 0, 9));

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);
                        LocalInputXmlElement.SetAttribute('NAME', 'QUANTITY');
                        LocalInputXmlElement.SetAttribute('VALUE', LocalInputText);

                        LocalInputXmlElement := XmlElement.Create('INPUT');
                        LocalInfoXmlElement.Add(LocalInputXmlElement);
                        Evaluate(LocalMultiplierDecimal, LocalInputText);

                        LocalSumDecimal := LocalMultiplierDecimal * Local2RecordSalesLine."Unit Price";

                        LocalInputXmlElement.SetAttribute('NAME', 'PRICE');
                        LocalInputXmlElement.SetAttribute('VALUE', Format(LocalSumDecimal, 0, 9));

                    until Local2RecordSalesLine.Next() = 0;
            end
    end;