edit-recipe.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. var addIngredientPopup = null;
  2. function handleChangeIgnoreWarnings(checkbox) {
  3. var newVal = 'false';
  4. if ( checkbox.checked ) {
  5. newVal = 'true';
  6. }
  7. checkbox.form.elements['ignoreWarnings'].value = newVal;
  8. }
  9. function getRecipeIngredientIdField(nameField) {
  10. var fieldId = nameField.id;
  11. var idFieldId = fieldId.replace(/\.([^.]+)\.name$/, '.$1.$1Id');
  12. return document.getElementById(idFieldId);
  13. }
  14. function toggleIngredientType() {
  15. var currentlyRecipe = $(this).hasClass('recipe');
  16. if ( currentlyRecipe ) {
  17. $(this).removeClass('recipe').addClass('ingredient');
  18. } else {
  19. $(this).addClass('recipe').removeClass('ingredient');
  20. }
  21. $(this).nextAll('div').each(function() {
  22. $(this).toggle();
  23. var div = this;
  24. $(this).find('input').each(function() {
  25. // clear out current value, and focus if this is the visible field
  26. $(this).val('');
  27. if ( $(div).is(':visible') ) {
  28. $(this).get(0).disabled = false;
  29. if ( $(this).is(':text') ) {
  30. $(this).focus().select();
  31. }
  32. } else {
  33. $(this).get(0).disabled = true;
  34. }
  35. });
  36. });
  37. return false;
  38. }
  39. function handleIngredientFocus(event) {
  40. $(this).data('startingValue',$(this).val());
  41. }
  42. function handleIngredientBlur(event) {
  43. console.log("blur: ", this, event, $(this).data('startingValue'), $(this).val());
  44. if ( $(this).parent().get(0).id.match('ingredient$')
  45. && $(this).data('startingValue') != $(this).val() ) {
  46. var idField = $(getRecipeIngredientIdField(this));
  47. idField.val('');
  48. // pop-up new ingredient now
  49. console.log("unknown ingredient " +$(this).val());
  50. addRecipeIngredient(this);
  51. }
  52. }
  53. function handleIngredientSearchResult(event, data, formatted) {
  54. console.log("chose ingredient result: ", data, "; ", formatted);
  55. $(getRecipeIngredientIdField(this)).val(data[1]);
  56. $(this).data('startingValue', $(this).val());
  57. }
  58. function addRecipeIngredient(input) {
  59. var rowIndex = input.id.match(/\[(\d+)\]/);
  60. if ( rowIndex ) {
  61. rowIndex = rowIndex[1];
  62. } else {
  63. return;
  64. }
  65. var url = webContext +'/addRecipeIngredient.do?mode=recipe.ingredient['
  66. +rowIndex +'].ingredient.name'
  67. +'&ingredient.name=' +$(input).val();
  68. var width = 500;
  69. var height = 300;
  70. var top = (screen.height - height ) / 2;
  71. var left = (screen.width - width ) / 2;
  72. var windowOpts = "titlebar,toolbar=no,resizable,scrollbars,left=" +left
  73. +",top=" +top +",width=" +width +",height=" +height;
  74. if ( addIngredientPopup != null && !addIngredientPopup.closed ) {
  75. addIngredientPopup.close();
  76. }
  77. addIngredientPopup = window.open(url, "add_ingredient", windowOpts);
  78. addIngredientPopup.focus();
  79. }
  80. function addedNewIngredient(elementId, ingredientId, ingredientName) {
  81. console.log("New ingredient added at [%s]: %s (%s)", elementId, ingredientId, ingredientName);
  82. var field = document.getElementById(elementId);
  83. $(field).val(ingredientName);
  84. $(getRecipeIngredientIdField(field)).val(ingredientId);
  85. $(field).data('startingValue', ingredientName);
  86. }
  87. function addIngredientRow() {
  88. var newRow = $('#ingredient_table > tbody > tr:first').clone().insertBefore('#ingredient_add_row');
  89. // remove 'id' attribute
  90. newRow.removeAttr('id');
  91. // clear out quantity, qualifier, ingredient/recipe name
  92. newRow.find('input:text,input:hidden').val('');
  93. // set new unit and ingredient to selected index 0
  94. newRow.find('input:select').each(function() {
  95. this.selectedIndex = 0;
  96. });
  97. // make the 'minus' button appear
  98. newRow.find('a.minus').show();
  99. updateIngredientRowIndexValues(newRow.get(0));
  100. applyIngredientRowBehaviors(newRow.get(0));
  101. if ( newRow.tableDnDUpdate ) {
  102. $('#ingredient_table').tableDnDUpdate();
  103. }
  104. newRow.find('input:text[name*=quantity]').focus();
  105. return false;
  106. }
  107. function addStepRow() {
  108. var newRow = $('#step_table > tbody > tr:first').clone().insertBefore('#step_add_row');
  109. // remove 'id' attribute
  110. newRow.removeAttr('id');
  111. // clear out contents
  112. newRow.find('textarea').val('').focus();
  113. // make the 'minus' button appear
  114. newRow.find('a.minus').show();
  115. updateStepRowIndexValues(newRow.get(0));
  116. applyStepRowBehaviors(newRow.get(0));
  117. if ( newRow.tableDnDUpdate ) {
  118. $('#step_table').tableDnDUpdate();
  119. }
  120. return false;
  121. }
  122. function updateIngredientRowIndexValues(row) {
  123. var myIndex = $(row).prevAll('tr.recipe-ingredient').size();
  124. // find all 'name' attributes, and increment index values
  125. replaceAttribute(row,'name','ingredient\\[\\d+\\]',
  126. 'ingredient[' +myIndex +']');
  127. // find all 'id' attributes, and increment index values
  128. replaceAttribute(row,'id','ingredient\\[\\d+\\]',
  129. 'ingredient[' +myIndex +']');
  130. }
  131. function updateStepRowIndexValues(row) {
  132. var myIndex = $(row).prevAll('tr.recipe-step').size();
  133. // find all 'name' attributes, and increment index values
  134. replaceAttribute(row,'name','step\\[\\d+\\]', 'step[' +myIndex +']');
  135. }
  136. function applyAutocomplete(el) {
  137. if ( !$(el).autocomplete ) {
  138. return;
  139. }
  140. $(el).find(".ingredient-autocomplete")
  141. .focus(handleIngredientFocus)
  142. .blur(handleIngredientBlur)
  143. .autocomplete("/ieat/ingredientSearch.json", {
  144. extraParams: {
  145. approximateSearch: 'true',
  146. recipeSearch: 'false'
  147. },
  148. dataType: 'json',
  149. autoFill: false,
  150. parse: function (data) {
  151. var searchResults = data[ 'magoffin.matt.xweb.MODEL'];
  152. console.log("Got ingredient searchResults: ", searchResults);
  153. var results =[];
  154. for (var i = 0; i < searchResults.ingredient.length; i++) {
  155. var ing = searchResults.ingredient[i];
  156. results[results.length] = {
  157. data:[ing.name, ing.ingredientId],
  158. value: ing.name,
  159. result: ing.name
  160. };
  161. }
  162. return results;
  163. }
  164. }).result(handleIngredientSearchResult);
  165. $(el).find(".recipe-autocomplete")
  166. .focus(handleIngredientFocus)
  167. .blur(handleIngredientBlur)
  168. .autocomplete("/ieat/ingredientSearch.json", {
  169. extraParams: {
  170. approximateSearch: 'false',
  171. recipeSearch: 'true'
  172. },
  173. dataType: 'json',
  174. autoFill: false,
  175. parse: function (data) {
  176. var searchResults = data[ 'magoffin.matt.xweb.MODEL'];
  177. console.log("Got recipe searchResults: ", searchResults);
  178. var results =[];
  179. for (var i = 0; i < searchResults.recipe.length; i++) {
  180. var ing = searchResults.recipe[i];
  181. results[results.length] = {
  182. data:[ing.name, ing.recipeId],
  183. value: ing.name,
  184. result: ing.name
  185. };
  186. }
  187. return results;
  188. }
  189. }).result(handleIngredientSearchResult);
  190. }
  191. function applyRecipeTypeChooser(el) {
  192. $(el).find('a.ingredient-type-chooser').click(toggleIngredientType);
  193. }
  194. function removeIngredientRow() {
  195. var ingredientIndex = $(this).parents('tr.recipe-ingredient').prevAll('tr.recipe-ingredient').size();
  196. console.log("remove ingredient row %d: ", ingredientIndex);
  197. if ( ingredientIndex < 1 ) {
  198. alert(XwebLocale.i18n('noDeleteFirstIngredient'));
  199. return;
  200. }
  201. // remove selected ingredient from table
  202. $(this).parents('tr.recipe-ingredient').remove();
  203. // update form field index values for ingredients *after* the removed one
  204. console.log("update index values >%d: ", ingredientIndex-1);
  205. $('#ingredient_table tr.recipe-ingredient:gt(' +(ingredientIndex-1) +')').each(function() {
  206. updateIngredientRowIndexValues(this);
  207. });
  208. return false;
  209. }
  210. function removeStepRow() {
  211. var stepIndex = $(this).parents('tr.recipe-step').prevAll('tr.recipe-step').size();
  212. console.log("remove step row %d: ", stepIndex);
  213. if ( stepIndex < 1 ) {
  214. alert(XwebLocale.i18n('noDeleteFirstStep'));
  215. return;
  216. }
  217. // remove selected ingredient from table
  218. $(this).parents('tr.recipe-step').remove();
  219. // update form field index values for ingredients *after* the removed one
  220. console.log("update index values >%d: ", stepIndex-1);
  221. $('#step_table tr.recipe-step:gt(' +(stepIndex-1) +')').each(function() {
  222. updateStepRowIndexValues(this);
  223. });
  224. return false;
  225. }
  226. function applyRecipeIngredientRemove(el) {
  227. $(el).find('a.minus').click(removeIngredientRow);
  228. }
  229. function applyRecipeStepRemove(el) {
  230. $(el).find('a.minus').click(removeStepRow);
  231. }
  232. function applyIngredientRowBehaviors(el) {
  233. applyAutocomplete(el);
  234. applyRecipeTypeChooser(el);
  235. applyRecipeIngredientRemove(el);
  236. }
  237. function applyStepRowBehaviors(el) {
  238. applyRecipeStepRemove(el);
  239. }
  240. $(document).ready(function () {
  241. $('#ingredient_add_link').click(addIngredientRow);
  242. $('#step_add_link').click(addStepRow);
  243. applyIngredientRowBehaviors($('#ingredient_table').get(0));
  244. applyStepRowBehaviors($('#step_table').get(0));
  245. if ( $(this).tableDnD ) {
  246. $("#ingredient_table").tableDnD({
  247. onDragClass: 'in-drag',
  248. onDrop: function(table, row) {
  249. $(table).find('tr.recipe-ingredient').each(function(i) {
  250. updateIngredientRowIndexValues(this);
  251. if ( i > 0 ) {
  252. $(this).find('a.minus').show();
  253. } else {
  254. $(this).find('a.minus').hide();
  255. }
  256. });
  257. }
  258. });
  259. $("#step_table").tableDnD({
  260. onDragClass: 'in-drag',
  261. onDrop: function(table, row) {
  262. $(table).find('tr.recipe-step').each(function(i) {
  263. updateStepRowIndexValues(this);
  264. if ( i > 0 ) {
  265. $(this).find('a.minus').show();
  266. } else {
  267. $(this).find('a.minus').hide();
  268. }
  269. });
  270. }
  271. });
  272. }
  273. installTextAreaFocusHandler();
  274. });