Front-End .. dialog collection render template

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • item
    Active Community Member
    • Mar 2017
    • 1476

    Front-End .. dialog collection render template

    Hi,

    i little learn front-end but here i loose
    un custom modal view..
    this open, template is rendered normaly..
    if you see code, commented, if i uncomment the hard coded nomenclatureList, the template "content" is ok.

    Here my goal is render the template after collection.fetch.
    the value is retreived from back-end in the this.listenTo(collection, 'sync', (collection, response, options) => { ...

    but i can not pass the value and render the dialog.

    Any front-end specialist ?


    PHP Code:
    
    define('custom:views/meeting/modals/dialog-care-nomenclature', ['views/modal', 'model', 'collection'], function (Dep, Model, Collection) {
    
        return Dep.extend({
    
            backdrop: true,
    
            templateContent: `
                <div class="margin-bottom">
                <p>{{viewObject.message}}</p>
                </div>
                <div>
                    <table width='100%'>
                        <tr>
                            <td width='20%'>nomenclature</td>
                            <td width='20%'>amountBase</td>
                            <td width='20%'>amountInsurance</td>
                            <td width='20%'>amountPatient</td>
                            <td width='20%'>nomenCode</td>
                        </tr>
                    </table>
                </div>
                <br />
                <div>
                    <table width='100%'>
                    {{#each viewObject.nomenclatureDataList}}
                        <tr>
                            <td width='20%'>
                                <button
                                    class="action btn btn-{{style}} btn-x-wide"
                                    type="button"
                                    data-action="setCare"
                                    data-nomenclature="{{name}}"
                                    data-nomen-code="{{nomenCode}}"
                                    data-amount-base="{{amountBase}}"
                                    data-amount-Insurance="{{amountInsurance}}"
                                    data-amount-Contact="{{amountContact}}"
                                >
                                {{label}}
                                </button>
                            </td>
                            <td width='20%'>
                                {{amountBase}}
                            </td>
                            <td width='20%'>
                                {{amountInsurance}}
                            </td>
                            <td width='20%'>
                                {{amountContact}}
                            </td>
                            <td width='20%'>
                                {{nomenCode}}
                            </td>    
                                {{#if selected}}<span class="check-icon fas fa-check" style="vertical-align: middle; margin: 0 10px;"></span>{{/if}}
                        </tr>
                    {{/each}}
                    </table>
                </div>
                <br/>
                <div class="margin-bottom">
                    <p>Select one nomenclature</p>
                </div>
            `,
    
            setup: function () {
                Dep.prototype.setup.call(this);
    
                let collection = new Collection;
                
                collection.url = 'Meeting/' + this.model.get('id') + '/Nomenclature';
    
                this.wait(
                    collection.fetch()
                );
    
                this.$header = $('<span>').append(
                    $('<span>').text(this.translate(this.model.entityType, 'scopeNames')),
                    ' <span class="chevron-right"></span> ',
                    $('<span>').text(this.model.get('name')),
                    ' <span class="chevron-right"></span> ',
                    $('<span>').text( 'Nomenclature' )
                );
    
                this.nomenclatureDataList = [];
                
    
                this.listenTo(collection, 'sync', (collection, response, options) => {
    
                    let val = response.list;
    
                    val.forEach(function (item) {
                        nomenclatureDataList.push(item);
                    });
    
                    this.reRender();
                    //
                });
    
    
                /*
                let o = {
                        name: 'LOGVAR',
                        nomenCode: 'logVar',
                        style: 'success',
                        label: 'LOGVAR',
                        selected: '',
                        amountBase: 1,
                        amountInsurance: 2,
                        amountContact: 3,
                    };
    
                this.nomenclatureDataList.push(o);
    
                o = {
                        name: 'LOG015',
                        nomenCode: 'log015',
                        style: 'default',
                        label: 'LOG015',
                        selected: '',
                        amountBase: 15,
                        amountInsurance: 0,
                        amountContact: 0,
                    };
                this.nomenclatureDataList.push(o);
                */
    
                console.log('END SETUP');
                
            },
    
            actionSetCare: function (nomenclature) {
                console.log(nomenclature);
                console.log(nomenclature.nomenCode);
                this.trigger('set-care', nomenclature);
                this.close();
            },
        });
    
    });
    
    If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​
  • item
    Active Community Member
    • Mar 2017
    • 1476

    #2
    A print-screen for better understand.


    If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

    Comment

    • telecastg
      Active Community Member
      • Jun 2018
      • 907

      #3
      Hello item

      At first sight it looks like you need to modify this:

      FROM:
      PHP Code:
                      val.forEach(function (item) {
                          nomenclatureDataList.push(item);
                      });
      
      TO:
      PHP Code:
                      val.forEach(function (item) {
                          this.nomenclatureDataList.push(item);
                      });
      
      write this.nommenclatureDataList.push(item) instead of nommenclatureDataList.push(item)

      I did not test it but it should work.

      Best Regards​
      Last edited by telecastg; 05-29-2023, 07:39 PM.

      Comment


      • item
        item commented
        Editing a comment
        Hi @telecastg,
        i have tested but no luck
        Uncaught TypeError: Cannot read properties of undefined (reading 'push')

        i have to try outside :
        let nommenclatureDataList = [];

        first problem :
        i can't not find the var nommenclatureDataList in the val.foreach

        second problem :
        if you see print-screen.. consol.log('SETUP END') is printed before collection.fetch
        in this situation, i think the template is rendered before collection.fetch.

        I think, the template must be rendered after collection.fetch and set nommenclatureDataList

        Hope this can useful for resolve my problem.
    • yuri
      Member
      • Mar 2014
      • 8442

      #4
      Context lost. Use an arrow function:

      Code:
      val.forEach(item => this.nomenclatureDataList.push(item));​​
      If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

      Comment

      • yuri
        Member
        • Mar 2014
        • 8442

        #5
        > if you see print-screen.. consol.log('SETUP END') is printed before collection.fetch
        > in this situation, i think the template is rendered before collection.fetch.

        No. It's not rendered before fetch. Setup is ended before fetch. Fetch is async and rendering is deferred until fetch is complete.
        If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

        Comment

        • item
          Active Community Member
          • Mar 2017
          • 1476

          #6
          Thank you Yuri,
          perfect.
          If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

          Comment

          • telecastg
            Active Community Member
            • Jun 2018
            • 907

            #7
            Let's try this way to solve the first problem:

            PHP Code:
                        this.listenTo(collection, 'sync', (collection, response, options) => {
            
                            let val = response.list;
            
                            val.forEach(function (item) {
                                this.nomenclatureDataList.push(item);
                            }.bind(this));
                            
                            this.reRender();
                            
                        }); 
            
            I don't think that the template is being rendered before the collection is fetched as the "wait" statement should be preventing that.


            The reason why the console.log statement is showing is because the statement is invoked without having to wait for the template to be rendered.

            Comment

            • item
              Active Community Member
              • Mar 2017
              • 1476

              #8
              Hi telecastg ..

              in custom view of meeting i have this

              PHP Code:
              setup: function () {
                          Dep.prototype.setup.call(this);
                      },...
              
              events: {
                          'click [data-action="attendee-care"]': function (e) {...
                     }, 
              
              Hum, i just realise that my above "events" .. kill the events of duplicate.

              but if you look : https://github.com/espocrm/documenta...725b8d58106338

              so i writed :

              PHP Code:
              
              setup() {    
                   super.setup();        
                   this.events['click [data-action="attendee-care"]'] = (e) => {        
                       console.log(e);
                  };    
              },  
              i have try with the doc of Yury, here above.. but he say : Uncaught TypeError: TypeError: (intermediate value).setup is not a function

              Any help ?

              If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

              Comment


              • telecastg
                telecastg commented
                Editing a comment
                Hi item,

                I would try the "traditional" way like this:
                setup() {

                Dep.prototype.setup.call(this);
                ...

                this.events['click [data-action="attendee-care"]'] = (e) => {
                console.log(e);
                };

                ....
                }

                If the traditional syntax is not working, one "low tech" solution could be to simply copy all events from the prototype view.

                The "super" keyword/function is part of the ECMAScript syntax, and only applies if a standard AMD Espo module (traditional) has been refactored into an ECMAScript Module and Class.

                For ECMAScript classes, the keyword "super" is equivalent to "prototype" in plain vanilla Javascript and in Espo AMD module implementation.

                So, unless the particular script that you are trying to customize has been refactored from AMD to ECMAScript the instruction Dep.prototype.setup.call(this); should work.
                Last edited by telecastg; 06-19-2023, 02:41 PM.

              • esforim
                esforim commented
                Editing a comment
                "Dep.prototype.setup"

                I read this exact same thing on Git today!

                Anyway this will be consider old legacy code soon with the upcoming UI code call EMS (???). But at least there is a promise of "Life-time backward compatibility" so not all is lost even if you do end up using this code?
            Working...