728x90
반응형

1. html 코드는 간단하다.
   thead와 tbody에 id를 준 뒤에 내용이 바뀔 때마다 pagereload를 실행하도록 하였다.

<table id="data-table-combine" class="table table-striped table-bordered table-hover table-td-valign-middle text-center">
  <thead id="memDiv1">
  </thead>
  <tbody id="memDiv2">
  </tbody>
</table>

 

 

2. script쪽에서 먼저 pagereload함수를 페이지가 켜지자마자 실행되도록 한다. 이전에 선언한 pagingObject를 인자로 담고 인자에 따라 리스트가 표시되도록 설정했다.( 어느 schema를 조회할지, 어떤 url로 보낼것인지 등)

var pagingObject = new Object({name : "Car",url : "/ajax/car_list", CNU : "{{company.CNU}}", array : [], sort : "CA", page : 0, postNum : 10, pageNum : 5, startpage : 0, endpage : 0, search: "", searchtext : "", searchdate : ""});

$(document).ready(function() {
		pagereload(pagingObject); // 첫 화면 페이지 로드
    });

 

- pagingObject

name 사용할 스키마의 이름
url Ajax URL
CNU 사업자번호( 페이징과 무관)
array 백엔드에서 가져온 list
sort 정렬 옵션
page 현재 페이지 번호
postNum 게시될 데이터의 갯수
pageNum 게시될 페이지번호의 갯수
startpage 시작 페이지
endpage 끝 페이지
search 검색 옵션
searchtext 검색 옵션(문자)
searchdate 검색 옵션(날짜)

 

 

3. pagereload 함수는 변경사항이 있을 때마다 (검색하거나 정렬하거나 페이지가 바뀌거나 등) 실행이 될것이며, 그 때마다 리스트의 내용을 바꿔주는 함수이다.

function pagereload(Object) {
			$("input:checkbox[name='allck']").prop("checked", false);
			$("input:checkbox[name='ck']").prop("checked", false);
    	    $.ajax({
	    		url: Object.url,
                type: "POST",
                async: false,
                dataType: 'json',
                data: {
                	CID : Object.CID,
                	CNU : Object.CNU,
                    sort : Object.sort,
                    search : Object.search,
                    searchtext : Object.searchtext,
                    searchdate : Object.searchdate
                }
	        }).done(function (data) {
	        	if(data.result == true) {
	    		    Object.array = data.pagelist; // 전체 리스트
	    		    Object.startpage = Math.floor((Object.page) / Object.pageNum) * Object.pageNum;
	    		    Object.endpage = Object.startpage + Object.pageNum;
	    		    
	    		    var postNum = Object.postNum; // 게시될 페이지 숫자
	    		    var pageNum = Object.pageNum; // 페이지 번호의 갯수
	    		    var totalPage = Math.ceil(Object.array.length/Object.postNum); // 전체 페이지의 갯수
	    		    
	    		    if (Object.endpage > totalPage) { // 끝 페이지가 총 페이지 수보다 많다면 같게끔 처리
				        Object.endpage = totalPage;
				    }
	    		    
		        	//tr 초기화
		        	$("#data-table-combine > tbody > tr").remove();
		        	//페이지 넘버 박스 초기화
			     	$("#pagebox *").remove();
			    	
		    		if(Object.name == "Company") {
						companylist_condition(Object);
					
					}
					else if (Object.name == "Car") {
						carlist_condition(Object);
					}
					
					var insertTr = " ";
					insertTr +=	"<a href='javascript:;' onclick=pageDoubleBtn('left',pagingObject,'basic') class='btn btn-primary mr-1 px-2'><i class='fas fa-angle-double-left'></i></a>";
					insertTr +=	"<a href='javascript:;' onclick=pageBtn('left',pagingObject,'basic') class='btn btn-primary mr-1 px-2'><i class='fas fa-angle-left'></i></a>";
					
					for(var i = Object.startpage; i < Object.endpage; i ++) {
						if(Object.page == i)
							insertTr +=	"<input type='button' onclick=pagebutton(pagingObject,"+ i +",'basic') value ='"+ (i+1) +"' class='btn btn-white mr-1 px-2 text-primary' style='background-color: #00acac; color: white !important;' >";
						else
							insertTr +=	"<input type='button' onclick=pagebutton(pagingObject,"+ i +",'basic') value ='"+ (i+1) +"' class='btn btn-white mr-1 px-2 text-primary' >";
					}
					insertTr +=	"<a href='javascript:;' onclick=pageBtn('right',pagingObject,'basic') class='btn btn-primary mr-1 px-2'><i class='fas fa-angle-right'></i></a>";
					insertTr +=	"<a href='javascript:;' onclick=pageDoubleBtn('right',pagingObject,'basic') class='btn btn-primary mr-1 px-2'><i class='fas fa-angle-double-right'></i></a>";
					$("#pagebox").append(insertTr);
					
					$("#pagebox").show();
	        	}
	        	
	        	else if (data.result == "nothing") {
	        		$("#searchtext").val('');
			    	$("#searchdatetext1").val('');
			    	$("#searchdatetext2").val('');
			    	$("#memDiv2").empty();
			    	Object.array = [];
			    	
			    	if(Object.name == "Company") {
						companylist_condition(Object);
					}
					else if (Object.name == "Car") {
						carlist_condition(Object);
					}
					
	        	}
	        	else {
			    	$("#searchdatetext1").val('');
			    	$("#searchdatetext2").val('');
	        	}
			});
    }

 

