home_block.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
  2. var statKeys = [
  3. {value: '', text: '不绑定(只用固定值)'},
  4. {value: 'factory_count', text: '入驻厂家'},
  5. {value: 'print_today', text: '今日打印量'},
  6. {value: 'print_total', text: '累计套打张数'},
  7. {value: 'template_count', text: '可用模板'}
  8. ];
  9. function escapeAttr(value) {
  10. return String(value == null ? '' : value)
  11. .replace(/&/g, '&')
  12. .replace(/"/g, '"')
  13. .replace(/</g, '&lt;')
  14. .replace(/>/g, '&gt;');
  15. }
  16. function parseContent() {
  17. var raw = $.trim($('#home-block-content').text() || '{}');
  18. try {
  19. var data = JSON.parse(raw);
  20. return data && typeof data === 'object' ? data : {};
  21. } catch (e) {
  22. return {};
  23. }
  24. }
  25. function rowHtml(type, item, index) {
  26. item = item || {};
  27. if (type === 'stats') {
  28. var options = statKeys.map(function (opt) {
  29. var selected = String(item.key || '') === opt.value ? ' selected' : '';
  30. return '<option value="' + escapeAttr(opt.value) + '"' + selected + '>' + opt.text + '</option>';
  31. }).join('');
  32. return '<div class="item-row well well-sm">' +
  33. '<div class="row">' +
  34. '<div class="col-xs-4"><input class="form-control" name="row[content][items][' + index + '][label]" placeholder="名称" value="' + escapeAttr(item.label) + '"></div>' +
  35. '<div class="col-xs-4"><select class="form-control" name="row[content][items][' + index + '][key]">' + options + '</select></div>' +
  36. '<div class="col-xs-3"><input class="form-control" name="row[content][items][' + index + '][value]" placeholder="固定值可空" value="' + escapeAttr(item.value) + '"></div>' +
  37. '<div class="col-xs-1"><a href="javascript:;" class="btn btn-xs btn-danger btn-remove-item" title="删除"><i class="fa fa-times"></i></a></div>' +
  38. '</div></div>';
  39. }
  40. if (type === 'steps') {
  41. return '<div class="item-row well well-sm">' +
  42. '<div class="form-group" style="margin-bottom:8px;"><input class="form-control" name="row[content][items][' + index + '][title]" placeholder="步骤标题" value="' + escapeAttr(item.title) + '"></div>' +
  43. '<div class="form-group" style="margin-bottom:8px;"><textarea class="form-control" rows="2" name="row[content][items][' + index + '][desc]" placeholder="步骤说明">' + escapeAttr(item.desc) + '</textarea></div>' +
  44. '<a href="javascript:;" class="btn btn-xs btn-danger btn-remove-item">删除步骤</a>' +
  45. '</div>';
  46. }
  47. return '<div class="item-row well well-sm">' +
  48. '<div class="row" style="margin-bottom:8px;">' +
  49. '<div class="col-xs-3"><input class="form-control" name="row[content][items][' + index + '][tag]" placeholder="标签" value="' + escapeAttr(item.tag) + '"></div>' +
  50. '<div class="col-xs-5"><input class="form-control" name="row[content][items][' + index + '][title]" placeholder="标题" value="' + escapeAttr(item.title) + '"></div>' +
  51. '<div class="col-xs-4"><input class="form-control" name="row[content][items][' + index + '][path]" placeholder="跳转路径" value="' + escapeAttr(item.path) + '"></div>' +
  52. '</div>' +
  53. '<div class="form-group" style="margin-bottom:8px;"><textarea class="form-control" rows="2" name="row[content][items][' + index + '][desc]" placeholder="说明">' + escapeAttr(item.desc) + '</textarea></div>' +
  54. '<a href="javascript:;" class="btn btn-xs btn-danger btn-remove-item">删除卡片</a>' +
  55. '</div>';
  56. }
  57. function fillItems(type, items) {
  58. var $box = $('.item-rows[data-type="' + type + '"]');
  59. if (!$box.length) {
  60. return;
  61. }
  62. $box.empty();
  63. (items || []).forEach(function (item, index) {
  64. $box.append(rowHtml(type, item, index));
  65. });
  66. }
  67. function reindex($box) {
  68. $box.children('.item-row').each(function (index) {
  69. $(this).find('[name]').each(function () {
  70. this.name = this.name.replace(/items\]\[\d+\]/, 'items][' + index + ']');
  71. });
  72. });
  73. }
  74. function syncTypePanel() {
  75. var type = $('#c-type').val() || 'custom';
  76. $('.type-panel').each(function () {
  77. var match = $(this).data('type') === type;
  78. $(this).toggle(match);
  79. $(this).find(':input').prop('disabled', !match);
  80. });
  81. }
  82. var Controller = {
  83. index: function () {
  84. Table.api.init({
  85. extend: {
  86. index_url: 'ps/home_block/index' + location.search,
  87. add_url: 'ps/home_block/add',
  88. edit_url: 'ps/home_block/edit',
  89. del_url: 'ps/home_block/del',
  90. multi_url: 'ps/home_block/multi',
  91. table: 'ps_home_block',
  92. }
  93. });
  94. $('.btn-add, .btn-edit').data('area', ['880px', '92%']);
  95. var table = $("#table");
  96. table.bootstrapTable({
  97. url: $.fn.bootstrapTable.defaults.extend.index_url,
  98. pk: 'id',
  99. sortName: 'weigh',
  100. sortOrder: 'desc',
  101. columns: [
  102. [
  103. {checkbox: true},
  104. {field: 'id', title: __('Id')},
  105. {
  106. field: 'type',
  107. title: __('Type'),
  108. searchList: {
  109. "hero": __('Hero'),
  110. "stats": __('Stats'),
  111. "steps": __('Steps'),
  112. "features": __('Features'),
  113. "cta": __('Cta'),
  114. "custom": __('Custom')
  115. },
  116. formatter: Table.api.formatter.normal
  117. },
  118. {field: 'name', title: __('Name'), operate: 'LIKE'},
  119. {field: 'title', title: __('Title'), operate: 'LIKE'},
  120. {field: 'kicker', title: __('Kicker'), operate: 'LIKE'},
  121. {field: 'weigh', title: __('Weigh'), operate: false},
  122. {field: 'status', title: __('Status'), searchList: {"normal": __('Normal'), "hidden": __('Hidden')}, formatter: Table.api.formatter.status},
  123. {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
  124. ]
  125. ]
  126. });
  127. Table.api.bindevent(table);
  128. table.data('area', ['880px', '92%']);
  129. },
  130. add: function () {
  131. Controller.api.bindevent();
  132. },
  133. edit: function () {
  134. Controller.api.bindevent();
  135. },
  136. api: {
  137. bindevent: function () {
  138. var content = parseContent();
  139. var currentType = $('#c-type').val();
  140. if (currentType === 'stats' || currentType === 'steps' || currentType === 'features') {
  141. var items = Array.isArray(content.items) && content.items.length ? content.items : [{}];
  142. fillItems(currentType, items);
  143. }
  144. $(document).on('change', '#c-type', function () {
  145. syncTypePanel();
  146. var type = $(this).val();
  147. var $box = $('.item-rows[data-type="' + type + '"]');
  148. if ($box.length && !$box.children().length && (type === 'stats' || type === 'steps' || type === 'features')) {
  149. fillItems(type, [{}]);
  150. }
  151. });
  152. $(document).on('click', '.btn-add-item', function () {
  153. var type = $(this).data('type');
  154. var $box = $('.item-rows[data-type="' + type + '"]');
  155. $box.append(rowHtml(type, {}, $box.children().length));
  156. });
  157. $(document).on('click', '.btn-remove-item', function () {
  158. var $box = $(this).closest('.item-rows');
  159. $(this).closest('.item-row').remove();
  160. reindex($box);
  161. });
  162. syncTypePanel();
  163. Form.api.bindevent($("form[role=form]"));
  164. }
  165. }
  166. };
  167. return Controller;
  168. });