본문 바로가기
Firebase 호스팅

firebase 게시판 만들기(5)-게시판에 글쓰기

by 메씨 2023. 6. 23.
728x90
반응형

1. 게시판 만들기

html 게시판과 페이지 이동

<section class="list-wrapper wrapper">
      <table class="table text-center table-hover border-bottom">
        <thead class="thead-light">
          <tr>
            <th>번호</th>
            <th>제목</th>
            <th>작성자</th>
            <th>작성일</th>
            <th>조회수</th>
          </tr>
        </thead>
        <tbody>
       <!--데이터 들어오는 영역-->
        </tbody>
      </table>
      <nav class="page-wrapper">
        <ul class="pagination">
          <li class="page-item"><a class="page-link bi-chevron-bar-left" href="#"></a> </li>
          <li class="page-item"><a class="page-link bi-chevron-double-left" href="#"></a> </li>
          <li class="page-item"><a class="page-link bi-chevron-left" href="#"></a> </li>
          <li class="page-item active"><a class="page-link" href="#">1</a></li>
          <li class="page-item"><a class="page-link" href="#">2</a></li>
          <li class="page-item"><a class="page-link" href="#">3</a></li>
          <li class="page-item"><a class="page-link" href="#">4</a></li>
          <li class="page-item"><a class="page-link bi-chevron-right" href="#"></a></li>
          <li class="page-item"><a class="page-link bi-chevron-double-right" href="#"></a></li>
          <li class="page-item"><a class="page-link bi-chevron-bar-right" href="#"></a></li>
        </ul>
      </nav>
    </section>

css

/********************** pagination *********************/
.pagination {
  margin-top: 2.5em;
  justify-content: center;
}
.page-item.active .page-link {
  background-color: rgb(194, 197, 229);
  border: 1px solid rgb(201, 201, 201);
}
/**********************list-wrapper *********************/
.list-wrapper {
}
.list-wrapper table > thead > tr > :nth-child(1) {
  width: 10%;
}
.list-wrapper table > thead > tr > :nth-child(3) {
  width: 15%;
}
.list-wrapper table > thead > tr > :nth-child(4) {
  width: 20%;
}
.list-wrapper table > thead > tr > :nth-child(5) {
  width: 10%;
}

 

2. 입력 폼 만들기

  • html
<section class="create-wrapper wrapper">
      <form class="create-form form-inline" onsubmit="return onSubmit(this)">
        <input type="text" name="writer" class="form-control" placeholder="작성자">
        <input type="text" name="content" class="form-control" placeholder="글 작성하기" autofocus>
        <button class="btn btn-secondary">등록</button>
      </form>
    </section>
  • css
.create-wrapper {
  padding: 0.75em 0;
  display: none;
}
.create-wrapper .create-form {
  display: flex;
  align-items: center;
}
.create-wrapper .create-form input[name='content'] {
  flex-grow: 1;
  margin: 0 0.75em;
}