4. 리스트에 따라 xx_condition 이라는 함수를 만들어서 리스트 내용을 채워준다.

ex}carlist_condition

 // 차량 리스트
    
    var carlist_condition = function (Object) {
		var num =  Object.array.length; 	
		var	insertTr = ""; // 채워넣을 HTML 초기화
		var indexcount = 1; // 인덱스번호 초기화
		
		$("#memDiv1").empty();
	    insertTr += "<tr>";
		insertTr += "<th id ='allcheck' width='1%'>";
		insertTr += "<input type='checkbox' name='allck' class='neHeros' value='' onChange='allCheckedBox(this);'/>";
		insertTr += "</th>";
		insertTr += "<th width='2.5%'></th>";
		insertTr += "<th width='10%' name='ANA'>"+i18nconvert("agent_branch")+"<a href='javascript:sortList(pagingObject,ANA);'><i id = 'ANA' class='float-right mx-1 fas fa-lg fa-fw m-t-3 ";
		if(Object.sort == "ANA-2")
			insertTr += "fa-sort-up'></a></i></th>";
		else if(Object.sort == "ANA")
			insertTr += "fa-sort-down'></a></i></th>";
		else 
			insertTr += "fa-sort'></a></i></th>";
		insertTr += "</th>";
		insertTr += "<th width='28%' name='CN'>"+i18nconvert("CN")+"<a href='javascript:sortList(pagingObject,CN);'><i id = 'CN' class='float-right mx-1 fas fa-lg fa-fw m-t-3 ";
		if(Object.sort == "CN-2")
			insertTr += "fa-sort-up'></a></i></th>";
		else if(Object.sort == "CN")
			insertTr += "fa-sort-down'></a></i></th>";
		else 
			insertTr += "fa-sort'></a></i></th>";
		
		insertTr += "<th width='30%'name='CPN'>"+i18nconvert("CPN")+"<a href='javascript:sortList(pagingObject,CPN);'><i id = 'CPN' class='float-right mx-1 fas fa-lg fa-fw m-t-3 ";
		if(Object.sort == "CPN-2")
			insertTr += "fa-sort-up'></a></i></th>";
		else if(Object.sort == "CPN")
			insertTr += "fa-sort-down'></a></i></th>";
		else 
			insertTr += "fa-sort'></a></i></th>";
			
		insertTr += "<th width='27.5%'name='CA'>"+i18nconvert("CA")+"<a href='javascript:sortList(pagingObject,CA);'><i id = 'CA' class='float-right mx-1 fas fa-lg fa-fw m-t-3 ";
		if(Object.sort == "CA-2")
			insertTr += "fa-sort-up'></a></i></th>";
		else if(Object.sort == "CA")
			insertTr += "fa-sort-down'></a></i></th>";
		else 
			insertTr += "fa-sort'></a></i></th>";
			
		insertTr += "<th width='1%'></th>";
		insertTr += "</tr>";
		
		$("#memDiv1").append(insertTr);
		
		insertTr = "";
		for (var i = ( Object.postNum *  Object.page) ; i < ( Object.postNum *  Object.page) +  Object.postNum ; i ++) { // 현재 페이지의 번호에 맞는 리스트 뽑아서 출력 (0 ~ 9, 10 ~ 19)
			if( Object.array.length != 0) {
				if( Object.array[i]) {
					insertTr += "<tr>";
					insertTr += "<td class='with-btn' nowrap>";
					insertTr += "<input id='ck' type='checkbox' name ='ck' class='neHeros' value="+  Object.array[i].CN +" onChange='eachCheckedBox(this);'/>";
					insertTr += "</td>";
					insertTr += "<td class='font-weight-bold'>"+(num - ( Object.page*10)) +" </td>";
					insertTr += "<td><a href='javascript:;' class='text-black' onclick=searchNow(pagingObject,'ANA','"+ Object.array[i].ANA +"')><u>"+ Object.array[i].ANA +"</u></a></td>";
					insertTr += "<td>"+ Object.array[i].CN+"</td>";
					
					if(! Object.array[i].CPN){
						insertTr+="<td>"+"N/A"+"</td><td>";
					}
					else {
						insertTr += "<td>"+  Object.array[i].CPN+"</td><td>";
					}
					
					if ( (moment( Object.array[i].CA).format('DD')) == moment().format('DD') )
					{
						insertTr +=  moment( Object.array[i].CA).format('HH:mm');
					}
					else {
						insertTr += moment( Object.array[i].CA).format('YYYY-MM-DD');
					}
					insertTr += "</td><td class='with-btn' nowrap>";
					insertTr += "<a href='javascript:;' id = 'carid' onclick='car_editone(this);' data-type='show' name='"+ Object.array[i]._id +"' data-carnum='"+ Object.array[i].CN +"' class='btn btn-sm btn-primary width-60 m-r-2 edit-btn'>"+i18nconvert("modify")+"</a>";
					insertTr += "<input type='button' value='"+i18nconvert("delete")+"' onclick=delete_one(this,'/car/ajax/car_deleteone') class='btn btn-sm btn-white width-60' name =' "+  Object.array[i].CN +"'></td> ";
					insertTr += "</tr>";
					num -= indexcount;
				}
			}
			else {
				insertTr += "<tr>";
				insertTr += "<td colspan='10'>No Data</td>";
				insertTr += "</tr>";
			
			break;
			}
		}
		
		$("#memDiv2").append(insertTr);
	};

 

 

