(function($) { 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; } }, prefetch: { url: '/ingredients/prefetch.json', cache: false }, remote: { url: '/ingredients/search.json?query=%QUERY', wildcard: '%QUERY' } }); // var tagSearchEngine = 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; // } // }, // prefetch: { // url: '/tags/prefetch.json', // cache: false // }, // remote: { // url: '/tags/search.json?query=%QUERY', // wildcard: '%QUERY' // } // }); function reorder($container) { $container.find("div.nested-fields").each(function(idx, editor) { var $editor = $(editor); $editor.find('input.sort_order').val(idx + 1).trigger("changed"); }) } function initializeStepEditor($container) { // $container is either an element that contains many editors, or a single editor. var $editors = $container.find("textarea.step").closest(".step-editor"); $editors.each(function(idx, elem) { var $editor = $(elem); var $step = $editor.find("textarea.step"); autosize($step); setTimeout(function() { autosize.update($step); }, 250); }); } function initializeIngredientEditor($container, ingredientSearchEngine) { // $container is either an element that contains many editors, or a single editor. var $editors = $container.find(".ingredient-typeahead").closest(".nested-fields"); $editors.each(function(idx, elem) { var $editor = $(elem); var $ingredientId = $editor.find("input.ingredient_id"); var $group = $editor.find("div.typeahead-group"); $editor.find(".ingredient-typeahead").typeahead({}, { name: 'ingredients', source: ingredientSearchEngine, display: function(datum) { return datum.name; } }); if ($ingredientId.val().length) { $group.addClass("has-success"); } }); } function ingredientItemPicked($typeahead, datum) { var $container = $typeahead.closest(".nested-fields"); var $ingredientId = $container.find("input.ingredient_id"); var $group = $container.find("div.typeahead-group"); $ingredientId.val(datum.id); $typeahead.typeahead('val', datum.name); $group.addClass("has-success"); } function ingredientNameChange($typeahead, ingredientSearchEngine) { var $container = $typeahead.closest(".nested-fields"); var $ingredientId = $container.find("input.ingredient_id"); var $group = $container.find("div.typeahead-group"); var id = $ingredientId.val(); var value = $typeahead.typeahead('val'); if (id && id.length) { var found = ingredientSearchEngine.get([id]); if (found && found[0] && found[0].name != value) { // User has chosen something custom $ingredientId.val(''); $group.removeClass("has-success"); } } } function addIngredient(item) { $("#ingredient-list").one("cocoon:before-insert", function(e, $container) { var $ingredientId = $container.find("input.ingredient_id"); var $name = $container.find("input.ingredient-typeahead"); var $quantity = $container.find("input.quantity"); var $units = $container.find("input.units"); var $preparation = $container.find("input.preparation"); $name.val(item.name); $ingredientId.val(item.ingredient_id); $units.val(item.units); $quantity.val(item.quantity); $preparation.val(item.preparation); }); $("#addIngredientButton").trigger("click"); } function getIngredients() { var data = []; $("#ingredient-list .ingredient-editor").each(function() { var $container = $(this); var $ingredientId = $container.find("input.ingredient_id"); var $name = $container.find("input.ingredient-typeahead.tt-input"); var $quantity = $container.find("input.quantity"); var $units = $container.find("input.units"); var $preparation = $container.find("input.preparation"); data.push({ingredient_id: $ingredientId.val(), name: $name.typeahead("val"), quantity: $quantity.val(), units: $units.val(), preparation: $preparation.val()}); }); return data; } function addStep(step) { $("#step-list").one("cocoon:before-insert", function(e, $container) { var $step = $container.find("textarea.step"); $step.val(step); }); $("#addStepButton").trigger("click"); } function getSteps() { var data = []; $("#step-list .step-editor").each(function() { var $container = $(this); var $step = $container.find("textarea.step"); data.push($step.val()); }); return data; } $(document).on("turbolinks:load", function() { var $ingredientList = $("#ingredient-list"); var $stepList = $("#step-list"); var $tagInput = $("select.tag_names"); if ($ingredientList.length) { ingredientSearchEngine.initialize(false); } $tagInput.tagsinput({ trimValue: true, confirmKeys: [9, 13, 32, 44] // tab, enter, space, comma }); initializeStepEditor($stepList); $stepList .on("cocoon:after-insert", function(e, item) { reorder($(this)); initializeStepEditor(item); }) .on("cocoon:after-remove", function(e, item) { if (item.find(".remove-button.existing").length) { item.detach().appendTo("#deleted_steps"); } reorder($(this)); }) .on('changed', 'input.sort_order', function() { var $this = $(this); var $span = $this.closest(".nested-fields").find(".sort-order-display"); $span.html($this.val()); }); initializeIngredientEditor($ingredientList, ingredientSearchEngine); $ingredientList .on("cocoon:after-insert", function(e, item) { reorder($ingredientList); initializeIngredientEditor(item, ingredientSearchEngine); }) .on("cocoon:after-remove", function(e, item) { if (item.find(".remove-button.existing").length) { item.detach().appendTo("#deleted_ingredients"); } reorder($ingredientList); }) .on("typeahead:change", function(evt, value) { ingredientNameChange($(evt.target), ingredientSearchEngine); }) .on("typeahead:select", function(evt, value) { ingredientItemPicked($(evt.target), value); }) .on("typeahead:autocomplete", function(evt, value) { ingredientItemPicked($(evt.target), value); }) .on("click", "button.ingredient_convert_btn", function(evt) { }); $('#convert_modal') .on('show.bs.modal', function (event) { var $button = $(event.relatedTarget); var $modal = $(this); var $editor = $button.closest(".ingredient-editor"); $modal.data('ingredient-editor', $editor); var $quantity = $editor.find("input.quantity"); var $units = $editor.find("input.units"); var $ingredientId = $editor.find("input.ingredient_id"); var $modalQuantity = $modal.find("input.quantity"); var $modalUnits = $modal.find("input.units"); var $modalIngredientId = $modal.find("input.ingredient_id"); $modalQuantity.val($quantity.val()); $modalUnits.val($units.val()); $modalIngredientId.val($ingredientId.val()); }) .on("ajax:success", "form", function(evt, data, status, xhr) { var $modal = $("#convert_modal"); var $editor = $modal.data('ingredient-editor'); if (data.success) { var $quantity = $editor.find("input.quantity"); var $units = $editor.find("input.units"); var $modalOutUnits = $modal.find("input.output_units"); $quantity.val(data.output_quantity); if ($modalOutUnits.val().length) { $units.val($modalOutUnits.val()); } $modal.modal('hide'); } else { } $("#modal_form_container").replaceWith($(data.form_html)); }); var $bulkIngredientsModal = $("#bulk_ingredients_modal"); var $ingredientBulkInput = $("#ingredient_bulk_input"); var $ingredientBulkList = $("#ingredient_bulk_parsed_list"); autosize($ingredientBulkInput); var parseBulkIngredients = function() { var data = $ingredientBulkInput.val(); $ingredientBulkList.empty(); var parsed = []; var x; var lines = data.replace("\r", "").split("\n"); var regex = /^(?:([\d\/.]+(?:\s+[\d\/]+)?)\s+)?(?:([\w-]+)(?:\s+of)?\s+)?([^,]*)(?:,\s*(.*))?$/i; var magicFunc = function(str) { if (str == "-") { return ""; } else { return str; } }; for (x = 0; x < lines.length; x++) { var line = lines[x].trim(); if (line.length == 0) { continue; } var barIndex = line.lastIndexOf("|"); var afterBar = null; if (barIndex >= 0) { afterBar = line.slice(barIndex + 1); line = line.slice(0, barIndex); } var match = line.match(regex); if (match) { item = {quantity: magicFunc(match[1]), units: magicFunc(match[2]), name: magicFunc(match[3]), preparation: magicFunc(match[4])}; if (afterBar) { item.name = item.name + ", " + item.preparation; item.preparation = afterBar; } parsed.push(item); } else { parsed.push(null); } } $bulkIngredientsModal.data("bulkData", parsed); for (x = 0; x < parsed.length; x++) { var item = parsed[x]; if (item != null) { $ingredientBulkList.append( $("") .append($("").addClass("quantity").text(item.quantity)) .append($("").addClass("units").text(item.units)) .append($("").addClass("name").text(item.name)) .append($("").addClass("preparation").text(item.preparation)) ); } else { $ingredientBulkList.append( $("") .append($("").attr("colspan", "4").text("")) ); } } }; $bulkIngredientsModal .on('show.bs.modal', function (event) { var data = getIngredients(); var x; var text = []; for (x = 0; x < data.length; x++) { var item = data[x]; text.push( item.quantity + " " + (item.units || "-") + " " + item.name + (item.preparation ? (", " + item.preparation) : "") ); } $ingredientBulkInput.val(text.join("\n")); setTimeout(function() { parseBulkIngredients(); autosize.update($ingredientBulkInput); }, 250); }); $ingredientBulkInput.on('keyup', function() { parseBulkIngredients(); }); $("#bulkIngredientAddSubmit").on("click", function() { var parsed = $bulkIngredientsModal.data("bulkData"); var x; $("#ingredient-list").find(".remove-button").trigger("click"); if (parsed && parsed.length) { for (x = 0; x < parsed.length; x++) { var item = parsed[x]; if (item) { addIngredient(item) } } } $bulkIngredientsModal.modal('hide') }); // =========================================== // =========================================== var $bulkStepsModal = $("#bulk_steps_modal"); var $stepBulkInput = $("#step_bulk_input"); var $stepBulkList = $("#step_bulk_parsed_list"); autosize($stepBulkInput); var parseBulkSteps = function() { var data = $stepBulkInput.val(); $stepBulkList.empty(); var parsed = []; var x; var lines = data.replace("\r", "").split("\n\n"); for (x = 0; x < lines.length; x++) { var line = lines[x].trim().replace(/^\d+\./, "").trim(); if (line.length == 0) { continue; } parsed.push(line); } $bulkStepsModal.data("bulkData", parsed); for (x = 0; x < parsed.length; x++) { var item = parsed[x]; if (item != null) { $stepBulkList.append( $("") .append($("").addClass("step").text(x + 1)) .append($("").addClass("direction").text(item)) ); } else { $stepBulkList.append( $("") .append($("").attr("colspan", "2").text("")) ); } } }; $bulkStepsModal .on('show.bs.modal', function (event) { var data = getSteps(); $stepBulkInput.val(data.join("\n\n")); $stepBulkList.empty(); setTimeout(function() { parseBulkSteps(); autosize.update($stepBulkInput); }, 250); }); $stepBulkInput.on('keyup', function() { parseBulkSteps(); }); $("#bulkStepAddSubmit").on("click", function() { var parsed = $bulkStepsModal.data("bulkData"); var x; $("#step-list").find(".remove-button").trigger("click"); if (parsed && parsed.length) { for (x = 0; x < parsed.length; x++) { var item = parsed[x]; if (item) { addStep(item); } } } $bulkStepsModal.modal('hide') }); }); })(jQuery);