Set Editor Field placeholder or field message from other field data

Set Editor Field placeholder or field message from other field data

timbcusicktimbcusick Posts: 21Questions: 6Answers: 0
edited May 2017 in Free community support

We need to display default values which are stored in other datatable columns in the placeholder or message of some of the editor fields. I know how to set placeholder and message statically, but is there a way to set them using values stored in other fields? would like to do something like below

   {
                label: "Per Unit EEU Incentive",
                name: "CustomerIncentive",
                attr: {
                    type: "number",  placeholder:  <<<field.ActualCustomerIncetive>>>  


                }
            }

Thanks.
Tim

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
    edited May 2017

    sure you can use a getFormatter to get the value from a different field on the server side. That can also be based on a condition (e.g. your field is still empty or something else).
    And subsequently you can use a setFormatter to update the database field with whatever you like.
    https://editor.datatables.net/manual/php/formatters

    Here is an example from my coding. As you can see I call functions that do all kind of complex manipulations, return this to the front end (getFormatter) and vice versa (setFormatter).

    The formatters provide access to the respective field itself ($val) but also to other fields in the same row ($data), e.g. $data['contract.id'] or $data['proposal.communication'] which would be the same as $val in the example below.

    PHP:
    --
    Field::inst( 'proposal.communication' )
        ->getFormatter( function($val, $data, $opts) {
            return getFormatterMessage($val, $data, 'proposalmessage');
        })
        //the table field is always set to space because the messages are saved in a child table
        ->setFormatter( function($val, $data, $opts) {
            if ($val > '') {
                return setFormatterMessage($val, $data, 'govdept', 'proposalmessage');
            } else {
                return '';
            }
        }),
    

    The formatters allow you to do anything you like including database manipulations using your own db handler like here:

    PHP
    --
    function getFormatterMessage(&$val, &$data, $table) {
        global $dbh;
        if ($table === 'proposalmessage') {
            $dbh->query('SELECT message FROM proposalmessage 
                          WHERE proposal_id = :proposal_id');
            $dbh->bind(':proposal_id', $data['proposal.id']);
        } else {
            $dbh->query('SELECT message FROM contractmessage 
                          WHERE contract_id = :contract_id');
            $dbh->bind(':contract_id', $data['contract.id']);
        }
        $row = $dbh->resultsetAssoc(); // a two dimensional array is returned
        (int)$rowCount = $dbh->rowCount();
        $message = '';    
        if ($rowCount > 0) {
            foreach ($row as $list => $values) {
                $message = $message . $values["message"];
            }
            $message = $message . '<br><br>';
            $dateTag = '\/YD-&L++\/';
            $msgOfTag = 'wDj|LM+0DW{||xIN2qy;O9A(m';
            $endOfMsg = 'UytO+;Y])l%lTY';
            if ($_SESSION['lang'] === 'de') {    
                $message = str_replace($dateTag, '.', $message);
                $message = str_replace($msgOfTag, '*** Nachricht von ', $message);
                $message = str_replace($endOfMsg, '*** Ende der Nachricht von ', $message);
            } else {
                $message = str_replace($dateTag, '/', $message);
                $message = str_replace($msgOfTag, '*** Message from ', $message);
                $message = str_replace($endOfMsg, '*** End of Message from ', $message);
            }
        }
        
        return $message;
    }
    
  • timbcusicktimbcusick Posts: 21Questions: 6Answers: 0

    Thanks rf1234,

    I should have been clearer. We are not using the PHP or .Net Api libraries and just using client side editor api. Is there a solution to do something similar client side?

    Thanks,

    Tim

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406

    sure, you can use this:
    https://editor.datatables.net/reference/option/fields.def
    "Default values can be given as any Javascript data type (numbers, strings, objects, etc), including functions."

  • timbcusicktimbcusick Posts: 21Questions: 6Answers: 0

    rf1234,

    I do not want to actually set the value, just the placeholder. I realize that I can set default values, but what I am looking to do is inject a different field value dynamically into the placeholder attribute and still not clear where or how to do that. Sorry if I'm missing something.

    Tim

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
    edited May 2017

    ok, if you look at this hard coded placeholder:

    {
        label: "Country Code:",
        name:  "govprefcreditor.countrycode",
        attr: {
            class: 'phoneCountryCode',
            placeholder: "+49"
        }
    }
    

    let's assume you want to change the placeholders depending on the language then you could define a gloval variable in Java Script

    var countryCode;
    

    you could set it based on the following logic:

    if (lang === 'de') {
      countryCode = "+49";
    } else {
      countryCode = "+44";
    }
    

    you would change the code above into:

    {
        label: "Country Code:",
        name:  "govprefcreditor.countrycode",
        attr: {
            class: 'phoneCountryCode',
            placeholder: countryCode
        }
    }
    

    This works because you can access the global variable inside Editor as well. I wouldn't know how you could pass the placeholder value in but you get it done with a global variable that you can change dynamically.

    Not sure whether you can change the placeholder dynamically AFTER Editor has been initialized. I don't think you can. In my example it doesn't matter because a change of the user language requires a refresh of the page which re-initializes everything. A simple ajax.reload() might not be enough. Just check it out!

  • timbcusicktimbcusick Posts: 21Questions: 6Answers: 0

    rf1234,

    I really appreciate your responses, but this really doesn't solve my issue. The data that I want to populate into placeholder is in the row data from the json response. I have about 10 columns that have 10 other columns which contain the placeholder data. With about 500 rows that would be 5,000 global variables. What I was hoping for was some type of render function similar to what I can do with datatables column rendering:

     {
                    data: "ActualCostPerUnit",
                    className: "text-right",
                    render: function(data, type, row) {
                        return '<span data-original-value="' + row.CostPerUnit + '">' + data + '</span>';
                    }
                },
    

    with your example what I'm trying to do would look something like this:

    {
        label: "Country Code:",
        name:  "govprefcreditor.countrycode",
        attr: {
            class: 'phoneCountryCode',
            placeholder: govprefcreditor.SOMEOTHERFIELD
        }
    }
    
  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406

    Maybe I am not getting it ... anyway, last attempt from my side :smiley:

    You can only show the user one placeholder at a time. Even though the value of the placeholder may depend on a very large number of input fields there must be an algorithm that selects just this single placeholder you want to display - which you can store in just one global variable.

    My idea is:
    - you get your json response
    - you run your algorithm that selects the one placeholder that you would like to display to your user
    - you assign the placeholder to the global variable
    - you initialize Editor with the global variable

    If that doesn't help I have to apologize. Maybe Allan can help?

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
    edited May 2017

    ok, my previous attempt wasn't the last one, I guess I was kidding :smile:

    I just thought about it. I am using Editor events to mask fields dynamically like this;

    part of the Editor instance:
    {
                    label: "Fee (if any):",
                    name:  "fixed.fee",
                    attr: {
                        class: amountMaskNoDecPlaces
                    }
                },
    
    
    contractFixedCredEditor
                .on('open', function(e, mode, action) {                
                    maskAmount();
                    maskDateTime(); ....
    

    maskAmount() contains an algorithm that assigns a class to a global variable called amountMaskNoDecPlaces. This class is set dynamically every time Editor is being opened. That should be exactly what you require: You can set your placeholder dynamically every time Editor is opened. If it is opened to create a new record you don't know the context data anyway because it is a new record. If it is opened to edit an existing records you have the data that are being edited available and you can dynamically define your placeholder depending on these data.

    check this:
    Editing an existing record:
    https://editor.datatables.net/reference/event/initEdit
    Scroll down to see all available Editor events and the parameters they provide:
    https://editor.datatables.net/manual/events

    Here is another example just to give you an idea how powerful Editor events are. Depending on the value of one field in the same record you can do something (e.g. assign a different placeholder which is contained in another field to your global variable ...).

    contractGovEditor
                .dependent('contract.expired', function ( val, data, callback ) {
                    if (val == '1') {
                        contractGovEditor
                                .show( ['contract.exp_date'] );
                        if ( contractGovEditor.val('contract.exp_date') <= '' ) {
                            contractGovEditor
                                .field('contract.exp_date').set(yesterday);
                        }
                    } else {
                        contractGovEditor
                                .set( { 'contract.exp_date': '' } )
                                .hide( ['contract.exp_date'] );
                    }
                })
                .on('open', function(e, mode, action) {
                    $('.DTE_Form_Info').addClass("text-warning");                
                    if (action === 'edit') {
                        contractGovEditor.field('contract.govdept_id').disable();                    
                    } else {
                        contractGovEditor.field('contract.govdept_id').enable();
                    }
                })
                .on('close', function() {
                    $('.DTE_Form_Info').removeClass("text-warning");
                })
    

    This one should be the solution to your problem, I hope:
    https://editor.datatables.net/reference/api/dependent()

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    edited May 2017 Answer ✓

    You can dynamically set the placeholder by using the field().input() method to get a reference to the input element and then manipulate it as you would with any other jQuery / DOM element:

    editor.field( 'myField' ).input().attr( 'placeholder', 'whatever' );
    

    There isn't the option of specifying the placeholder as a function (although nice idea), but you could easily dynamically change the placeholder value based on the state of the form or what is being edited by using the event listeners - initEdit and initCreate specifically, or if you want to do it when the user is entering data, you could use a change event manually or the dependent() method rf1234 mentioned.

    Allan

  • timbcusicktimbcusick Posts: 21Questions: 6Answers: 0
    edited May 2017

    allan, rf1234,

    Thanks for all the help! Here is the final solution:

      editor.on('initEdit', function (e, node, data ) {
                editor.field('CostPerUnit').input().attr('placeholder', data.ActualCostPerUnit);
            });
    

    Tim

This discussion has been closed.