Sorting a Table

I am trying to do a simple table sort. Right now I would not like to use reactive table, because I want to understand how to sort a Collection. I am new at meteor .
JS
I created a Collection

ProductList = new Mongo.Collection("products");

after

if (Meteor.isClient){
Template.productos.events({
    'click #sortTec': function(){
      ProductList.find({},{sort:{tipotec:-1}});
      console.log('test');
    }
})
}

HTML

<table type="table" class="table table-hover">
     <thead>
        <th>Codigo <span 

class="glyphicon glyphicon-chevron-down"></span></th>
        <th>Descripción <span class="glyphicon glyphicon-chevron-down"></span></th>
        <th>Precio <span class="glyphicon glyphicon-chevron-down"></span></th>
        <th id="sortTec">Tecnologia <span class="glyphicon glyphicon-chevron-down"></span></th>
        <th>Cambios</th>
      </thead>
      <tbody>
        {{# each productos}}
        <tr>
          <td>{{codigo}}</td>
          <td>{{descripcion}}</td>
          <td>{{precioa}}</td>
          <td><span class="label {{tipotec}}">{{tipotec}}</span></td>
          <td>{{#afModal collection="ProductList" operation="update"
                doc=_id title=codigo}}
                <span class="glyphicon glyphicon-wrench"></span>
                {{/afModal}}
              {{#afModal collection="ProductList" operation="remove"
                doc=_id title=codigo prompt="Estas seguro de que quieres borrar"}}
                <span class="glyphicon glyphicon-remove red"></span>
                {{/afModal}}
          </td>
        </tr>
    
        {{/each}}
      </tbody>
    </table>

I want to sort the table when the user clicks #sortTec

What am I doing wrong?

You need to use helpers to return your cursor. Like this:

Template.productos.helpers({
    productos: function () {
        return ProductList.find({}, { sort: { tipotec: -1 } });
    }
});

you need to change your productos template helper.

Template.productos.events({
  'click #sortTec': function() {
    Session.set("sortTecOrder", -1);
  }
})
Template.productos.helpers({
  productos: function () {
    var sortTecOrder = Session.get("sortTecOrder") || 1;
    return ProductList.find({}, { sort: { tipotec: sortTecOrder } });
  }
});

Thank you this worked perfectly. Is there a way I can toggle with the sorting order between ascending and descending?

1 Like

Set it to 1 (one) will do that?

Yes it does the trick, but how can I use an if statement to determine if it is 1, or -1?

1 Like

To toggle you could do Session.set("sortTecOrder", Session.get("sortTecOrder") * -1);

However, you must ensure that the Session variable is set to 1 or -1 when first created.

Incidentally, this would be cleaner (reduced global pollution) using ReactiveVar.

I’d probably do it something like this:

Template.productos.onCreated(function() {
  this.sortTecOrder = new ReactiveVar(1);
});
Template.productos.events({
  'click #sortTec': function() {
    var self = Template.instance();
    self.sortTecOrder.set(self.sortTecOrder.get() * -1);
  }
})
Template.productos.helpers({
  productos: function () {
    var self = Template.instance();
    var sortTecOrder = self.sortTecOrder.get();
    return ProductList.find({}, { sort: { tipotec: sortTecOrder } });
  }
});

Not forgetting to meteor add reactive-var.

2 Likes

This worked like a charm. Thank you!

2 Likes

why not use template instance object you receive from event handler ?

1 Like

Good call - it was a quick off-the-cuff bit of code. You’re absolutely right - I would do that.

@robfallows, @pahans sorry for reviving this thread. I see how this works using a reactive variable, but I don’t get why we need a reactive variable in the first place – and running a sort command on a Mongo Collection cursor doesn’t achieve the same effect.

To my understanding when I return a Collection cursor in my template helper, that cursor is reactive. So when I run a mongo sort function without using a reactive var, e.g.

Products.find({}, { sort: { name: -1 } })

why doesn’t this change still trigger a reflow of the UI? (I tested this out by running sort commands against a Collection in the console; the page doesn’t re-render.)

A template helper establishes a reactive dependency on the cursor (if the cursor changes, the helper is re-run). However, the cursor itself is not reactive.

In the example above, another reactive dependency (the ReactiveVar) is also used to cause the helper to re-run (independently of any cursor changes). A by-product of that re-run is to change the cursor by means of its sort property. Hence the re-render.