5. 백엔드에서 옵션에 관한 내용들을 받고, 데이터를 클라이언트로 보내준다.

 ( searchCNU는 미들웨어에서 이 사이트에서 필요한 내용을 실행한 것이므로 무시하고 원하는 데이터를 얻을 수 있게끔 하시면 됩니다. )

//car list
router.post('/car_list', isNotLoggedIn, DataSet, agentDevide, async function(req, res, next) {
  const CNU = req.body.CNU;
  var sort = req.body.sort;
  var search = req.body.search;
  var searchtext = req.body.searchtext;
  var searchdate = req.body.searchdate;
  var sortText = "";
  var sortNum = 0;
  var cars = new Object;
  
  // company list에서 접속한 것인지 확인
  if(CNU.includes("#") == true) {
    req.searchCNU = CNU.split("#")[0]; // '#' 을 잘라
  }
  else {
    req.searchCNU = req.searchCNU; // 기존 middleware에서 받아온 본사,지점 CNU 그대로 다시 담음
  }
  
  // 정렬 기능
  if(sort.includes('-') == true) {
    sortText = sort.split('-')[0];
    sortNum = 1;
  }
  else {
    sortText = sort;
    sortNum = -1;
  }
  
  try {
    
    var doc = {
      lookup : { from : "Company", localField : "CNU", foreignField : "CNU", as : "ANA" } ,
      unwind : "$ANA",
      match : {},
      project : { CN : '$CN', CPN : '$CPN', CA : '$CA', ANA : '$ANA.ANA' },
      sort : { [sortText]: sortNum }
    }
    
    if(cars.length == 0) {
        return res.send({ result : "nothing" });
      }
    else {
      if (searchdate) {
      var searchtext2 = searchdate.split("~");
        if(search == "ANA") {
          doc.match = { "CNU": { $regex: req.searchCNU }, "ANA.ANA" : {$regex:searchtext}, "CA" : { $gte: new Date(searchtext2[0]+"T00:00:00.000Z"), $lt: new Date(searchtext2[1]+"T23:59:59.999Z") } };
        }
        else if(search == "CN") {
          doc.match = { "CNU": { $regex: req.searchCNU }, "CN" : {$regex:searchtext}, "CA" : { $gte: new Date(searchtext2[0]+"T00:00:00.000Z"), $lt: new Date(searchtext2[1]+"T23:59:59.999Z") } };
        }
        else if(search == "CPN") {
          doc.match = { "CNU": { $regex: req.searchCNU }, "CPN" : {$regex:searchtext}, "CA" : { $gte: new Date(searchtext2[0]+"T00:00:00.000Z"), $lt: new Date(searchtext2[1]+"T23:59:59.999Z") } };
        }
        else {
          doc.match = { "CNU": { $regex: req.searchCNU }, "CA" : { $gte: new Date(searchtext2[0]+"T00:00:00.000Z"), $lt: new Date(searchtext2[1]+"T23:59:59.999Z") } } ;
        }
      }
      else {
          if(search == "ANA") {
            doc.match = { "CNU": { $regex: req.searchCNU }, "ANA.ANA" : {$regex:searchtext} };
          }
          else if (search =="CN") {
            doc.match = { "CNU": { $regex: req.searchCNU }, "CN" : {$regex:searchtext} };
          }
          else if (search =="CPN") {
            doc.match = { "CNU": { $regex: req.searchCNU }, "CPN" : {$regex:searchtext} };
          }
          else {
            doc.match ={ "CNU": { $regex: req.searchCNU } };
          }
      }
    }
  
    cars = await modelQuery(QUERY.Aggregate,COLLECTION_NAME.Car,doc,{});
    if(cars.length == 0) {
      return res.send({ result : "nothing" });
    }
    
    var carlist = [];
    if(cars.length) {
      for(var i = 0; i < cars.length; i ++) {
        carlist[i] = cars[i];
      }
    }
    
    res.send({ result: true, pagelist : carlist });
  
  } catch(err) {
    console.error(err);
    next(err);
  }
});

 

try catch  문에서 나는 mongoose aggregate라는 쿼리를 사용했지만, 각자 용도에 맞게 쿼리문을 사용하면 된다.

몽고 쿼리에 관한 내용은 차후에 올리도록 하겠다.

728x90
반응형

+ Recent posts