(function($) { function State() { this.input = null; this.outputUnit = null; this.density = null; this.changed = false; } State.prototype.setInput = function(value) { if (value != this.input) { this.changed = true; this.input = value; } }; State.prototype.setDensity = function(value) { if (value != this.density) { this.changed = true; this.density = value; } }; State.prototype.setOutputUnit = function(value) { if (value != this.outputUnit) { this.changed = true; this.outputUnit = value; } }; State.prototype.is_changed = function() { return this.changed; }; State.prototype.reset = function() { this.changed = false; }; var ingredientSearchEngine = new Bloodhound({ initialize: false, datumTokenizer: function(datum) { return Bloodhound.tokenizers.whitespace(datum.name); }, queryTokenizer: Bloodhound.tokenizers.whitespace, identify: function(datum) { return datum.id; }, sorter: function(a, b) { if (a.name < b.name) { return -1; } else if (b.name < a.name) { return 1; } else { return 0; } }, remote: { url: '/calculator/ingredient_search.json?query=%QUERY', wildcard: '%QUERY' } }); $(document).on("turbolinks:load", function() { var state = new State(); var $input = $("#input"); var $output = $("#output"); var $density = $("#density"); var $outputUnit = $("#output_unit"); var performUpdate = _.debounce(function() { $.getJSON( "/calculator/calculate", {input: $input.val(), output_unit: $outputUnit.val(), density: $density.val()}, function(data) { if (data.errors.length) { $("#errors_panel").show(); $("#errors_container").html(data.errors.join(" ")); } else { $("#errors_panel").hide(); } $output.val(data.output); } ); }, 500); var ingredientPicked = function(i) { $density.val(i.density); $density.trigger('change'); }; $input.add($outputUnit).add($density).on('change blur keyup', function(evt) { state.setInput($input.val()); state.setOutputUnit($outputUnit.val()); state.setDensity($density.val()); if (state.is_changed()) { performUpdate(); state.reset(); } }); if ($("#calculator").length) { ingredientSearchEngine.initialize(false); $("#ingredient").typeahead({}, { name: 'ingredients', source: ingredientSearchEngine, display: function(datum) { return datum.name; } }) .on("typeahead:select", function(evt, value) { ingredientPicked(value); }) .on("typeahead:autocomplete", function(evt, value) { ingredientPicked(value); }); } }); })(jQuery);