MultipleSelector.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. MWF.xApplication.Selector = MWF.xApplication.Selector || {};
  2. MWF.xDesktop.requireApp("Selector", "lp."+MWF.language, null, false);
  3. //MWF.xDesktop.requireApp("Selector", "Actions.RestActions", null, false);
  4. MWF.xApplication.Selector.MultipleSelector = new Class({
  5. Extends: MWF.widget.Common,
  6. Implements: [Options, Events],
  7. options: {
  8. "style": "default",
  9. "types" : [],
  10. "count": 0,
  11. "title": "Select",
  12. "groups": [], //选person, group, role 时的范围
  13. "roles": [], //选选person, group, role 时的范围
  14. "units": [], //选 company, department, duty, identity 时的范围
  15. "values" : [],
  16. "zIndex": 1000,
  17. "expand": true
  18. },
  19. initialize: function(container, options){
  20. this.setOptions(options);
  21. this.path = "/x_component_Selector/$Selector/";
  22. this.cssPath = "/x_component_Selector/$Selector/"+this.options.style+"/css.wcss";
  23. this._loadCss();
  24. this.container = $(container);
  25. this.lp = MWF.xApplication.Selector.LP;
  26. this.lastPeople = "";
  27. this.pageCount = "13";
  28. this.selectedItems = [];
  29. this.selectedItemsObject = {};
  30. this.items = [];
  31. this.selectors = {};
  32. },
  33. load: function(){
  34. if (layout.mobile){
  35. this.loadMobile();
  36. }else{
  37. this.loadPc();
  38. }
  39. this.fireEvent("load");
  40. },
  41. loadMobile: function(){
  42. this.maskRelativeNode = $(document.body);
  43. this.maskRelativeNode.mask({
  44. "destroyOnHide": true,
  45. "style": this.css.maskNode
  46. });
  47. this.node = new Element("div", {"styles": this.css.containerNodeMobile});
  48. this.node.setStyle("z-index", this.options.zIndex.toInt()+1);
  49. this.node.setStyle("height", ( document.body.getSize().y ) + "px");
  50. this.titleNode = new Element("div", {
  51. "styles": this.css.titleNodeMobile
  52. }).inject(this.node);
  53. this.titleCancelActionNode = new Element("div", {
  54. "styles": this.css.titleCancelActionNodeMobile,
  55. "text": MWF.SelectorLP.back
  56. }).inject(this.titleNode);
  57. this.titleOkActionNode = new Element("div", {
  58. "styles": this.css.titleOkActionNodeMobile,
  59. "text": MWF.SelectorLP.ok
  60. }).inject(this.titleNode);
  61. this.titleTextNode = new Element("div", {
  62. "styles": {
  63. "margin": "0px 50px",
  64. "height": "40px",
  65. "padding": "0px 10px",
  66. "color": "#FFF",
  67. "font-weight": "bold",
  68. "font-size": "14px",
  69. "line-height": "40px"
  70. //"overflow" : "hidden"
  71. }
  72. //"text": this.options.title
  73. }).inject(this.titleNode);
  74. this.contentNode = new Element("div", {
  75. "styles": this.css.contentNode
  76. }).inject(this.node);
  77. var size = document.body.getSize();
  78. //var height = size.y-40;
  79. var height = size.y;
  80. this.contentNode.setStyle("height", ""+height+"px");
  81. this.contentNode.setStyle("margin-top", "2px");
  82. this.loadContent();
  83. this.node.inject(document.body);
  84. this.node.setStyles({
  85. "top": "0px",
  86. "left": "0px"
  87. });
  88. this.setEvent();
  89. },
  90. loadPc: function(){
  91. this.css.maskNode["z-index"] = this.options.zIndex;
  92. var position = this.container.getPosition(this.container.getOffsetParent());
  93. this.container.mask({
  94. "destroyOnHide": true,
  95. "style": this.css.maskNode,
  96. "useIframeShim": true,
  97. "iframeShimOptions": {"browsers": true},
  98. "onShow": function(){
  99. this.shim.shim.setStyles({
  100. "opacity": 0,
  101. "top": ""+position.y+"px",
  102. "left": ""+position.x+"px"
  103. });
  104. }
  105. });
  106. // this.container.setStyle("z-index", this.options.zIndex);
  107. this.node = new Element("div", {
  108. "styles": this.css.containerNode_multiple //this.isSingle() ? this.css.containerNodeSingle_multiple : this.css.containerNode_multiple
  109. });
  110. this.node.setStyle("z-index", this.options.zIndex.toInt()+1);
  111. this.titleNode = new Element("div", {
  112. "styles": this.css.titleNode
  113. }).inject(this.node);
  114. this.titleActionNode = new Element("div", {
  115. "styles": this.css.titleActionNode
  116. }).inject(this.titleNode);
  117. this.titleTextNode = new Element("div", {
  118. "styles": this.css.titleTextNode,
  119. "text": this.options.title
  120. }).inject(this.titleNode);
  121. this.contentNode = new Element("div", {
  122. "styles": this.css.contentNode
  123. }).inject(this.node);
  124. this.actionNode = new Element("div", {
  125. "styles": this.css.actionNode
  126. }).inject(this.node);
  127. //if ( this.isSingle() ) this.actionNode.setStyle("text-align", "center");
  128. this.loadAction();
  129. this.node.inject(this.container);
  130. if( this.options.width || this.options.height ){
  131. this.setSize()
  132. }
  133. this.loadContent();
  134. this.node.position({
  135. relativeTo: this.container,
  136. position: "center",
  137. edge: "center"
  138. });
  139. var size = this.container.getSize();
  140. var nodeSize = this.node.getSize();
  141. this.node.makeDraggable({
  142. "handle": this.titleNode,
  143. "limit": {
  144. "x": [0, size.x-nodeSize.x],
  145. "y": [0, size.y-nodeSize.y]
  146. }
  147. });
  148. this.setEvent();
  149. },
  150. isSingle : function(){
  151. var single = true;
  152. var flag = true;
  153. this.options.types.each( function( type, index ){
  154. var opt = this.options[ type + "Options" ];
  155. if( opt ){
  156. if( Number.convert(opt.count) !== 1 )single = false;
  157. flag = false;
  158. }
  159. }.bind(this));
  160. if( flag ){
  161. single = Number.convert( this.options.count ) === 1;
  162. }
  163. return single;
  164. },
  165. setEvent: function(){
  166. if (this.titleActionNode){
  167. this.titleActionNode.addEvent("click", function(){
  168. this.close();
  169. }.bind(this));
  170. }
  171. if (this.titleCancelActionNode){
  172. this.titleCancelActionNode.addEvent("click", function(){
  173. this.close();
  174. }.bind(this));
  175. }
  176. if (this.titleOkActionNode){
  177. this.titleOkActionNode.addEvent("click", function(){
  178. this.fireEvent("complete", [this.getSelectedItems(), this.getSelectedItemsObject() ]);
  179. this.close();
  180. }.bind(this));
  181. }
  182. },
  183. close: function(){
  184. this.fireEvent("close");
  185. this.node.destroy();
  186. (this.maskRelativeNode || this.container).unmask();
  187. MWF.release(this);
  188. delete this;
  189. },
  190. loadAction: function(){
  191. this.okActionNode = new Element("button", {
  192. "styles": this.css.okActionNode,
  193. "text": "确定"
  194. }).inject(this.actionNode);
  195. this.cancelActionNode = new Element("button", {
  196. "styles": this.css.cancelActionNode,
  197. "text": "取消"
  198. }).inject(this.actionNode);
  199. this.okActionNode.addEvent("click", function(){
  200. this.fireEvent("complete", [this.getSelectedItems(), this.getSelectedItemsObject() ]);
  201. this.close();
  202. }.bind(this));
  203. this.cancelActionNode.addEvent("click", function(){this.fireEvent("cancel"); this.close();}.bind(this));
  204. },
  205. loadContent: function(){
  206. if (layout.mobile){
  207. MWF.require("MWF.widget.Tab", function(){
  208. this.tab = new MWF.widget.Tab(this.titleTextNode, {"style": "orgMobile" });
  209. var width = this.container.getSize().x - 160; //160是确定和返回按钮的宽度
  210. var w = width / this.options.types.length - 2;
  211. var tabWidth = w < 60 ? w : 60;
  212. if( this.tab.css.tabNode ){
  213. this.tab.css.tabNode["min-width"] = tabWidth+"px";
  214. }
  215. if( this.tab.css.tabNodeCurrent ){
  216. this.tab.css.tabNodeCurrent["min-width"] = tabWidth+"px";
  217. }
  218. this.tab.load();
  219. this.tab.contentNodeContainer.inject(this.contentNode);
  220. }.bind(this), false);
  221. }else{
  222. MWF.require("MWF.widget.Tab", function(){
  223. this.tab = new MWF.widget.Tab(this.contentNode, {"style": this.options.tabStyle || "default" });
  224. this.tab.load();
  225. }.bind(this), false);
  226. }
  227. var isFormWithAction = window.location.href.toLowerCase().indexOf("workmobilewithaction.html") > -1;
  228. this.options.types.each( function( type, index ){
  229. var options = Object.clone( this.options );
  230. if( type.toLowerCase()==="identity" ){
  231. options.expand = false;
  232. }
  233. if( this.options[ type + "Options" ] ){
  234. options = Object.merge( options, this.options[ type + "Options" ] );
  235. }
  236. var pageNode = new Element( "div" ).inject( this.contentNode );
  237. var tab = this.tab.addTab( pageNode, this.lp[type], false );
  238. if( index === 0 && this.contentHeight ){
  239. //this.contentHeight = this.contentHeight - this.getOffsetY( tab.tabNode ) - tab.tabNode.getStyle("height").toInt();
  240. this.contentHeight = this.contentHeight - this.getOffsetY( tab.tab.tabNodeContainer ) - tab.tab.tabNodeContainer.getStyle("height").toInt();
  241. }
  242. var t = type.capitalize();
  243. if ((type.toLowerCase()==="unit") && ( options.unitType)){
  244. t = "UnitWithType";
  245. }
  246. if ((type.toLowerCase()==="identity") && (( options.dutys) && options.dutys.length && options.categoryType.toLowerCase()==="duty")){
  247. t = "IdentityWidthDuty";
  248. }
  249. MWF.xDesktop.requireApp("Selector", t, function(){
  250. if( type.toLowerCase()==="identity" && options.resultType && options.resultType === "person" ){
  251. options.values = this.getValueByType( options.values, [ type, "person" ] );
  252. }else{
  253. options.values = this.getValueByType( options.values, type );
  254. }
  255. //options.values = [];
  256. //if( options.multipleValues[type] ){
  257. // options.values = options.multipleValues[type];
  258. //}
  259. //if( options[type+"Values"] && options[type+"Values"].length ){
  260. // options.values = options.values.concat( options[type+"Values"] )
  261. //}
  262. //
  263. //options.names = [];
  264. //if( options.multipleNames[type] ){
  265. // options.names = options.multipleNames[type];
  266. //}
  267. //if( options[type+"Names"] && options[type+"Names"].length ){
  268. // options.names = options.names.concat( options[type+"Names"] )
  269. //}
  270. if( this.contentWidth )options.width = this.contentWidth;
  271. if( this.contentHeight )options.height = this.contentHeight;
  272. this.selectors[t] = new MWF.xApplication.Selector[t](this.container, options );
  273. this.selectors[t].loadContent( pageNode );
  274. this.selectors[t].setSize();
  275. if( layout.mobile ){
  276. var containerSize = this.container.getSize();
  277. var bodySize = $(document.body).getSize();
  278. var size = {
  279. "x" : Math.min( containerSize.x, bodySize.x ),
  280. "y" : Math.min( containerSize.y, bodySize.y )
  281. };
  282. var height;
  283. if( isFormWithAction ){
  284. height = size.y-40-20-6-20;
  285. }else{
  286. height = size.y;
  287. }
  288. if(this.selectors[t].selectNode){
  289. this.selectors[t].selectNode.setStyle("height", ""+height+"px");
  290. }
  291. if( isFormWithAction ){
  292. height = size.y-40-20-78 - 20;
  293. }else{
  294. height = size.y-42-31-40;
  295. }
  296. var itemAreaScrollNode = this.selectors[t].itemAreaScrollNode;
  297. if( itemAreaScrollNode ){
  298. itemAreaScrollNode.setStyle("height", ""+height+"px");
  299. }
  300. if( t.toLowerCase() == "person" || t.toLowerCase() == "group" ){
  301. var startY=0, y=0;
  302. itemAreaScrollNode.addEvents({
  303. 'touchstart' : function( ev ){
  304. var touch = ev.touches[0]; //获取第一个触点
  305. startY = Number(touch.pageY); //页面触点Y坐标
  306. }.bind(this),
  307. 'touchmove' : function(ev){
  308. var touch = ev.touches[0]; //获取第一个触点
  309. y = Number(touch.pageY); //页面触点Y坐标
  310. }.bind(this),
  311. 'touchend' : function( ev ){
  312. if (startY - y > 10) { //向上滑动超过10像素
  313. var obj = this.selectors.Person;
  314. obj._scrollEvent( obj.itemAreaScrollNode.scrollTop + 100 );
  315. }
  316. startY = 0;
  317. y = 0;
  318. }.bind(this)
  319. })
  320. }
  321. }else{
  322. //if( !this.isSingle() && Number.convert( options.count ) === 1 ){
  323. // this.selectors[t].selectNode.setStyles({
  324. // "float" : "none",
  325. // "margin-left" : "auto",
  326. // "margin-right" : "auto"
  327. // })
  328. //}
  329. }
  330. if( index == 0 )tab.showIm();
  331. }.bind(this));
  332. }.bind(this));
  333. },
  334. getValueByType : function( values, type ){
  335. var result = [];
  336. values = typeOf( values == "array" ) ? values : [values];
  337. var types = typeOf( type == "array" ) ? type : [type];
  338. values.each( function( data ){
  339. if( typeOf( data ) == "string" ){
  340. var dn = data;
  341. }else{
  342. var dn = data.distinguishedName;
  343. }
  344. if (dn && type ){
  345. var flag = dn.substr(dn.length-1, 1);
  346. switch (flag.toLowerCase()){
  347. case "i":
  348. if( type == "identity" || types.contains( "identity" ) )result.push( data );
  349. break;
  350. case "p":
  351. if( type == "person" || types.contains( "person" ) )result.push( data );
  352. break;
  353. case "u":
  354. if( type == "unit" )result.push( data );
  355. break;
  356. case "g":
  357. if( type == "group" )result.push( data );
  358. break;
  359. case "r":
  360. if( type == "role" )result.push( data );
  361. break;
  362. default:
  363. if( type == "person" )result.push( data );
  364. break;
  365. //result.push( data );
  366. }
  367. }else{
  368. //result.push( data );
  369. }
  370. });
  371. return result;
  372. },
  373. getSelectedItems : function(){
  374. this.selectedItems = [];
  375. for( var key in this.selectors ){
  376. var selector = this.selectors[key];
  377. if( selector.selectedItems && selector.selectedItems.length > 0 ){
  378. this.selectedItems = this.selectedItems.concat( selector.selectedItems );
  379. }
  380. }
  381. return this.selectedItems;
  382. },
  383. getSelectedItemsObject : function(){
  384. this.selectedItemsObject = {};
  385. for( var key in this.selectors ){
  386. var selector = this.selectors[key];
  387. if( selector.selectedItems && selector.selectedItems.length > 0 ){
  388. this.selectedItemsObject[key.toLowerCase()] = selector.selectedItems;
  389. }
  390. }
  391. return this.selectedItemsObject;
  392. },
  393. getOffsetX : function(node){
  394. return (node.getStyle("margin-left").toInt() || 0 )+
  395. (node.getStyle("margin-right").toInt() || 0 ) +
  396. (node.getStyle("padding-left").toInt() || 0 ) +
  397. (node.getStyle("padding-right").toInt() || 0 ) +
  398. (node.getStyle("border-left-width").toInt() || 0 ) +
  399. (node.getStyle("border-right-width").toInt() || 0 );
  400. },
  401. getOffsetY : function(node){
  402. return (node.getStyle("margin-top").toInt() || 0 ) +
  403. (node.getStyle("margin-bottom").toInt() || 0 ) +
  404. (node.getStyle("padding-top").toInt() || 0 ) +
  405. (node.getStyle("padding-bottom").toInt() || 0 )+
  406. (node.getStyle("border-top-width").toInt() || 0 ) +
  407. (node.getStyle("border-bottom-width").toInt() || 0 );
  408. },
  409. setSize : function(){
  410. if( !this.options.width && !this.options.height )return;
  411. if( this.options.width && this.options.width === "auto" ){
  412. //if (this.options.count.toInt() !== 1){
  413. this.node.setStyle("width", "auto");
  414. this.contentWidth = "auto";
  415. }else if( this.options.width && typeOf( this.options.width.toInt() ) === "number" ){
  416. var nodeWidth = this.options.width.toInt() - this.getOffsetX(this.node);
  417. this.node.setStyle("width", nodeWidth);
  418. if( this.contentNode ){
  419. nodeWidth = nodeWidth - this.getOffsetX( this.contentNode );
  420. }
  421. this.contentWidth = nodeWidth;
  422. }
  423. if( this.options.height && typeOf( this.options.height.toInt() ) === "number" ){
  424. var nodeHeight = this.options.height.toInt() - this.getOffsetY(this.node);
  425. this.node.setStyle("height", nodeHeight);
  426. if( this.titleNode ){
  427. nodeHeight = nodeHeight - this.getOffsetY( this.titleNode ) - this.titleNode.getStyle("height").toInt();
  428. }
  429. if( this.actionNode ){
  430. nodeHeight = nodeHeight - this.getOffsetY( this.actionNode ) - this.actionNode.getStyle("height").toInt();
  431. }
  432. if( this.contentNode ){
  433. nodeHeight = nodeHeight - this.getOffsetY( this.contentNode );
  434. }
  435. this.contentHeight = nodeHeight;
  436. }
  437. }
  438. });
  439. MWF.xApplication.Selector.MultipleSelector.Filter = new Class({
  440. Implements: [Options, Events],
  441. options: {
  442. "types" : [],
  443. "groups": [], //选person, group, role 时的范围
  444. "roles": [], //选选person, group, role 时的范围
  445. "units": [], //选 company, department, duty, identity 时的范围
  446. },
  447. initialize: function(value, options){
  448. this.setOptions(options);
  449. this.value = value;
  450. this.orgAction = MWF.Actions.get("x_organization_assemble_control");
  451. this.selectors = {};
  452. this.options.types.each( function( type, index ){
  453. var opt = Object.clone( this.options );
  454. if( this.options[ type + "Options" ] ){
  455. opt = Object.merge( opt, this.options[ type + "Options" ] );
  456. }
  457. var t = type.capitalize();
  458. if ((type.toLowerCase()==="unit") && ( opt.unitType)){
  459. t = "UnitWithType";
  460. }
  461. if ((type.toLowerCase()==="identity") && ((opt.dutys) && opt.dutys.length)){
  462. t = "IdentityWidthDuty";
  463. }
  464. MWF.xDesktop.requireApp("Selector", t, function(){
  465. this.selectors[t] = new MWF.xApplication.Selector[t].Filter(this.value, opt);
  466. }.bind(this), false);
  467. }.bind(this));
  468. },
  469. filter: function(value, callback){
  470. this.value = value;
  471. var key = this.value;
  472. this.filterData = [];
  473. this.filterCount = 0;
  474. for (i in this.selectors){
  475. this.selectors[i].filter(value, function(data){
  476. this.filterData = this.filterData.concat(data);
  477. this.filterCount++;
  478. this.endFilter(callback);
  479. }.bind(this))
  480. }
  481. //
  482. // this.orgAction.listPersonByKey(function(json){
  483. // data = json.data;
  484. // if (callback) callback(data)
  485. // }.bind(this), failure, key);
  486. },
  487. endFilter: function(callback){
  488. if (this.filterCount>=Object.keys(this.selectors).length){
  489. if (callback) callback(this.filterData);
  490. }
  491. }
  492. });