Meteor Reactivity Playground 2.0

by chicagogrooves

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://s3.amazonaws.com/www.chicagogrooves.com/js/meteor-reactive-packages.js"></script>
<form>
    <h1>Meteor Reactive Form</h1>
    <div>
        <label for="question_11">
            <span class="required">*</span>
            What is your name:
        </label>
        <input name="question_11" id="question_11" autofocus="1"/>
    </div>
    <div>
        <label for="question_22">What is your BFF's name:</label>
        <input name="question_22" id="question_22"/>
    </div>
    <div>
        <label for="question_33">
            <span class="required">*</span>
            You are a child of the:
        </label>
        <select name="question_33" id="question_33">
            <option value="">Select One</option>
            <option value="2000">2000's</option>
            <option value="1990">1990's</option>
            <option value="1980">1980's</option>
            <option value="1970">1970's</option>
            <option value="1960">1960's</option>
            <option value="1950">1950's</option>
            <option value="-1">an earlier era</option>
        </select>
    </div>
    <div>
        <input type="submit"/>
    </div>
</form>





<a id="fs" style="position:absolute; top: 5px; left: 5px;" href="http://jsfiddle.net/chicagogrooves/y18er7wr/embedded/result/" target="_blank">Launch Full Screen -&gt;</a>

CSS

body{ margin-top: 25px; margin-left: 10px;}
.error, .required{ color: red; }
input[type=submit]{ margin-top: 20px; }
input, select{ margin-right: 20px; }

JavaScript

MeteorComputation = function (fn) {
  var computation,
      lastReturnVal;

  Tracker.autorun(function (c) {
    if (c.firstRun) computation = c;
    lastReturnVal = fn.call();
  });

  _.extend(computation, {
    rerun: function () {
      computation.invalidate();
      return computation.nextValue();
    },
    nextValue: function () {
      return new Promise (function (resolve) {
        Tracker.afterFlush(function () {
          resolve(lastReturnVal);
        });
      });
    }
  });

  Object.defineProperty(computation, "currentValue", {
    get: function () {
      return lastReturnVal;
    }
  })
  Object.defineProperty(computation, "value", {
    get: function () {
      return computation.nextValue();
    }
  })

  return computation;
}.bind(Meteor);

// patch Meteor global - requires Meteor to load first
Meteor.Computation = MeteorComputation;