Dynamic calculation when inputting data in editor

Dynamic calculation when inputting data in editor

SamanthaTsangSamanthaTsang Posts: 12Questions: 4Answers: 0

Hello,

I have a table to calculate the marks of the student projects (see below). I would like to know how to do a dynamic calculation in the non-editable fields (in blue) instantly when I input some marks in the editable fields (in red). In other words, when I type some numbers in the editable fields, the non-editable fields will show the calculated numbers. And when I click the "Update" button, the showed calculated numbers will be updated to the database. Many thanks.

This question has accepted answers - jump to:

Answers

  • rf1234rf1234 Posts: 2,806Questions: 85Answers: 406
    Answer ✓

    Use "dependent" with an array of the fields whose changes should trigger (re)calculation of your non-editable fields and set the fields accordingly. You might also want to use field().message() to display calculated results.

    Here is an example from my own coding with lots of calculations and field setting

    editor
        .dependent(['sub_app.app_total_costs', 'sub_app.app_sub_costs'], function ( val, data, callback ) {
            //Zuwendungsfähige Kosten = Gesamtkosten, wenn noch leer
            var subRatio         = toFloat(this.val("sub.sub_ratio")) / 100;
            var totalCosts       = toFloat(this.val("sub_app.app_total_costs"));
            var subCosts         = toFloat(this.val("sub_app.app_sub_costs"));
            var totalCostsAbs    = Math.abs(totalCosts);
            var subCostsAbs      = Math.abs(subCosts);
            var theirShare = ""; var ownShare = ""; var effSubRatio = "";
            if ( subCostsAbs > totalCostsAbs ) { //sub costs cannot be higher than total costs
                this.set( {'sub_app.app_sub_costs': this.val("sub_app.app_total_costs")} )
            }
            if ( subCosts < 0 && totalCosts > 0 ) {
                this.set( {'sub_app.app_sub_costs': this.val("sub_app.app_sub_costs").substr(1)} )
                subCosts *= -1;
            } else if ( subCosts > 0 && totalCosts < 0 ) {
                this.set( {'sub_app.app_sub_costs': "-" + this.val("sub_app.app_sub_costs")} )
                subCosts *= -1;
            }
            if ( subRatio != 0 ) {
                var fundingRate = ( lang === 'de' ? 'Fördersatz (Basisdaten): ' : 'Funding Rate (Base Data): ') +
                            this.val("sub.sub_ratio") + " %";
            } else {
                var fundingRate = ( lang === 'de' ? 'Festbetragsförderung (Basisdaten)' : 'Fixed Amount Funding (Base Data)');
            }
            var subAmount = subRatio * subCosts;
            if ( subAmount != 0 ) {          
                theirShare = '<br>' + ( lang === 'de' ? 'Zuwendungsbetrag: ' 
                                                      :  'Grant Amount: ' ) +
                            renderAmountCurrency( toFormattedNum(
                            subAmount), this.val("ctr.currency") );
                ownShare = '<br>' + ( lang === 'de' ? 'Eigenanteil: ' 
                                                    : 'Own Contribution: ' ) +
                            renderAmountCurrency( toFormattedNum(
                            totalCosts - subAmount ), 
                            this.val("ctr.currency") );
                if ( totalCosts != 0 ) {
                    effSubRatio = '<br>' + ( lang === 'de' 
                                    ? 'Effektive Förderquote: ' 
                                    : 'Effective Funding Rate: ' ) +
                        toFormattedNum( subAmount / totalCosts * 100 ) + '%';
                }
            }
            this.field('sub_app.app_sub_costs')
                    .message(fundingRate + theirShare + ownShare + effSubRatio);
            callback({});
        })
    

    This is the result:

  • SamanthaTsangSamanthaTsang Posts: 12Questions: 4Answers: 0

    Thanks a lot !! It works perfectly well !! :D

    How about if I want to change the background color of a non-editable field to red, when a calculated value is larger than 10. Is there any suggested codes? Thank you.

    var diff = report_mark - presentation_mark;
    if (diff > 10) {
    // how to change the background color of a field named 'difference' to red
    // this.field('difference').background-color(red); ??
    }

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin
    Answer ✓

    field().input() is the method you want:

    this.field('difference').input().css('background-color', 'red');
    

    You'll want an else statement as well to remove the background colour should it become valid with additional input.

    Allan

  • rf1234rf1234 Posts: 2,806Questions: 85Answers: 406
    edited December 2022

    @allan: looks good!

    I did the same thing for groups of fields that I grouped using "className" like this:

    }, {
        label: lang === 'de' ? 'Wert anderer VorSt-Satz (%)' : 'Value other input tax rate (%)',
        name: "ctr.input_tax_mixed_rate",
        className: "vat-final-fields"
    }, {
        label: lang === 'de' ? 'Kommentar' : 'Comment',
        name: "ctr.VAT_comment",
        type: "textarea",
        className: "vat-final-fields"
    

    And then I assigned bootstrap background classes to the fields of each group:

    editor
        .dependent('ctr.VAT_decision', function ( val, data, callback ) {
            if (val == '1') {
                $('.vat-final-fields').addClass("bg-success");
                this.show( ['ctr.VAT_charged', 'ctr.input_tax_deductible', 
                            'ctr.VAT_start_date', 'ctr.VAT_comment'] );
            } else {
                $('.vat-final-fields').removeClass("bg-success");
                this.set( { 'ctr.VAT_charged': 0, 'ctr.input_tax_deductible': 0, 
                            'ctr.VAT_start_date': '', 'ctr.VAT_comment': '',
                            'ctr.VAT_rate': 0, 'ctr.input_tax_rate': 0,
                            'ctr.VAT_mixed_rate': '', 'ctr.input_tax_mixed_rate': ''} )
                    .hide( ['ctr.VAT_charged', 'ctr.input_tax_deductible', 
                            'ctr.VAT_start_date', 'ctr.VAT_comment',
                            'ctr.VAT_rate', 'ctr.input_tax_rate',
                            'ctr.VAT_mixed_rate', 'ctr.input_tax_mixed_rate'] );
            }
            callback({});
        })
    

    Looks like this; the green fields have class "bg-success"

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin

    That looks superb - nice one!

    Allan

Sign In or Register to comment.