273 行
11KB

  1. yii.gii = (function ($) {
  2. var $clipboardContainer = $("#clipboard-container"),
  3. valueToCopy = '',
  4. onKeydown = function(e) {
  5. var $target;
  6. $target = $(e.target);
  7. if ($target.is("input:visible, textarea:visible")) {
  8. return;
  9. }
  10. if (typeof window.getSelection === "function" && window.getSelection().toString()) {
  11. return;
  12. }
  13. if (document.selection != null && document.selection.createRange().text) {
  14. return;
  15. }
  16. $clipboardContainer.empty().show();
  17. return $("<textarea id='clipboard'></textarea>").val(valueToCopy).appendTo($clipboardContainer).focus().select();
  18. },
  19. onKeyup = function(e) {
  20. if ($(e.target).is("#clipboard")) {
  21. $("#clipboard-container").empty().hide();
  22. }
  23. return true;
  24. };
  25. var initHintBlocks = function () {
  26. $('.hint-block').each(function () {
  27. var $hint = $(this);
  28. $hint.parent().find('label').addClass('help').popover({
  29. html: true,
  30. trigger: 'hover',
  31. placement: 'right',
  32. content: $hint.html()
  33. });
  34. });
  35. };
  36. var initStickyInputs = function () {
  37. $('.sticky:not(.error)').find('input[type="text"],select,textarea').each(function () {
  38. var value;
  39. if (this.tagName === 'SELECT') {
  40. value = this.options[this.selectedIndex].text;
  41. } else if (this.tagName === 'TEXTAREA') {
  42. value = $(this).html();
  43. } else {
  44. value = $(this).val();
  45. }
  46. if (value === '') {
  47. value = '[empty]';
  48. }
  49. $(this).before('<div class="sticky-value">' + value + '</div>').hide();
  50. });
  51. $('.sticky-value').on('click', function () {
  52. $(this).hide();
  53. $(this).next().show().get(0).focus();
  54. });
  55. };
  56. var fillModal = function(data) {
  57. var $modal = $('#preview-modal'),
  58. $link = $(this),
  59. $modalBody = $modal.find('.modal-body');
  60. if (!$link.hasClass('modal-refresh')) {
  61. var filesSelector = 'a.' + $modal.data('action');
  62. var $files = $(filesSelector);
  63. var index = $files.filter('[href="' + $link.attr('href') + '"]').index(filesSelector);
  64. var $prev = $files.eq(index - 1);
  65. var $next = $files.eq((index + 1 == $files.length ? 0 : index + 1));
  66. $modal.data('current', $files.eq(index));
  67. $modal.find('.modal-previous').attr('href', $prev.attr('href')).data('title', $prev.data('title'));
  68. $modal.find('.modal-next').attr('href', $next.attr('href')).data('title', $next.data('title'));
  69. }
  70. $modalBody.html(data);
  71. valueToCopy = $("<div/>").html(data.replace(/(<(br[^>]*)>)/ig, '\n')).text().trim() + '\n';
  72. $modal.find('.content').css('max-height', ($(window).height() - 200) + 'px');
  73. };
  74. var initPreviewDiffLinks = function () {
  75. $('.preview-code, .diff-code, .modal-refresh, .modal-previous, .modal-next').on('click', function () {
  76. var $modal = $('#preview-modal');
  77. var $link = $(this);
  78. $modal.find('.modal-refresh').attr('href', $link.attr('href'));
  79. if ($link.hasClass('preview-code') || $link.hasClass('diff-code')) {
  80. $modal.data('action', ($link.hasClass('preview-code') ? 'preview-code' : 'diff-code'))
  81. }
  82. $modal.find('.modal-title').text($link.data('title'));
  83. $modal.find('.modal-body').html('Loading ...');
  84. $modal.modal('show');
  85. var checkbox = $('a.' + $modal.data('action') + '[href="' + $link.attr('href') + '"]').closest('tr').find('input').get(0);
  86. var checked = false;
  87. if (checkbox) {
  88. checked = checkbox.checked;
  89. $modal.find('.modal-checkbox').removeClass('disabled');
  90. } else {
  91. $modal.find('.modal-checkbox').addClass('disabled');
  92. }
  93. $modal.find('.modal-checkbox span').toggleClass('glyphicon-check', checked).toggleClass('glyphicon-unchecked', !checked);
  94. $.ajax({
  95. type: 'POST',
  96. cache: false,
  97. url: $link.prop('href'),
  98. data: $('.default-view form').serializeArray(),
  99. success: function (data) {
  100. fillModal(data);
  101. },
  102. error: function (XMLHttpRequest, textStatus, errorThrown) {
  103. $modal.find('.modal-body').html('<div class="error">' + XMLHttpRequest.responseText + '</div>');
  104. }
  105. });
  106. return false;
  107. });
  108. $('#preview-modal').on('keydown', function (e) {
  109. if (e.keyCode === 37) {
  110. $('.modal-previous').trigger('click');
  111. } else if (e.keyCode === 39) {
  112. $('.modal-next').trigger('click');
  113. } else if (e.keyCode === 82) {
  114. $('.modal-refresh').trigger('click');
  115. } else if (e.keyCode === 32) {
  116. $('.modal-checkbox').trigger('click');
  117. }
  118. });
  119. $('.modal-checkbox').on('click', checkFileToggle);
  120. };
  121. var checkFileToggle = function () {
  122. var $modal = $('#preview-modal');
  123. var $checkbox = $modal.data('current').closest('tr').find('input');
  124. var checked = !$checkbox.prop('checked');
  125. $checkbox.prop('checked', checked);
  126. $modal.find('.modal-checkbox span').toggleClass('glyphicon-check', checked).toggleClass('glyphicon-unchecked', !checked);
  127. return false;
  128. };
  129. var checkAllToggle = function () {
  130. $('#check-all').prop('checked', !$('.default-view-files table .check input:enabled:not(:checked)').length);
  131. };
  132. var initConfirmationCheckboxes = function () {
  133. var $checkAll = $('#check-all');
  134. $checkAll.click(function () {
  135. $('.default-view-files table .check input:enabled').prop('checked', this.checked);
  136. });
  137. $('.default-view-files table .check input').click(function () {
  138. checkAllToggle();
  139. });
  140. checkAllToggle();
  141. };
  142. var initToggleActions = function () {
  143. $('#action-toggle :input').change(function () {
  144. $(this).parent('label').toggleClass('active', this.checked);
  145. $('.' + this.value, '.default-view-files table').toggle(this.checked).find('.check input').attr('disabled', !this.checked);
  146. checkAllToggle();
  147. });
  148. };
  149. $(document).on("keydown", function(e) {
  150. if (valueToCopy && (e.ctrlKey || e.metaKey) && (e.which === 67)) {
  151. return onKeydown(e);
  152. }
  153. }).on("keyup", onKeyup);
  154. return {
  155. autocomplete: function (counter, data) {
  156. var datum = new Bloodhound({
  157. datumTokenizer: function (d) {
  158. return Bloodhound.tokenizers.whitespace(d.word);
  159. },
  160. queryTokenizer: Bloodhound.tokenizers.whitespace,
  161. local: data
  162. });
  163. datum.initialize();
  164. jQuery('.typeahead-' + counter).typeahead(null, {displayKey: 'word', source: datum.ttAdapter()});
  165. },
  166. init: function () {
  167. initHintBlocks();
  168. initStickyInputs();
  169. initPreviewDiffLinks();
  170. initConfirmationCheckboxes();
  171. initToggleActions();
  172. // model generator: hide class name inputs when table name input contains *
  173. $('#model-generator #generator-tablename').change(function () {
  174. var show = ($(this).val().indexOf('*') === -1);
  175. $('.field-generator-modelclass').toggle(show);
  176. if ($('#generator-generatequery').is(':checked')) {
  177. $('.field-generator-queryclass').toggle(show);
  178. }
  179. }).change();
  180. // model generator: translate table name to model class
  181. $('#model-generator #generator-tablename').on('blur', function () {
  182. var tableName = $(this).val();
  183. var tablePrefix = $(this).attr('table_prefix') || '';
  184. if (tablePrefix.length) {
  185. // if starts with prefix
  186. if (tableName.slice(0, tablePrefix.length) === tablePrefix) {
  187. // remove prefix
  188. tableName = tableName.slice(tablePrefix.length);
  189. }
  190. }
  191. if ($('#generator-modelclass').val() === '' && tableName && tableName.indexOf('*') === -1) {
  192. var modelClass = '';
  193. $.each(tableName.split('_'), function() {
  194. if(this.length>0)
  195. modelClass+=this.substring(0,1).toUpperCase()+this.substring(1);
  196. });
  197. $('#generator-modelclass').val(modelClass).blur();
  198. }
  199. });
  200. // model generator: translate model class to query class
  201. $('#model-generator #generator-modelclass').on('blur', function () {
  202. var modelClass = $(this).val();
  203. if (modelClass !== '') {
  204. var queryClass = $('#generator-queryclass').val();
  205. if (queryClass === '') {
  206. queryClass = modelClass + 'Query';
  207. $('#generator-queryclass').val(queryClass);
  208. }
  209. }
  210. });
  211. // model generator: synchronize query namespace with model namespace
  212. $('#model-generator #generator-ns').on('blur', function () {
  213. var stickyValue = $('#model-generator .field-generator-queryns .sticky-value');
  214. var input = $('#model-generator #generator-queryns');
  215. if (stickyValue.is(':visible') || !input.is(':visible')) {
  216. var ns = $(this).val();
  217. stickyValue.html(ns);
  218. input.val(ns);
  219. }
  220. });
  221. // model generator: toggle query fields
  222. $('form #generator-generatequery').change(function () {
  223. $('form .field-generator-queryns').toggle($(this).is(':checked'));
  224. $('form .field-generator-queryclass').toggle($(this).is(':checked'));
  225. $('form .field-generator-querybaseclass').toggle($(this).is(':checked'));
  226. }).change();
  227. // hide message category when I18N is disabled
  228. $('form #generator-enablei18n').change(function () {
  229. $('form .field-generator-messagecategory').toggle($(this).is(':checked'));
  230. }).change();
  231. // hide Generate button if any input is changed
  232. $('.default-view .form-group input,select,textarea').change(function () {
  233. $('.default-view-results,.default-view-files').hide();
  234. $('.default-view button[name="generate"]').hide();
  235. });
  236. $('.module-form #generator-moduleclass').change(function () {
  237. var value = $(this).val().match(/(\w+)\\\w+$/);
  238. var $idInput = $('#generator-moduleid');
  239. if (value && value[1] && $idInput.val() === '') {
  240. $idInput.val(value[1]);
  241. }
  242. });
  243. }
  244. };
  245. })(jQuery);