base.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. jQuery(document).ready(function() {
  2. jQuery('html').removeClass('no-js');
  3. if (window.SONATA_CONFIG.CONFIRM_EXIT) {
  4. jQuery('.sonata-ba-form form').confirmExit();
  5. }
  6. Admin.add_pretty_errors(document);
  7. Admin.add_filters(document);
  8. Admin.set_object_field_value(document);
  9. Admin.setup_collection_buttons(document);
  10. Admin.setup_per_page_switcher(document);
  11. Admin.setup_form_tabs_for_errors(document);
  12. Admin.setup_inline_form_errors(document);
  13. });
  14. var Admin = {
  15. /**
  16. * render log message
  17. * @param mixed
  18. */
  19. log: function() {
  20. var msg = '[Sonata.Admin] ' + Array.prototype.join.call(arguments,', ');
  21. if (window.console && window.console.log) {
  22. window.console.log(msg);
  23. } else if (window.opera && window.opera.postError) {
  24. window.opera.postError(msg);
  25. }
  26. },
  27. /**
  28. * display related errors messages
  29. *
  30. * @param subject
  31. */
  32. add_pretty_errors: function(subject) {
  33. jQuery('div.sonata-ba-field-error', subject).each(function(index, element) {
  34. var input = jQuery('input, textarea, select', element);
  35. var message = jQuery('div.sonata-ba-field-error-messages', element).html();
  36. jQuery('div.sonata-ba-field-error-messages', element).html('');
  37. if (!message) {
  38. message = '';
  39. }
  40. if (message.length == 0) {
  41. return;
  42. }
  43. var target;
  44. /* Hack to handle qTip on select */
  45. if(jQuery(input).is('select')) {
  46. input.wrap('<span></span>');
  47. target = input.parent();
  48. }
  49. else {
  50. target = input;
  51. }
  52. target.popover({
  53. content: message,
  54. trigger:'focus',
  55. html: true,
  56. placement: 'right',
  57. template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content alert-error"><p></p></div></div></div>'
  58. });
  59. });
  60. },
  61. stopEvent: function(event) {
  62. // https://github.com/sonata-project/SonataAdminBundle/issues/151
  63. //if it is a standard browser use preventDefault otherwise it is IE then return false
  64. if(event.preventDefault) {
  65. event.preventDefault();
  66. } else {
  67. event.returnValue = false;
  68. }
  69. //if it is a standard browser get target otherwise it is IE then adapt syntax and get target
  70. if (typeof event.target != 'undefined') {
  71. targetElement = event.target;
  72. } else {
  73. targetElement = event.srcElement;
  74. }
  75. return targetElement;
  76. },
  77. add_filters: function(subject) {
  78. jQuery('div.filter_container .sonata-filter-option', subject).hide();
  79. jQuery('fieldset.filter_legend', subject).click(function(event) {
  80. jQuery('div.filter_container .sonata-filter-option', jQuery(event.target).parent()).toggle();
  81. });
  82. },
  83. /**
  84. * Change object field value
  85. * @param subject
  86. */
  87. set_object_field_value: function(subject) {
  88. this.log(jQuery('a.sonata-ba-edit-inline', subject));
  89. jQuery('a.sonata-ba-edit-inline', subject).click(function(event) {
  90. Admin.stopEvent(event);
  91. var subject = jQuery(this);
  92. jQuery.ajax({
  93. url: subject.attr('href'),
  94. type: 'POST',
  95. success: function(json) {
  96. if(json.status === "OK") {
  97. var elm = jQuery(subject).parent();
  98. elm.children().remove();
  99. // fix issue with html comment ...
  100. elm.html(jQuery(json.content.replace(/<!--[\s\S]*?-->/g, "")).html());
  101. elm.effect("highlight", {'color' : '#57A957'}, 2000);
  102. Admin.set_object_field_value(elm);
  103. } else {
  104. jQuery(subject).parent().effect("highlight", {'color' : '#C43C35'}, 2000);
  105. }
  106. }
  107. });
  108. });
  109. },
  110. setup_collection_buttons: function(subject) {
  111. jQuery(subject).on('click', '.sonata-collection-add', function(event) {
  112. Admin.stopEvent(event);
  113. var container = jQuery(this).closest('[data-prototype]');
  114. var proto = container.attr('data-prototype');
  115. var protoName = container.attr('data-prototype-name') || '__name__';
  116. // Set field id
  117. var idRegexp = new RegExp(container.attr('id')+'_'+protoName,'g');
  118. proto = proto.replace(idRegexp, container.attr('id')+'_'+(container.children().length - 1));
  119. // Set field name
  120. var parts = container.attr('id').split('_');
  121. var nameRegexp = new RegExp(parts[parts.length-1]+'\\]\\['+protoName,'g');
  122. proto = proto.replace(nameRegexp, parts[parts.length-1]+']['+(container.children().length - 1));
  123. jQuery(proto).insertBefore(jQuery(this).parent());
  124. jQuery(this).trigger('sonata-collection-item-added');
  125. });
  126. jQuery(subject).on('click', '.sonata-collection-delete', function(event) {
  127. Admin.stopEvent(event);
  128. jQuery(this).closest('.sonata-collection-row').remove();
  129. jQuery(this).trigger('sonata-collection-item-deleted');
  130. });
  131. },
  132. setup_per_page_switcher: function(subject) {
  133. jQuery('select.per-page').change(function(event) {
  134. jQuery('input[type=submit]').hide();
  135. window.top.location.href=this.options[this.selectedIndex].value;
  136. });
  137. },
  138. setup_form_tabs_for_errors: function(subject) {
  139. // Switch to first tab with server side validation errors on page load
  140. jQuery('form', subject).each(function() {
  141. Admin.show_form_first_tab_with_errors(jQuery(this), '.sonata-ba-field-error');
  142. });
  143. // Switch to first tab with HTML5 errors on form submit
  144. jQuery(subject)
  145. .on('click', 'form [type="submit"]', function() {
  146. Admin.show_form_first_tab_with_errors(jQuery(this).closest('form'), ':invalid');
  147. })
  148. .on('keypress', 'form [type="text"]', function(e) {
  149. if (13 === e.which) {
  150. Admin.show_form_first_tab_with_errors(jQuery(this), ':invalid');
  151. }
  152. })
  153. ;
  154. },
  155. show_form_first_tab_with_errors: function(form, errorSelector) {
  156. var tabs = form.find('.nav-tabs a'),
  157. firstTabWithErrors;
  158. tabs.each(function() {
  159. var id = jQuery(this).attr('href'),
  160. tab = jQuery(this),
  161. icon = tab.find('.has-errors');
  162. if (jQuery(id).find(errorSelector).length > 0) {
  163. // Only show first tab with errors
  164. if (!firstTabWithErrors) {
  165. tab.tab('show');
  166. firstTabWithErrors = tab;
  167. }
  168. icon.removeClass('hide');
  169. } else {
  170. icon.addClass('hide');
  171. }
  172. });
  173. },
  174. setup_inline_form_errors: function(subject) {
  175. var deleteCheckboxSelector = '.sonata-ba-field-inline-table [id$="_delete"][type="checkbox"]';
  176. jQuery(deleteCheckboxSelector, subject).each(function() {
  177. Admin.switch_inline_form_errors(jQuery(this));
  178. });
  179. $(subject).on('change', deleteCheckboxSelector, function() {
  180. Admin.switch_inline_form_errors(jQuery(this));
  181. });
  182. },
  183. /**
  184. * Disable inline form errors when the row is marked for deletion
  185. */
  186. switch_inline_form_errors: function(deleteCheckbox) {
  187. var row = deleteCheckbox.closest('.sonata-ba-field-inline-table'),
  188. errors = row.find('.sonata-ba-field-error-messages')
  189. ;
  190. if (deleteCheckbox.is(':checked')) {
  191. row
  192. .find('[required]')
  193. .removeAttr('required')
  194. .attr('data-required', 'required')
  195. ;
  196. errors.hide();
  197. } else {
  198. row
  199. .find('[data-required]')
  200. .attr('required', 'required')
  201. ;
  202. errors.show();
  203. }
  204. }
  205. };