asimryu

indexeddb - 등록,정렬,검색 포함(2016.07.30)

Jul 31st, 2016
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 17.02 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>indexedDB Address Book</title>
  6.     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  7.     <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css">
  8.     <style>
  9.         .hideonready {
  10.             display: none;
  11.         }
  12.         #photos {
  13.             height:150px;
  14.             background: #FF0;
  15.             border: 1px solid #888;
  16.         }
  17.         .photolist-edit {
  18.             position: relative;
  19.             display: inline-block;
  20.             width: 100px;
  21.             height: 100px;
  22.             border: 1px solid #888;
  23.             margin: 5px;
  24.         }
  25.         .photolist-edit img {
  26.             position: absolute;
  27.             width: 100px;
  28.             height: 100px;
  29.             left: 0;
  30.             top: 0;
  31.         }
  32.         .photolist-delete {
  33.             position: absolute;
  34.             top: 3px;
  35.             right: 3px;
  36.             width: 20px;
  37.             height: 20px;
  38.             border-radius: 10px;
  39.             line-height: 20px;
  40.             text-align: center;
  41.             background-color: black;
  42.             color: white;
  43.             cursor: pointer;
  44.         }
  45.         .sort-selection {
  46.             margin: 10px 0;
  47.         }
  48.         .novalue::-webkit-input-placeholder {
  49.             color: red;
  50.         }
  51.         .novalue:-moz-placeholder {
  52.             color: red;
  53.         }
  54.         .novalue::-moz-placeholder {
  55.             color: red;
  56.         }
  57.         .novalue:-ms-input-placeholder {
  58.             color: red;
  59.         }
  60.     </style>
  61. </head>
  62. <body>
  63.     <div class="container">
  64.         <div class="jumbotron">
  65.             <h1>My Address Book</h1>
  66.         </div>
  67.         <div class="add-form">
  68.             <form class="form-horizontal" onsubmit="return false">
  69.                 <div class="form-group">
  70.                     <label for="adname" class="col-sm-2 control-label">Name</label>
  71.                     <div class="col-sm-10">
  72.                         <input type="text" class="form-control" id="adname" placeholder="이름을 입력하세요." required>
  73.                     </div>
  74.                 </div>
  75.  
  76.                 <div class="form-group">
  77.                     <label for="ademail" class="col-sm-2 control-label">Email Address</label>
  78.                     <div class="col-sm-10">
  79.                         <input type="email" class="form-control" id="ademail" placeholder="your@email.com" required>
  80.                     </div>
  81.                 </div>
  82.  
  83.                 <div class="form-group">
  84.                     <label for="adaddress" class="col-sm-2 control-label">Home Address</label>
  85.                     <div class="col-sm-10">
  86.                         <input type="text" class="form-control" id="adaddress" placeholder="주소를 입력하세요." required>
  87.                     </div>
  88.                 </div>
  89.  
  90.                 <div class="form-group">
  91.                     <label for="adphone" class="col-sm-2 control-label">Phone Number</label>
  92.                     <div class="col-sm-10">
  93.                         <input type="text" class="form-control" id="adphone" placeholder="010-111-2222" required>
  94.                     </div>
  95.                 </div>
  96.  
  97.                 <div class="form-group">
  98.                     <label for="adphotos" class="col-sm-2 control-label">Photos</label>
  99.                     <div class="col-sm-10">
  100.                         <div id="photos" ondragover="dragover(event)" ondrop="drop(event)" ondragleave="dragleave(event)" class="col-sm-12"></div>
  101.                     </div>
  102.                 </div>         
  103.  
  104.                 <div class="form-group">
  105.                     <div class="col-sm-offset-2 col-sm-10">
  106.                         <button type="submit" class="btn-add btn btn-success">Add Friend</button>
  107.                     </div>
  108.                 </div>
  109.             </form>
  110.         </div>
  111.  
  112.             <div class="sort-selection">
  113.                 <form class="form-inline" onsubmit="return false">
  114.                     <strong>search field and order by&nbsp;&nbsp;</strong>
  115.                     <div class="radio">
  116.                         <label>
  117.                             <input type="radio" name="orderby" id="orderbyAdname" value="adname" checked> Name
  118.                         </label>
  119.                     </div>
  120.                     <div class="radio">
  121.                         <label>
  122.                             <input type="radio" name="orderby" id="orderbyAdemail" value="ademail"> Email
  123.                         </label>
  124.                     </div>
  125.                     <div class="radio">
  126.                         <label>
  127.                             <input type="radio" name="orderby" id="orderbyAdaddress" value="adaddress"> Address
  128.                         </label>
  129.                     </div>     
  130.                     <div class="radio">
  131.                         <label>
  132.                             <input type="radio" name="orderby" id="orderbyAdphone" value="adphone"> Phone
  133.                         </label>
  134.                     </div>         
  135.                     <strong>&nbsp;&nbsp;|&nbsp;&nbsp;</strong>
  136.                     <div class="radio">
  137.                         <label>
  138.                             <input type="radio" name="ascdesc" id="ascdescAsc" value="next" checked> asc
  139.                         </label>
  140.                     </div> 
  141.                     <div class="radio">
  142.                         <label>
  143.                             <input type="radio" name="ascdesc" id="ascdescDesc" value="prev"> desc
  144.                         </label>
  145.                     </div>
  146.                     <strong>&nbsp;&nbsp;|&nbsp;&nbsp;</strong>
  147.                     <div class="form-group">
  148.                         <label for="searchText" class="control-label">검색어</label>
  149.                         <input type="text" class="form-control" id="searchText" placeholder="search text here">
  150.                     </div>
  151.                     <button type="button" id="searchBtn" class="btn btn-sm btn-default">찾기</button>        
  152.                 </form>
  153.             </div>
  154.  
  155.             <div id="list">
  156.                 <table class="table">
  157.                     <tr>
  158.                         <th>Name</th>
  159.                         <th>Address</th>
  160.                         <th>Email</th>
  161.                         <th>Phone</th>
  162.                         <th>&nbsp;</th>
  163.                     </tr>
  164.                 </table>
  165.             </div>
  166.     </div>
  167.  
  168.     <div id="moreinfo" class="hideonready" title="상세정보">
  169.         <h1 id="friendname"></h1>
  170.         <p id="friendemail"></p>
  171.         <p id="friendaddress"></p>
  172.         <p id="friendphone"></p>
  173.         <p id="friendphotos"></p>
  174.     </div>
  175.  
  176.     <div id="updatefrm" class="hideonready" title="정보수정">
  177.         <form class="form">
  178.             <div class="form-group">
  179.                 <label for="adname-input">Name</label>
  180.                 <input type="text" class="form-control" id="adname-input" value="">
  181.             </div>
  182.             <div class="form-group">
  183.                 <label for="ademail-input">Email</label>
  184.                 <input type="email" class="form-control" id="ademail-input" value="">
  185.             </div>
  186.             <div class="form-group">
  187.                 <label for="adaddress-input">Address</label>
  188.                 <input type="text" class="form-control" id="adaddress-input" value="">
  189.             </div>
  190.             <div class="form-group">
  191.                 <label for="adphone-input">Phone</label>
  192.                 <input type="text" class="form-control" id="adphone-input" value="">
  193.             </div>
  194.             <div class="form-group">
  195.                 <label for="adphotos-input">Photos</label>
  196.                 <div id="adphotos-input"></div>
  197.             </div>         
  198.         </form>
  199.     </div> 
  200.  
  201.     <script src="http://code.jquery.com/jquery-1.12.4.js"></script>
  202.     <script src="http://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
  203.     <script>
  204.         var db;
  205.         //addressbook 데이터베이스 오픈(없으면 생성)
  206.         var request = window.indexedDB.open("adbook",1);
  207.  
  208.         //DB Open Error Handling
  209.         request.onerror = function(event) {
  210.             console.log("DB Open Error");
  211.         }
  212.  
  213.         //After DB Open
  214.         request.onsuccess = function(event) {
  215.           db = request.result;
  216.           readAllData();
  217.         }
  218.  
  219.         request.onupgradeneeded = function(event) {
  220.             var result = event.target.result;
  221.             var objectStore = result.createObjectStore("address",{ keyPath: "id", autoIncrement:true });
  222.  
  223.             //정렬을 위해 key들을 index에 추가
  224.             objectStore.createIndex("adname", "adname", { unique: false });
  225.             objectStore.createIndex("ademail", "ademail", { unique: false });
  226.             objectStore.createIndex("adaddress", "adaddress", { unique: false });
  227.             objectStore.createIndex("adphone", "adphone", { unique: false });
  228.         }
  229.  
  230.         function readAllData(orderKey, ascdescType, searchText){
  231.             var orderKey = orderKey ? orderKey : "adname";
  232.             var ascdescType = ascdescType ? ascdescType : "next";
  233.             var searchText = searchText ? searchText : "";
  234.             var tr = db.transaction(["address"]);
  235.             var store = tr.objectStore("address");
  236.  
  237.             $("#list table tr:not(:first)").remove();
  238.             var keyRangeValue = null;
  239.             if(searchText !== "") {
  240.                 //검색어 처리 : IDBKeyRange.bound("시작문자열","끝문자열");
  241.                 //시작문자열과 끝문자열을 같은 것으로 하여 검색
  242.                 //끝문자열에 \uffff 문자열을 더해 주면 like 검색과 같은 효과를 냄
  243.                 //만일 \uffff를 빼면 일치하는 단어가 포함된 경우만 검색
  244.                 keyRangeValue = IDBKeyRange.bound(searchText, searchText); 
  245.             }
  246.  
  247.             var request = store.index(orderKey).openCursor(keyRangeValue, ascdescType);
  248.            
  249.             request.onsuccess = function(event) {
  250.                 var cursor = event.target.result; //한 줄 얻어내기
  251.                 if (cursor) {
  252.                     addList(cursor.value); 
  253.                     cursor.continue(); //다음 줄로 이동
  254.                 }
  255.             };
  256.         }
  257.  
  258.         function readData(id,act){
  259.             if( ! id ) return;
  260.             var tr = db.transaction(["address"]);
  261.             var store = tr.objectStore("address");
  262.             var request = store.get(id);
  263.             request.onsuccess = function(event){
  264.                 var data = request.result;
  265.                 if( act == "read") {
  266.                     popUpInfo(data);   
  267.                 } else if( act =="edit" ) {
  268.                     popUpEdit(data);   
  269.                 }
  270.             };
  271.             request.onerror = function(event){
  272.                 console.log("read error");
  273.             };
  274.         }
  275.  
  276.         function popUpInfo(data){
  277.             if( ! data ) return;
  278.             $("#friendname").text(data.adname);
  279.             $("#friendemail").text(data.ademail);
  280.             $("#friendaddress").text(data.adaddress);
  281.             $("#friendphone").text(data.adphone);
  282.             if(data.photos){
  283.                 var photolist = data.photos;
  284.                 var i;
  285.                 for( i=0; i<photolist.length;i++){
  286.                     var src = photolist[i].src;
  287.                     var img = "<img src='" + src + "' width='100' height='100' style='margin: 5px;'>";
  288.                     $("#friendphotos").append(img);
  289.                 }
  290.             }
  291.  
  292.             $("#moreinfo").dialog({
  293.                 width: 500,
  294.                 height: 500,
  295.                 title: data.adname + " 상세정보",
  296.                 modal: true
  297.             });
  298.         }
  299.  
  300.         var photoeditlist = [];
  301.  
  302.         function popUpEdit(data){
  303.             if( ! data ) return;
  304.             var id;
  305.             $("#updatefrm").dialog({
  306.                 width: 500,
  307.                 height: 500,
  308.                 title: data.adname + " 정보수정",
  309.                 modal: true,
  310.                 open: function(){
  311.                     id = data.id;
  312.                     $("#adname-input").val(data.adname);
  313.                     $("#ademail-input").val(data.ademail);
  314.                     $("#adaddress-input").val(data.adaddress);
  315.                     $("#adphone-input").val(data.adphone);
  316.                     if(data.photos){
  317.                         photoeditlist = data.photos;
  318.                         var i;
  319.                         for( i=0; i<photoeditlist.length;i++){
  320.                             var src = photoeditlist[i].src;
  321.                             var img = "<div class='photolist-edit'>";
  322.                             img += "<img src='" + src + "'>";
  323.                             img += "<div class='photolist-delete' data-imgid='" + i + "'>X</div>";
  324.                             img += "</div>";
  325.                             $("#adphotos-input").append(img);
  326.                         }
  327.                     }
  328.                 },
  329.                 buttons: {
  330.                     "저장":function(){
  331.                         var tr = db.transaction(["address"], "readwrite");
  332.                         var store = tr.objectStore("address");
  333.                         var request = store.get(id);
  334.  
  335.                         request.onsuccess = function(event){
  336.                             var data = event.target.result;
  337.                             data.adname = $("#adname-input").val();
  338.                             data.ademail = $("#ademail-input").val();
  339.                             data.adaddress = $("#ademail-input").val();
  340.                             data.adphone = $("#adphone-input").val();
  341.                             data.photos = photoeditlist;
  342.  
  343.                             var dbupdate = store.put(data);
  344.                             dbupdate.onsuccess = function(event){
  345.                                 console.log('데이터 수정 성공');
  346.                                 $("#list" + id + " .adname").text(data.adname);
  347.                                 $("#updatefrm").dialog("close");
  348.                             };
  349.                             dbupdate.onerror = function(event){
  350.                                 console.log('데이터 수정 실패');
  351.                             };
  352.                         };
  353.                         request.onerror = function(event){
  354.                             console.log('데이터 수정 실패');
  355.                         }
  356.                     },
  357.                     "닫기":function(){
  358.                         $(this).dialog("close");
  359.                     }
  360.                 },
  361.                 close: function(){
  362.                     $("#adname-input").val("");
  363.                     $("#ademail-input").val("");
  364.                     $("#ademail-input").val("");
  365.                     $("#adphone-input").val("");   
  366.                     $("#adphotos-input").html("");
  367.                     while (photoeditlist.length) { photoeditlist.pop(); }
  368.                 }
  369.             });
  370.         }
  371.  
  372.         $("#adphotos-input").on("click",".photolist-delete",function(){
  373.             var id = $(this).attr("data-imgid");
  374.             photoeditlist.splice(id, 1);//배열에서 특정 index를 제거함
  375.             $(this).parent(".photolist-edit").remove();
  376.  
  377.             //배열에서 하나를 삭제하였으므로 포토리스트에서 버튼마다 주어진 번호(배열기준)를 다시 0부터 순서대로 부여해주어야 함.
  378.             var i = 0;
  379.             $("#adphotos-input .photolist-delete").each(function(){
  380.                 $(this).attr("data-imgid",i);
  381.                 i++;
  382.             });
  383.  
  384.         });
  385.  
  386.         function addList(data){
  387.             if( ! data ) return;
  388.             var row  = "<tr id='list" + data.id + "'>";
  389.                 row += "<td class='adname'>" + data.adname + "</td>";
  390.                 row += "<td class='adaddress'>" + data.adaddress + "</td>";
  391.                 row += "<td class='ademail'>" + data.ademail + "</td>";
  392.                 row += "<td class='adphone'>" + data.adphone + "</td>";
  393.                 row += "<td>";
  394.                 row += "<a class='btn-del btn btn-danger' data-id='" + data.id + "'>삭제</a>";
  395.                 row += "&nbsp;<a class='btn-read btn btn-primary' data-id='" + data.id + "'>보기</a>";
  396.                 row += "&nbsp;<a class='btn-edit btn btn-warning' data-id='" + data.id + "'>수정</a>";
  397.                 row += "</td>";
  398.                 row += "</tr>";
  399.             $(row).insertAfter("#list table tr:last");
  400.         }
  401.  
  402.  
  403.  
  404.         function deleteData(id){
  405.             if( ! id ) return false;
  406.             var tr = db.transaction(["address"], "readwrite");
  407.             var store = tr.objectStore("address");
  408.             var request = store.delete(id);
  409.             request.onsuccess = function(event) {
  410.                 $("#list" + id).remove();
  411.             }; 
  412.             request.onerror = function(event) {
  413.                 //some error code
  414.             }
  415.         }
  416.  
  417.  
  418.         function saveData(data){
  419.             var tr = db.transaction(["address"], "readwrite");
  420.             var store = tr.objectStore("address");
  421.             var request = store.add(data);
  422.             request.onsuccess = function(event){
  423.                 //마지막에 추가한 레코드의 id를 구함
  424.                 var id = event.target.result;
  425.                 data.id = id; // 데이터 객체 data에 id를 추가
  426.                 addList(data);
  427.                 $("#adname").val("");
  428.                 $("#ademail").val("");
  429.                 $("#adaddress").val("");
  430.                 $("#adphone").val("");
  431.             };
  432.             request.onerror = function(event) {
  433.                 console.log("Error : data save error");
  434.             }  
  435.         }
  436.  
  437.         function updateData(id){
  438.             var tr = db.transaction(["address"], "readwrite");
  439.             var store = tr.objectStore("address");
  440.             var request = store.get(id);
  441.  
  442.             request.onsuccess = function(event){
  443.                 var data = event.target.result;
  444.                 data.adname = $("#adname-input").val();
  445.                 data.ademail = $("#ademail-input").val();
  446.                 data.adaddress = $("#ademail-input").val();
  447.                 data.adphone = $("#adphone-input").val();
  448.  
  449.                 var dbupdate = store.put(data);
  450.                 dbupdate.onsuccess = function(event){
  451.                     console.log('데이터 수정 성공');
  452.                     return true;
  453.                 };
  454.                 dbupdate.onerror = function(event){
  455.                     console.log('데이터 수정 실패');
  456.                     return false;
  457.                 };
  458.             };
  459.             request.onerror = function(event){
  460.                 console.log('데이터 수정 실패');
  461.                 return false;
  462.             }
  463.         }
  464.  
  465.         $("#searchBtn").on("click",function(event){
  466.             event.preventDefault();
  467.             var searchText = $("#searchText").val();
  468.             var orderKey = $("input[name='orderby']:checked").val();
  469.             var ascdescType = $("input[name='ascdesc']:checked").val();
  470.             var searchText = $("#searchText").val();
  471.             readAllData(orderKey,ascdescType,searchText);
  472.         });
  473.  
  474.         $("#searchText").keypress(function(event){
  475.             if(event.which == 13) {
  476.                 $("#searchBtn").click();
  477.             }
  478.         });
  479.  
  480.         $(".btn-add").on("click",function(event){
  481.             event.preventDefault();
  482.             var friend = {};
  483.             friend.adname = $("#adname").val();
  484.             friend.ademail = $("#ademail").val();
  485.             friend.adaddress = $("#adaddress").val();
  486.             friend.adphone = $("#adphone").val();
  487.             friend.photos = photos;
  488.             var dataok = true;
  489.             if( ! friend.adname ) {
  490.                 $("#adname").addClass("novalue");
  491.                 dataok = false;
  492.             } else {
  493.                 $("#adname").removeClass("novalue");
  494.             }
  495.             if( ! friend.ademail ) {
  496.                 $("#ademail").addClass("novalue");
  497.                 dataok = false;
  498.             } else {
  499.                 $("#ademail").removeClass("novalue");
  500.             }
  501.             if( ! friend.adaddress ) {
  502.                 $("#adaddress").addClass("novalue");
  503.                 dataok = false;
  504.             } else {
  505.                 $("#adaddress").removeClass("novalue");
  506.             }
  507.             if( ! friend.adphone ) {
  508.                 $("#adphone").addClass("novalue");
  509.                 dataok = false;
  510.             } else {
  511.                 $("#adphone").removeClass("novalue");
  512.             }
  513.             if( dataok === true ) saveData(friend);
  514.         });
  515.  
  516.         $("#list").on("click",".btn-del",function(){
  517.             var id = $(this).attr("data-id");
  518.             if( ! id ) return;
  519.             id = parseInt(id,10);
  520.             deleteData(id);
  521.         });
  522.  
  523.         $("#list").on("click",".btn-read",function(){
  524.             var id = $(this).attr("data-id");
  525.             if( ! id ) return;
  526.             id = parseInt(id,10);
  527.             readData(id,"read");
  528.         });
  529.  
  530.         $("#list").on("click",".btn-edit",function(){
  531.             var id = $(this).attr("data-id");
  532.             if( ! id ) return;
  533.             id = parseInt(id,10);
  534.             readData(id,"edit");
  535.         });
  536.  
  537.         function dragover(event){
  538.             event.preventDefault();
  539.             var id = event.target.id;
  540.             $("#" + id).css({"background":"red"});
  541.         }
  542.  
  543.         function dragleave(event){
  544.             event.preventDefault();
  545.             var id = event.target.id;
  546.             $("#" + id).css({"background":"#ff0"});
  547.         }
  548.  
  549.         var photos;
  550.         function drop(event){
  551.             event.preventDefault();
  552.             photos = [];
  553.             var data = event.dataTransfer;
  554.             var files = data.files;
  555.             var i;
  556.             for( i=0; i<files.length; i++){
  557.                 if( files[i].type == "image/jpeg" || files[i].type == "image/png" || files[i].type == "image/gif" ) {
  558.                     addPhotos(files[i]);
  559.                 }
  560.             }
  561.         }
  562.  
  563.         function addPhotos(file){
  564.             var photo = {};
  565.             photo.name = file.name;
  566.             photo.size = file.size;
  567.             photo.type = file.type;
  568.             var reader = new FileReader();
  569.             reader.addEventListener("load",function(){
  570.                 photo.src = reader.result;
  571.                 //console.log(photo);
  572.                 photos.push(photo);
  573.             });
  574.             reader.readAsDataURL(file);
  575.         }      
  576.     </script>
  577. </body>
  578. </html>
Add Comment
Please, Sign In to add comment