How to display multiple panes (e.g. similar to email clients)?


#1

I’d like to implement a two-pane design in a Meteor application, similar to how many email clients do it:

If you go to “static.filehorse.com/screenshots/messaging-and-chat/thunderbird-screenshot-01”, and add .png to the end, you’ll see what I mean.

(In this case, I actually am dealing with emails :smile:)

The idea is that one pane will have a scrollable table of emails, one email per row, whilst the other pane will display more details about the currently selected email.

Any thoughts on what’s the best way of doing this in Meteor?

How do I synchronise selecting in the list with what’s displayed in the other pane? And ideally, allow the user to resize the divider between panes.

I tried to do a Google to see if there’s pre-existing helpers for this, or even just somebody else who’s done it before, but I couldn’t find anything.

It’s hard to imagine it hasn’t been tried before, so I may just not be using the right search terms (meteor multi pane).


#2

Upon selection of an email in the click event of one view, you can store the id of the email in a session variable, and use it in the template of the other view.

Emails = new Mongo.Collection("emails");

if (Meteor.isClient) {

  Session.set("selected_email_id", -1);

  Template.email_list.helpers({
    emails:function(){ return Emails.find({}); }
  });

  Template.email_summary.events({
    "click li": function(){
      Session.set("selected_email_id", this._id);
    }
  });

  Template.email_content.helpers({
    selected_email: function(){ 
      var selectedId=Session.get("selected_email_id");
      if(selectedId===-1)
        return;
      return Emails.findOne(selectedId);
    }
  });
}

if (Meteor.isServer) {
  Meteor.startup(function () {
    Emails.remove({});
    Emails.insert({
      subject: "subject 1",
      content: "content 1",
    });
    Emails.insert({
      subject: "subject 2",
      content: "content 2",
    });
    Emails.insert({
      subject: "subject 3",
      content: "content 3",
    });
  });
}

and

<template name="email_summary">
  <li>{{subject}}</li>
</template>

<template name="email_content">
  {{#with selected_email}}
    {{subject}}
    <hr />
    {{content}}
  {{/with}}
</template>

<template name="email_list">
  <ul>
  {{#each emails}}
    {{>email_summary}}
  {{/each}}
  </ul>
</template>

<template name="emails">
  {{>email_list}}
  {{>email_content}}
</template>

#3

OK, I will give that approach a try.

I’m assuming the Session.set("selected_email_id", -1); only gets run once on the client, on page load right?

Also, whilst my list of emails is currently just a <table>, I’m also thinking of using this:

Hopefully the suggested approach will also work with that package. (The README does mention an example with events on clicking on table rows).


#4

Correct.

Also true. As soon as you can have a click event, the same approach will work.