components.js 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496
  1. angular.module('components', [])
  2. .factory('baseService', function ($rootScope,$http,$compile,$rootElement) {
  3. $rootScope.modalShown = false;
  4. var touchmoveHandler= function(e){e.preventDefault();};
  5. $rootScope.$watch('modalShown',function(newVal,oldVal){
  6. if(newVal!==oldVal){
  7. if(newVal){
  8. document.addEventListener('touchmove',touchmoveHandler, false);
  9. }else{
  10. document.removeEventListener('touchmove',touchmoveHandler, false);
  11. }
  12. }
  13. });
  14. var baseService = {
  15. mytimeSwitch:false,
  16. agentType:"all"
  17. };
  18. /**
  19. * 获取服务器的JSONP数据
  20. * @param {Object}
  21. * url 待载入页面的URL地址
  22. * @param {Object} conf 配置文件
  23. * params 待发送数据 Key/value 参数。
  24. * callback 载入成功时回调函数。
  25. */
  26. baseService.jsonp = function(url,conf){
  27. var params = conf.params,
  28. callback = conf.callback,
  29. isCloseToast = true,
  30. type = true;
  31. if(!params){
  32. params = {};
  33. }
  34. //附加回调函数
  35. params.callback = 'JSON_CALLBACK';
  36. conf.params = params;
  37. conf.params.__rnd = new Date().getTime();
  38. if( conf.isCloseToast)
  39. type = false;
  40. if (!conf.__notshowtoast) {
  41. window.setTimeout(function(){
  42. HT.toastInWindow(conf.___id, conf.___popid, conf.___waitmsg, conf.___waittime);
  43. }, 1);
  44. }
  45. function successFn(data){
  46. if (isCloseToast && type) {//如果不需要关闭请传false
  47. HT.closeToastInWindow(conf.___id, conf.___popid);
  48. if (conf.___colseid)
  49. HT.closeToastInWindow(conf.___colseid);
  50. }
  51. callback(data);
  52. }
  53. function errorFn(data, status, headers, config, statusText){
  54. if (!HT.networkStatus())
  55. return;
  56. if (headers && headers('__timeout')) {
  57. window.setTimeout(function(){
  58. HT.toastInWindow(conf.___id, conf.___popid, $i18n$.LOGIN.LOGIN_TIME_OUT, 2000, 0)
  59. }, 1);
  60. HT.goback(-1);
  61. HT.goToHtml("login");
  62. }
  63. else {
  64. if (url.indexOf('getUserInfo') > 0) {
  65. alert("xxxx");
  66. }
  67. else
  68. if (url.indexOf('mobileLogin') > 0) {
  69. window.setTimeout(function(){
  70. HT.toastInWindow(conf.___id, conf.___popid, $i18n$.COMMON.GET_REMOTE_DATA_FAIL, 2000, 0);
  71. }, 1);
  72. }
  73. else {
  74. window.setTimeout(function(){
  75. HT.toastInWindow(conf.___id, conf.___popid, $i18n$.COMMON.GET_NOT_LOGIN, 2000, 0);
  76. window.setTimeout(function(){
  77. HT.goback("-1");
  78. HT.goToHtml("login");
  79. }, 1000);
  80. }, 1);
  81. }
  82. }
  83. }
  84. if(conf.post){
  85. $http.jsonp(url, conf).success(successFn).error(errorFn);// $http.post(url, conf.params).success(successFn).error(errorFn);
  86. }else{
  87. $http.jsonp(url, conf).success(successFn).error(errorFn);
  88. }
  89. };
  90. baseService.post = function(url,params,callback,conf){
  91. if(!conf)
  92. conf = {};
  93. conf.params = params;
  94. conf.callback = callback;
  95. baseService.jsonp(url,conf);
  96. };
  97. baseService.pageList1 = function(url, params, callback, conf){
  98. var pageSize = HT.pageSize,
  99. start = params.start,
  100. p = HT.parseInt(start/pageSize);
  101. var page = start%pageSize>0?(p+1):p;
  102. params.page = page;
  103. params.pageSize = pageSize;
  104. params.start = start;
  105. var type = params.type;
  106. //附加回调函数
  107. params.callback = 'JSON_CALLBACK';
  108. conf.params = params;
  109. try{uexWindow.toast(1,5,conf.waitmsg?conf.waitmsg:$i18n$.COMMON.WATTING_MSG,0);}catch(e){}
  110. $http.jsonp(url,conf)
  111. .success(function(data){
  112. if (type == 0) {
  113. callback(data);
  114. uexWindow.toast('0', '5', $i18n$.COMMON.QUERY_SUCCESS, '1000');
  115. }
  116. else {
  117. if (conf.params.start >= data.totalCounts) {
  118. uexWindow.toast('0', '5', $i18n$.COMMON.REACH_THE_END, '1000');
  119. return;
  120. }
  121. else if(data.results.length>0){
  122. callback(data);
  123. uexWindow.toast('0', '5', $i18n$.COMMON.LOAD_SUCCESS, '1000');
  124. }
  125. else if(data.results.length==0){
  126. uexWindow.toast('0', '5', $i18n$.COMMON.NULL_PAGE, '1000');
  127. }
  128. }
  129. })
  130. .error(function(data,status,headers,config,statusText){
  131. try{
  132. uexWindow.closeToast();
  133. uexWindow.toast(0,5,$i18n$.COMMON.GET_REMOTE_DATA_FAIL,1000);
  134. window.setTimeout(function(){HT.goToHtml("login");},1000);
  135. }catch(e){}
  136. });
  137. };
  138. /**
  139. * 分页查询
  140. */
  141. baseService.pageList = function(url,params,callback,conf){
  142. if(!conf)
  143. conf = {};
  144. //是否查询
  145. var isSearch = conf.isSearch?conf.isSearch:false;
  146. if(isSearch)
  147. params.pageBean = HT.getDefaultPage();
  148. var flag = params.pageBean?(params.pageBean._flag?params.pageBean._flag:0):2;
  149. conf.params = HT.trustPageBean(params);
  150. //附加回调函数
  151. conf.params.callback = 'JSON_CALLBACK';
  152. conf.params = params;
  153. conf.params.__rnd = new Date().getTime();
  154. try{uexWindow.toast(1,5,conf.waitmsg?conf.waitmsg:$i18n$.COMMON.WATTING_MSG,0);}catch(e){}
  155. $http.jsonp(url,conf)
  156. .success(function(data){
  157. if(flag == 1 && !isSearch && conf.params.start > data.totalCounts){
  158. try{
  159. uexWindow.resetBounceView(flag);
  160. uexWindow.toast('0', '5', $i18n$.COMMON.REACH_THE_END,'1000');
  161. }catch(e){}
  162. return;
  163. }
  164. if (flag == 1)
  165. data.results = HT.merge(conf.pageLists,data.results);
  166. try{
  167. uexWindow.closeToast();
  168. if(flag !=2){
  169. uexWindow.resetBounceView(flag);
  170. uexWindow.toast('0', '5', flag==0?$i18n$.COMMON.RELOAD_SUCCESS:$i18n$.COMMON.LOAD_SUCCESS, '1000');
  171. }else{
  172. uexWindow.resetBounceView(0);
  173. }
  174. }catch(e){}
  175. callback(data);
  176. })
  177. .error(function(data,status,headers,config,statusText){
  178. try{
  179. uexWindow.closeToast();
  180. if(flag !=2)
  181. uexWindow.resetBounceView(flag);
  182. uexWindow.toast(0,5,$i18n$.COMMON.GET_REMOTE_DATA_FAIL,1000);
  183. window.setTimeout(function(){HT.goToHtml("login");},1000);
  184. }catch(e){}
  185. });
  186. };
  187. /**
  188. * 打开一个模态弹出窗口
  189. * @param {Object} param
  190. */
  191. baseService.openDialog = function(param){
  192. baseService.hasModal = false;
  193. param = param||{};
  194. if(!$rootScope.modalElement){
  195. var modal = angular.element("<modal-dialog show='modalShown'></modal-dialog>");
  196. var el = $compile(modal)($rootScope);
  197. $rootElement.find("body").append(el);
  198. $rootScope.modalElement = angular.element(el[0].lastChild);
  199. }
  200. var content = angular.element('<div></div>');
  201. //标题部分
  202. if(param.title){
  203. var title = angular.element('<div></div>');
  204. title.addClass('ng-modal-title');
  205. title.text(param.title);
  206. content.append(title);
  207. }
  208. //内容部分
  209. if(param.html){
  210. var contentDiv = angular.element('<div style="margin:1em;text-align: center;"></div>');
  211. contentDiv.append(param.html);
  212. content.append(contentDiv);
  213. }
  214. //按钮部分
  215. if(param.buttons){
  216. var type=param.inline?"":"ub-ver",style=param.inline?"":"padding: 0.5em 0 0 0 ;",uba=param.inline?"border:1px solid #eee;":"";
  217. var btnDiv = angular.element('<div class="ub ub-ac '+type+' brd-t1sc" style="'+style+'"></div>');
  218. angular.forEach(param.buttons,function(button,i){
  219. var temp=i==(param.buttons.length-1)?'':'ubb';
  220. var div='<div class="ub-f1 ng-modal-btn '+temp+' b-ddd w100" style="height: 1.5em;padding: 0.5em 0 0.5em 0;'+uba+'"></div>';
  221. var btn = angular.element(div);
  222. btn.text(button.label);
  223. if(button.backcolor){
  224. btn.css("background-color",button.backcolor);
  225. }
  226. if(button.forecolor){
  227. btn.css("color",button.forecolor);
  228. }
  229. if(button.bordercolor){
  230. btn.css("border-color",button.bordercolor);
  231. }
  232. btn.bind('click',button.callback);
  233. btnDiv.append(btn);
  234. });
  235. content.append(btnDiv);
  236. }
  237. $rootScope.modalElement.empty().append(content);
  238. $rootScope.modalShown = true;
  239. if (param.digest) {
  240. $rootScope.$digest();
  241. }
  242. // var location=window.document.body.scrollTop/parseInt(document.body.style.fontSize)+window.document.body.clientHeight/parseInt(document.body.style.fontSize)/3
  243. if(param.marTop){
  244. HT.$(document.querySelectorAll(".ng-modal-dialog")[0]).attr({"style":"top:"+param.marTop+"% !important;"})
  245. }
  246. HT.addModalToParent();
  247. }
  248. /**
  249. * 关闭模态窗口
  250. */
  251. baseService.closeDialog = function(){
  252. HT.hideModalFromParent();
  253. baseService.hasModal = true;
  254. $rootScope.modalShown = false;
  255. $rootScope.$digest();
  256. }
  257. return baseService;
  258. })
  259. /**
  260. * 国际化工厂
  261. */
  262. .factory('translateCustomLoader', function ($q) {
  263. return function (options) {
  264. //修改当前语言,则加载对应的语言
  265. $i18n$ = HT.getI18n(options.key);
  266. var def = $q.defer();
  267. def.resolve($i18n$);
  268. return def.promise;
  269. };
  270. })
  271. /**
  272. * 选择器(人员、组织选择器)
  273. * <pre>
  274. * <selector type="user" write="true" multi="false" name="user" ng-model="user"/>
  275. * 属性:
  276. * type:选择器类型(可选)“user”、“org”等 默认 user
  277. * write:是否可写 默认false(只读)
  278. * multi:是否多选 默认false(单选)
  279. * name: 标示值
  280. * ng-model:
  281. * </pre>
  282. */
  283. .directive('selector', function() {
  284. return {
  285. restrict: 'E',
  286. transclude: true,
  287. scope: {},
  288. controller: function($scope,$attrs,$element,$http,baseService) {
  289. $scope.users = [];
  290. $scope.flag = $attrs.name;
  291. $scope.readonly = true;
  292. if($attrs.write&&$attrs.write=='true')
  293. $scope.readonly = false;
  294. var type = $attrs.type?$attrs.type:'user';
  295. /**
  296. * 显示明细(首先从常用联系人中获取,没有则从服务器获取)
  297. * @param info
  298. * @returns
  299. */
  300. $scope.displayDetail = function(info){
  301. switch(type){
  302. case "user":
  303. HT.userInfo(baseService,info);
  304. break;
  305. case "org":
  306. case "pos":
  307. var html = '<ul ontouchstart="zy_touch()" class="ub ubb b-ddd t-bla ub-ac lis h275"><li class="ut-s t-111 f-sz10625">'+$i18n$.ORG.NAME+'</li><li class="ub-f1 ulev-app1 t-888 t-right">' + info.un
  308. +'</li></ul><ul ontouchstart="zy_touch()" class=" ub t-bla ub-ac lis h275"><li class="ut-s t-111 f-sz10625">'+$i18n$.ORG.TITLE+'ID</li><li class="ub-f1 ulev-app1 t-888 t-right">'+ info.id
  309. +'</li></ul>';
  310. baseService.openDialog({title:$i18n$.ORG.ORG_INFO,html:html,buttons:[{
  311. label:$i18n$.COMMON.CLOSE,
  312. callback:function(){
  313. baseService.closeDialog();
  314. }
  315. }]});
  316. break;
  317. default :
  318. alert($i18n$.COMMON.NO_MATCH_TYPE);
  319. break;
  320. }
  321. };
  322. /**
  323. * 选择用户
  324. * @returns
  325. */
  326. $scope.chooseUser = function(){
  327. var us = $scope.users;
  328. if(us==null)
  329. us = [];
  330. var items=[];
  331. angular.forEach(us,function(item){
  332. items.push({id:item.id,
  333. name:item.un?
  334. item.un:
  335. item.name});
  336. });
  337. HT.setStorageJSON(HT_LS.selectorSelected,items);
  338. HT.setStorage("isfromform","true");
  339. HT.setStorage("isMulti",$attrs.multi!="false"?1:0);
  340. HT.setStorage(HT_LS.formToSeletor,$scope.flag);
  341. switch(type){
  342. case "user":
  343. uexWindow.open("contact", 0, "contact.html", 0, "", "", 0);
  344. break;
  345. case "org":
  346. uexWindow.open("org", 0, "org.html", 0, "", "", 0);
  347. break;
  348. default :
  349. alert($i18n$.COMMON.NO_MATCH_TYPE);
  350. break;
  351. }
  352. };
  353. $scope.wrap = function(){
  354. $element.parent().addClass("user-c-bd").addClass("ub-f1").addClass("w95").removeClass("t-right").removeClass("umar-l1").removeClass("mar-t-03");
  355. var pui = $element.parent().parent();
  356. pui.addClass("ub-ver");
  357. var preli = $element.parent().parent().find("li").eq(0);
  358. preli.addClass("ub-f1").addClass("w100");
  359. };
  360. if ($attrs.wrap)
  361. $scope.wrap();
  362. },
  363. template:'<div id="{{flag}}" class="ub uc-a1 b-ddd ub-ac pad040" selector="selector"><div class="mar-rl0a ub ub-ac w100">'
  364. +'<div class="ub ub-ver ub-f1 ut-s t-left mar-r0125" >'
  365. +'<span class="info-span ut-s ub-f1 filespan mar-r0125 mar-t0125 userStyle" ng-repeat="user in users" ng-click="displayDetail(user)">'
  366. +'<span ontouchstart="zy_touch()" ontouchstart="zy_touch(\'c-gra\') class="umar-r05 no-break ut-s">'
  367. +'{{user.un}}</span>'
  368. +'</span></div>'
  369. +'<div class="h256 w3" ontouchstart="zy_touch(\'\')" ng-click="chooseUser()" ><div class="filec ub f-r" ng-class="{uhide:readonly}" ><div class="icon-plus5 ub-f1 center mar-t05"></div></div></div>',
  370. replace: true
  371. };
  372. })
  373. .directive('tabs', function() {
  374. return {
  375. restrict: 'E',
  376. transclude: true,
  377. scope: {},
  378. controller: function($scope,$element) {
  379. var panes = $scope.panes = [];
  380. $scope.select = function(pane){
  381. if(!pane){
  382. if(!panes||panes.length==0)return;
  383. angular.forEach(panes,function(p){
  384. if(p.show){
  385. pane = p;
  386. }
  387. });
  388. }
  389. else{
  390. angular.forEach(panes,function(pane){
  391. pane.selected = false;
  392. });
  393. pane.selected = true;
  394. }
  395. var callfun = pane.callfun;
  396. if(callfun){
  397. eval(callfun);
  398. }
  399. createContent(pane);
  400. }
  401. createContent = function(pane){
  402. var param = window.location.search;
  403. url = pane.url;
  404. setTimeout(function(){
  405. HT.openPopFrame(url,null,param);
  406. uexWindow.bringPopoverToFront(url);
  407. },500);
  408. }
  409. this.select = function(){
  410. $scope.select();
  411. }
  412. this.addPane = function(pane){
  413. if(pane.show){
  414. angular.forEach(panes,function(pane){
  415. pane.selected = false;
  416. });
  417. pane.selected = true;
  418. }
  419. panes.push(pane);
  420. }
  421. },
  422. template:'<div class="ub ub-pc ub-f1 nav-content" style="height: 100%;">'
  423. +'<div ng-repeat="pane in panes" ontouchstart="zy_touch()" class="ub-f1 tabs " ng-class="{ubb1:pane.selected,ubb2:!pane.selected,\'t-51aeee\':pane.selected}" ng-click="select(pane)">'
  424. +'<span class="center">{{pane.title}}</span>'
  425. +'</div><div class="uhide" ng-transclude></div>'
  426. +'</div>',
  427. replace: true
  428. };
  429. })
  430. .directive('pane', function() {
  431. return {
  432. require:'^tabs',
  433. restrict: 'E',
  434. transclude: true,
  435. scope: {
  436. title:'@',
  437. url:'@',
  438. show:'@',
  439. noCotent:"@",
  440. callfun:"@"
  441. },
  442. link:function(scope,element,attrs,tabsCtrl){
  443. tabsCtrl.addPane(scope);
  444. if (!attrs.nocotent) {
  445. var onloadedHandler = window.uexOnload;
  446. window.uexOnload = function(type){
  447. if(onloadedHandler)onloadedHandler(type);
  448. if (!type) {
  449. tabsCtrl.select();
  450. }
  451. }
  452. }
  453. },
  454. template: '<div class="uhide" ng-transclude></div>',
  455. replace: true
  456. };
  457. })
  458. /**
  459. * 表单展示html
  460. */
  461. .directive('formHtmlBind', function($compile) {
  462. return function(scope,elm,attrs){
  463. scope.$watch(attrs.formHtmlBind,function(newVal,oldVal){
  464. if(newVal&&newVal!==oldVal){
  465. elm.html(newVal);
  466. $compile(elm.parent().contents())(scope);
  467. // __scxmainwindow=HT.scrollH('mainWindow');
  468. }
  469. });
  470. };
  471. })
  472. /**
  473. * 权限控制
  474. * 例子:permission-bind这个属性
  475. * <li class="ub-f1 ulev-app1 t-888 t-right umar-l1 mar-t-03">
  476. * <input controltype="input" type="text" permission-bind="permission.field.test1" ng-model="main.test1" name="test1" validate="{}" class="uc-a1 mr42">
  477. * </li>
  478. */
  479. .directive('permissionBind', function($compile) {
  480. return {
  481. priority:5,
  482. link:function(scope,elm,attrs){
  483. scope.$watch(attrs.permissionBind,function(newVal,oldVal){
  484. if(HT.isEmpty(newVal))//如果值为空返回
  485. return;
  486. var ngModel=attrs.ngModel,
  487. scopeVal = '',
  488. formtype =attrs.formtype;
  489. try{
  490. if(attrs.controltype=="select"){
  491. scopeVal=HT.getSelectedOption(elm);
  492. }else{
  493. scopeVal= eval('( scope.'+ngModel + ')')||'';
  494. }
  495. } catch (e) {
  496. scopeVal = "";
  497. }
  498. if(HT.isEmpty(formtype) || formtype == 'field'){//字段权限
  499. scope.fieldPermission(newVal,elm,scopeVal);
  500. }else if(formtype == 'subTable'){//子表权限
  501. scope.subTablePermission(newVal,elm,scopeVal);
  502. }else if(formtype == 'opinion'){//意见权限
  503. scope.opinionPermission(newVal,elm,scopeVal);
  504. }
  505. });
  506. /**
  507. * 字段权限
  508. */
  509. scope.fieldPermission = function(val,elm,scopeVal){
  510. switch (val) {
  511. case 'b': //必填
  512. //让字段必填
  513. break;
  514. case 'r': //只读
  515. var parent=elm.parent().parent();
  516. var type=elm.attr("type");
  517. if(elm.attr("selector")=="selector"||elm.attr("selector")=="file"){
  518. elm.children().find("div").eq(1).remove();
  519. }else if(type=="checkbox"||type=="radio"){
  520. elm.parent().parent().parent().attr("onclick","");
  521. if(type=="checkbox"&&scopeVal&&HT.checkInArr(scopeVal.split(","),elm.val())){
  522. elm.next().find("div").eq(1).removeClass("icon-checkbox").addClass("icon-disable-checkbox");
  523. }else if(type=="checkbox"){
  524. elm.next().find("div").eq(1).removeClass("icon-checkbox").addClass("icon-checkbox-eee");
  525. }else if(scopeVal&&scopeVal==elm.val()){
  526. elm.next().find("div").eq(1).removeClass("icon-radio").addClass("icon-disable-radio");
  527. }
  528. }else{
  529. elm.parent().remove();
  530. parent.html("<span class='left'>"+scopeVal+"</span>")
  531. }
  532. break;
  533. case 'rp': //只读提交
  534. var parent = elm.parent();
  535. //然后加个隐藏
  536. parent.addClass('uhide');
  537. //设置
  538. parent.parent().append(scopeVal);
  539. break;
  540. default://编辑没修改(w)
  541. break;
  542. }
  543. };
  544. /**
  545. * 子表权限
  546. */
  547. scope.subTablePermission = function(val,elm,scopeVal){
  548. switch (val) {
  549. case 'b': //必填
  550. //让子表必填
  551. break;
  552. case 'r': //只读
  553. elm.children().find("li").removeClass("icon-plus-square");
  554. scope.$$childTail.isOnlyRead=true;
  555. // elm.find("tr").attr("ng-click","");
  556. // elm.children().attr("ng-click","");
  557. break;
  558. default://编辑没修改(w)
  559. break;
  560. };
  561. /**
  562. * 意见权限
  563. */
  564. scope.opinionPermission = function(val,elm,scopeVal){
  565. switch (val) {
  566. case 'b': //必填
  567. //让字段必填
  568. break;
  569. case 'r': //只读
  570. var parent=elm.parent().parent();
  571. elm.parent().remove();
  572. parent.text(scopeVal);
  573. break;
  574. default://编辑没修改(w)
  575. break;
  576. }
  577. }
  578. }
  579. }
  580. };
  581. })
  582. /**
  583. * 表单验证
  584. */
  585. .directive('validate', function($compile) {
  586. return {
  587. require:'?ngModel',
  588. priority:6,
  589. link:function(scope,elm,attrs,ctrl){
  590. if(!ctrl) return ;
  591. scope._validRules = function(conf,me){
  592. var _valid = true,
  593. rules = conf.rules,//规则json
  594. ruleName = conf.ruleName,// 规则名称
  595. validValue = conf.validValue,//验证的值
  596. value =conf.value;//实际的值
  597. for (var m = 0; m < rules.length; m++) {
  598. // 取得验证规则。
  599. var rule = rules[m];
  600. if (ruleName.toLowerCase() != rule.name.toLowerCase()) continue;
  601. // 验证规则如下:
  602. // email:true,url:true. 或者数组类型,
  603. //验证规则是boolean类型
  604. if (typeof validValue === "boolean")
  605. _valid = (!rule.rule(value) && validValue == true) ? false:true;
  606. else
  607. _valid = rule.rule(value, validValue);
  608. if (!_valid) //验证不通过返回消息
  609. return me._format(rule.msg, validValue);
  610. }
  611. return "";
  612. };
  613. /**
  614. * 消息格式化
  615. **/
  616. scope._format = function(msg,args){
  617. //boolean类型的直接返回
  618. if (typeof args === 'boolean')
  619. return msg;
  620. if (!angular.isArray(args)) //不是数组类型的
  621. args = [args];
  622. //数组类型的
  623. angular.forEach(args,function(val, key) {
  624. msg = msg.replace(RegExp("\\{" + key + "\\}", "g"), val)
  625. });
  626. return msg;
  627. };
  628. scope._rules = [{
  629. name : "required",
  630. rule : function(v) {
  631. if( v === null || v === undefined || v === '')
  632. return false;
  633. if( v.length == 0)
  634. return false;
  635. return true;
  636. },
  637. msg : $i18n$.RULES.REQUIRED
  638. }, {
  639. name : "number",
  640. rule : function(v) {
  641. return /^((\d{1,3}(,\d{3})+?|\d+)(\.\d{1,5})?)$/
  642. .test(v.trim());
  643. },
  644. msg : $i18n$.RULES.ENTER_A_REGAL_NUMBER
  645. }, {
  646. name : "variable",
  647. rule : function(v) {
  648. return /^[A-Za-z_0-9]*$/gi.test(v.trim());
  649. },
  650. msg : $i18n$.RULES.ONLY_LETTER_AND_UNDERLINE
  651. }, {
  652. name : "fields",
  653. rule : function(v){
  654. return /^[A-Za-z]{1}([a-zA-Z0-9_]{1,17})?$/gi.test(v.trim());
  655. },
  656. msg : $i18n$.RULES.LETTER_FIRST_AND_MAX_18
  657. },{
  658. name : "minLength",
  659. rule : function(v, b) {
  660. return (v.length >= b);
  661. },
  662. msg : $i18n$.RULES.MIN_LENGTH
  663. }, {
  664. name : "maxLength",
  665. rule : function(v, b) {
  666. return (v.trim().length <= b);
  667. },
  668. msg : $i18n$.RULES.MAX_LENGTH
  669. }, {
  670. name : "rangeLength",
  671. rule : function(v, args) {
  672. return (v.trim().length >= args[0] && v.trim().length <= args[1]);
  673. },
  674. msg : $i18n$.RULES.RANGE_LENGTH
  675. }, {
  676. name : "email",
  677. rule : function(v) {
  678. return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i
  679. .test(v.trim());
  680. },
  681. msg : $i18n$.RULES.ENTER_A_REGAL_EMAIL
  682. }, {
  683. name : "url",
  684. rule : function(v) {
  685. return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i
  686. .test(v.trim());
  687. },
  688. msg : $i18n$.RULES.ENTER_A_REGAL_URL
  689. }, {
  690. name : "date",
  691. rule : function(v) {
  692. var re = /^[\d]{4}-[\d]{1,2}-[\d]{1,2}\s*[\d]{1,2}:[\d]{1,2}:[\d]{1,2}|[\d]{4}-[\d]{1,2}-[\d]{1,2}|[\d]{1,2}:[\d]{1,2}:[\d]{1,2}$/g
  693. .test(v.trim());
  694. return re;
  695. },
  696. msg : $i18n$.RULES.ENTER_A_REGAL_DATE
  697. }, {
  698. name : "digits",
  699. rule : function(v) {
  700. return /^\d+$/.test(v.trim());
  701. },
  702. msg : $i18n$.RULES.ENTER_DIGITS
  703. }, {
  704. name : "equalTo",
  705. rule : function(v, b) {
  706. var a = $("#" + b).val();
  707. return (v.trim() == a.trim());
  708. },
  709. msg : $i18n$.RULES.NOT_EQUAL_TWICE
  710. }, {
  711. name : "range",
  712. rule : function(v, args) {
  713. return v <= args[1] && v >= args[0];
  714. },
  715. msg : $i18n$.RULES.ENTER_NUM_RANGE
  716. }, {
  717. name : "maxvalue",
  718. rule : function(v, max) {
  719. return v <= max;
  720. },
  721. msg : $i18n$.RULES.MAX_VALUE
  722. },{
  723. name : "minvalue",
  724. rule : function(v, min) {
  725. return v >= min;
  726. },
  727. msg : $i18n$.RULES.MIN_VALUE
  728. },{
  729. // 判断数字整数位
  730. name : "maxIntLen",
  731. rule : function(v, b) {
  732. return (v + '').split(".")[0].replaceAll(",","").length <= b;
  733. },
  734. msg : $i18n$.RULES.MAX_INT_LEN
  735. }, {
  736. // 判断数字小数位
  737. name : "maxDecimalLen",
  738. rule : function(v, b) {
  739. return (v + '').replace(/^[^.]*[.]*/, '').length <= b;
  740. },
  741. msg : $i18n$.RULES.MAX_DECIMAL_LEN
  742. }, {
  743. // 判断日期范围{dateRangeStart:'xx'} xx:结束时间的日期的ID
  744. name : "dateRangeStart",
  745. rule : function(v, b) {
  746. var end = $("#" + b).val();
  747. return daysBetween(v, end);
  748. },
  749. msg : $i18n$.RULES.DATE_RANGE_START
  750. }, {
  751. // 判断日期范围{dateRangeEnd:'xx'} xx:开始时间的日期的ID
  752. name : "dateRangeEnd",
  753. rule : function(v, b) {
  754. var start = $("#" + b).val();
  755. return daysBetween(start, v);
  756. },
  757. msg : $i18n$.RULES.DATE_RANGE_END
  758. }];
  759. /**
  760. * 验证每个元素
  761. * @param me
  762. * @param el
  763. * @param validRule
  764. * @param ngModel
  765. * @param viewValue
  766. * @returns
  767. */
  768. scope._validEach = function (me,el,validRule,ngModel,viewValue){
  769. var value = '';
  770. try{
  771. value= eval('( me.'+ngModel + ')');
  772. if(value === null || value === undefined || value === '')
  773. value = '';
  774. } catch (e) {
  775. }
  776. value =viewValue?viewValue: value;
  777. if(!validRule)
  778. return '';
  779. // 获取json。
  780. var json = eval('(' + validRule + ')');
  781. //必填
  782. var isRequired = json.required;
  783. // 非必填的字段且值为空 那么直接返回成功。
  784. if ((isRequired == false || isRequired == undefined) && value == "" )
  785. return '';
  786. for (var name in json) {
  787. var validValue = json[name];
  788. var msg = me._validRules({
  789. rules:me._rules,//规则json
  790. ruleName:name,// 规则名称
  791. validValue:validValue,//验证的值
  792. value:value//实际的值
  793. },me);
  794. if (msg != '')
  795. return msg;
  796. }
  797. return '';
  798. }
  799. /**
  800. * 判断元素是否在不需要校验的范围内。
  801. */
  802. scope._isInNotValid= function(el) {
  803. var nodeName ,
  804. type = el.attr('type');
  805. if(el)
  806. nodeName = el[0].nodeName.toLowerCase();
  807. //判断是否隐藏
  808. if(type== 'checkbox' ||
  809. type == 'radio')//单选、复选
  810. el = el.parent().parent().parent().parent().parent();
  811. else if(nodeName && nodeName == 'select')//下拉
  812. el = el.parent();
  813. if(el.hasClass('uhide'))
  814. return true;
  815. //if($(obj).is(":hidden"))return true;
  816. // if (!this.excludes)
  817. // return false;
  818. // var scope = $(this.excludes, this);
  819. // var aryInput = $(
  820. // "input:text,input:hidden,textarea,select,input:checkbox,input:radio",
  821. // scope);
  822. // for (var i = 0, len = aryInput.length; i < len; i++) {
  823. // var tmp = aryInput.get(i);
  824. // if (obj == tmp) {
  825. // return true;
  826. // }
  827. // }
  828. return false;
  829. };
  830. /**
  831. * 错误提示
  832. * @param el
  833. * @param msg
  834. * @returns
  835. */
  836. scope._error = function(el,msg){
  837. var parent = el.parent(),isdate= false,controltype=el.attr("controltype") ;
  838. if(el.attr('type') == 'checkbox' ||
  839. el.attr('type') == 'radio'){//单选、复选
  840. parent = parent.parent().parent().parent().parent();
  841. if(!parent.hasClass("has-error")) {
  842. parent.addClass('has-error');
  843. }
  844. //日期格式是yyyy-MM-dd HH:mm:ss 有bug
  845. }else if(el.attr('datefmt') && (el.attr('datefmt') == 'yyyy-MM-dd HH:mm:ss'||el.attr('datefmt') == 'yyyy-MM-dd HH:mm:00' )){
  846. isdate = true;
  847. parent = parent.parent();
  848. if(!parent.hasClass("has-error")) {
  849. parent.addClass('has-error');
  850. }
  851. }else if(controltype=="input"||controltype=="textarea"){
  852. if(!parent.hasClass("has-error")) {
  853. parent.addClass('has-error');
  854. }
  855. }else if(!el.hasClass("has-error")) {
  856. el.addClass('has-error');
  857. }
  858. if(parent.parent()[0].querySelectorAll(".__cvToolTip").length==0){
  859. var tips=angular.element('<div class="__cvToolTip " style="float:right !important;" ng-show="!!text" > <div class="__cvToolTipDIV"> <span class="__cvBorderSpan"></span> <span class="__cvBackSpan"></span> </div> <div class="__cvText"> '+msg+' </div> </div>');
  860. if(controltype=="textarea"||controltype=="input"||controltype=="select" || (!isdate&&(controltype=="date" ||controltype=="time")) ){
  861. parent.parent().append(tips);
  862. tips.css({"float":"right"})
  863. }else{
  864. parent.append(tips);
  865. }
  866. }
  867. };
  868. /**
  869. * 正确提示
  870. * @param el
  871. * @returns
  872. */
  873. scope._success = function(el){
  874. var parent = el.parent(),isdate= false,controltype=el.attr("controltype") ;
  875. if(el.attr('type') == 'checkbox' ||
  876. el.attr('type') == 'radio'){//单选、复选
  877. parent = parent.parent().parent().parent();
  878. if (parent.parent().hasClass("has-error")) {
  879. parent.parent().removeClass('has-error');
  880. }
  881. }
  882. if(el.attr('datefmt') && (el.attr('datefmt') == 'yyyy-MM-dd HH:mm:ss'||el.attr('datefmt') == 'yyyy-MM-dd HH:mm:00' )){
  883. isdate = true;
  884. if (parent.parent().hasClass("has-error")) {
  885. parent.parent().removeClass('has-error');
  886. }
  887. if(controltype=="date"&&parent.next().next('div').hasClass("__cvToolTip")){
  888. parent.next().next('div').remove();
  889. }
  890. if (parent.hasClass("has-error")) {
  891. parent.removeClass('has-error');
  892. }
  893. }
  894. if (el.hasClass("has-error")) {
  895. el.removeClass('has-error');
  896. }
  897. if (parent.hasClass("has-error")) {
  898. parent.removeClass('has-error');
  899. }
  900. if (parent.parent().hasClass("has-error")) {
  901. parent.parent().removeClass('has-error');
  902. }
  903. if(controltype=="dicCombo"||el.attr("selector")=="selector"||el.attr("selector")=="file" ){
  904. parent = el;
  905. }
  906. if((!isdate&&(controltype=="date" ||controltype=="time"))){
  907. parent = el.parent();
  908. }
  909. if(el.next('div').hasClass("__cvToolTip"))
  910. el.next('div').remove();
  911. if(parent.next('div').hasClass("__cvToolTip"))
  912. parent.next('div').remove();
  913. if(parent.parent().next('div').hasClass("__cvToolTip"))
  914. parent.parent().next('div').remove();
  915. };
  916. scope._handValidResult = function(me,el,validRule,ngModel,viewValue) {
  917. // 是否在不需要验证的范围内,在的话就不需要验证。
  918. if (me._isInNotValid(el)){
  919. me._success(el);
  920. return true;
  921. }
  922. var msg = me._validEach(me,el,validRule,ngModel,viewValue);
  923. me._success(el);
  924. if (msg != '') {
  925. me._error(el,msg);
  926. return false;
  927. } else {
  928. me._success(el);
  929. return true;
  930. }
  931. };
  932. /**
  933. * 验证表单
  934. * @param conf
  935. * {
  936. * ignoreRequired: 是否忽略必填
  937. * element:angular的节点
  938. * dom: dom属性
  939. * withoutdom:
  940. * }
  941. * @returns
  942. */
  943. scope.valid = function(conf){
  944. scope.ignoreRequired= conf?((conf.ignoreRequired==undefined)?false:conf.ignoreRequired):false;
  945. var _v = true,doms=[];
  946. if(conf&&conf.element){
  947. var el =conf.element,
  948. me =el.scope(),
  949. validate = el.attr("validate"),
  950. ngModel = el.attr("ng-model");
  951. var rtn = scope._handValidResult(me,el,validate,ngModel);
  952. if (!rtn)
  953. _v = false;
  954. }else{
  955. if(conf&&conf.dom){
  956. doms = conf.dom.querySelectorAll("[validate]");
  957. }else if(conf&&conf.withoutdom){
  958. doms = document.querySelectorAll("[validate]");
  959. for(var i=0;i<conf.withoutdom.length;i++){
  960. doms = HT.getDomWithSubDom(doms,conf.withoutdom[i].querySelectorAll("[validate]"));
  961. }
  962. }else{
  963. doms = document.querySelectorAll("[validate]");
  964. }
  965. angular.forEach(doms,function(dom){
  966. var el =HT.$(dom),
  967. me =el.scope(),
  968. validate = el.attr("validate"),
  969. ngModel = el.attr("ng-model");
  970. var rtn = scope._handValidResult(me,el,validate,ngModel);
  971. if (!rtn)
  972. _v = false;
  973. });
  974. }
  975. ctrl.$setValidity("validate",_v);
  976. return _v;
  977. }
  978. //初始调用
  979. //scope._handValidResult(scope,elm,attrs,ctrl);
  980. //值更新监控
  981. ctrl.$parsers.unshift(function (viewValue) {
  982. var valid =scope._handValidResult(scope,elm,attrs.validate,attrs.ngModel,viewValue);
  983. ctrl.$setValidity("validate",valid);
  984. return viewValue;
  985. });
  986. //控件focus、blur监控
  987. ctrl.$focused = false;
  988. elm.bind("focus",function(event){
  989. var el = event.serElement|| event.target;
  990. scope.valid({element:angular.element(el)});
  991. scope.$apply(function(){
  992. ctrl.$focused = true;
  993. });
  994. }).bind("blur",function(event){
  995. var el = event.serElement|| event.target;
  996. scope.valid({element:angular.element(el)});
  997. scope.$apply(function(){
  998. ctrl.$focused = true;
  999. });
  1000. });
  1001. }
  1002. }
  1003. })
  1004. /**
  1005. * checkbox 值选中
  1006. * @param {Object} $compile
  1007. */
  1008. .directive('checkValueBind', function($compile) {
  1009. return function(scope,elm,attrs){
  1010. scope.$watch(attrs.checkValueBind,function(newVal,oldVal){
  1011. if(newVal!==oldVal){
  1012. var name = elm.attr("name"),
  1013. parent = elm.parent().parent().parent(),
  1014. brothers = parent.find("input"),
  1015. valAry = newVal.split(",");
  1016. brothers.removeAttr("check-value-bind");
  1017. angular.forEach(brothers,function(brother){
  1018. var b = angular.element(brother);
  1019. var value = b.attr("value");
  1020. b.attr("checked",false);
  1021. for(var i=0,c;c=valAry[i++];){
  1022. if(c==value){
  1023. b.attr("checked",true);
  1024. }
  1025. }
  1026. });
  1027. //$compile(parent.contents())(scope);
  1028. }
  1029. });
  1030. };
  1031. })
  1032. /**
  1033. * 日期格式化
  1034. * @param {Object} $window
  1035. */
  1036. .directive('ngDateFormat', function ($window) {
  1037. return {
  1038. require:'^ngModel',
  1039. restrict:'A',
  1040. priority:3,
  1041. link:function (scope, elm, attrs, ctrl) {
  1042. var dateFormat = attrs.ngDateFormat;
  1043. attrs.$observe('ngDateFormat', function (newValue) {
  1044. if (dateFormat == newValue || !ctrl.$modelValue) return;
  1045. dateFormat = newValue;
  1046. ctrl.$modelValue = new Date(ctrl.$setViewValue);
  1047. });
  1048. ctrl.$formatters.unshift(function (modelValue) {
  1049. scope = scope;
  1050. if (!dateFormat || !modelValue) return "";
  1051. var retVal = "";
  1052. if(!HT.isDate(modelValue)){//判断是否是日期 TODO
  1053. //不是日期则把当前值转为日期
  1054. if(HT.isOnlyTime(modelValue)){
  1055. retVal = modelValue.substring(0,modelValue.lastIndexOf(":"));
  1056. }else{
  1057. retVal = HT.date(modelValue,dateFormat);
  1058. }
  1059. }else{
  1060. retVal = modelValue.Format(dateFormat);
  1061. }
  1062. ctrl.$render();
  1063. return retVal;
  1064. });
  1065. ctrl.$parsers.unshift(function (viewValue) {
  1066. scope = scope;
  1067. var date = new Date(viewValue);
  1068. var tempDate = date.Format("yyyy-MM-dd HH:mm:ss");
  1069. return (date && date.getFullYear() > 1950 ) ? tempDate : "";
  1070. });
  1071. }
  1072. };
  1073. })
  1074. /**
  1075. * 监听时间改变后的格式化
  1076. * @param {Object} $parse
  1077. */
  1078. .directive('ngDateChange', function ($parse) {
  1079. return {
  1080. require:'^ngModel',
  1081. restrict:'A',
  1082. priority:2,
  1083. link:function (scope, elm, attrs, ctrl) {
  1084. var proxyExp = attrs.ngDateChange;
  1085. var modelExp = attrs.ngModel;
  1086. scope.$watch(proxyExp, function (nVal,oVal) {
  1087. if (nVal != oVal)
  1088. $parse(modelExp).assign(scope, nVal);
  1089. });
  1090. }
  1091. };
  1092. })
  1093. .directive('controltype', function($compile,$timeout){
  1094. return {
  1095. restrict: 'A',
  1096. scope: {},
  1097. priority:1,
  1098. link:function(scope,element,attrs){
  1099. var wrap="";
  1100. var html="";
  1101. switch(attrs.controltype){
  1102. case "radio":
  1103. element.addClass("uhide");
  1104. if(attrs.readonly){
  1105. element.parent().parent().parent().find("li").eq(0).addClass('t-disable');
  1106. }else{
  1107. element.parent().parent().attr({
  1108. "onclick": "zy_for_input(event)",
  1109. "ontouchstart": "zy_touch('c-foc')"
  1110. });
  1111. }
  1112. wrap='<div class="uba_whi h22""></div>';
  1113. html = '<div class="ub c-m2"><div class="ub-f1 ut-s tx-l"></div><div class="icon-radio ub-img umw2 umh2"></div></div>' ;
  1114. element.wrap(wrap).after(html);
  1115. if(attrs.checked)element[0].checked = "checked";
  1116. break;
  1117. case "checkbox":
  1118. element.addClass("uhide");
  1119. var ul = element.parent().parent();
  1120. ul.attr({
  1121. "onclick": "zy_for_input(event)",
  1122. "ontouchstart": "zy_touch('c-foc')"
  1123. });
  1124. wrap='<div class="uba_whi h22""></div>';
  1125. html = '<div class="ub c-m2"><div class="ub-f1 ut-s tx-l"></div><div class="icon-checkbox ub-img umw2 umh2"></div></div>' ;
  1126. element.wrap(wrap).after(html);
  1127. break;
  1128. case "date":
  1129. if(element.attr("ng-date-format")) return;
  1130. if(element.attr("wrap")){
  1131. element.parent().addClass("ub-f1").addClass("time-div").addClass("w95").addClass("mar-t043").removeClass("t-right").removeClass("umar-l1").removeClass("mar-t-03");
  1132. element.addClass("user-c-bd");
  1133. element.parent().parent().addClass("ub-ver");
  1134. var preli=element.parent().parent().find("li").eq(0);
  1135. preli.addClass("ub-f1").addClass("w100");
  1136. }
  1137. var dateWrap=' <div class="ub uc-a1 b-ddd uinput ub-ac h22" ontouchstart="zy_touch(\'\')" onclick="HT.getDate(event)">' +
  1138. ' </div>';
  1139. var timeWrap=' <div class="ub uc-a1 b-ddd uinput ub-ac h22" ontouchstart="zy_touch(\'\')" onclick="HT.getTime(event)">' +
  1140. ' </div>';
  1141. var html ='<div class="icon-calendar2 ">'+
  1142. '</div>';
  1143. var dateFmt=attrs.datefmt;
  1144. //时间的格式
  1145. var formatArrs=["yyyy-MM-dd","yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm:00","HH:mm:ss"];
  1146. //设置默认格式为yyyy-MM-dd
  1147. dateFmt=dateFmt?dateFmt:"yyyy-MM-dd";
  1148. var ngModel=attrs.ngModel;
  1149. element.attr({"ng-date-change":ngModel});
  1150. element.addClass("ub-f1").addClass("ipt-date").css("text-align","left");
  1151. switch(dateFmt) {
  1152. case formatArrs[0]:
  1153. element.wrap(dateWrap).after(html);
  1154. element.attr("ng-date-format",formatArrs[0]);
  1155. element.attr("ng-date-format","yyyy-MM-dd");
  1156. break;
  1157. case formatArrs[1]:
  1158. case formatArrs[2]:
  1159. var elementTemp=element.clone().attr({"controltype":"time","ng-date-format":"hh:mm","ng-date-change":ngModel});
  1160. // (elementTemp.wrap(timeWrap).after(html).parent().addClass("umar-t")).parent().after(element.wrap(dateWrap).after(html));
  1161. (element.wrap(dateWrap).after(html)).parent().after(elementTemp.wrap(timeWrap).after(html).parent().addClass("umar-t"));
  1162. element.attr({"ng-date-format":formatArrs[0]});
  1163. elementTemp.addClass("ub-f1").addClass("ipt-date").css("text-align","left");
  1164. $compile(elementTemp)(scope.$parent);
  1165. break;
  1166. case formatArrs[3]:
  1167. element.wrap(timeWrap).after(html);
  1168. element.attr("ng-date-format","hh:mm");
  1169. break;
  1170. }
  1171. $compile(element)(scope.$parent);
  1172. break;
  1173. case "select":
  1174. wrap=' <div class="ub uba uc-a1 c-wh b-ddd tx-r h22 uof-x"></div>';
  1175. html ='<div class="ub-f1 "></div><div class="ubl b-ddd c-wh z-index1 umw2 ub ub-pc uc-r1 ub-ac" onclick="HT.triggerSelect();"><div class="ub-img icon-caret-down ulev1"></div></div>';
  1176. element.wrap(wrap).addClass("select").parent().prepend(html);
  1177. break;
  1178. case "file":
  1179. // element.parent().addClass("user-c-bd").addClass("ub-f1").addClass("w95").removeClass("t-right").removeClass("umar-l1").removeClass("mar-t-03");
  1180. // var pui=element.parent().parent();
  1181. // pui.addClass("ub-ver");
  1182. // var preli=element.parent().parent().find("li").eq(0);
  1183. // preli.addClass("ub-f1").addClass("w100");
  1184. //
  1185. // wrap=' <div class="ub uc-a1 b-ddd uinput ub-ac ub" ontouchstart="zy_touch(\'\')" onclick="HT.openFilePicter(true,event);"></div>';
  1186. // html ='<div class="filec ub"><div class="icon-plus5 ub-f1 center mar-t05"></div></div>';
  1187. // element.removeClass("mr42");
  1188. // element.wrap(wrap).after(html);
  1189. break;
  1190. case "input":
  1191. if (element.attr("wrap")) {
  1192. element.parent().addClass("user-c-bd").addClass("ub-f1").addClass("w95").removeClass("t-right").removeClass("umar-l1").removeClass("mar-t-03");
  1193. var pui = element.parent().parent();
  1194. pui.addClass("ub-ver");
  1195. var preli = element.parent().parent().find("li").eq(0);
  1196. preli.addClass("ub-f1").addClass("w100");
  1197. }
  1198. wrap=' <div class="ub uc-a1 b-ddd uinput ub-ac h22"></div>';
  1199. element.addClass("t-left").addClass("t-888");
  1200. element.wrap(wrap);
  1201. break;
  1202. case "textarea":
  1203. if (element.attr("wrap")) {
  1204. element.parent().addClass("user-c-bd").addClass("ub-f1").addClass("w95").removeClass("t-right").removeClass("umar-l1").removeClass("mar-t-03");
  1205. var pui = element.parent().parent();
  1206. pui.addClass("ub-ver");
  1207. var preli = element.parent().parent().find("li").eq(0);
  1208. preli.addClass("ub-f1").addClass("w100");
  1209. }
  1210. wrap='<div class=" uc-a1 b-ddd uinput uinn4"></div>';
  1211. element.addClass("t-888");
  1212. element.wrap(wrap);
  1213. break;
  1214. case "toggle":
  1215. wrap='<div class="toggle toggle-positive ufr" onclick="zy_for_input(event)" ontouchstart="zy_touch(\'\')"></div>';
  1216. html =' <div class="track"><div class="icon-check t-wh mar-t02 mar-l02 absolute"></div><div class="handle"></div><div class="icon-times2 t-wh mar-t02 mar-r02"></div></div>';
  1217. element.wrap(wrap).after(html);
  1218. break;
  1219. }
  1220. }
  1221. };
  1222. })
  1223. .directive('file', function() {
  1224. return {
  1225. restrict: 'E',
  1226. transclude: true,
  1227. scope: {},
  1228. controller: function($scope,$attrs,$element,baseService) {
  1229. $scope.files = [];
  1230. $scope.ngModel=$attrs.ngModel;
  1231. $scope.mutil = $attrs.mutil||"true";
  1232. $scope.readonly = true;
  1233. if($attrs.write&&$attrs.write=='true'){
  1234. $scope.readonly = false;
  1235. }
  1236. $scope.wrap = function(){
  1237. $element.parent().addClass("user-c-bd").addClass("ub-f1").addClass("w95").removeClass("t-right").removeClass("umar-l1").removeClass("mar-t-03");
  1238. var pui = $element.parent().parent();
  1239. pui.addClass("ub-ver");
  1240. var preli = $element.parent().parent().find("li").eq(0);
  1241. preli.addClass("ub-f1").addClass("w100");
  1242. }
  1243. $scope.open = function(ngModel){
  1244. HT.fileTarget.scope=$scope.$parent;
  1245. HT.fileTarget.ngModel=ngModel;
  1246. var html = '<div id="fileDiv" targatname="" class="ub ub-ver c-192 w100 h100" > <div class="ub-f1 ub c-wh b-radius03"> <div class="ub ub-ver ub-f1 relative" onclick="HT.multiExplorerFile();" id="__filePic" ontouchstart="zy_touch(\'\')"> <div class="ub ub-f3 ub-ver center"> <div class="ub-f1 file"> <span class="icon-folder2 center t-109 pad-t08 f-sz2"></span> </div> </div> <div class="ub ub-f1 ub-ver center mra-t-2" > <div class="ub-f1"> <span class="center t-109 ">'+$i18n$.FILE.FILES+'</span> </div> </div> </div> <div class="ub ub-ver ub-f1 relative" onclick="HT.openBrowser();" id="__photoPic" ontouchstart="zy_touch(\'\')"> <div class="ub ub-f3 ub-ver center"> <div class="ub-f1 file"> <span class="icon-pictures center t-109 pad-t08 f-sz2" ></span> </div> </div> <div class="ub ub-f1 ub-ver center mra-t-2"> <div class="ub-f1"> <span class="center t-109 ">'+$i18n$.FILE.PICTURE+'</span> </div> </div> </div> </div> </div>';
  1247. baseService.openDialog({
  1248. title: $i18n$.FILE.UPLOAD,
  1249. html: html,
  1250. buttons: [{
  1251. label: $i18n$.COMMON.CANCEL,
  1252. callback: function(){
  1253. baseService.closeDialog();
  1254. }
  1255. }]
  1256. })
  1257. }
  1258. /**
  1259. * //TODO 通过fileId获取用户信息,首先从常用联系人中获取,没有则从服务器获取
  1260. * @param file
  1261. * @returns
  1262. */
  1263. $scope.displayDetail = function(file){
  1264. var buttons = [{
  1265. label: $i18n$.COMMON.CANCEL,
  1266. callback: function(){
  1267. baseService.closeDialog();
  1268. }
  1269. }]
  1270. var showdialog = function(u, buttons, digest){
  1271. var html = '<ul ontouchstart="zy_touch()" class="ub ubb b-ddd t-bla ub-ac lis h275"><li class="ut-s t-111 f-sz10625">文件名</li><li class="ub-f1 ulev-app1 t-888 t-right">' + file.name +
  1272. '</li></ul><ul ontouchstart="zy_touch()" class=" ub t-bla ub-ac lis h275"><li class="ut-s t-111 f-sz10625">文件ID</li><li class="ub-f1 ulev-app1 t-888 t-right">' +
  1273. file.id +
  1274. '</li></ul>';
  1275. baseService.openDialog({
  1276. title: $i18n$.FILE.FILEINFO,
  1277. html: html,
  1278. digest: digest,
  1279. buttons: buttons
  1280. });
  1281. }
  1282. showdialog(file,buttons,false);
  1283. };
  1284. if ($attrs.wrap)
  1285. $scope.wrap();
  1286. },
  1287. template:'<div class="ub uc-a1 b-ddd ub-ac pad040" selector="file"><div id="{{flag}}" class="mar-rl0a ub ub-ac w100">'
  1288. +'<div class="ub ub-ver ub-f1 ut-s t-left mar-r0125" >'
  1289. +'<span class="info-span ut-s ub-f1 filespan mar-r0125 mar-t0125" ng-repeat="file in files" style="border: 1px solid #219a52;background-color: #2dcd70;max-width: 8em;float:left;" ng-click="displayDetail(file)">'
  1290. +'<span ontouchstart="zy_touch()" ontouchstart="zy_touch(\'c-gra\') class="umar-r05 no-break ut-s">'
  1291. +'{{file.name}}</div>'
  1292. +'</span></span>'
  1293. +'<div class="h256 w3" ontouchstart="zy_touch(\'\')" ng-click="open(ngModel)"><div class="filec ub f-r"><div class="icon-plus5 ub-f1 center mar-t05"></div></div></div>',
  1294. replace: true
  1295. };
  1296. })
  1297. /**
  1298. * 选择器值监听
  1299. */
  1300. .directive('selector', function($compile) {
  1301. return {
  1302. restrict: 'A',
  1303. priority:4,
  1304. link:function (scope, elm, attrs, ctrl) {
  1305. //修改该方法要修改util.addSubTableCol()
  1306. var parentScope = scope.$parent;
  1307. if(attrs.selector=="selector"){
  1308. parentScope.$watch(attrs.refid,function(newVal,oldVal){
  1309. var ary = [];
  1310. if(oldVal&&newVal==oldVal)return;
  1311. if (newVal) {
  1312. if (!HT.isStirng(newVal))
  1313. newVal = new String(newVal);
  1314. var ids = newVal.split(',');
  1315. var name = 'parentScope.' + attrs.ngModel;
  1316. var nameStr = eval('(' + name + ')');
  1317. var uns = nameStr.split(',');
  1318. var count = ids.length;
  1319. for (var i = 0; i < count; i++) {
  1320. var id = ids[i], un = uns[i];
  1321. if(un){
  1322. ary.push({
  1323. "id": id,
  1324. "un": un
  1325. });
  1326. }
  1327. }
  1328. }
  1329. scope.users = ary;
  1330. parentScope.valid();
  1331. });
  1332. }else if(attrs.selector=="file"){
  1333. parentScope.$watch(attrs.ngModel,function(newVal,oldVal){
  1334. if(!newVal||newVal.indexOf("¥@@¥")==-1)return;
  1335. var jsonArr=eval(newVal.replaceAll("¥@@¥","\""));
  1336. if(scope.files.length>0){
  1337. scope.files=jsonArr;
  1338. }else{
  1339. for(var i=0;i<jsonArr.length;i++){
  1340. var id = jsonArr[i].id,
  1341. name = jsonArr[i].name;
  1342. scope.files.push({"id":id,"name":name});
  1343. }
  1344. }
  1345. parentScope.valid();
  1346. });
  1347. }
  1348. }
  1349. };
  1350. })
  1351. /**
  1352. * 查询展示
  1353. */
  1354. .directive('ngSearch', function($compile) {
  1355. return {
  1356. restrict: 'A',
  1357. link:function (scope, elm, attrs, ctrl) {
  1358. scope.keywords = "" ;
  1359. scope.reload=function(){
  1360. scope.keywords="";
  1361. scope.search();
  1362. }
  1363. scope.$watch(attrs.ngSearch, function(newVal, oldVal) {
  1364. if(!HT.isEmpty(newVal))
  1365. scope._disclick=false;
  1366. else
  1367. scope._disclick=true;
  1368. });
  1369. }
  1370. }
  1371. })
  1372. /**
  1373. * 监听Modal的改变状态
  1374. */
  1375. .directive('eventModal', function($compile,$injector) {
  1376. return {
  1377. restrict: 'A',
  1378. link:function (scope, elm, attrs, ctrl) {
  1379. scope.baseService = $injector.get("baseService");
  1380. scope.$watch('baseService', function(newVal, oldVal) {
  1381. if (newVal !== oldVal&&!newVal.hasModal) {
  1382. HT.addModalToParent();
  1383. }else{
  1384. HT.hideModalFromParent();
  1385. }
  1386. }, true);
  1387. }
  1388. }
  1389. })
  1390. /**
  1391. * 监听是否点击过搜索按钮,如果有,则显示reload按钮。否则隐藏
  1392. */
  1393. .directive('ngSearchCancel', function($compile) {
  1394. return {
  1395. restrict: 'A',
  1396. link:function (scope, elm, attrs, ctrl) {
  1397. scope.$watch(attrs.ngSearchCancel, function(newVal, oldVal) {
  1398. if(newVal)
  1399. elm.removeClass("uhide");
  1400. if(!newVal&&attrs.allownull)
  1401. elm.addClass("uhide");
  1402. });
  1403. }
  1404. }
  1405. })
  1406. /**
  1407. * 当list数据为空时,设置空页面
  1408. */
  1409. .directive('ngNullPage', function($compile) {
  1410. return {
  1411. restrict: 'A',
  1412. link:function (scope, elm, attrs, ctrl) {
  1413. var text=attrs.nullText?attrs.nullText:$i18n$.COMMON.NULL_PAGE_PULL_RELOAD;
  1414. if(attrs.isForm) text='<div style="z-index: 1000;background-color: rgba(3, 0, 0, 0.3);padding: 0.625em;color: white;margin-top: 20%;border-radius: 3%;"><div class="icon-spinner" style="display:-webkit-inline-box;"></div><span>'+$i18n$.COMMON.WATTING_MSG+'</span></div>';
  1415. var nullpic=attrs.nullPic?attrs.nullPic:'icon-smiley';
  1416. elm.parent().append("<div class=' pad-t30 t-gra uhide' id='ngNullPage'><div class='"+nullpic+" center f-sz3'></div><div class='center'>"+text+"</div></div>");
  1417. var ngNullPage=HT.$($$("ngNullPage"));
  1418. scope.$watch(attrs.ngNullPage, function(newVal, oldVal) {
  1419. if((newVal&&newVal.length==0)||(attrs.isText&&!newVal)){
  1420. elm.addClass("uhide");
  1421. ngNullPage.removeClass("uhide");
  1422. }else{
  1423. elm.removeClass("uhide");
  1424. ngNullPage.addClass("uhide");
  1425. }
  1426. });
  1427. }
  1428. }
  1429. }).directive('modalDialog', function() {
  1430. return {
  1431. restrict: 'E',
  1432. scope: {
  1433. show: '='
  1434. },
  1435. replace: true, // Replace with the template below
  1436. transclude: true, // we want to insert custom content inside the directive
  1437. link: function(scope, element, attrs) {
  1438. scope.dialogStyle = {};
  1439. if (attrs.width) scope.dialogStyle.width = attrs.width;
  1440. if (attrs.height) scope.dialogStyle.height = attrs.height;
  1441. scope.hideModal = function() {
  1442. scope.show = false;
  1443. };
  1444. },
  1445. template: '<div class="ng-modal " ng-show="show">'
  1446. +'<div ontouchstart="zy_touch()" class="ng-modal-overlay"></div>'
  1447. +'<div class="ng-modal-dialog" ng-style="dialogStyle">'
  1448. +'<div class="ng-modal-dialog-content" ng-transclude></div>'
  1449. +'</div>'
  1450. +'</div>'
  1451. };
  1452. });