MSelector.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. //提供两种方式,一种是传入selectValue,selectText, 另外一种是 用onLoadData 或 loadData 加载数据,
  2. MWF.xDesktop.requireApp("Template", "MTooltips", null, false);
  3. var MSelector = new Class({
  4. Extends: MWF.widget.Common,
  5. Implements: [Options, Events],
  6. options: {
  7. "style": "default",
  8. "width": "230px",
  9. "height": "30px",
  10. "defaultOptionLp" : "请选择",
  11. "trigger" : "delay", //immediately
  12. "isSetSelectedValue" : true,
  13. "isChangeOptionStyle" : true,
  14. "inputEnable" : false,
  15. "isCreateReadNode" : true, //适应给MDomitem的做法
  16. "emptyOptionEnable" : true,
  17. "containerIsTarget" : false,
  18. "textField" : "",
  19. "valueField" : "",
  20. "value" : "",
  21. "text" : "",
  22. "defaultVaue" : "",
  23. "selectValue" : "",
  24. "selectText" : "",
  25. "isEdited" : true,
  26. "tooltipsOptions" : {
  27. axis: "y", //箭头在x轴还是y轴上展现
  28. position : { //node 固定的位置
  29. x : "center", //x轴上left center right, auto 系统自动计算
  30. y : "bottom" //y 轴上top middle bottom, auto 系统自动计算
  31. },
  32. event : "click", //事件类型,有target 时有效, mouseenter对应mouseleave,click 对应 container 的 click
  33. hiddenDelay : 200, //ms , 有target 且 事件类型为 mouseenter 时有效
  34. displayDelay : 0 //ms , 有target 且事件类型为 mouseenter 时有效
  35. }
  36. },
  37. initialize: function (container, options , app, css, dropdownContainer ) {
  38. this.setOptions(options);
  39. if( !this.options.isEdited && !this.options.isCreateReadNode ){
  40. }else{
  41. this.path = "/x_component_Template/$MSelector/";
  42. this.cssPath = "/x_component_Template/$MSelector/"+this.options.style+"/css.wcss";
  43. this._loadCss();
  44. if( css ){
  45. this.css = Object.merge( this.css, css )
  46. }
  47. }
  48. this.valSeparator = /,|;|\^\^|\|/; //如果是多值对象,作为用户选择的多个值的分隔符
  49. this.app = app;
  50. this.container = $(container);
  51. this.dropdownContainer = dropdownContainer || $(dropdownContainer);
  52. },
  53. load : function( callback ){
  54. if( this.options.isEdited ){
  55. this.loadEdit(callback)
  56. }else{
  57. this.loadRead(callback)
  58. }
  59. },
  60. initPara: function(){
  61. this.itemNodeList = [];
  62. this.itemNodeObject = {};
  63. this.value = this.options.value || this.options.text || this.options.defaultVaue;
  64. this.text = this.options.text || this.options.value || this.options.defaultVaue;
  65. this.textField = this.options.textField || this.options.valueField;
  66. this.valueField = this.options.valueField || this.options.textField;
  67. if( this.options.selectValue || this.options.selectText ){
  68. this.textField = "text";
  69. this.valueField = "value";
  70. var selectValue = this.options.selectValue;
  71. var selectText = this.options.selectText;
  72. this.selectValues = typeOf( selectValue ) == "array" ? selectValue : selectValue.split( this.valSeparator );
  73. this.selectTexts = typeOf( selectText ) == "array" ? selectText : selectText.split(this.valSeparator);
  74. this.data = [];
  75. if( this.options.emptyOptionEnable ){
  76. this.data.push({
  77. value : "",
  78. text : this.options.defaultOptionLp || ""
  79. })
  80. }
  81. this.selectValues.each( function( v,i ){
  82. this.data.push({
  83. value : v,
  84. text : this.selectTexts[i]
  85. })
  86. }.bind(this))
  87. }
  88. },
  89. loadRead: function(callback){
  90. this.initPara();
  91. var fun = function(){
  92. for( var i=0; i<this.data.length; i++ ){
  93. var d = this.data[i];
  94. if( this.options.text ){
  95. if( d[this.textField] == this.options.text ){
  96. this.value = d[this.valueField];
  97. this.text = this.options.text;
  98. this.currentItemData = d;
  99. break;
  100. }
  101. }else if( this.options.value ){
  102. if( d[this.valueField] == this.options.value ){
  103. this.value = this.options.value;
  104. this.text = d[this.textField];
  105. this.currentItemData = d;
  106. break;
  107. }
  108. }
  109. }
  110. this.loadReadNode( this.text );
  111. if( callback )callback();
  112. }.bind(this);
  113. if( this.data ){
  114. fun()
  115. }else{
  116. this._loadData( function( data ) {
  117. this.data = this.parseData(data);
  118. fun();
  119. }.bind(this))
  120. }
  121. },
  122. loadReadNode: function( text ){
  123. this.fireEvent( "loadReadNode", text );
  124. if( this.options.isCreateReadNode ){
  125. if( this.node )this.node.destroy();
  126. this.node = new Element("div", {
  127. styles : this.css.readNode,
  128. text : text
  129. }).inject( this.container );
  130. }
  131. },
  132. loadEdit:function( callback ){
  133. this.initPara();
  134. if( this.options.containerIsTarget ){
  135. this.node = this.container
  136. }else{
  137. this.node = new Element("div.selectNode", {
  138. styles : this.css.selectNode
  139. }).inject( this.container );
  140. this.node.setStyles({
  141. "width":this.options.width,
  142. "height":this.options.height
  143. });
  144. }
  145. if( this.data ){
  146. this.createDefaultItem();
  147. this.loadContent( this.data );
  148. this.fireEvent("postLoad", [this]);
  149. }else{
  150. this._loadData( function( data ){
  151. this.data = this.parseData( data );
  152. this.createDefaultItem();
  153. this.loadContent( this.data );
  154. this.fireEvent("postLoad", [this]);
  155. }.bind(this))
  156. }
  157. //this.node.addEvent( "click" , function( ev ){
  158. // this.loadContent();
  159. // ev.stopPropagation();
  160. //}.bind(this));
  161. if(callback)callback();
  162. },
  163. loadContent : function( data ){
  164. if( !this.contentTooltip ){
  165. var width = parseInt(this.options.width)+"px";
  166. this.css.tooltipNode.width = width;
  167. this.css.tooltipNode["max-width"] = width;
  168. var options = Object.merge({
  169. nodeStyles : this.css.tooltipNode,
  170. onPostLoad : function(){
  171. if( this.selectArrowNode )this.selectArrowNode.setStyles( this.css.selectArrowNode_up );
  172. if( this.inputNode ){
  173. this.inputNode.focus();
  174. }
  175. }.bind(this),
  176. onPostInitialize : function(){
  177. if(this.options.trigger == "immediately" ){
  178. this.contentTooltip.load();
  179. }
  180. }.bind(this),
  181. onHide : function(){
  182. this.status = "hidden";
  183. if(this.selectArrowNode) this.selectArrowNode.setStyles( this.css.selectArrowNode );
  184. }.bind(this)
  185. }, this.options.tooltipsOptions );
  186. this.contentTooltip = new MSelector.Tootips( this.dropdownContainer || this.app.content, this.node, this.app, data, options );
  187. this.contentTooltip.selector = this;
  188. }
  189. },
  190. createDefaultItem:function(){
  191. if( this.options.containerIsTarget )return;
  192. this.selectValueNode = new Element("div.selectValueNode",{
  193. "styles":this.css.selectValueNode
  194. }).inject(this.node);
  195. this.selectValueNode.setStyles({
  196. "width":(parseInt(this.options.width)-parseInt(this.options.height)-10)+"px",
  197. "height":this.options.height,
  198. "line-height":this.options.height
  199. });
  200. var d = this._getData( this.options.value );
  201. var text = d ? d[ this.textField ] : this.options.value;
  202. if( this.options.inputEnable ){
  203. this.inputNode = new Element("input", {
  204. "value" : text || this.options.defaultOptionLp ,
  205. "styles" : this.css.inputNode
  206. }).inject( this.selectValueNode );
  207. this.inputNode.addEvents( {
  208. focus : function(){
  209. if( this.inputNode.get("value") == this.options.defaultOptionLp ){
  210. this.inputNode.set("value", "" );
  211. }
  212. }.bind(this),
  213. blur : function(){
  214. var flag = false;
  215. var val = this.inputNode.get("value");
  216. if( val == "" ){
  217. this.inputNode.set("value", this.options.defaultOptionLp);
  218. }else{
  219. for( var i=0; i<this.data.length; i++ ){
  220. var d = this.data[i];
  221. if( d[ this.textField ] == val ){
  222. var itemNode = this.itemNodeObject[ d[this.valueField] ];
  223. this.setCurrentItem( itemNode );
  224. flag = true;
  225. break;
  226. }
  227. }
  228. if( !flag ){
  229. this.cancelCurrentItem();
  230. }
  231. }
  232. }.bind(this)
  233. } )
  234. }else{
  235. this.selectValueNode.set("text", text || this.options.defaultOptionLp);
  236. }
  237. this.selectArrowNode = new Element("div.selectArrowNode",{
  238. "styles":this.css.selectArrowNode
  239. }).inject(this.node);
  240. this.selectArrowNode.setStyles({
  241. "width":this.options.height,
  242. "height":this.options.height
  243. });
  244. },
  245. setCurrentItem : function( itemNode ){
  246. var data = itemNode.retrieve( "data" );
  247. if( this.currentItemNode ){
  248. this.currentItemNode.setStyles( this.css.listItemNode );
  249. }
  250. this.currentItemNode = itemNode;
  251. this.currentItemData = data;
  252. this.currentItemText = itemNode.get("text");
  253. if( this.options.isChangeOptionStyle )itemNode.setStyles( this.css.listItemNode_current );
  254. if( this.options.isSetSelectedValue && this.selectValueNode ){
  255. if( this.options.inputEnable ){
  256. this.inputNode.set("value", data[ this.textField ] );
  257. }else{
  258. this.selectValueNode.set("text", data[ this.textField ] );
  259. }
  260. }
  261. },
  262. cancelCurrentItem: function(){
  263. if( this.currentItemNode ){
  264. this.currentItemNode.setStyles( this.css.listItemNode );
  265. }
  266. this.currentItemNode = null;
  267. this.currentItemData = null;
  268. this.currentItemText = null;
  269. },
  270. parseData: function( data ){
  271. if( typeOf( data[0] ) == "string" ){
  272. var arr = [];
  273. this.textField = "text";
  274. this.valueField = "value";
  275. if(this.options.emptyOptionEnable ){
  276. arr.push({
  277. value : "",
  278. text : this.options.defaultOptionLp || ""
  279. });
  280. }
  281. data.each( function(d){
  282. arr.push({
  283. value : d,
  284. text : d
  285. })
  286. }.bind(this));
  287. return arr;
  288. }else{
  289. if( this.options.emptyOptionEnable && this.textField ){
  290. var obj = {};
  291. obj[ this.textField ] = this.options.defaultOptionLp || "";
  292. if( this.valueField != this.textField )obj[ this.valueField ] = "";
  293. data.unshift( obj )
  294. }
  295. return data;
  296. }
  297. },
  298. destroy : function(){
  299. if( this.node )this.node.destroy();
  300. if( this.contentTooltip )this.contentTooltip.destroy();
  301. },
  302. showTooltip : function(){
  303. this.contentTooltip.load();
  304. },
  305. hide : function(){
  306. this.status = "hidden";
  307. if(this.selectArrowNode) this.selectArrowNode.setStyles( this.css.selectArrowNode );
  308. if( this.contentTooltip )this.contentTooltip.hide();
  309. },
  310. setValue : function( value ){
  311. if( this.options.isEdited ){
  312. var itemNode = this.itemNodeObject[ value ];
  313. if( itemNode ){
  314. this.setCurrentItem( itemNode );
  315. }else if( this.options.inputEnable ) {
  316. var d = this._getData( value );
  317. if( d ){
  318. this.inputNode.set("value", d[ this.textField ] );
  319. }else{
  320. this.inputNode.set("value", value );
  321. }
  322. }
  323. }else{
  324. var d = this._getData( value );
  325. if( d ){
  326. this.loadReadNode( d[this.textField] );
  327. }else{
  328. this.loadReadNode( value );
  329. }
  330. }
  331. },
  332. get : function(){
  333. return {
  334. "value" : this.getValue(),
  335. "text" : this.getText()
  336. }
  337. },
  338. getValue : function(){
  339. if( this.options.isEdited ){
  340. if( this.currentItemData && this.valueField ) {
  341. return this.currentItemData[this.valueField]
  342. }else if( this.inputNode ){
  343. return this.inputNode.get("value");
  344. }else{
  345. return this.value;
  346. }
  347. }else{
  348. return this.value;
  349. }
  350. },
  351. getText : function(){
  352. if( this.options.isEdited ){
  353. if( this.currentItemData && this.textField ) {
  354. return this.currentItemData[this.textField]
  355. }else if( this.inputNode ){
  356. var d = this._getData( this.inputNode.get("value"), "text" );
  357. if( d ){
  358. return d[ this.textField ];
  359. }else{
  360. return this.inputNode.get("value");
  361. }
  362. }else{
  363. return this.text;
  364. }
  365. }else{
  366. return this.text;
  367. }
  368. },
  369. getData : function(){
  370. if( this.currentItemData )return this.currentItemData;
  371. if( this.inputNode )return this.inputNode.get("value");
  372. if( !this.options.text || !this.options.value )return null;
  373. for( var i=0; i<this.data.length; i++ ){
  374. var d = this.data[i];
  375. if( this.options.text ){
  376. if( d[this.textField] == this.options.text ){
  377. return d;
  378. }
  379. }else if( this.options.value ){
  380. if( d[this.valueField] == this.options.value ){
  381. return d;
  382. }
  383. }
  384. }
  385. return null;
  386. },
  387. _getData : function( vort, type ){
  388. for( var i=0; i<this.data.length; i++ ){
  389. var d = this.data[i];
  390. if( type == "text" ){
  391. if( d[this.textField] == vort ){
  392. return d;
  393. }
  394. }else{
  395. if( d[this.valueField] == vort ){
  396. return d;
  397. }
  398. }
  399. }
  400. return null;
  401. },
  402. _selectItem : function( itemNode, itemData ){
  403. },
  404. _loadData : function( callback ){
  405. //if(callback)callback();
  406. this.fireEvent("loadData",callback );
  407. },
  408. _postCreateItem: function(listItemNode, data){
  409. }
  410. });
  411. MSelector.Tootips = new Class({
  412. Extends: MTooltips,
  413. options : {
  414. axis: "y", //箭头在x轴还是y轴上展现
  415. position : { //node 固定的位置
  416. x : "center", //x轴上left center right, auto 系统自动计算
  417. y : "bottom" //y 轴上top middle bottom, auto 系统自动计算
  418. },
  419. event : "click", //事件类型,有target 时有效, mouseenter对应mouseleave,click 对应 container 的 click
  420. hiddenDelay : 200, //ms , 有target 且 事件类型为 mouseenter 时有效
  421. displayDelay : 0, //ms , 有target 且事件类型为 mouseenter 时有效
  422. hasArrow : false
  423. },
  424. _customNode : function( node, contentNode ){
  425. //var width = ( parseInt( this.selector.options.width ) )+ "px";
  426. //node.setStyles({
  427. // "width": width,
  428. // "max-width": width
  429. //});
  430. this.createItemList( this.data, contentNode )
  431. },
  432. createItemList:function(data, node){
  433. data = data || [];
  434. var _selector = this.selector;
  435. this.css = _selector.css;
  436. if(_selector.selectArrowNode)_selector.selectArrowNode.setStyles( this.css.selectArrowNode_up );
  437. _selector.listContentNode = new Element("div.listContentNode",{
  438. "styles":this.css.listContentNode
  439. }).inject( node );
  440. //_selector.listContentNode.setStyles({
  441. // "width": node.getSize().x+"px"
  442. //});
  443. _selector.listNode = new Element("div.listNode",{
  444. "styles":this.css.listNode
  445. }).inject(_selector.listContentNode);
  446. _selector.setScrollBar(_selector.listNode);
  447. data.each(function(d){
  448. this.createItem( d );
  449. }.bind(this));
  450. },
  451. createItem: function( data ){
  452. var _selector = this.selector;
  453. var listItemNode = new Element("div.listItemNode",{
  454. "styles":this.css.listItemNode,
  455. "text": data[ _selector.textField ]
  456. }).inject(_selector.listNode);
  457. listItemNode.setStyles({
  458. "height":_selector.options.height,
  459. "line-height":_selector.options.height
  460. });
  461. if(data)listItemNode.store("data",data);
  462. listItemNode.addEvents({
  463. "click":function(ev){
  464. var _self = this.obj;
  465. var data = this.itemNode.retrieve( "data" );
  466. _self.selector.setCurrentItem( this.itemNode );
  467. _self.selector._selectItem( this.itemNode, data, ev );
  468. _self.selector.fireEvent("selectItem", [ this.itemNode, data, ev ] );
  469. _self.hide();
  470. ev.stopPropagation();
  471. }.bind({ obj : this, itemNode : listItemNode }),
  472. "mouseover":function(){
  473. if( this.obj.selector.currentItemNode != this.itemNode || !this.obj.selector.options.isChangeOptionStyle ){
  474. this.itemNode.setStyles( this.obj.selector.css.listItemNode_over );
  475. }
  476. }.bind( {obj : this, itemNode : listItemNode }),
  477. "mouseout":function(){
  478. if( this.obj.selector.currentItemNode != this.itemNode || !this.obj.selector.options.isChangeOptionStyle ){
  479. this.itemNode.setStyles( this.obj.selector.css.listItemNode );
  480. }
  481. }.bind( {obj : this, itemNode : listItemNode })
  482. });
  483. _selector.itemNodeList.push( listItemNode );
  484. _selector.itemNodeObject[ data[ _selector.valueField ] ] = listItemNode;
  485. var isCurrent = false;
  486. if( _selector.currentItemData ){
  487. isCurrent = data[ _selector.valueField ] == _selector.currentItemData[ _selector.valueField ];
  488. }else if( _selector.value ){
  489. isCurrent = data[ _selector.valueField ] == _selector.value;
  490. }else if( _selector.text ){
  491. isCurrent = data[ _selector.textField ] == _selector.text;
  492. }
  493. if( isCurrent )_selector.setCurrentItem( listItemNode );
  494. _selector.fireEvent("postCreateItem", [ listItemNode, data ] );
  495. _selector._postCreateItem(listItemNode, data)
  496. }
  497. });