2
votes

I'm trying to simply display some JSON using Underscore and Backbone. Following are the codes. I am getting some parsing error for the template I have used. The error is like this: "The content of elements must consist of well-formed character data or markup." Any help is appreciated:

Following is the JSON object I have:

[  { name: 'mem1 mem1', 
     enrolmentDate: '12 May 2023', 
     optOutExpiryDate: '17 May 2023', 
     enrolmentType: 'Without qualifying earnings', 
     paymentSource: 'pmtSrc', 
     group: 'grp' 
   }, 
   { name: 'mem2 mem2', 
     enrolmentDate: '21 Jan 2022', 
     optOutExpiryDate: '26 Jan 2022', 
     enrolmentType: 'Without qualifying earnings', 
     paymentSource: 'pmtSrc', group: 'grp' 
   }
];

Following is the template:

<script id="workerTemplate" type="text/template">
<td><&percnt;&equals; name &percnt;></td>
<td><&percnt;&equals; enrolmentDate &percnt;></td>
<td><&percnt;&equals; optOutExpiryDate &percnt;></td>
<td><&percnt;&equals; enrolmentType &percnt;></td>
<td><&percnt;&equals; paymentSource &percnt;></td>
<td><&percnt;&equals; group &percnt;></td>
</script>

Following is the table in which the JSON datas need to be displayed:

<table id="addAndSearchActiveMemberTableId"             styleClass="table_cont_shedule worker_table col_align" rowClasses="odd,even">
                                        <thead>
                                            <tr>
                                            <th class="name" scope="col">Name</th>
                                            <th class="enrol_date" scope="col">Enrolment date</th>
                                            <th class="oo_exp_date" scope="col">Opt out expiry date</th>
                                            <th class="enrol_type" scope="col">Enrolment type</th>
                                            <th class="pay_src" scope="col">Payment source</th>
                                            <th class="grp" scope="col">Group</th>
                                            </tr>
                                        </thead>
                                        <tbody id="workers">
                                        </tbody>
                                    </table>


Follwing is the JavaScript using backbone framework:

                <script type="text/javascript">

                  var app = app || {};
                //This is the backbone model of worker
                  app.Worker = Backbone.Model.extend({
                      defaults: {
                          name: 'None',
                          enrolmentDate: 'None',
                          optOutExpiryDate: 'None',
                          enrolmentType: 'None',
                          paymentSource: 'None',
                          group: 'None'
                      }
                  });

//this is workerlist
                  app.WorkerList = Backbone.Collection.extend({
                        model: app.Worker
                  });


//The workerView
                  app.WorkerView = Backbone.View.extend({
                        tagName: 'tr',
                        className: '',
                        template: _.template( $( '#workerTemplate' ).html() ),

                        render: function() {
//this.el is what we defined in tagName. use $el to get access to jQuery html() function
                            window.alert("I am in render function of WorkerView");
                            this.$el.html( this.template( this.model.attributes ) );

                            return this;
                        }
                    }); 


//The workerListView
                  app.WorkerListView = Backbone.View.extend({
                        el: '#workers',

                        initialize: function( initialWorkers ) {
                            window.alert("initialize method called");
                            this.collection = new app.WorkerList( initialWorkers );
                            this.render();

                        },

// render workerCollection by rendering each worker in its collection
                        render: function() {
                            this.collection.each(function( item ) {
                                window.alert("calling renderWorker from render function of WorkerListView");
                                this.renderWorker( item );
                            }, this );
                        },

// render a worker by creating a workerView and appending the
// element it renders to the workerCollection's element
                        renderWorker: function( item ) {
                            window.alert("I am in renderWorker of WorkerListView");
                            var workerView = new app.WorkerView({
                                model: item
                            });
                            this.$el.append( workerView.render().el );
                        }
                    });

                  $(function() {

                        window.alert("function invoked");
                        var workers = [
                            { name: 'mem1 mem1', enrolmentDate: '12 May 2023', optOutExpiryDate: '17 May 2023', enrolmentType: 'Without qualifying earnings', paymentSource: 'pmtSrc', group: 'grp' },
                            { name: 'mem2 mem2', enrolmentDate: '21 Jan 2022', optOutExpiryDate: '26 Jan 2022', enrolmentType: 'Without qualifying earnings', paymentSource: 'pmtSrc', group: 'grp' }
                        ];
                        window.alert("Data passed to WorkerListView");
                        new app.WorkerListView( workers );
                    });
                  </script>


Now the question is:Is this the correct way to implement? It's not working :( 
 what are the flaws in the code. I have tried the code in html page, it's working fine , but in xhtml it's not working.
1
Is your template actually html escaped, or was that just from copying and pasting into your question? - Jack
No, it is as I copied here. - Shahid

1 Answers

2
votes

You need to unescape your template in order for underscore to be able to interpolate the values passed in. Try the following template:

<script id="workerTemplate" type="text/template">
<td><%= name %></td>
<td><%= enrolmentDate %></td>
<td><%= optOutExpiryDate %></td>
<td><%= enrolmentType %></td>
<td><%= paymentSource %></td>
<td><%= group %></td>
</script>

In addition it's better practice to call model.toJSON() rather then passing in the attributes directly.

So instead of:

this.$el.html( this.template( this.model.attributes ) );

you should be calling:

 this.$el.html( this.template( this.model.toJSON()) );

Here's a link to a jsBin