Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

353 řádky
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 = $('<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. }