3. 게시판에 올리기

  • js
      • onSubmit 함수 실행
        1. 작성자와 내용이 빈칸으로 제출되지 않게 함
        2. data 변수 정의: 작성자, 작성내용, 작성시간, 유저아이디(구글계정로그인), 조회수
        3. 유저가 비어있지 않고 유저아이디(계정마다 생성되는 고유값)이 있다면 데이터베이스의 루트-보드에 data 전송(firebase의 데이터베이스에 저장)
        4. 그리고 내용 작성 폼 포맷
    • db 변수와 onAdded 함수
      1. db 는 firebase.database 모듈
      2. db의 ref('root/board')안에 자식요소가 추가되면 onAdded 함수 실행
      3. k는 데이터베이스의 고유아이디, v는 배열 안의 값, i는 html 안의 표 개수
      4. k는 작성된 폼의 아이디, v는 데이터의 값(작성자와 작성시간 등..), i는 작성된 순서
      5. html 안의 tbody 전에 위의 html 생성값 붙이기
    ;/******************************* 글로벌 설정 ********************************/
    var auth = firebase.auth();	//firebase의 auth(인증)모듈을 불러온다.
    var googleAuth = new firebase.auth.GoogleAuthProvider(); //구글로그인 모듈을 불러온다.
    var db= firebase.database();//firebase data 모듈
    var user = null;
    
    var $tbody = $('.list-wrapper tbody');
    
    /******************************* 사용자 함수 *******************************/
    $tbody.empty();
    $('.create-wrapper input[name="content"]').val('');
    
    /******************************* 이벤트 등록 ******************************/
    auth.onAuthStateChanged(onChangeAuth);
    db.ref('root/board').on('child_added',onAdded);//데이터베이스의 루트-보드에 자식요소가 추가되면 
    // ref.on('child_removed', onRemoved);
    $('.bt-login').click(onLoginGoogle);
    $('.bt-logout').click(onLogOut);
    
    /******************************* 이벤트 콜백 *****************************/
    function onAdded(r){//이벤트 실행!
        var k =r.key;
        var v =r.val();
        var i = $tbody.find('tr').length+1;
        var html = '';
        html += '<tr id ="'+k+'">';
        html += '<td>'+i+'</td>';
        html += '<td class="text-left">'+v.content+'</td>';
        html += '<td>'+v.writer+'</td>';
        html += '<td>'+moment(v.createAt).format('MM-DD HH:mm:ss')+'</td>';
        html += '<td>'+v.readnum+'</td>';
        html += '</tr>';
        $tbody.prepend(html);
    }
    
    function onRemoved(r){
    
    }
    
    function onSubmit(f){
        if(f.writer.value.trim()===''){
            alert('작성자를 입력해주세요.');
            f.writer.focus();
            return false;
        }
        if(f.content.value.trim()===''){
            alert('내용을 입력해주세요.');
            f.content.focus();
            return false;
           
        }  
    
        var data = {
            writer: f.writer.value,
            content: f.content.value,
            createAt: new Date().getTime(),
            uid:user.uid,
            readnum: 0//조회수
        
        }
        if(user && user.uid){
            db.ref('root/board/').push(data);
            $('.create-wrapper input[name="content"]').val('');
           
        }
        else alert('비정상적인 접근입니다.')
    
        return false;
       
    	
    	
    
    }
    function onChangeAuth(r){
       user = r;
       console.log(user);
       if(user){
        $('.header-wrapper .email').text(user.email);
        $('.header-wrapper .photo img').attr('src', user.photoURL);
        $('.header-wrapper .info-wrap').css('display','flex');
        $('.create-wrapper').show();
        $('.create-wrapper input[name="writer"]').val(user.displayName);
        $('.bt-login').hide();
        $('.bt-logout').show();
       }
       else{
        $('.header-wrapper .email').text('');
        $('.header-wrapper .photo').attr('src', '//via.placeholder.com/1x1/333/');
        $('.create-wrapper').hide();
        $('.header-wrapper .info-wrap').css('display','none');
        $('.create-wrapper input[name="writer"]').val('');
        $('.create-wrapper input[name="content"]').val('');
        $('.bt-login').show();
        $('.bt-logout').hide();
        console.log('welcome');
       }
    }
    
    function onLogOut(){
        console.log("hi");
        firebase.auth().signOut().then(() => {
            // Sign-out successful.
          }).catch((error) => {
            // An error happened.
          });
          
    }
    
    function onLoginGoogle(){
        auth.signInWithPopup(googleAuth);
        
    }
    
    1. 게시판 만들기
    • html 게시판과 페이지 이동
    • <section class="list-wrapper wrapper"> <table class="table text-center table-hover border-bottom"> <thead class="thead-light"> <tr> <th>번호</th> <th>제목</th> <th>작성자</th> <th>작성일</th> <th>조회수</th> </tr> </thead> <tbody> <!--데이터 들어오는 영역--> </tbody> </table> <nav class="page-wrapper"> <ul class="pagination"> <li class="page-item"><a class="page-link bi-chevron-bar-left" href="#"></a> </li> <li class="page-item"><a class="page-link bi-chevron-double-left" href="#"></a> </li> <li class="page-item"><a class="page-link bi-chevron-left" href="#"></a> </li> <li class="page-item active"><a class="page-link" href="#">1</a></li> <li class="page-item"><a class="page-link" href="#">2</a></li> <li class="page-item"><a class="page-link" href="#">3</a></li> <li class="page-item"><a class="page-link" href="#">4</a></li> <li class="page-item"><a class="page-link bi-chevron-right" href="#"></a></li> <li class="page-item"><a class="page-link bi-chevron-double-right" href="#"></a></li> <li class="page-item"><a class="page-link bi-chevron-bar-right" href="#"></a></li> </ul> </nav> </section>
    • css
    • /********************** pagination *********************/ .pagination { margin-top: 2.5em; justify-content: center; } .page-item.active .page-link { background-color: rgb(194, 197, 229); border: 1px solid rgb(201, 201, 201); } /**********************list-wrapper *********************/ .list-wrapper { } .list-wrapper table > thead > tr > :nth-child(1) { width: 10%; } .list-wrapper table > thead > tr > :nth-child(3) { width: 15%; } .list-wrapper table > thead > tr > :nth-child(4) { width: 20%; } .list-wrapper table > thead > tr > :nth-child(5) { width: 10%; }
    2. 입력 폼 만들기
    • html
    <section class="create-wrapper wrapper">
          <form class="create-form form-inline" onsubmit="return onSubmit(this)">
            <input type="text" name="writer" class="form-control" placeholder="작성자">
            <input type="text" name="content" class="form-control" placeholder="글 작성하기" autofocus>
            <button class="btn btn-secondary">등록</button>
          </form>
        </section>
    
    • css
    .create-wrapper {
      padding: 0.75em 0;
      display: none;
    }
    .create-wrapper .create-form {
      display: flex;
      align-items: center;
    }
    .create-wrapper .create-form input[name='content'] {
      flex-grow: 1;
      margin: 0 0.75em;
    }
    
    3. 게시판에 올리기
    • js
        • onSubmit 함수 실행
          1. 작성자와 내용이 빈칸으로 제출되지 않게 함
          2. data 변수 정의: 작성자, 작성내용, 작성시간, 유저아이디(구글계정로그인), 조회수
          3. 유저가 비어있지 않고 유저아이디(계정마다 생성되는 고유값)이 있다면 데이터베이스의 루트-보드에 data 전송(firebase의 데이터베이스에 저장)
          4. 그리고 내용 작성 폼 포맷
      • db 변수와 onAdded 함수
        1. db 는 firebase.database 모듈
        2. db의 ref('root/board')안에 자식요소가 추가되면 onAdded 함수 실행
        3. k는 데이터베이스의 고유아이디, v는 배열 안의 값, i는 html 안의 표 개수
        4. k는 작성된 폼의 아이디, v는 데이터의 값(작성자와 작성시간 등..), i는 작성된 순서
        5. html 안의 tbody 전에 위의 html 생성값 붙이기
      ;/******************************* 글로벌 설정 ********************************/
      var auth = firebase.auth();	//firebase의 auth(인증)모듈을 불러온다.
      var googleAuth = new firebase.auth.GoogleAuthProvider(); //구글로그인 모듈을 불러온다.
      var db= firebase.database();//firebase data 모듈
      var user = null;
      
      var $tbody = $('.list-wrapper tbody');
      
      /******************************* 사용자 함수 *******************************/
      $tbody.empty();
      $('.create-wrapper input[name="content"]').val('');
      
      /******************************* 이벤트 등록 ******************************/
      auth.onAuthStateChanged(onChangeAuth);
      db.ref('root/board').on('child_added',onAdded);//데이터베이스의 루트-보드에 자식요소가 추가되면 
      // ref.on('child_removed', onRemoved);
      $('.bt-login').click(onLoginGoogle);
      $('.bt-logout').click(onLogOut);
      
      /******************************* 이벤트 콜백 *****************************/
      function onAdded(r){//이벤트 실행!
          var k =r.key;
          var v =r.val();
          var i = $tbody.find('tr').length+1;
          var html = '';
          html += '<tr id ="'+k+'">';
          html += '<td>'+i+'</td>';
          html += '<td class="text-left">'+v.content+'</td>';
          html += '<td>'+v.writer+'</td>';
          html += '<td>'+moment(v.createAt).format('MM-DD HH:mm:ss')+'</td>';
          html += '<td>'+v.readnum+'</td>';
          html += '</tr>';
          $tbody.prepend(html);
      }
      
      function onRemoved(r){
      
      }
      
      function onSubmit(f){
          if(f.writer.value.trim()===''){
              alert('작성자를 입력해주세요.');
              f.writer.focus();
              return false;
          }
          if(f.content.value.trim()===''){
              alert('내용을 입력해주세요.');
              f.content.focus();
              return false;
             
          }  
      
          var data = {
              writer: f.writer.value,
              content: f.content.value,
              createAt: new Date().getTime(),
              uid:user.uid,
              readnum: 0//조회수
          
          }
          if(user && user.uid){
              db.ref('root/board/').push(data);
              $('.create-wrapper input[name="content"]').val('');
             
          }
          else alert('비정상적인 접근입니다.')
      
          return false;
         
      	
      	
      
      }
      function onChangeAuth(r){
         user = r;
         console.log(user);
         if(user){
          $('.header-wrapper .email').text(user.email);
          $('.header-wrapper .photo img').attr('src', user.photoURL);
          $('.header-wrapper .info-wrap').css('display','flex');
          $('.create-wrapper').show();
          $('.create-wrapper input[name="writer"]').val(user.displayName);
          $('.bt-login').hide();
          $('.bt-logout').show();
         }
         else{
          $('.header-wrapper .email').text('');
          $('.header-wrapper .photo').attr('src', '//via.placeholder.com/1x1/333/');
          $('.create-wrapper').hide();
          $('.header-wrapper .info-wrap').css('display','none');
          $('.create-wrapper input[name="writer"]').val('');
          $('.create-wrapper input[name="content"]').val('');
          $('.bt-login').show();
          $('.bt-logout').hide();
          console.log('welcome');
         }
      }
      
      function onLogOut(){
          console.log("hi");
          firebase.auth().signOut().then(() => {
              // Sign-out successful.
            }).catch((error) => {
              // An error happened.
            });
            
      }
      
      function onLoginGoogle(){
          auth.signInWithPopup(googleAuth);
          
      }
      

728x90
반응형

댓글