選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

348 行
9.8 KiB

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