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 10 KiB

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