Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set value of a select HTML element reactively with Meteor

I want to set the value of an HTML <select> element reactively, without changing the various options for the element. I have found a solution, but it in not elegant.

To test, create a barebones Meteor app with create meteor select and change the contents of the select.html and select.js files to the following:

select.html

<body>
  {{> select}}
</body>

<template name="select">
  <label for="select">{{category}}</label>

  <select id="select">
    <option value='' disabled selected style='display:none;'>Select...</option>
    <option value="Animal">Animal</option> 
    <option value="Vegetable">Vegetable</option>
    <option value="Mineral">Mineral</option>
  </select>
</template>

select.js

if (Meteor.isClient) {
  Session.set("category", "")
  Session.set("label", "Category")

  Template.select.onRendered(function () {
    setSelectValue()
  })

  Template.select.helpers({
    category: function () {
      setSelectValue()
      return Session.get("label")
    }
  });

  function setSelectValue() {
    var select = $("#select")[0]
    if (select) {
      select.value = Session.get("category")
    }
  }
}

Now launch your app. In the browser console, you can change the value of the category Session variable:

Session.set("category", "Animal")

However, the select element will not update until you change the label:

Session.set("label", "category") // was "Category'

Now the select element updates, and any subsequent change the category Session variable will also update the select element.

Session.set("category", "Vegetable") // Now the select element updates

Is it possible to achieve the same effect directly, without using this clumsy workaround?

like image 336
James Newton Avatar asked Sep 20 '15 10:09

James Newton


1 Answers

Yes. You can do it as follows:

  <select id="select">
    <option value="Animal" {{animalSelected}}>Animal</option> 
    <option value="Vegetable" {{vegetableSelected}}>Vegetable</option>
    <option value="Mineral" {{mineralSelected}}>Mineral</option>
  </select>

And helpers that looks something like this:

  Template.select.helpers({
    animalSelected: function () {
      return (someCondition === true) ? 'selected' : '';
    },
    vegetableSelected: function () {
      return (someOtherCondition) ? 'selected' : '';
    }
  });

A better way might be something like this though:

  <select id="select">
    {{#each options}}
      <option value="{{value}}" {{selected}}>{{label}}</option> 
    {{/each}}
  </select>

And then you can use this in the helpers to decide what is selected and what isn't.

Another option is just using standard jQuery to change the select box. Something like this:

$('[name=options]').val( 3 );

Or this SO answer.

like image 68
Eliezer Steinbock Avatar answered Oct 14 '22 02:10

Eliezer Steinbock