searchgrid.js 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. //快速检索下拉列表
  2. (function($){
  3. function createpage(target){
  4. var grid = $.data(target,'searchgrid').grid;
  5. var opts = $.data(target, 'searchgrid').options;
  6. if(!opts.localdb && !opts.remotedb){
  7. $('.searchgrid-pages',grid).hide();
  8. return true;
  9. }
  10. var pageCount = Math.ceil(opts.total/opts.pageSize);
  11. var pages = $('.searchgrid-pages .searchgrid-pages-inner',grid);
  12. pages.html('');
  13. var table = $('<table style="width:100%;"></table>').appendTo(pages);
  14. var tr = $('<tr></tr>').appendTo(table);
  15. $('<td width="10px"></td>').appendTo(tr);
  16. $('<td width="30px"><a href="javascript:void(0)" icon="FisrtPage" >首页</a></td>').appendTo(tr);
  17. $('<td width="30px"><a href="javascript:void(0)" icon="PrevPage" >上页</a></td>').appendTo(tr);
  18. $('<td width="30px"><a href="javascript:void(0)" icon="NextPage" >下页</a></td>').appendTo(tr);
  19. $('<td width="30px"><a href="javascript:void(0)" icon="LastPage" >尾页</a></td>').appendTo(tr);
  20. $('<td><span></span></td>').appendTo(tr);
  21. $('<td width="150px" align="right" ><span icon="PageInfo"></span></td>').appendTo(tr);
  22. pages.find('a[icon=FisrtPage]').unbind('.searchgrid').bind('click.searchgrid', function(){
  23. if (opts.pageNumber > 1) selectPage(target, 1);
  24. });
  25. pages.find('a[icon=PrevPage]').unbind('.searchgrid').bind('click.searchgrid', function(){
  26. if (opts.pageNumber > 1) selectPage(target, opts.pageNumber - 1);
  27. });
  28. pages.find('a[icon=NextPage]').unbind('.searchgrid').bind('click.searchgrid', function(){
  29. var pageCount = Math.ceil(opts.total/opts.pageSize);
  30. if (opts.pageNumber < pageCount) selectPage(target, opts.pageNumber + 1);
  31. });
  32. pages.find('a[icon=LastPage]').unbind('.searchgrid').bind('click.searchgrid', function(){
  33. var pageCount = Math.ceil(opts.total/opts.pageSize);
  34. if (opts.pageNumber < pageCount) selectPage(target, pageCount);
  35. });
  36. }
  37. function selectPage(target, pageCount){
  38. var opts = $.data(target, 'searchgrid').options;
  39. var input = $.data(target,'searchgrid').input;
  40. opts.pageclick =true;
  41. opts.pageNumber = pageCount;
  42. if( opts.localdb){
  43. LoadLocalData(target,input.val(),opts.querySQL);
  44. }else{
  45. request(target,input.val());
  46. }
  47. }
  48. function showPageInfo(target){
  49. var grid = $.data(target, 'searchgrid').grid;
  50. var pages = $('.searchgrid-pages .searchgrid-pages-inner',grid);
  51. var span = pages.find('span[icon=PageInfo]');
  52. var opts = $.data(target, 'searchgrid').options;
  53. var pageCount = Math.ceil(opts.total/opts.pageSize);
  54. span.html('第 '+opts.pageNumber+'/'+pageCount+' 页 共 '+opts.total+' 行');
  55. }
  56. function setSize(target) {
  57. var grid = $.data(target, 'searchgrid').grid;
  58. var opts = $.data(target, 'searchgrid').options;
  59. var box = $.data(target, 'searchgrid').input;
  60. var gridWidth = opts.width;
  61. if (gridWidth == 'auto') {
  62. /*以表头的宽度作为总体的宽度*/
  63. gridWidth = grid.find('table').outerWidth()+20;
  64. }else{
  65. gridWidth = parseInt(gridWidth);
  66. }
  67. grid.find('div.searchgrid-body').width(gridWidth);
  68. var innerWidth = gridWidth;
  69. innerWidth = gridWidth - grid.outerWidth() + grid.width();
  70. //设置左上角位置(考虑屏幕边界截屏的问题)
  71. if(box.offset().left+gridWidth>$(window).width()){
  72. grid.css({
  73. left:$(window).width()-gridWidth-3,/*加3预防window出现水平滚动栏*/
  74. top:box.offset().top + 22
  75. });
  76. }else{
  77. grid.css({
  78. left:box.offset().left,
  79. top:box.offset().top + 22
  80. });
  81. }
  82. $('div.searchgrid-view', grid).width(innerWidth);
  83. if (opts.height == 'auto') {
  84. $('div.searchgrid-body', grid).height(200);
  85. } else {
  86. $('div.searchgrid-body', grid).height(
  87. opts.height
  88. - (grid.outerHeight() - grid.height())
  89. - $('div.searchgrid-header', grid).outerHeight(true)
  90. - $('div.searchgrid-title', grid).outerHeight(true)
  91. );
  92. }
  93. var header = $('.searchgrid-view div.searchgrid-header',grid);
  94. header.width(innerWidth);
  95. };
  96. /**
  97. * wrap and return the grid object, fields and columns
  98. */
  99. function wrapGrid(target, rownumbers) {
  100. var grid = jQuery('<div class="searchgrid"></div>').appendTo('body');
  101. grid.append(
  102. '<div class="searchgrid-wrap">' +
  103. '<div class="searchgrid-view">' +
  104. '<div class="searchgrid-header">' +
  105. '<div class="searchgrid-header-inner"></div>' +
  106. '</div>' +
  107. '<div class="searchgrid-body">' +
  108. '<table border="0" cellspacing="0" cellpadding="0"></table></div>' +
  109. '<div class="searchgrid-pages">' +
  110. '<div class="searchgrid-pages-inner"></div>' +
  111. '</div>' +
  112. '</div>' +
  113. '</div>'
  114. );
  115. function getColumns(thead){
  116. var columns = [];
  117. $('tr', thead).each(function(){
  118. var cols = [];
  119. $('td', this).each(function(){
  120. var th = $(this);
  121. var col = {
  122. title: th.html(),
  123. align: th.attr('align') || 'left',
  124. sortable: th.attr('sortable')=='true' || false,
  125. checkbox: th.attr('checkbox')=='true' || false
  126. };
  127. if (th.attr('field')) {
  128. col.field = th.attr('field');
  129. }
  130. if (th.attr('formatter')){
  131. col.formatter = eval(th.attr('formatter'));
  132. }
  133. if (th.attr('rowspan')) col.rowspan = parseInt(th.attr('rowspan'));
  134. if (th.attr('colspan')) col.colspan = parseInt(th.attr('colspan'));
  135. if (th.attr('width')) col.width = parseInt(th.attr('width'));
  136. cols.push(col);
  137. });
  138. columns.push(cols);
  139. });
  140. return columns;
  141. }
  142. return {
  143. grid: grid,
  144. frozenColumns: null,
  145. columns: null
  146. };
  147. }
  148. function createColumnHeader(target){
  149. var opts = $.data(target, 'searchgrid').options;
  150. var columns = opts.columns;
  151. var width = opts.width;
  152. var t = $('<table border="0" cellspacing="0" cellpadding="0"><thead></thead></table>');
  153. for(var i=0; i<columns.length; i++) {
  154. var tr = $('<tr></tr>').appendTo($('thead', t));
  155. var cols = columns[i];
  156. for(var j=0; j<cols.length; j++){
  157. var col = cols[j];
  158. if(typeof col.width=='undefined'){
  159. col.width = Math.ceil(col.title.length*15)+10;
  160. opts.columns[i][j].width = col.width;
  161. }
  162. opts.headwidth = opts.headwidth + parseInt(col.width,10);
  163. var attr = '';
  164. if (col.rowspan) attr += 'rowspan="' + col.rowspan + '" ';
  165. if (col.colspan) attr += 'colspan="' + col.colspan + '" ';
  166. var th = $('<td ' + attr + '></td>').appendTo(tr);
  167. if(col.field){
  168. th.append('<div class="searchgrid-cell"><span class="spancolumn"></span></div>');
  169. th.attr('field', col.field);
  170. $('.searchgrid-cell', th).width(col.width);
  171. $('span', th).html(col.title);
  172. } else {
  173. th.append('<div class="searchgrid-cell-group"></div>');
  174. $('.searchgrid-cell-group', th).html(col.title);
  175. }
  176. }
  177. }
  178. return t;
  179. }
  180. /**
  181. * set the common properties
  182. */
  183. function setProperties(target) {
  184. var grid = $.data(target, 'searchgrid').grid;
  185. var opts = $.data(target, 'searchgrid').options;
  186. var data = $.data(target, 'searchgrid').data;
  187. if (opts.striped) {
  188. $('.searchgrid-view .searchgrid-body tr:odd', grid).addClass('searchgrid-row-alt');
  189. }
  190. if (opts.nowrap == false) {
  191. $('.searchgrid-body .searchgrid-cell', grid).css('white-space', 'normal');
  192. }
  193. $('.searchgrid-header td:has(.searchgrid-cell)', grid).hover(
  194. function(){$(this).addClass('searchgrid-header-over');},
  195. function(){$(this).removeClass('searchgrid-header-over');}
  196. );
  197. $('.searchgrid-body tr', grid).unbind();
  198. $('.searchgrid-body tr', grid).mouseover(function(){
  199. var index = $(this).attr('searchgrid-row-index');
  200. $('.searchgrid-body tr[searchgrid-row-index='+index+']',grid).addClass('searchgrid-row-over');
  201. }).mouseout(function(){
  202. var index = $(this).attr('searchgrid-row-index');
  203. $('.searchgrid-body tr[searchgrid-row-index='+index+']',grid).removeClass('searchgrid-row-over');
  204. }).click(function(){
  205. var index;
  206. $('.searchgrid-view .searchgrid-body tr.searchgrid-row-selected', grid).each(function(){
  207. index = parseInt($(this).attr('searchgrid-row-index'));
  208. });
  209. if(index>0||index==0){
  210. unselectRow(target, index);
  211. };
  212. index = $(this).attr('searchgrid-row-index');
  213. selectRow(target, index);
  214. grid.hide();
  215. setValues(target);
  216. });
  217. var body = $('.searchgrid-view .searchgrid-body', grid);
  218. var header = $('.searchgrid-view .searchgrid-header', grid);
  219. body.scroll(function(){
  220. header.scrollLeft(body.scrollLeft());
  221. });
  222. }
  223. function getColumnOption(target, field){
  224. var opts = $.data(target, 'searchgrid').options;
  225. if (opts.columns){
  226. for(var i=0; i<opts.columns.length; i++){
  227. var cols = opts.columns[i];
  228. for(var j=0; j<cols.length; j++){
  229. var col = cols[j];
  230. if (col.field == field){
  231. return col;
  232. }
  233. }
  234. }
  235. }
  236. return null;
  237. }
  238. /**
  239. * get column fields which will be show in row
  240. */
  241. function getColumnFields(columns){
  242. if (columns.length == 0) return [];
  243. function getFields(ridx,cidx,count){
  244. var fields = [];
  245. while(fields.length < count){
  246. var col = columns[ridx][cidx];
  247. if (col.colspan && parseInt(col.colspan)>1){
  248. var ff = getFields(ridx+1, getSubColIndex(ridx,cidx), parseInt(col.colspan));
  249. fields = fields.concat(ff);
  250. } else if (col.field){
  251. fields.push(col.field);
  252. }
  253. cidx++;
  254. }
  255. return fields;
  256. }
  257. function getSubColIndex(ridx, cidx){
  258. var index = 0;
  259. for(var i=0; i<cidx; i++){
  260. var colspan = parseInt(columns[ridx][i].colspan || '1');
  261. if (colspan > 1){
  262. index += colspan;
  263. }
  264. }
  265. return index;
  266. }
  267. var fields = [];
  268. for(var i=0; i<columns[0].length; i++){
  269. var col = columns[0][i];
  270. if (col.colspan && parseInt(col.colspan)>1){
  271. var ff = getFields(1, getSubColIndex(0,i), parseInt(col.colspan));
  272. fields = fields.concat(ff);
  273. } else if (col.field){
  274. fields.push(col.field);
  275. }
  276. }
  277. return fields;
  278. }
  279. /**
  280. * load data to the grid
  281. */
  282. function loadData(target, data){
  283. var grid = $.data(target, 'searchgrid').grid;
  284. var opts = $.data(target, 'searchgrid').options;
  285. var selectedRows = $.data(target, 'searchgrid').selectedRows;
  286. var rows = data.rows;
  287. var headers = data.headers;
  288. opts.total = data.total;
  289. var getWidthDelta = function(){
  290. var headerCell = $('.searchgrid-header .searchgrid-cell:first');
  291. var headerDelta = headerCell.outerWidth() - headerCell.width();
  292. var t = $('.searchgrid-body table', grid);
  293. t.append($('<tr><td><div class="searchgrid-cell"></div></td></tr>'));
  294. var bodyCell = $('.searchgrid-cell', t);
  295. var bodyDelta = bodyCell.outerWidth() - bodyCell.width();
  296. return headerDelta - bodyDelta;
  297. };
  298. var widthDelta = getWidthDelta();
  299. function getTBody(fields, rownumbers){
  300. var tbody = ['<tbody>'];
  301. for(var i=0; i<rows.length; i++) {
  302. var row = rows[i];
  303. if (i % 2 && opts.striped){
  304. tbody.push('<tr searchgrid-row-index="' + i + '" class="searchgrid-row-alt');
  305. } else {
  306. tbody.push('<tr searchgrid-row-index="' + i + '" class="');
  307. }
  308. tbody.push('">');
  309. for(var j=0; j<fields.length; j++){
  310. var field = fields[j];
  311. var col ;
  312. if(data.headers){
  313. col = getColumnOption(target, (j+1)+"");
  314. }else{
  315. col = getColumnOption(target, field);
  316. }
  317. if (col){
  318. var style = 'width:' + col.width + 'px;';
  319. style += 'text-align:' + (col.align || 'left');
  320. tbody.push('<td class="searchgrid-column-' + field + '">');
  321. tbody.push('<div style="' + style + '" ');
  322. tbody.push('class="searchgrid-cell ');
  323. tbody.push('">');
  324. var value = row['_DIC_'+field];
  325. if(value == null){
  326. value = row[field];
  327. }
  328. if (col.formatter){
  329. tbody.push(col.formatter(value, row));
  330. } else {
  331. tbody.push(value);
  332. }
  333. tbody.push('</div>');
  334. tbody.push('</td>');
  335. }
  336. }
  337. tbody.push('</tr>');
  338. }
  339. tbody.push('</tbody>');
  340. return tbody.join('');
  341. }
  342. $('.searchgrid-body, div.searchgrid-header', grid).scrollLeft(0).scrollTop(0);
  343. //重写列头field属性
  344. var fields = getColumnFields(opts.columns);
  345. var headers = null;
  346. if(data.headers){
  347. headers = data.headers.slice(0,fields.length);
  348. }else{
  349. headers = fields;
  350. }
  351. $('.searchgrid-view .searchgrid-body table', grid).html(getTBody(headers));
  352. $.data(target, 'searchgrid').data = data;
  353. setSize(target);
  354. setProperties(target);
  355. if(data.rows&&data.rows.length>0){
  356. //有数据才去选择第一行
  357. selectRow(target,0);
  358. }
  359. }
  360. function getSelectedRows(target){
  361. var opts = $.data(target, 'searchgrid').options;
  362. var grid = $.data(target, 'searchgrid').grid;
  363. var data = $.data(target, 'searchgrid').data;
  364. if (opts.idField){
  365. return $.data(target, 'searchgrid').selectedRows;
  366. }
  367. var rows = [];
  368. $('.searchgrid-view .searchgrid-body tr.searchgrid-row-selected', grid).each(function(){
  369. var index = parseInt($(this).attr('searchgrid-row-index'));
  370. if (data.rows[index]){
  371. rows.push(data.rows[index]);
  372. }
  373. });
  374. return rows;
  375. }
  376. /**
  377. * clear all the selection records
  378. */
  379. function clearSelections(target){
  380. var grid = $.data(target, 'searchgrid').grid;
  381. $('.searchgrid-body tr.searchgrid-row-selected', grid).removeClass('searchgrid-row-selected');
  382. $('.searchgrid-body .searchgrid-cell-check input[type=checkbox]', grid).attr('checked', false);
  383. var selectedRows = $.data(target, 'searchgrid').selectedRows;
  384. while(selectedRows.length > 0){
  385. selectedRows.pop();
  386. }
  387. }
  388. //处理键盘上下左右键
  389. function inputRow(target,step){
  390. var grid = $.data(target, 'searchgrid').grid;
  391. var opts = $.data(target, 'searchgrid').options;
  392. var index=0;
  393. var iPre=-1;
  394. var iNext=-2;
  395. var iTemp=0;
  396. $('.searchgrid-view .searchgrid-body tr.searchgrid-row-selected', grid).each(function(){
  397. index = parseInt($(this).attr('searchgrid-row-index'),10);
  398. });
  399. //获取可见的行
  400. $('.searchgrid-view .searchgrid-body tr:visible', grid).each(function(){
  401. iTemp = parseInt($(this).attr('searchgrid-row-index'),10);
  402. if(iNext==-1){iNext=iTemp;return false;}
  403. if(iTemp==index){
  404. if(step==-1){return false;}
  405. if(step==1){iNext=-1;}//标记下一条记录在下次循环时调用
  406. }
  407. iPre = iTemp; //上一条记录
  408. });
  409. //若已选的可见行是最后一行那么就不用选
  410. if(iNext==0||iNext==-1){return true;}
  411. //若已选的可见行是第一行那么就不用选
  412. if(iPre==-1){iPre=index;return true;}
  413. unselectRow(target,index);
  414. if(step==1){
  415. selectRow(target,iNext);
  416. }else{
  417. selectRow(target,iPre);
  418. }
  419. MoveScroll(grid);
  420. //setValues(target);
  421. }
  422. function MoveScroll(grid){
  423. var body = $('.searchgrid-view div.searchgrid-body', grid);
  424. var item = $('.searchgrid-view .searchgrid-body tr.searchgrid-row-selected', grid);
  425. if(item.length==0){
  426. return ;
  427. }
  428. if (item.position().top <= 0){
  429. var h = body.scrollTop() + item.position().top - item.outerHeight();
  430. body.scrollTop(h);
  431. } else if (item.position().top + item.outerHeight() > body.height()){
  432. var h = body.scrollTop() + item.position().top + item.outerHeight() - body.height();
  433. body.scrollTop(h);
  434. }
  435. }
  436. /**
  437. * select a row with specified row index which start with 0.
  438. */
  439. function selectRow(target, index){
  440. var grid = $.data(target, 'searchgrid').grid;
  441. var opts = $.data(target, 'searchgrid').options;
  442. var data = $.data(target, 'searchgrid').data;
  443. var index2;
  444. $('.searchgrid-view .searchgrid-body tr.searchgrid-row-selected', grid).each(function(){
  445. index2 = parseInt($(this).attr('searchgrid-row-index'),10);
  446. });
  447. if(index2>=0){
  448. unselectRow(target,index2);
  449. }
  450. var selectedRows = $.data(target, 'searchgrid').selectedRows;
  451. var tr = $('.searchgrid-body tr[searchgrid-row-index='+index+']',grid);
  452. tr.addClass('searchgrid-row-selected');
  453. if (opts.idField){
  454. var row = data.rows[index];
  455. /*这段代码没意义
  456. for(var i=0; i<selectedRows.length; i++){
  457. if (selectedRows[i][opts.idField] == row[opts.idField]){
  458. return;
  459. }
  460. }*/
  461. while(selectedRows.length > 0){
  462. selectedRows.pop();
  463. }
  464. selectedRows.push(row);
  465. }
  466. opts.search = false;
  467. }
  468. //查找相应的输入框内的值
  469. function filter(target, query, callback){
  470. var grid = $.data(target, 'searchgrid').grid;
  471. var opts = $.data(target, 'searchgrid').options;
  472. var bEnter = false;
  473. opts.search = false;
  474. $('.searchgrid-body table tr',grid).each(function(){
  475. $(this).show();
  476. });
  477. if(!opts.localdb&&!opts.remotedb){
  478. if(query==null||query.length==0){return true;}
  479. var hasSelected = false;
  480. var visibleRows = $('.searchgrid-body table tr',grid).each(function(){
  481. var tr = this;
  482. var index = parseInt($(this).attr('searchgrid-row-index'),10);
  483. bEnter = false;
  484. $(this).show();
  485. $('div.searchgrid-cell', tr).each(function(){
  486. var item = $(this);
  487. //模糊查询,只要输入的字符在项目的任何地方存在就显示
  488. if (item.text().indexOf(query) !=-1 && query.length!=0){
  489. bEnter = true;
  490. if(item.text()==query){
  491. hasSelected = true;
  492. selectRow(target, index);
  493. }
  494. }
  495. });
  496. if(bEnter){
  497. //$(this).show();
  498. }else{
  499. $(this).hide();
  500. unselectRow(target, index);
  501. }
  502. }).filter(':visible');
  503. //默认选择第一条记录
  504. if(!hasSelected&&visibleRows.length>0){
  505. selectRow(target, parseInt(visibleRows.eq(0).attr('searchgrid-row-index'),10));
  506. }
  507. MoveScroll(grid);
  508. }
  509. if(query==null||query.length==0){return true;}
  510. if(opts.localdb){ //实现本地客户端文件搜素
  511. $.data(target, 'searchgrid').selectedRows=[];
  512. opts.total = 1;
  513. opts.pageNumber = 1;
  514. LoadLocalData(target,query,opts.querySQL);
  515. }
  516. //查询生成库数据库
  517. if(!opts.localdb && opts.remotedb){
  518. $.data(target, 'searchgrid').selectedRows=[];
  519. opts.total = 1;
  520. opts.pageNumber = 1;
  521. request(target,query,callback);
  522. }
  523. //为了避免频繁的查询过滤
  524. opts.search = false;
  525. }
  526. function setValues(target, bTriggerOnselect){
  527. var grid = $.data(target, 'searchgrid').searchgrid;
  528. var opts = $.data(target, 'searchgrid').options;
  529. var rows = $.data(target, 'searchgrid').selectedRows;
  530. var input= $.data(target, 'searchgrid').input;
  531. //下面三行处理的目的是为了录入框获取焦点时不清除掉页面初始化时的默认值
  532. var inText = input.val();
  533. var tx = input.attr('tx');
  534. var vl = input.attr('vl');
  535. if(!opts.textFieldOnly){
  536. target.value='';
  537. }
  538. for(var i=0; i<rows.length; i++){
  539. var row = rows[i];
  540. if(row==null){
  541. return;
  542. }
  543. if(!opts.textFieldOnly){
  544. if(row[opts.idField]!=null && row[opts.idField]!=undefined){
  545. target.value=row[opts.idField];
  546. }else{
  547. target.value='';
  548. }
  549. }
  550. if(row[opts.textField]!=null && row[opts.textField]!=undefined){
  551. input.val(row[opts.textField]);
  552. }else{
  553. input.val('');
  554. }
  555. if(opts.onselect && false !== bTriggerOnselect){
  556. opts.onselect(rows[0]);
  557. }
  558. }
  559. //以下处理单击回车键后若没有选择下拉列表的内容而且是默认值的情况
  560. //就恢复数据库保存字段的值
  561. if(target.value==''&&vl!=''&&tx==input.val()){
  562. target.value=vl;
  563. input.val(tx);
  564. }else if(target.value!=''&&input.val()!=''){
  565. input.attr('vl',target.value);
  566. input.attr('tx',input.val());
  567. }
  568. if(!opts.textFieldOnly){
  569. $(target).trigger('blur');
  570. }
  571. if(!opts.textFieldOnly){
  572. $(target).trigger('change');
  573. }
  574. }
  575. /**
  576. * select record by idField.
  577. */
  578. function selectRecord(target, idValue){
  579. var opts = $.data(target, 'searchgrid').options;
  580. var data = $.data(target, 'searchgrid').data;
  581. if (opts.idField){
  582. var index = -1;
  583. for(var i=0; i<data.rows.length; i++){
  584. if (data.rows[i][opts.idField] == idValue){
  585. index = i;
  586. break;
  587. }
  588. }
  589. if (index >= 0){
  590. selectRow(target, index);
  591. }
  592. }
  593. }
  594. /**
  595. * unselect a row.
  596. */
  597. function unselectRow(target, index){
  598. var opts = $.data(target, 'searchgrid').options;
  599. var grid = $.data(target, 'searchgrid').grid;
  600. var selectedRows = $.data(target, 'searchgrid').selectedRows;
  601. var tr = $('.searchgrid-body tr[searchgrid-row-index='+index+']',grid);
  602. tr.removeClass('searchgrid-row-selected');
  603. if(!opts.textFieldOnly){
  604. target.value ='';
  605. }
  606. var row = $.data(target, 'searchgrid').data.rows[index];
  607. if (opts.idField){
  608. for(var i=0; i<selectedRows.length; i++){
  609. var row1 = selectedRows[i];
  610. if (row1[opts.idField] == row[opts.idField]){
  611. for(var j=i+1; j<selectedRows.length; j++){
  612. selectedRows[j-1] = selectedRows[j];
  613. }
  614. selectedRows.pop();
  615. break;
  616. }
  617. }
  618. }
  619. }
  620. //生成提示信息
  621. function createmsg(target,msg){
  622. var grid = $.data(target, 'searchgrid').grid;
  623. var wrap = $('div.searchgrid-wrap', grid);
  624. $('<div class="searchgrid-mask"></div>').css({
  625. display:'block',
  626. width: wrap.width(),
  627. height: wrap.height()
  628. }).appendTo(wrap);
  629. $('<div class="searchgrid-mask-msg"></div>')
  630. .html(msg)
  631. .appendTo(wrap)
  632. .css({
  633. display:'block',
  634. left:(wrap.width()-$('div.searchgrid-mask-msg:first',grid).outerWidth())/2,
  635. top:(wrap.height()-$('div.searchgrid-mask-msg:first',grid).outerHeight())/2
  636. });
  637. var vthis=grid;
  638. setTimeout(function(){
  639. $('div.searchgrid-mask', vthis).remove();
  640. $('div.searchgrid-mask-msg', vthis).remove();
  641. },3*1000);
  642. }
  643. /**
  644. * request remote data
  645. */
  646. function request(target,query,callback){
  647. var grid = $.data(target, 'searchgrid').grid;
  648. var opts = $.data(target, 'searchgrid').options;
  649. var input = $.data(target, 'searchgrid').input;
  650. var where = opts.whereCls;
  651. var confid = opts.confid;
  652. if (!opts.url) return;
  653. if(opts.pageclick&&query==''){
  654. query = opts.query;
  655. input.val(query);
  656. }else{
  657. opts.query = query;
  658. }
  659. opts.pageclick = false;
  660. var rowstart = (opts.pageNumber - 1 ) * opts.pageSize + 1;
  661. var pageSize = opts.pageSize;
  662. var param = $.extend({}, {
  663. 'confid' : confid,
  664. 'rowstart' : rowstart,
  665. 'pageSize' : pageSize,
  666. 'whereCls' : where,
  667. 'pname' : target.name,
  668. 'query' : query
  669. });
  670. var wrap = $('div.searchgrid-wrap', grid);
  671. $('<div class="searchgrid-mask"></div>').css({
  672. display:'block',
  673. width: wrap.width(),
  674. height: wrap.height()
  675. }).appendTo(wrap);
  676. $('<div class="searchgrid-mask-msg"></div>')
  677. .html(opts.loadMsg)
  678. .appendTo(wrap)
  679. .css({
  680. display:'block',
  681. left:(wrap.width()-$('div.searchgrid-mask-msg',grid).outerWidth())/2,
  682. top:(wrap.height()-$('div.searchgrid-mask-msg',grid).outerHeight())/2
  683. });
  684. $.ajax({
  685. type: opts.method,
  686. url: opts.url,
  687. data: param,
  688. dataType: 'json',
  689. cache:false,
  690. success: function(data){
  691. if(data.Token!=null){
  692. token=data.Token;//更新全局变量token标志
  693. }
  694. if("1"!=data.FHZ){//出错了,弹出错误提醒
  695. if("CSRF" == data.FHZ){
  696. showMsg(data.MSG||'',3);
  697. }
  698. $('.searchgrid-mask', grid).remove();
  699. $('.searchgrid-mask-msg', grid).remove();
  700. return;
  701. }
  702. $('.searchgrid-mask', grid).remove();
  703. $('.searchgrid-mask-msg', grid).remove();
  704. //根据返回的数据设置ID域和文本域
  705. //有时idField是通过setIdField来设置的
  706. if(opts.idField==null){
  707. opts.idField=data.headers[opts.fieldIndices[0]];
  708. }
  709. if(opts.textField==null){
  710. opts.textField=data.headers[opts.fieldIndices[1]];
  711. }
  712. loadData(target, data);
  713. showPageInfo(target);
  714. if($.isFunction(callback)){
  715. callback(target);
  716. }
  717. },
  718. error: function(){
  719. $('div.searchgrid-mask', grid).remove();
  720. $('div.searchgrid-mask-msg', grid).remove();
  721. },
  722. beforeSend:function(XMLHttpRequest ){
  723. var cToken = $.cookie("Token") || token;XMLHttpRequest.setRequestHeader('Token',cToken);
  724. }
  725. });
  726. }
  727. //搜索客户端的数据库
  728. function LoadLocalData(target,query,sql){
  729. var opts = $.data(target, 'searchgrid').options;
  730. var pageNumber = opts.pageNumber;
  731. var pageSize = opts.pageSize;
  732. var startTime = new Date();
  733. //获取别名
  734. var t_headers = FWGetDictApplet().getHeaders(opts.confid);
  735. var headers = [];
  736. for ( var i = 0; i < t_headers.length; i++) {
  737. headers[i] = t_headers[i];
  738. }
  739. //根据返回的别名数据设置ID域和文本域
  740. if(opts.fieldIndices){
  741. if(opts.idField==null){
  742. opts.idField=headers[opts.fieldIndices[0]];
  743. }
  744. if(opts.textField==null){
  745. opts.textField=headers[opts.fieldIndices[1]];
  746. }
  747. }
  748. var rowStart = (pageNumber - 1) * pageSize;
  749. var result = FWGetDictApplet().selectPage(opts.confid, query, rowStart,
  750. pageSize);
  751. result = JSON.parse(result);
  752. var datas = result.pageData||[];
  753. var rows = [];
  754. for ( var i = 0; i < datas.length; i++) {
  755. // 单行转换格式处理
  756. var arr = datas[i];
  757. var obj = {};
  758. // 换成map结构
  759. for ( var j = 0; j < headers.length; j++) {
  760. obj[headers[j]] = arr[j];
  761. }
  762. rows.push(obj);
  763. }
  764. loadData(target, {
  765. total : result.total,
  766. headers:headers,
  767. rows : rows
  768. });
  769. showPageInfo(target);
  770. }
  771. function initInput(target){
  772. var grid = $.data(target, 'searchgrid').grid;
  773. var opts = $.data(target, 'searchgrid').options;
  774. if(!opts.textFieldOnly){
  775. var input = $('<input class="searchgrid-text" ></input>').insertAfter(target);
  776. input.attr('vldStr', $(target).attr('vldStr'));
  777. input.val($(target).attr('textfield'));
  778. //初始化默认值
  779. var displayValue = target['displayValue'];
  780. if(displayValue){
  781. //有值才设置
  782. input[0].value = displayValue;
  783. }
  784. }else{
  785. var input = $(target);
  786. }
  787. if(target.readOnly||target.disabled){
  788. disablePrimitiveInput(input[0]);
  789. }
  790. input.bind('mousedown', function(e){
  791. return false;
  792. });
  793. input.bind('focus',function(){
  794. var opts = $.data(target, 'searchgrid').options;
  795. if(!target.readOnly&&!target.disabled&&!opts.disabled){
  796. $('div.searchgrid').hide();
  797. var box = $(input);
  798. var gridWidth = grid.width();
  799. if(gridWidth<40){
  800. $('.searchgrid-view',grid).width(opts.headwidth+25);
  801. $('.searchgrid-header',grid).width(opts.headwidth+25);
  802. $('.searchgrid-body',grid).width(opts.headwidth+25);
  803. gridWidth = grid.width();
  804. }
  805. //设置左上角位置(考虑屏幕边界截屏的问题)
  806. if(box.offset().left+gridWidth>$(window).width()){
  807. grid.css({
  808. left:$(window).width()-gridWidth-3,/*加3预防window出现水平滚动栏*/
  809. top:box.offset().top + 22
  810. });
  811. }else{
  812. grid.css({
  813. left:box.offset().left,
  814. top:box.offset().top + 22
  815. });
  816. }
  817. //有时单击了下拉框后,再单击快速查询框,会导致下框显示列表重叠
  818. //关闭下拉框
  819. $('div.fwcombox-panel').hide();
  820. grid.show();
  821. try{
  822. this.select();
  823. }catch(e){};
  824. }
  825. });
  826. input.bind('blur',function(){
  827. if($(this).attr("readOnly")){
  828. return true;
  829. }
  830. var msg = FWelementValidate(this);
  831. if(msg!=null){
  832. FWvalidateTip(this,msg);
  833. } else {
  834. $(this).qtip("destroy");
  835. }
  836. if(target.value==''){
  837. this.value="";
  838. }
  839. });
  840. input.bind('keydown',function(e){
  841. switch(e.keyCode){
  842. case 187: // 屏蔽=
  843. case 222: // 屏蔽'
  844. return false;
  845. case 9:
  846. case 13:
  847. grid.hide();
  848. if(input[0].value==''){
  849. //如果前台什么都没有输入,那么取消默认选中项,否则控件无法清空原来的值。
  850. $.data(target, 'searchgrid').selectedRows=[];
  851. }
  852. setValues(target);
  853. event.keyCode = 9; //转成TAB键
  854. return true;
  855. default:
  856. return true;
  857. }
  858. return true;
  859. });
  860. input.bind('keyup',function(e){
  861. switch(e.keyCode){
  862. case 37: // left
  863. case 38: // up
  864. inputRow(target, -1);
  865. break;
  866. case 39: // right
  867. case 40: // down
  868. inputRow(target, 1);
  869. break;
  870. case 9: //tab
  871. case 13: // enter
  872. case 16: //shift 不处理这些
  873. break;
  874. case 27: // esc
  875. grid.hide();
  876. break;
  877. default:
  878. //凡是有输入事件都需要清除隐藏框的代码值
  879. if(!opts.textFieldOnly){
  880. target.value='';
  881. }
  882. clearTimeout(self.searching);
  883. if(!opts.search){ //为了避免频繁的查询过滤
  884. opts.search = true;
  885. opts.searching = setTimeout(function(){
  886. filter(target,input.val());
  887. },300); //延迟0.3秒处理
  888. }
  889. break;
  890. }
  891. return false;
  892. });
  893. return input;
  894. }
  895. var methods = {
  896. /**设置或者获取控件是否只读。
  897. * 参数flag可不传,不传表示获取控件的只读属性。
  898. * @param flag 只读标志,true为设置只读,false为取消只读。
  899. * @return 获取只读属性时为true和false,true表示控件只读,false表示控件;
  900. * 设置控件只读属性时返回jquery,当前jquery集合。
  901. */
  902. disabled : function(flag){
  903. if(arguments.length==0){
  904. //如果没有入参,那么属于要返回当前是否只读的状态
  905. if(this.length==0){return null;}
  906. var opts = $.data(this[0],'searchgrid').options;
  907. return opts.disabled;
  908. }else{
  909. return this.each(function(){
  910. if(flag){
  911. //设置为只读
  912. var opts = $.data(this, 'searchgrid').options;
  913. var input = $.data(this,'searchgrid').input;
  914. opts.disabled = true;
  915. $(this).removeAttr('disabled');
  916. disablePrimitiveInput(input[0]);
  917. }else{
  918. //设置为非只读
  919. var opts = $.data(this, 'searchgrid').options;
  920. if(opts.disabled){
  921. var input = $.data(this,'searchgrid').input;
  922. enablePrimitiveInput(input[0]);
  923. opts.disabled = false;
  924. }
  925. }
  926. });
  927. }
  928. },
  929. /**
  930. * 设置控件的显示文本字段
  931. * @param text
  932. * @returns
  933. */
  934. setTextField:function(text){
  935. if(this.length==0){return null;}
  936. if(text.length==0){return null;}
  937. var opts = $.data(this[0],'searchgrid').options;
  938. opts.textField = text;
  939. return true;
  940. },
  941. /**
  942. * 设置控件的保存字段
  943. * @param text
  944. * @returns
  945. */
  946. setIdField:function(value){
  947. if(this.length==0){return null;}
  948. if(value.length==0){return null;}
  949. var opts = $.data(this[0],'searchgrid').options;
  950. opts.idField = value;
  951. return true;
  952. },
  953. /**
  954. * 清空下拉面板的记录
  955. */
  956. clearPanel: function(){
  957. return this.each(function(){
  958. var data = $.data(this, 'searchgrid').data;
  959. //没有输入条件搜索的时候,05q控件的data == null,下拉面板已经为空,无需清空
  960. if(null != data){
  961. //清空下拉列表的所有数据
  962. data.rows = [];
  963. //清空选中行的数据
  964. $.data(this, 'searchgrid').selectedRows = [];
  965. //从HTML上移除面板
  966. var grid = $.data(this, 'searchgrid').grid;
  967. grid.find("div.searchgrid-body TBODY").empty();
  968. grid.find("div.searchgrid-pages span[icon=PageInfo]").empty();
  969. }
  970. });
  971. },
  972. /**
  973. * 设置下拉列表的初始值
  974. */
  975. setData:function(value){
  976. if(this.length==0){return null;}
  977. if(value.length==0){return null;}
  978. filter(this[0], value);
  979. return true;
  980. },
  981. /**
  982. * 返回控件是否可见
  983. * 返回值:true表示可见,false表示不可见。
  984. */
  985. visible:function(){
  986. if(this.length==0){return null;}
  987. var input = $.data(this[0],'searchgrid').input;
  988. return input.is(":visible");
  989. },
  990. /**
  991. * 获取或设置集合中第一个元素的查询控件的文本
  992. * 获取的方法:
  993. * function searchgrid('text') :string
  994. * 设置的方法
  995. * function searchgrid('text',text) :jquery
  996. */
  997. text : function(text){
  998. if(arguments.length==0){
  999. return this.map(function(){
  1000. return $.data(this,'searchgrid').input.val();
  1001. }).get(0);
  1002. }else{
  1003. return this.each(function(){
  1004. $.data(this,'searchgrid').input.val(text);
  1005. $.data(this,'searchgrid').input.attr("tx",text);
  1006. $.data(this,'searchgrid').input.attr("vl",this.value);
  1007. });
  1008. }
  1009. },
  1010. /**
  1011. * 设置字典过滤条件
  1012. */
  1013. setWhereCls : function (whereCls){
  1014. whereCls = whereCls || "1=2";
  1015. var opts = $.data(this[0],'searchgrid').options;
  1016. opts.whereCls = whereCls;
  1017. },
  1018. setTextById : function (id){
  1019. if(null==id || ""==id){
  1020. this[0].value = '';
  1021. $.data(this[0], 'searchgrid').input.val('');
  1022. return ;
  1023. }
  1024. var opts = $.data(this[0],'searchgrid').options;
  1025. var orginWhereCls = opts.whereCls;
  1026. if('STRING' == opts.idFieldType.toUpperCase()){
  1027. opts.whereCls = opts.idField + "='" + id + "'";
  1028. }else if('NUMBER' == opts.idFieldType.toUpperCase()){
  1029. opts.whereCls = opts.idField + "=" + id;
  1030. }else{
  1031. opts.whereCls = opts.idField + "='" + id + "'";
  1032. }
  1033. filter(this[0], '1=1',function(target){
  1034. selectRow(target,0);
  1035. setValues(target,false);//不触发onselect事件
  1036. $.data(target,'searchgrid').options.whereCls = orginWhereCls;
  1037. });
  1038. },
  1039. /**
  1040. * 控件的初始化函数
  1041. */
  1042. init : function(options){
  1043. options = options || {};
  1044. return this.each(function(){
  1045. var state = $.data(this, 'searchgrid');
  1046. var opts;
  1047. if (state) {
  1048. opts = $.extend(state.options, options);
  1049. state.options = opts;
  1050. } else {
  1051. opts = $.extend({}, $.fn.searchgrid.defaults, {
  1052. width:'auto',
  1053. height:'auto',
  1054. fit:false
  1055. }, options);
  1056. var wrapResult = wrapGrid(this, opts.rownumbers);
  1057. if (!opts.columns) opts.columns = wrapResult.columns;
  1058. $.data(this, 'searchgrid', {
  1059. options: opts,
  1060. grid: wrapResult.grid,
  1061. selectedRows: [],
  1062. input:null
  1063. });
  1064. }
  1065. var input = initInput(this);
  1066. //创建新的输入框原先生成的隐藏
  1067. if(!opts.textFieldOnly){
  1068. $(this).removeAttr('vldStr');
  1069. //将hidden控件的onfocus事件专递到外部可见的input来
  1070. $(this).focus(function(){input.focus();});
  1071. //回传外部的blur事件
  1072. var vthis = $(this);
  1073. $(this).hide();
  1074. }
  1075. $.data(this,'searchgrid').input = input;
  1076. var textfield = $(this).attr('textfield');
  1077. var target = this;
  1078. var grid = $.data(this, 'searchgrid').grid;
  1079. if (opts.columns){
  1080. var t = createColumnHeader(target);
  1081. $('.searchgrid-view div.searchgrid-header-inner', grid).html(t);
  1082. }
  1083. setSize(target);
  1084. createpage(target);
  1085. /*if (opts.url) {
  1086. request(target);
  1087. }*/
  1088. if(opts.initdata!=null){
  1089. loadData(target, opts.initdata);
  1090. if(target.value!=null){
  1091. selectRecord(target, target.value);
  1092. }
  1093. }
  1094. // setProperties(target);
  1095. grid.hide();
  1096. //鼠标点击其他地方就隐藏列表
  1097. $(document).bind('mousedown', function(e){
  1098. $('div.searchgrid').hide();
  1099. }).keydown(function(e){
  1100. //如果不是input控件,那么也隐藏
  1101. if(e.target!=input[0]){
  1102. grid.hide();
  1103. }
  1104. });
  1105. //鼠标移动到上面屏蔽掉
  1106. grid.bind('mousedown', function(e){
  1107. return false;
  1108. });
  1109. });
  1110. }
  1111. };
  1112. $.fn.searchgrid = function(options){
  1113. if (methods[options]) {
  1114. return methods[options].apply(this, Array.prototype.slice.call(
  1115. arguments, 1));
  1116. } else if (typeof options == 'object' || !options) {
  1117. return methods.init.apply(this, arguments);
  1118. } else {
  1119. $.error('Method ' + options + ' does not exist on searchgrid');
  1120. }
  1121. };
  1122. $.fn.searchgrid.defaults = {
  1123. border: true,
  1124. search:false, //开始搜索数据库时改为true 停止搜索会自动改为false 为避免频繁搜索设置此参数
  1125. localdb:false, //需要检索本地的ACCESS数据库就设置为true
  1126. remotedb:false,//需要检索远程的数据库就设置为true 优先级必localdb低
  1127. width: 'auto',
  1128. height: 'auto',
  1129. columns: null, //列表框的列名称
  1130. striped: true, //是否需要显示每行间隔的颜色
  1131. method: 'post',
  1132. nowrap: true,
  1133. confid:null,
  1134. whereCls:null,//远程数据库的查询条件
  1135. idField: null, //输入框录入的文字对应数据库内的代码
  1136. idFieldType:null,//ID字段的类型,NUMBER,STRING
  1137. textField:null, //代码所对应的显示值
  1138. querySQL:null, //检索的SQL语句
  1139. initdata:null, //页面初始化时列表框内的内容
  1140. url: null, //Aajx 取数时对应的路径
  1141. loadMsg: '正在处理中 ...',
  1142. rownumbers:null,
  1143. fit: false,
  1144. total: 1,
  1145. pageSize: 20,
  1146. pageNumber: 1,
  1147. query:'',
  1148. pageclick:false,
  1149. headwidth:0
  1150. };
  1151. })(jQuery);