You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

appframe.js 9.6 KiB

13 年之前
13 年之前
13 年之前
13 年之前
13 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  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.$w = $('<div class="appframe-header col-md-12">\
  10. <div class="row appframe-title">\
  11. <div class="col-md-12">\
  12. <div class="title-button-area btn-group pull-right" \
  13. style="margin-top: 10px;"></div>\
  14. <div class="title-button-area-1 btn-group pull-right" \
  15. style="margin-top: 10px;"></div>\
  16. <div class="title-area"><h2 style="display: inline-block">\
  17. <span class="title-icon" style="display: none"></span>\
  18. <span class="title-text"></span></h2></div>\
  19. <div class="sub-title-area text-muted small">&nbsp;</div>\
  20. <div class="status-bar"></div>\
  21. </div>\
  22. </div>\
  23. <div class="info-bar" style="display: none;"><ul class="hidden-xs-inline"></ul></div>\
  24. <div class="appframe-toolbar" style="display: none;">\
  25. </div>\
  26. <div>').prependTo(parent);
  27. this.$w.find('.close').click(function() {
  28. window.history.back();
  29. })
  30. this.toolbar = this.$w.find(".appframe-toolbar");
  31. this.setup_toolbar();
  32. if(title)
  33. this.set_title(title);
  34. },
  35. setup_toolbar: function() {
  36. $('<div class="btn-group form-group pull-left"></div>\
  37. <div class="appframe-form"></div>\
  38. <div class="clearfix"></div>').appendTo(this.toolbar.toggle(false));
  39. },
  40. get_title_area: function() {
  41. return this.$w.find(".title-area");
  42. },
  43. set_title: function(txt, full_text) {
  44. this.title = txt;
  45. document.title = txt;
  46. this.$w.find(".breadcrumb .appframe-title").html(txt);
  47. this.$w.find(".title-text").html(txt);
  48. },
  49. set_sub_title: function(txt) {
  50. this.$w.find(".sub-title-area").html(txt);
  51. },
  52. add_infobar: function(label, onclick) {
  53. var $ul = this.$w.find(".info-bar").toggle(true).find("ul"),
  54. $li = $('<li><a href="#">' + label + '</a></li>')
  55. .appendTo($ul)
  56. .click(function() {
  57. onclick();
  58. return false;
  59. })
  60. return $li;
  61. },
  62. clear_infobar: function() {
  63. this.$w.find(".info-bar").toggle(false).find("ul").empty();
  64. },
  65. add_module_icon: function(module, doctype) {
  66. var module_info = wn.modules[module];
  67. if(!module_info) {
  68. module_info = {
  69. icon: "icon-question-sign",
  70. color: "#ddd"
  71. }
  72. }
  73. var icon = wn.boot.doctype_icons[doctype] || module_info.icon;
  74. this.$w.find(".title-icon").html('<i class="'+icon+'"></i> ')
  75. .toggle(true)
  76. .css({
  77. "background-color": module_info.color,
  78. })
  79. .attr("doctype-name", doctype)
  80. .click(function() {
  81. if($(this).attr("doctype-name")) {
  82. wn.set_route("List", $(this).attr("doctype-name"))
  83. } else {
  84. wn.set_route("");
  85. }
  86. });
  87. },
  88. set_views_for: function(doctype, active_view) {
  89. this.doctype = doctype;
  90. var me = this,
  91. meta = locals.DocType[doctype],
  92. views = [],
  93. module_info = wn.modules[meta.module];
  94. if(module_info) {
  95. views.push({
  96. icon: module_info.icon,
  97. route: module_info.link,
  98. type: "module"
  99. })
  100. }
  101. views.push({
  102. icon: "icon-file-alt",
  103. route: "",
  104. type: "form",
  105. set_route: function() {
  106. if(wn.views.formview[me.doctype]) {
  107. wn.set_route("Form", me.doctype, wn.views.formview[me.doctype].frm.docname);
  108. } else {
  109. new_doc(doctype);
  110. }
  111. }
  112. });
  113. if(!meta.issingle) {
  114. views.push({
  115. icon: "icon-list",
  116. route: "List/" + doctype,
  117. type: "list"
  118. });
  119. }
  120. if(wn.views.calendar[doctype]) {
  121. views.push({
  122. icon: "icon-calendar",
  123. route: "Calendar/" + doctype,
  124. type: "calendar"
  125. });
  126. }
  127. if(wn.views.calendar[doctype] && wn.views.calendar[doctype]) {
  128. views.push({
  129. icon: "icon-tasks",
  130. route: "Gantt/" + doctype,
  131. type: "gantt"
  132. });
  133. }
  134. if(wn.model.can_get_report(doctype)) {
  135. views.push({
  136. icon: "icon-table",
  137. route: "Report/" + doctype,
  138. type: "report"
  139. });
  140. }
  141. this.set_views(views, active_view);
  142. },
  143. set_views: function(views, active_view) {
  144. var me = this;
  145. $right = this.$w.find(".title-button-area");
  146. $.each(views, function(i, e) {
  147. var btn = $(repl('<button class="btn btn-default" data-route="%(route)s">\
  148. <i class="%(icon)s"></i></button>', e))
  149. .click(e.set_route || function() {
  150. window.location.hash = "#" + $(this).attr("data-route");
  151. })
  152. .css({
  153. width: "39px"
  154. })
  155. .attr("title", wn._(toTitle(e.type)))
  156. .appendTo($right);
  157. if(e.type==active_view) {
  158. btn.removeClass("btn-default").addClass("btn-info");
  159. }
  160. });
  161. },
  162. add_help_button: function(txt) {
  163. $('<button class="btn btn-default pull-right" button-type="help">\
  164. <b>?</b></button>')
  165. .data('help-text', txt)
  166. .click(function() { msgprint($(this).data('help-text'), 'Help'); })
  167. .insertBefore(this.toolbar.find(".clearfix"));
  168. },
  169. show_toolbar: function() {
  170. this.toolbar.toggle(true);
  171. },
  172. clear_buttons: function() {
  173. this.toolbar.empty();
  174. this.setup_toolbar();
  175. $(".custom-menu").remove();
  176. },
  177. add_button: function(label, click, icon, is_title) {
  178. this.show_toolbar();
  179. args = { label: wn._(label), icon:'' };
  180. if(icon) {
  181. args.icon = '<i class="'+icon+'"></i>';
  182. }
  183. this.buttons[label] && this.buttons[label].remove();
  184. var append_or_prepend = is_title ? "prependTo" : "appendTo";
  185. this.buttons[label] = $(repl('<button class="btn btn-default">\
  186. %(icon)s <span class="hidden-xs-inline">%(label)s</span></button>', args))
  187. [append_or_prepend](this.toolbar.find(".btn-group").css({"margin-right": "5px"}))
  188. .attr("title", wn._(label))
  189. .click(click);
  190. if(is_title) {
  191. this.buttons[label].addClass("btn-title");
  192. }
  193. return this.buttons[label];
  194. },
  195. get_menu: function(label) {
  196. return $("#navbar-" + label.toLowerCase());
  197. },
  198. add_menu_divider: function(menu) {
  199. menu = typeof menu == "string" ?
  200. this.get_menu(menu) : menu;
  201. $('<li class="divider custom-menu"></li>').prependTo(menu);
  202. },
  203. add_dropdown_button: function(parent, label, click, icon) {
  204. var menu = this.get_menu(parent);
  205. if(menu.find("li:not(.custom-menu)").length && !menu.find(".divider").length) {
  206. this.add_menu_divider(menu);
  207. }
  208. return $('<li class="custom-menu"><a><i class="'
  209. +icon+'"></i> '+label+'</a></li>')
  210. .insertBefore(menu.find(".divider"))
  211. .find("a")
  212. .click(function() {
  213. click();
  214. });
  215. },
  216. add_label: function(label) {
  217. this.show_toolbar();
  218. return $("<label style='margin-top: 0.8%; margin-left: 5px; margin-right: 5px; float: left;'>"+label+" </label>")
  219. .appendTo(this.toolbar.find(".appframe-form"));
  220. },
  221. add_select: function(label, options) {
  222. var field = this.add_field({label:label, fieldtype:"Select"})
  223. return field.$wrapper.find("select").empty().add_options(options);
  224. },
  225. add_data: function(label) {
  226. var field = this.add_field({label: label, fieldtype: "Data"});
  227. return field.$wrapper.find("input").attr("placeholder", label);
  228. },
  229. add_date: function(label, date) {
  230. var field = this.add_field({label: label, fieldtype: "Date", "default": date});
  231. return field.$wrapper.find("input").attr("placeholder", label);
  232. },
  233. add_check: function(label) {
  234. this.show_toolbar();
  235. return $("<div class='checkbox' style='margin-right: 10px; margin-top: 7px; float: left;'><label><input type='checkbox'>" + label + "</label></div>")
  236. .appendTo(this.toolbar.find(".appframe-form"))
  237. .find("input");
  238. },
  239. add_field: function(df) {
  240. this.show_toolbar();
  241. var f = wn.ui.form.make_control({
  242. df: df,
  243. parent: this.toolbar.find(".appframe-form"),
  244. only_input: true,
  245. })
  246. f.refresh();
  247. $(f.wrapper)
  248. .addClass('col-md-2 form-group')
  249. .css({
  250. "padding-left": "0px",
  251. "padding-right": "0px",
  252. "margin-right": "5px"
  253. })
  254. .attr("title", df.label).tooltip();
  255. if(df["default"])
  256. f.set_input(df["default"])
  257. this.fields_dict[df.fieldname || df.label] = f;
  258. return f;
  259. },
  260. add_ripped_paper_effect: function(wrapper) {
  261. if(!wrapper) var wrapper = wn.container.page;
  262. var layout_main = $(wrapper).find('.layout-main');
  263. if(!layout_main.length) {
  264. layout_main = $(wrapper).find('.layout-main-section');
  265. }
  266. layout_main.css({"padding-top":"25px"});
  267. $('<div class="ripped-paper-border"></div>')
  268. .prependTo(layout_main)
  269. .css({"width": $(layout_main).width()});
  270. },
  271. /* deprecated */
  272. clear_breadcrumbs: function() {
  273. this.$w.find(".breadcrumb").empty();
  274. },
  275. add_breadcrumb: function(icon, link, title) {
  276. return; // bc
  277. },
  278. add_home_breadcrumb: function() {
  279. this.add_breadcrumb("icon-home", wn.home_page, "Home");
  280. },
  281. add_list_breadcrumb: function(doctype) {
  282. this.add_breadcrumb("icon-list", "List/" + encodeURIComponent(doctype), doctype + " List");
  283. },
  284. });
  285. // parent, title, single_column
  286. // standard page with appframe
  287. wn.ui.make_app_page = function(opts) {
  288. /* help: make a standard page layout with a toolbar and title */
  289. /* options: [
  290. "parent: [HTMLElement] parent element",
  291. "single_column: [Boolean] false/true",
  292. "title: [optional] set this title"
  293. ]
  294. */
  295. if(opts.single_column) {
  296. $('<div class="appframe col-md-12">\
  297. <div class="layout-appframe row"></div>\
  298. <div class="layout-main"></div>\
  299. </div>').appendTo(opts.parent);
  300. } else {
  301. $('<div class="appframe col-md-12">\
  302. <div class="layout-appframe row"></div>\
  303. <div class="row">\
  304. <div class="layout-main-section col-md-9"></div>\
  305. <div class="layout-side-section col-md-3"></div>\
  306. </div>\
  307. </div>').appendTo(opts.parent);
  308. }
  309. opts.parent.appframe = new wn.ui.AppFrame($(opts.parent).find('.layout-appframe'));
  310. if(opts.set_document_title!==undefined)
  311. opts.parent.appframe.set_document_title = opts.set_document_title;
  312. if(opts.title) opts.parent.appframe.set_title(opts.title);
  313. if(opts.icon) opts.parent.appframe.add_module_icon(null, opts.icon);
  314. }