function getRecipeIngredientIdField(nameField) { var fieldId = nameField.id; var idFieldId = fieldId.replace(/\.([^.]+)\.name$/, '.$1.$1Id'); return document.getElementById(idFieldId); } function handleIngredientFocus(event) { $(this).data('startingValue',$(this).val()); } function handleIngredientBlur(event) { console.log("blur: ", this, event, $(this).data('startingValue'), $(this).val()); if ( $(this).data('startingValue') != $(this).val() ) { var idField = $(getRecipeIngredientIdField(this)); idField.val('0'); console.log("unknown ingredient " +$(this).val()); } } function handleIngredientSearchResult(event, data, formatted) { console.log("chose ingredient result: ", data, "; ", formatted); $(getRecipeIngredientIdField(this)).val(data[1]); $(this).data('startingValue', $(this).val()); } function addIngredientRow() { var newRow = $('#ingredient_table > tbody > tr:first').clone().insertBefore('#ingredient_add_row'); // remove 'id' attribute newRow.removeAttr('id'); newRow.find('input:text').val(''); newRow.find('input:hidden').val('0'); // set new unit and ingredient to selected index 0 newRow.find('input:select').each(function() { this.selectedIndex = 0; }); // unset any 'optional' flag newRow.find('input:checkbox').each(function() { this.checked = false; }); // make the 'minus' button appear newRow.find('.minus').css('display', 'block'); updateIngredientRowIndexValues(newRow.get(0)); applyIngredientRowBehaviors(newRow.get(0)); newRow.find('input:text').focus(); return false; } function updateIngredientRowIndexValues(row) { var myIndex = $(row).prevAll('tr.recipe-ingredient').size(); // find all 'name' attributes, and increment index values replaceAttribute(row,'name','ingredient\\[\\d+\\]', 'ingredient[' +myIndex +']'); // find all 'id' attributes, and increment index values replaceAttribute(row,'id','ingredient\\[\\d+\\]', 'ingredient[' +myIndex +']'); } function applyAutocomplete(el) { $(el).find(".ingredient-autocomplete") .focus(handleIngredientFocus) .blur(handleIngredientBlur) .autocomplete("/ieat/ingredientSearch.json", { extraParams: { approximateSearch: 'true', recipeSearch: 'false' }, dataType: 'json', autoFill: false, parse: function (data) { var searchResults = data[ 'magoffin.matt.xweb.MODEL']; var results =[]; for (var i = 0; i < searchResults.ingredient.length; i++) { var ing = searchResults.ingredient[i]; results[results.length] = { data:[ing.name, ing.ingredientId], value: ing.name, result: ing.name }; } return results; } }).result(handleIngredientSearchResult); } function removeIngredientRow() { var ingredientIndex = $(this).parents('tr.recipe-ingredient').prevAll('tr.recipe-ingredient').size(); console.log("remove ingredient row %d: ", ingredientIndex); if ( ingredientIndex < 1 ) { alert(XwebLocale.i18n('noDeleteFirstIngredient')); return; } // remove selected ingredient from table $(this).parents('tr.recipe-ingredient').remove(); // update form field index values for ingredients *after* the removed one console.log("update index values >%d: ", ingredientIndex-1); $('#ingredient_table tr.recipe-ingredient:gt(' +(ingredientIndex-1) +')').each(function() { updateIngredientRowIndexValues(this); }); return false; } function applyRecipeIngredientRemove(el) { $(el).find('a.minus').click(removeIngredientRow); } function applyIngredientRowBehaviors(el) { applyAutocomplete(el); applyRecipeIngredientRemove(el); } $(document).ready(function () { $('#ingredient_add_link').click(addIngredientRow); applyIngredientRowBehaviors(this); installTextAreaFocusHandler(); $(document.forms[0].elements['criteria.ingredient[0].ingredient.name']).focus().select(); });