您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

367 行
10 KiB

  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. // wn._("Form")
  4. wn.ui.AppFrame = Class.extend({
  5. init: function(parent, title, module) {
  6. this.set_document_title = true;
  7. this.buttons = {};
  8. this.fields_dict = {};
  9. this.parent = parent;
  10. this.$title_area = $('<div class="title-area">\
  11. <h4>\
  12. <span class="title-icon text-muted" style="display: none"></span>\
  13. <span class="title-text"></span>\
  14. </h4></div>').appendTo(parent.find(".titlebar-item.text-center"));
  15. this.setup_iconbar();
  16. if(title)
  17. this.set_title(title);
  18. },
  19. setup_iconbar: function() {
  20. var me = this;
  21. this.iconbar = new wn.ui.IconBar(this.parent.find(".appframe-iconbar .container"), 3);
  22. this.iconbar.$wrapper.find(".iconbar-3").addClass("pull-right");
  23. this.iconbar.$wrapper.on("shown", function() {
  24. me.parent.find(".appframe-iconbar").removeClass("hide")
  25. })
  26. this.iconbar.$wrapper.on("hidden", function() {
  27. me.parent.find(".appframe-iconbar").addClass("hide")
  28. })
  29. },
  30. // appframe::title
  31. get_title_area: function() {
  32. return this.$title_area;
  33. },
  34. set_title: function(txt) {
  35. // strip icon
  36. this.title = txt;
  37. document.title = txt.replace(/<[^>]*>/g, "");
  38. this.$title_area.find(".title-text").html(txt);
  39. },
  40. set_title_left: function(txt, click) {
  41. return $("<a>")
  42. .html(txt)
  43. .on("click", function() { click.apply(this); })
  44. .appendTo(this.parent.find(".titlebar-item.text-left").empty());
  45. },
  46. set_title_right: function(txt, click, icon) {
  47. var $right = this.parent.find(".titlebar-item.text-right")
  48. if(txt) {
  49. this.title_right && this.title_right.remove();
  50. this.title_right = $("<a>")
  51. .html((icon ? '<i class="'+icon+'"></i> ' : "") + txt)
  52. .click(click)
  53. .appendTo($right.attr("data-text", txt));
  54. return this.title_right;
  55. } else {
  56. $right.empty().attr("data-text", "");
  57. this.title_right = null;
  58. this.primary_dropdown = null;
  59. this.primary_action = null;
  60. }
  61. },
  62. get_title_right_text: function() {
  63. return this.parent.find(".titlebar-item.text-right").attr("data-text");
  64. },
  65. add_primary_action: function(label, click, icon) {
  66. if(!this.primary_dropdown) {
  67. if(!this.primary_action) {
  68. var $right = this.parent.find(".titlebar-item.text-right");
  69. this.primary_action = $("<a>")
  70. .html(wn._("Actions") + " <i class='icon-caret-down'></i>")
  71. .css({"margin-right":"15px", "display":"inline-block"})
  72. .prependTo($right);
  73. }
  74. var id = "dropdown-" + wn.dom.set_unique_id();
  75. this.primary_action
  76. .attr("id", id)
  77. .attr("data-toggle", "dropdown")
  78. .addClass("dropdown-toggle")
  79. .parent()
  80. .addClass("dropdown")
  81. this.primary_dropdown = $('<ul class="dropdown-menu pull-right" role="menu" \
  82. aria-labelledby="'+ id +'"></ul>')
  83. .appendTo(this.primary_action.parent()).dropdown();
  84. }
  85. var $li = $('<li role="presentation"><a role="menuitem" class="text-left">'
  86. + (icon ? '<i class="'+icon+' icon-fixed-width"></i> ' : "") + label+'</a></li>')
  87. .appendTo(this.primary_dropdown)
  88. .on("click", function() { click && click.apply(this); });
  89. return $li;
  90. },
  91. set_views_for: function(doctype, active_view) {
  92. this.doctype = doctype;
  93. var me = this,
  94. meta = locals.DocType[doctype],
  95. views = [],
  96. module_info = wn.modules[meta.module];
  97. if(module_info) {
  98. views.push({
  99. icon: module_info.icon,
  100. route: module_info.link,
  101. type: "module"
  102. })
  103. }
  104. views.push({
  105. icon: "icon-file-alt",
  106. route: "",
  107. type: "form",
  108. set_route: function() {
  109. if(wn.views.formview[me.doctype]) {
  110. wn.set_route("Form", me.doctype, wn.views.formview[me.doctype].frm.docname);
  111. } else {
  112. new_doc(doctype);
  113. }
  114. }
  115. });
  116. if(!meta.issingle) {
  117. views.push({
  118. icon: "icon-list",
  119. route: "List/" + doctype,
  120. type: "list"
  121. });
  122. }
  123. if(wn.views.calendar[doctype]) {
  124. views.push({
  125. icon: "icon-calendar",
  126. route: "Calendar/" + doctype,
  127. type: "calendar"
  128. });
  129. }
  130. if(wn.views.calendar[doctype] && wn.views.calendar[doctype]) {
  131. views.push({
  132. icon: "icon-tasks",
  133. route: "Gantt/" + doctype,
  134. type: "gantt"
  135. });
  136. }
  137. if(wn.model.can_get_report(doctype)) {
  138. views.push({
  139. icon: "icon-table",
  140. route: "Report/" + doctype,
  141. type: "report"
  142. });
  143. }
  144. this.set_views(views, active_view);
  145. },
  146. set_views: function(views, active_view) {
  147. var me = this;
  148. $.each(views, function(i, e) {
  149. var btn = me.add_icon_btn("3", e.icon, wn._(toTitle(e.type)), function() {
  150. window.location.hash = "#" + $(this).attr("data-route");
  151. }).attr("data-route", e.route);
  152. if(e.type===active_view) {
  153. btn.find("i").css({"color": "#428bca"});
  154. }
  155. });
  156. },
  157. add_module_icon: function(module, doctype, onclick, sub_title) {
  158. var module_info = wn.modules[module];
  159. if(!module_info) {
  160. module_info = {
  161. icon: "icon-question-sign",
  162. color: "#ddd"
  163. }
  164. }
  165. var icon = wn.boot.doctype_icons[doctype] || module_info.icon;
  166. this.$title_area.find(".title-icon").html('<i class="'+icon+'"></i> ')
  167. .toggle(true)
  168. .attr("doctype-name", doctype)
  169. .attr("module-link", module_info.link)
  170. .click(onclick || function() {
  171. var route = wn.get_route();
  172. var doctype = $(this).attr("doctype-name");
  173. if(doctype && route[0]!=="List" && !locals["DocType"][doctype].issingle) {
  174. wn.set_route("List", doctype)
  175. } else if($(this).attr("module-link")!==route[0]){
  176. wn.set_route($(this).attr("module-link"));
  177. } else {
  178. wn.set_route("");
  179. }
  180. return false;
  181. });
  182. if(sub_title) {
  183. this.set_title_left('<i class="icon-angle-left"></i> ' + module,
  184. function() { wn.set_route($(this).attr("module-link")); }).attr("module-link", module_info.link)
  185. }
  186. },
  187. add_help_button: function(txt) {
  188. this.add_icon_btn("2", "icon-question-sign", wn._("Help"),
  189. function() { msgprint($(this).data('help-text'), 'Help'); })
  190. .data("help-text", txt);
  191. },
  192. add_icon_btn: function(group, icon, label, click) {
  193. return this.iconbar.add_btn(group, icon, label, click);
  194. },
  195. add_button: function(label, click, icon, is_title) {
  196. return this.iconbar.add_btn("1", icon, wn._(label), click);
  197. },
  198. // appframe::navbar links
  199. add_dropdown_button: function(parent, label, click, icon) {
  200. var menu = this.get_menu(parent);
  201. if(menu.find("li:not(.custom-menu)").length && !menu.find(".divider").length) {
  202. this.add_menu_divider(menu);
  203. }
  204. return $('<li class="custom-menu"><a><i class="'
  205. +icon+'"></i> '+label+'</a></li>')
  206. .insertBefore(menu.find(".divider"))
  207. .find("a")
  208. .click(function() {
  209. click();
  210. });
  211. },
  212. get_menu: function(label) {
  213. return $("#navbar-" + label.toLowerCase());
  214. },
  215. add_menu_divider: function(menu) {
  216. menu = typeof menu == "string" ?
  217. this.get_menu(menu) : menu;
  218. $('<li class="divider custom-menu"></li>').prependTo(menu);
  219. },
  220. // appframe::form
  221. add_label: function(label) {
  222. this.show_form();
  223. return $("<label class='col-md-1'>"+label+" </label>")
  224. .appendTo(this.parent.find(".appframe-form .container"));
  225. },
  226. add_select: function(label, options) {
  227. var field = this.add_field({label:label, fieldtype:"Select"})
  228. return field.$wrapper.find("select").empty().add_options(options);
  229. },
  230. add_data: function(label) {
  231. var field = this.add_field({label: label, fieldtype: "Data"});
  232. return field.$wrapper.find("input").attr("placeholder", label);
  233. },
  234. add_date: function(label, date) {
  235. var field = this.add_field({label: label, fieldtype: "Date", "default": date});
  236. return field.$wrapper.find("input").attr("placeholder", label);
  237. },
  238. add_check: function(label) {
  239. return $("<div class='checkbox' style='margin-right: 10px; margin-top: 7px; float: left;'><label><input type='checkbox'>" + label + "</label></div>")
  240. .appendTo(this.parent.find(".appframe-form .container"))
  241. .find("input");
  242. },
  243. add_break: function() {
  244. // add further fields in the next line
  245. this.parent.find(".appframe-form .container")
  246. .append('<div class="clearfix invisible-xs"></div>');
  247. },
  248. add_field: function(df) {
  249. this.show_form();
  250. var f = wn.ui.form.make_control({
  251. df: df,
  252. parent: this.parent.find(".appframe-form .container"),
  253. only_input: df.fieldtype=="Check" ? false : true,
  254. })
  255. f.refresh();
  256. $(f.wrapper)
  257. .addClass('col-md-2')
  258. .css({
  259. "padding-left": "0px",
  260. "padding-right": "0px",
  261. "margin-right": "5px",
  262. })
  263. .attr("title", wn._(df.label)).tooltip();
  264. f.$input.attr("placeholder", wn._(df.label));
  265. if(df.fieldtype==="Check") {
  266. $(f.wrapper).find(":first-child")
  267. .removeClass("col-md-offset-4 col-md-8");
  268. }
  269. if(df["default"])
  270. f.set_input(df["default"])
  271. this.fields_dict[df.fieldname || df.label] = f;
  272. return f;
  273. },
  274. show_form: function() {
  275. this.parent.find(".appframe-form").removeClass("hide");
  276. },
  277. });
  278. // parent, title, single_column
  279. // standard page with appframe
  280. wn.ui.make_app_page = function(opts) {
  281. /* help: make a standard page layout with a toolbar and title */
  282. /* options: [
  283. "parent: [HTMLElement] parent element",
  284. "single_column: [Boolean] false/true",
  285. "title: [optional] set this title"
  286. ]
  287. */
  288. $wrapper = $(opts.parent)
  289. $('<div class="appframe-titlebar">\
  290. <div class="container">\
  291. <div class="row">\
  292. <div class="titlebar-item text-left col-xs-3"></div>\
  293. <div class="titlebar-item titlebar-center-item text-center col-xs-6"></div>\
  294. <div class="titlebar-item text-right col-xs-3"></div>\
  295. </div>\
  296. </div>\
  297. </div>\
  298. <div class="appframe-iconbar hide">\
  299. <div class="container">\
  300. </div>\
  301. </div>\
  302. <div class="appframe-form hide">\
  303. <div class="container">\
  304. </div>\
  305. </div>\
  306. <div class="appframe container">\
  307. <div class="appframe-timestamp hide"></div>\
  308. <div class="workflow-button-area btn-group pull-right hide"></div>\
  309. </div>\
  310. <div class="appframe-footer hide"></div>').appendTo($wrapper);
  311. if(opts.single_column) {
  312. $('<div class="layout-main"></div>').appendTo($wrapper.find(".appframe"));
  313. } else {
  314. $('<div class="row">\
  315. <div class="layout-main-section col-sm-9"></div>\
  316. <div class="layout-side-section col-sm-3"></div>\
  317. </div>').appendTo($wrapper.find(".appframe"));
  318. }
  319. opts.parent.appframe = new wn.ui.AppFrame($wrapper);
  320. if(opts.set_document_title!==undefined)
  321. opts.parent.appframe.set_document_title = opts.set_document_title;
  322. if(opts.title) opts.parent.appframe.set_title(opts.title);
  323. if(opts.icon) opts.parent.appframe.add_module_icon(null, opts.icon);
  324. }