Question

I'm trying to add a class to a list item depending on a value sent through in my querystring parameters, but I'm having trouble working out the running order of things and passing my data through to the right place.

in my template I have the following fragment

<ul id="reviews">
  <li>
    <label class="great"><span></span><input type="radio" name="review" value="Great" placeholder="Great">Great</label>
  </li>
  <li>
    <label class="fair"><span></span><input type="radio" name="review" value="Fair" placeholder="Fair">Fair</label>
  </li>
  <li>
    <label class="not-good"><span></span><input type="radio" name="review" value="Not good" placeholder="Not good">Not good</label>
  </li>
</ul>

in my client side JavaScript I have the following Router config:

Router.map(function () {
  this.route('review', {
  path: '/',
  template: 'review',
  data: function () {
    var params = this.params;
    return {
      fullname : params.fullname,
    }
  },
  after: function() {
    var params = this.params;

    setReview(params.review);

  }
});

Which calls the function setReview:

function setReview(review) {
  console.log('setReview called with: '+review);
  switch(review) {
    case "Great":
      console.log($('#reviews'));
      $('#reviews').find('.great').addClass('selected');
      $('#reviews').find('.great').find('input').prop('checked', true);
      break;
    case "Fair":
      $('#reviews').find('.fair').addClass('selected');
      $('#reviews').find('.fair').find('input').prop('checked', true);
      break;
    case "Bad":
      $('#reviews').find('.not-good').addClass('selected');
      $('#reviews').find('.not-good').find('input').prop('checked', true);
      break;
  }
}

This last function is called but doesn't work properly, as $('reviews') doesn't find the correct element on the page, but instead seems to return the whole document.

It looks like this is all happening before the page has rendered, so it can't find my list yet.

Is there a better way I should go about doing this kind of thing?

TIA

Was it helpful?

Solution

If you are certain that you want to use iron-router for this, then you might be able to get it to work with something like this:

Router.map(function () {
  this.route('review', {
  path: '/',
  template: 'review',
  after: function() {
    Session.set('params', this.params);
  }
});

Template.reviews.rendered = function() {
    setReview(Session.get('params');
};

But overall, this doesn't quite seem like the Meteor way of doing things.

Why not try something like this:

<ul id="reviews">
  <li>
    <label class="great {{greatselected}">
       <span></span>
       <input type="radio" name="review" value="Great" 
              placeholder="Great" {{greatchecked}}>Great</label>
  </li>
  .....
</ul>

And then say:

Template.reviews.greatselected = function() {
   return (Session.get('params').review == "Great" ? "selected" : "");
}

Template.reviews.greatchecked = function() {
   return (Session.get('params').review == "Great" ? "checked" : "");
}

...

OTHER TIPS

The simplest was would be to extend your data function to include the review parameter:

data: function () {
  var params = this.params;
  return {
    fullname : params.fullname,
    review: params.review
  }
}

Then proceed as @christian-fritz suggests:

<input type="radio" name="review" value="Great" 
          placeholder="Great" checked="{{greatchecked}}">Great</label>

and

Template.reviews.greatselected = function() {
  return this.review === "Great";
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top