학원에서 일주일간 JSP로 개인프로젝트를 했다. 주제는 영어 학습 사이트. 벤치마킹?할 사이트는 캠블리로 선정했다.

강의 구매와 튜터 매칭 시스템, 캘린더에서 날짜를 골라서 수업을 듣는 기능은 구현하지 못했다. 

 

https://www.cambly.com/english?lang=ko

 

캠블리 Cambly, 전화영어 그 이상의 영어회화어플

Cambly에서 원어민 튜터와 언제 어디서나 간편하게 영어 수업을 받으시고, 영어 회화의 자신감을 키우세요!

www.cambly.com

 

내가 구현한 기능은

1. 회원가입, 로그인

2. 관리자 강의입력, 관리자 강의목록 보기 및 수정, 회원정보 수정

3. 사용자 강의목록 전체보기, 상세보기

4. 수강후기 게시판 전체보기, 회원 게시글 입력

5. 수강후기 게시글 상세보기 및 수정 삭제, 댓글 입력 삭제

6. 강의 장바구니 담기 및 삭제

 


사이트 디자인은 부트스트랩 템플릿을 이용했다.

https://startbootstrap.com/themes/landing-page/

 

Landing Page - Free Bootstrap 4 Landing Page Theme

A responsive Bootstrap 4 landing page theme by Start Bootstrap. All Start Bootstrap templates are free to download and open source.

startbootstrap.com

이외에도 다른 무료 부트스트랩 템플릿에 있는 사진들을 활용했다. 이 템플릿의 이름인 Wiser을 따와서 사이트 이름을 Wiser로 했다.

https://colorlib.com/wp/template/wiser/

 

Wiser - Free LMS Website Template Design 2020 - Colorlib

Wiser is a top-notch, responsive and free LMS website template design for establishing a striking online learning platform.

colorlib.com


DB구성 (Oracle SQL Developer)과 Table명

1. 회원과 관련된 DB -> WMember

2. 강의와 관련된 DB -> WClass

3. 수강후기 게시판 DB -> WBoard

4. 수강후기 댓글 DB -> WComment_Board

5. 장바구니 DB -> WCart

 

  • WClass의 기본키인 classnum(강의번호. 시퀀스로 부여)은 WBoard의 외래키로 참조된다. 
  • 수강후기 게시글에 해당하는 댓글 리스트를 보여줘야 하므로, WBoard의 기본키인 NUM은 WComment_Board의 BNUM 외래키로 참조된다.
  • (WMember의 classnum, WCart의 classnum또한 WClass의 classnum을 참조해야하는데 제약조건 설정을 빼먹었다..)

 

 


회원 DB관련 DTO (WmemberDTO.java)

 

package com.wmember.model;

public class WMemberDTO {
	private int num;
	private String name;
	private String userid;
	private String pwd;
	private String email;
	
	private int postcode;
	private String address;
	private String detailAddress;
	private String extraAddress;
	
	private String classnum;
	private String reg_date;
	private int admin;
	
	public int getPostcode() {
		return postcode;
	}
	public void setPostcode(int postcode) {
		this.postcode = postcode;
	}
	public String getAddress() {
		return address == null ? "" : address.trim();
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getDetailAddress() {
		return detailAddress == null ? "" : detailAddress.trim();
	}
	public void setDetailAddress(String detailAddress) {
		this.detailAddress = detailAddress;
	}
	public String getExtraAddress() {
		return extraAddress == null ? "" : extraAddress.trim();
	}
	public void setExtraAddress(String extraAddress) {
		this.extraAddress = extraAddress;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getName() {
		return name == null ? "" : name.trim();
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getUserid() {
		return userid == null ? "" : userid.trim();
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getPwd() {
		return pwd == null ? "" : pwd.trim();
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getEmail() {
		return email == null ? "" : email.trim();
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getClassnum() {
		return classnum == null ? "" : classnum.trim();
	}
	public void setClassnum(String classnum) {
		this.classnum = classnum;
	}
	public String getReg_date() {
		return reg_date == null ? "" : reg_date.trim();
	}
	public void setReg_date(String reg_date) {
		this.reg_date = reg_date;
	}
	public int getAdmin() {
		return admin;
	}
	public void setAdmin(int admin) {
		this.admin = admin;
	}
}

 


첫 시작화면에 해당하는 index.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/include/header.jsp" %>
<style>
h1{
	text-align: left;
}
</style>
  <!-- Masthead -->
  <header class="masthead text-white text-center">
    <div class="overlay"></div>
       
        <div class="mainLine">
          <span style="width: 100%; height: 200px;"></span>
          <h1 style="color:#484848; font-size: 48px; line-height: 1.5em;">생생한 원어민 화상영어,<br/> 지금바로 시작하세요!</h1>
        </div>
       
          <form>
            <div class="form-row" style="width: 30%;">
              <div class="col-12 col-md-9 mb-2 mb-md-0">
                <input type="email" class="form-control form-control-lg" placeholder="  이메일 주소">
              </div>
              <div class="col-12 col-md-3">
                <input type="button" value="회원가입" class="btn btn-block btn-lg btn-primary" onclick="location.href='/Tutoring/member/insert'">
              </div>
            </div>
          </form>
  </header>

  <!-- Icons Grid -->
  <section class="features-icons bg-light text-center">
    <div class="container">
      <div class="row">
        <div class="col-lg-4">
          <div class="features-icons-item mx-auto mb-5 mb-lg-0 mb-lg-3">
            <div class="features-icons-icon d-flex">
              <i class="icon-screen-desktop m-auto text-primary"></i>
            </div>
            <h3>수업</h3>
            <p class="lead mb-0">튜터와 만들어 나가는 유연한 학습 스케쥴</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="features-icons-item mx-auto mb-5 mb-lg-0 mb-lg-3">
            <div class="features-icons-icon d-flex">
              <i class="icon-layers m-auto text-primary"></i>
            </div>
            <h3>커리큘럼</h3>
            <p class="lead mb-0">내 레벨에 맞춰 선택해 더욱 체계적인 수업 진행</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="features-icons-item mx-auto mb-0 mb-lg-3">
            <div class="features-icons-icon d-flex">
              <i class="icon-check m-auto text-primary"></i>
            </div>
            <h3>수료증</h3>
            <p class="lead mb-0">10시간 이상 수업 시, 캠블리 수료증 발급</p>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- Testimonials -->
  <section class="testimonials text-center bg-light">
    <div class="container">
      <h2 class="mb-5">유학 없이도 유창하게 영어로 말할 수 있어요!</h2>
      <div class="row">
        <div class="col-lg-4">
          <div class="testimonial-item mx-auto mb-5 mb-lg-0">
            <img class="img-fluid rounded-circle mb-3" src="img/testimonials-1.jpg" alt="">
            <h5>Margaret E.</h5>
            <p class="font-weight-light mb-0">"I have been teaching English for 3 years. I am very patient, kind and I love to learn about new cultures and your thoughts about life."</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="testimonial-item mx-auto mb-5 mb-lg-0">
            <img class="img-fluid rounded-circle mb-3" src="img/testimonials-2.jpg" alt="">
            <h5>Fred S.</h5>
            <p class="font-weight-light mb-0">"A conversationalist, I have worked internationally in business (operations, sales, training and HR) and am also licensed to teach scuba!"</p>
          </div>
        </div>
        <div class="col-lg-4">
          <div class="testimonial-item mx-auto mb-5 mb-lg-0">
            <img class="img-fluid rounded-circle mb-3" src="img/testimonials-3.jpg" alt="">
            <h5>Sarah W.</h5>
            <p class="font-weight-light mb-0">"I own and run a small business, am easy to speak to and hold a TEFL qualification. I look forward to meeting you!"</p>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- Call to Action -->
  <section class="call-to-action text-white text-center">
    <div class="overlay"></div>
    <div class="container">
      <div class="row">
        <div class="col-xl-9 mx-auto">
          <h2 class="mb-4">내게 꼭 맞는 튜터를 찾아보세요</h2>
        </div>
        <div class="col-md-10 col-lg-8 col-xl-7 mx-auto">
          <form>
            <div class="form-row">
              <div class="col-12 col-md-9 mb-2 mb-md-0">
                <input type="email" class="form-control form-control-lg" placeholder="  이메일 주소">
              </div>
              <div class="col-12 col-md-3">
                 <input type="button" value="회원가입" class="btn btn-block btn-lg btn-primary" onclick="location.href='/Tutoring/member/insert'">
              </div>
            </div>
          </form>
        </div>
      </div>
    </div>
  </section>
<%@ include file="/include/footer.jsp" %>

 


header.jsp와 footer.jsp를 나누어서 페이지마다 포함시켰다.

 

header.jsp

 

sessionScope.userid 값이 비어있으면 로그인/회원가입 링크가, 

sessionScope.admin 값이 1이면 관리자이므로 관리자/로그아웃 링크가,

sessionScope.admin 값이 0이면 일반회원이므로 내계정/로그아웃 링크가 나타난다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>영어 수업</title>
  <!-- Bootstrap core CSS -->
  <link href="/Tutoring/vendor/bootstrap/css/bootstrap.css"  rel="stylesheet">
  <!-- Custom fonts for this template -->
  <link href="/Tutoring/vendor/fontawesome-free/css/all.css" rel="stylesheet">
  <link href="/Tutoring/vendor/simple-line-icons/css/simple-line-icons.css"  rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic,700italic"  rel="stylesheet" type="text/css">
  <!-- Custom styles for this template -->
  <link href="/Tutoring/css/landing-page.css" rel="stylesheet">
  
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  


</head>
<body>

  <!-- Navigation -->
  <nav class="navbar navbar-light bg-light static-top">
    <div class="container">
         <a class="navbar-brand" href="/Tutoring/index.jsp">Wiser English</a>
         <a class="navbar-nav" href="/Tutoring/include/about.jsp">와이저</a>
         <a class="navbar-nav" href="/Tutoring/class/courseList">과정</a>
    </div>
      <c:choose>
     	<c:when test="${empty sessionScope.userid}">
		    <ul class="navbar-nav">
		      <li class="nav-item">
		      	<a class="btn btn-gray" href="/Tutoring/member/login">로그인</a>
			    <a class="btn btn-primary" href="/Tutoring/member/insert">회원가입</a>
		      </li>
		  	</ul>
    	</c:when>
    	<c:when test="${sessionScope.admin==1}">
		    <ul class="navbar-nav">
		      <li class="nav-item">
		      	<a class="btn btn-gray" href="/Tutoring/member/Adminview">관리자</a>
			    <a class="btn btn-primary" href="/Tutoring/member/logout">로그아웃</a>
		      </li>
		  	</ul>
    	</c:when>
    	<c:when test="${sessionScope.admin==0}">
    		<ul class="navbar-nav">
		      <li class="nav-item">
		      	<a class="btn btn-gray" href="/Tutoring/member/view">내계정</a>
			    <a class="btn btn-info" href="/Tutoring/member/logout">로그아웃</a>
		      </li>
		  	</ul>
    	</c:when>
     </c:choose>  
  	
  </nav>
  
<!-- Bootstrap core JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="/Tutoring/vendor/jquery/jquery.js"></script>
<script src="/Tutoring/vendor/bootstrap/js/bootstrap.bundle.js"></script>

header.jsp 실행화면

 

sessionScope.userid, sessionScope.admin 값은 로그인을 할때 받아온다.

 


WMemberLoginAction.java

(로그인 링크에 해당하는 "/Tutoring/member/login" 경로의 서블릿이다.)

 

package com.wmember.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.wmember.model.WMemberDAO;

/**
 * Servlet implementation class WMemberLoginAction
 */
@WebServlet("/member/login")
public class WMemberLoginAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberLoginAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("login.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String userid=request.getParameter("userid");
		String pwd=request.getParameter("pwd");
		WMemberDAO dao=WMemberDAO.getInstance();
		int flag=dao.loginCheck(userid, pwd);
		int admin=-1;
		if(flag==0 || flag==1) {
			HttpSession session=request.getSession();
			session.setAttribute("userid", userid);
			admin=flag;
			session.setAttribute("admin", admin);
		}
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter(); 
		out.println(flag);
	}

}

 

  • a링크를 통해 이동하였으므로 doGet에서 처리된다. RequestDispatcher의 forward 메소드로 login.jsp로 이동한다.

  • login.jsp에서 ajax의 post방식으로 다시 WMemberLoginAction.java로 돌아온다. post방식이므로 doPost내에서 처리된다.
  • 파라미터 값으로 받아온 userid와 pwd를 들고 WMemberDAO.java내의 loginCheck 메소드를 실행한다. 
  • 리턴값을 flag에 담는다. 
  • 변수 admin을 -1값을 입력하여 선언한다. admin은 관리자, 일반회원을 구분하는 변수이다. 우선 모든 이용자는 일반회원으로 가입되고, DB에서 admin값에 1을 부여하여 관리자를 선별한다. 
  • loginCheck메소드에 의해 flag값이 0 또는 1로 저장되면 session값으로 userid를 받아온다. admin은 flag값과 통일되고 마찬가지로 session값으로 admin을 받는다.
  • out객체를 통해 flag값을 내보낸다.

 

<WMemberDAO.java 중 loginCheck메소드>

 

//디비셋팅
	private static WMemberDAO instance=new WMemberDAO();
	public static WMemberDAO getInstance() {
		return instance;
	}
	private Connection getConnection() throws Exception{
		Context initCtx=new InitialContext();
		Context envCtx=(Context) initCtx.lookup("java:comp/env");
		DataSource ds=(DataSource) envCtx.lookup("jdbc/wiser"); //context.xml의 name을 jdbc/member로 바꾸기
		return ds.getConnection();
	}
    
    
//로그인체크 (비밀번호 오류: 2, 회원아님: -1, 회원: 0, 관리자: 1)
	public int loginCheck(String userid, String pwd) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		int flag=-1;
		try {
			con=getConnection();
			String sql="select pwd, admin from wmember where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			if(rs.next()) { //id 맞음
				if(rs.getString("pwd").equals(pwd)) { //비번 일치
					flag=rs.getInt("admin");
				}else { //비번 오류
					flag=2;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return flag;
	}
    
//닫기 closeConnection
	private void closeConnection(Connection con, PreparedStatement ps) {
		try {
			if(ps!=null) ps.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}
	private void closeConnection(Connection con, Statement st, ResultSet rs) {
		try {
			if(st!=null) st.close();
			if(con!=null) con.close();
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} 
	}

 


login.jsp

  • 아이디와 패스워드를 입력하는 폼이 있다.
  • 자바스크립트 태그 안에서 공백을 확인하고 ajax를 이용하여 /Tutoring/member/login으로 다시 이동한다.
  • loginCheck을 끝내고 돌아온 flag값을 switch문을 통해 구분하고 alert창을 띄운 후 각각에 맞게 링크가 이동된다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<style>
img{
	display: inline-block;
	float: right;
}
#loginFrm{
	width: 60%;
	height: auto;
	position: absolute;
	top: 50%;
	left: 35%;
	transform: translate(-50%, -50%);
}
</style>
<div class="container-fluid">
	<div class="row">
		<div class="col-md-8">
			<img src="/Tutoring/img/banner.png" alt="loginImage">
		</div>
		<div class="col-md-4">
				<form action="login" method="post" id="loginFrm">
				  <div class="form-group">
				    <label for="userid">아이디</label>
				    <input type="text" class="form-control" id="userid" placeholder="Enter id" name="userid">
				  </div>
				  <div class="form-group">
				    <label for="pwd">패스워드</label>
				    <input type="password" class="form-control" id="pwd" placeholder="Enter password" name="pwd">
				  </div>
				  <button type="button" id="loginBtn" class="btn btn-primary" style="width: 100%;">로그인</button>
				</form>
		</div>
</div>
<script>
$("#loginBtn").click(function(){
	if($("#userid").val()==""){
		alert("아이디를 입력하세요");
		$("#userid").focus();
		return false;
	}
	if($("#pwd").val()==""){
		alert("암호를 입력하세요");
		$("#pwd").focus();
		return false;
	}
	$.ajax({
		type : "post",
		url  : "login",
		data : {"userid":$("#userid").val(), "pwd":$("#pwd").val()},
		success : function(value){
			switch(value.trim()){
			case "0" : alert("로그인 성공"); location.href="/Tutoring/index.jsp"; break;
			case "1" : alert("관리자 로그인"); location.href="/Tutoring/member/Adminview"; break;
			case "2" : alert("비밀번호 오류"); break;
			case "-1": alert("회원이 아닙니다"); location.href="/Tutoring/member/insert"; break;
			default: alert(value.trim());
			}
		},
		error: function(e){
			alert("error:"+e);
		}
	})
})//loginBtn
</script>
<%@ include file="../include/footer.jsp" %>

 

  • 로그인에 성공했을경우 시작페이지로 이동하고 
  • 관리자로 로그인했을경우 관리자 페이지로 이동,
  • 회원이 아니라고 판단되었을 경우 회원가입페이지로 이동한다.

WMemberInsert.java (/Tutoring/member/insert)

(회원가입 링크에 해당하는 "/Tutoring/member/insert" 경로의 서블릿이다.)

package com.wmember.action;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wmember.model.WMemberDAO;
import com.wmember.model.WMemberDTO;

/**
 * Servlet implementation class WMemberInsertAction
 */
@WebServlet("/member/insert")
public class WMemberInsertAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberInsertAction() {
        super();
        // TODO Auto-generated constructor stub
    }

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    RequestDispatcher rd=request.getRequestDispatcher("join.jsp");
    rd.forward(request, response);
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("utf-8");
    WMemberDAO dao=WMemberDAO.getInstance();
    WMemberDTO member=new WMemberDTO();
    member.setName(request.getParameter("name"));
    member.setUserid(request.getParameter("userid"));
    member.setPwd(request.getParameter("pwd"));
    member.setEmail(request.getParameter("email"));
    member.setPostcode(Integer.parseInt(request.getParameter("sample6_postcode")));
    member.setAddress(request.getParameter("sample6_address"));
    member.setDetailAddress(request.getParameter("sample6_detailAddress"));
    member.setExtraAddress(request.getParameter("sample6_extraAddress"));

    dao.memberInsert(member);
    response.sendRedirect("login");
    }

}

 

  • a링크를 통해 이동하였으므로 doGet에서 처리된다. RequestDispatcher의 forward 메소드로 join.jsp로 이동한다.

 

 


join.jsp

  • 아이디, 아이디중복확인 버튼, 이름, 비밀번호, 비밀번호 확인, 우편번호 입력 폼이다.
  • 우편번호는 다음 우편번호 API를 이용하였고 예제 자바스크립트 코드를 그대로 복사 붙여넣기했다. 
  • 회원정보 수정할때 주소를 다시 고칠 것을 생각하여 WMemberDB에서 우편번호, 주소, 상세주소, 여분의 주소 컬럼을 만들었다. 
  • 아이디 중복과 여백확인등은 member.js 파일을 만들어서 그곳에서 처리하였다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../include/header.jsp" %>
<script src="/Tutoring/js/member.js"></script>
<style>
img{
	display: inline-block;
	float: right;
}
#frm{
	width: 60%;
	height: auto;
	position: absolute;
	top: 50%;
	left: 35%;
	transform: translate(-50%, -50%);
}
.button{
	text-align: center;
	margin: 0 auto;
	padding: 20px;
}
</style>
<div class="container-fluid">
	<div class="row">
		<div class="col-md-7">
			<img src="/Tutoring/img/join.jpg" alt="joinImage">
		</div>
		<div class="col-md-5">
			<form action="insert" method="post" id="frm">
			  <br/><br/>
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">아이디</span>
			    </div>
			      <input type="text" class="form-control" id="userid" name="userid" readonly="readonly" size=20>
			    <div class="col align-self-end" >
			          <button  type="button"  id="idcheckBtn"  class="btn btn-primary">중복확인</button>
			   	</div>
			  </div>
			  <br/>
			   
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">이름</span>
			    </div>
			      <input type="text" class="form-control" id="name" name="name">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">비밀번호</span>
			    </div>
			    <input type="password" class="form-control" placeholder="6자리 이상" id="pwd" name="pwd">
			    <input type="password" class="form-control" placeholder="비밀번호 확인" id="pwd_check" name="pwd_check">
			  </div>
			  <br/>
			  
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">이메일</span>
			    </div>
			      <input type="text" class="form-control" id="email" name="email" placeholder="email@email.com">
			  </div>
			  <br/>
			    
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">우편번호</span>
			    </div>
			      <input type="text" id="sample6_postcode" name="sample6_postcode" readonly="readonly" class="form-control">
			    <div class="col align-self-end" >
			      <input type="button" onclick="sample6_execDaumPostcode()" value="우편번호" class="btn btn-primary"><br>
			   	</div>
			  </div>
			  <br/>  
			
			  <div class="input-group mb-3">
			    <div class="input-group-prepend">
			      <span class="input-group-text">주소</span>
			    </div>
			    <input type="text" id="sample6_address" name="sample6_address" placeholder="주소" class="form-control"><br>
			  </div>
			
			  <div class="input-group mb-3">
				<input type="text" id="sample6_detailAddress" name="sample6_detailAddress" placeholder="상세주소" class="form-control">
				<input type="text" id="sample6_extraAddress" name="sample6_extraAddress" placeholder="참고항목" class="form-control">
			  </div>
			    
			  <div class="button">
			 	  <input type="reset" class="btn btn-gray" value="취소">
			 	  <button  id="send"  class="btn btn-primary">회원가입</button>
			  </div>
	  </div>
	</form>
	</div>
</div>
<%@ include file="../include/footer.jsp" %>
<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    function sample6_execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
                if(data.userSelectedType === 'R'){
                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있고, 공동주택일 경우 추가한다.
                    if(data.buildingName !== '' && data.apartment === 'Y'){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                    if(extraAddr !== ''){
                        extraAddr = ' (' + extraAddr + ')';
                    }
                    // 조합된 참고항목을 해당 필드에 넣는다.
                    document.getElementById("sample6_extraAddress").value = extraAddr;
                
                } else {
                    document.getElementById("sample6_extraAddress").value = '';
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('sample6_postcode').value = data.zonecode;
                document.getElementById("sample6_address").value = addr;
                // 커서를 상세주소 필드로 이동한다.
                document.getElementById("sample6_detailAddress").focus();
            }
        }).open();
    }
</script>

 


 

 

http://postcode.map.daum.net/guide

 

Daum 우편번호 서비스

우편번호 검색과 도로명 주소 입력 기능을 너무 간단하게 적용할 수 있는 방법. Daum 우편번호 서비스를 이용해보세요. 어느 사이트에서나 무료로 제약없이 사용 가능하답니다.

postcode.map.daum.net

 


member.js

email의 경우 정규식을 입력하여 정확하게 입력하도록 유도했다.

id중복확인 버튼을 누를 경우 idCheck.jsp 새 창이 뜬다. 

var reg_email = /^([0-9a-zA-Z_\.-]+)@([0-9a-zA-Z_-]+)(\.[0-9a-zA-Z_-]+){1,2}$/;


$(document).ready(function(){
	$("#send").click(function(){
		//아이디가 공백일때
		if($("#userid").val()==""){
			alert("아이디를 입력하세요");
			$("#userid").focus();
			return false;
		}
		//암호가 공백일때
		if($("#pwd").val()==""){
			alert("암호를 입력하세요");
			$("#pwd").focus();
			return false;
		}
		//암호확인이 공백일때
		if($("#pwd_check").val()==""){
			alert("암호확인 필수");
			$("#pwd_check").focus();
			return false;
		}
		//암호 일치확인
		if($("#pwd").val()!=$("#pwd_check").val()){
			alert("암호 불일치");
			$("#pwd_check").focus();
			return false;
		}
		if($("#pwd").val().length<6){
	        alert("비밀번호는 6글자 이상이어야 합니다.");
	        pw1.value="";
	        pw1.focus();
	        return false;
	    }
		//이름이 공백일때
		if($("#name").val()==""){
			alert("이름을 입력하세요");
			return false;
		}
		//이메일이 공백일때
		if($("#email").val()==""){
			alert("이메일을 입력하세요");
			return false;
		}
		//이메일 양식
		if(!$("#email").val().match(reg_email)){
			alert("이메일을 정확하게 입력하세요");
			$("#email").focus();
			return false;
		}
		$("#frm").submit();
	})//send
	
	//아이디 중복체크 버튼
	$("#idcheckBtn").click(function(){
		window.open("idCheck", "", "width=600 height=500")
	}); //idcheckBtn
	
	//id중복확인 사용버튼
	$("#useBtn").click(function(){
		if($("#userid").val()==""){
			alert("아이디를 입력하세요");
			$("#userid").focus();
			return false;
		}
		$.ajax({
			type: "post",
			url : "idCheck",
			data: {"userid":$("#userid").val()},
			success: function(val){
				if(val.trim()=="yes"){
					alert("사용가능한 아이디");
					$(opener.document).find("#userid").val($("#userid").val());
					self.close();
				}else if(val.trim()=="no"){
					alert("중복된 아이디");
					$("#userid").val("");
				}
			},
			error: function(e){
				alert("error:"+e);
			}
		}); //ajax
	}) //useBtn
	
});//document

 

  • ajax를 이용하여 post방식으로 WMemberIdCheck.java 서블릿으로 이동하고 받아온 값에 따라 alert창을 다르게 띄운다. 사용가능한 아이디일 경우 회원가입 창의 userid칸에 그 값이 담긴다.

 


idCheck.jsp

  • member.js에서 팝업된 화면으로 id입력 칸과 사용여부 버튼이 있다.
  • member.js를 포함하고 있으므로 사용여부 버튼 ("#useBtn")을 누를경우 WMemberIdCheck.java로 이동한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<script src="/Tutoring/js/member.js"></script>

<div class="container">
    <div class="row">
	    <div class="col">
	      <br/>
	      <input type="text" class="form-control" id="userid" placeholder="Enter id" name="userid" >
	    </div>
      	<div class="col align-self-end" >
          <button  type="button"  id="useBtn"  class="btn btn-primary">사용여부</button>
   		</div>
    </div>
</div>

 

 


WMemberIdCheck.java

(아이디 중복확인 체크 서블릿)

package com.wmember.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wmember.model.WMemberDAO;

/**
 * Servlet implementation class MemberIdCheck
 */
@WebServlet("/member/idCheck")
public class WMemberIdCheck extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WMemberIdCheck() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd=request.getRequestDispatcher("idCheck.jsp");
		rd.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String userid=request.getParameter("userid");
		WMemberDAO dao=WMemberDAO.getInstance();
		String flag=dao.idCheck(userid);
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();                     
		out.println(flag);
	}
}

 

  • ajax에서 post방식으로 넘어왔으므로 doPost내에서 실행된다. 파라미터 값으로 userid를 받아와서 WMemberDAO.java의 idCheck메소드로 이동한다.
  • flag 값을 받아와서 다시 idCheck.jsp로 이동

 

<WMemberDAO.java의 idCheck메소드>

 

//아이디 중복확인 사용하기 버튼
	public String idCheck(String userid) {
		Connection con=null;
		Statement st=null;
		ResultSet rs=null;
		String flag="yes"; //사용가능
		try {
			con=getConnection();
			String sql="select * from wmember where userid='"+userid+"'";
			st=con.createStatement();
			rs=st.executeQuery(sql);
			if(rs.next()) {
				flag="no"; //사용불가능
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, st, rs);
		}
		return flag;
	}

 


다시 회원가입 join.jsp로 돌아와서.. 버튼 id가 send, form action의 경로는 insert, 방식은 post임을 확인할 수 있다.

 

<form action="insert" method="post" id="frm">
<button  id="send"  class="btn btn-primary">회원가입</button>

 

member.js에서 공백확인 등을 거치고 폼이 submint 되면 insert서블릿으로 이동한다.

 

$("#frm").submit();

 


WMemberInsertAction.java

(앞에서 본 회원가입 서블릿으로 doPost부분만 가져왔다.)

 

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		WMemberDAO dao=WMemberDAO.getInstance();
		WMemberDTO member=new WMemberDTO();
		member.setName(request.getParameter("name"));
		member.setUserid(request.getParameter("userid"));
		member.setPwd(request.getParameter("pwd"));
		member.setEmail(request.getParameter("email"));
		member.setPostcode(Integer.parseInt(request.getParameter("sample6_postcode")));
		member.setAddress(request.getParameter("sample6_address"));
		member.setDetailAddress(request.getParameter("sample6_detailAddress"));
		member.setExtraAddress(request.getParameter("sample6_extraAddress"));
		
		dao.memberInsert(member);
		response.sendRedirect("login");
	}

 

 


<WMemberDAO.java의 memberInsert메소드>

 

//회원가입
	public void memberInsert(WMemberDTO vo) {
		Connection con=null;
		PreparedStatement ps=null;
		
		try {
			con=getConnection();
			String sql="INSERT INTO wmember(num, name, userid, pwd, email, address, "
					+ "classnum, reg_date, postcode, detailaddress, extraaddress, admin)"
					+ "VALUES(wmember_seq.nextval,?,?,?,?,?,0,sysdate,?,?,?,0)";
			ps=con.prepareStatement(sql);
			ps.setString(1, vo.getName());
			ps.setString(2, vo.getUserid());
			ps.setString(3, vo.getPwd());
			ps.setString(4, vo.getEmail());
			ps.setString(5, vo.getAddress());
			ps.setInt(6, vo.getPostcode());
			ps.setString(7, vo.getDetailAddress());
			ps.setString(8, vo.getExtraAddress());
			ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeConnection(con, ps);
		}
	}

 

 

 


https://github.com/kkj0712/JspProject_Tutoring

 

kkj0712/JspProject_Tutoring

Contribute to kkj0712/JspProject_Tutoring development by creating an account on GitHub.

github.com

 

  • webcontent에 file 이라는 폴더 만들기. upload.jsp 생성

  • cos.jar 라는 라이브러리 파일을 lib 폴더에 넣음. 

  • com.file 패키지 만들고 FileUploadAction.java 서블릿 생성 (경로는 /file/upload.do)

  • WebContent안에 upload폴더를 만들기 (파일 저장 경로)

 

 

  • upload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<form method="post" action="upload.do" enctype="multipart/form-data">

글쓴이: <input type="text" name="name"><br>

제목: <input type="text" name="title"><br>

파일 지정하기: <input type="file" name="uploadFile"><br>

<input type="submit" value="전송">

</form>

</body>

</html>

  • FileUploadAction.java

 

package com.file;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;

import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

/**

 * Servlet implementation class FileUploadAction

 */

@WebServlet("/file/upload.do")

public class FileUploadAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public FileUploadAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        int uploadFileSizeLimit=5*1024*1024; //5mb로 지정

        String encType="UTF-8";

        String savePath="upload";

        ServletContext context=getServletContext();

        String uploadFilePath=context.getRealPath(savePath);

        System.out.println("서버 상의 실제 디렉토리: "+uploadFilePath);

        

        //multipart/form 방식은 request.getParameter로 받아올 수 없음

        MultipartRequest multi=new MultipartRequest(

                request, //request객체

                uploadFilePath, //서버상의 실제 디렉토리

                uploadFileSizeLimit, //최대 업로드 파일 크기

                encType, //인코딩 방법

                new DefaultFileRenamePolicy()); //동일 파일 새이름 부여

        //업로드된 파일이름 구하기

        String fileName=multi.getFilesystemName("uploadFile");

        System.out.println("fileName:"+fileName);

        if(fileName==null) { //파일 업로드 안됨

            System.out.println("파일 업로드 되지 않았음");

        }else {

            response.setContentType("text/html;charset=utf-8");

            PrintWriter out=response.getWriter();

            out.println("<b>글쓴이: "+multi.getParameter("name")+"<br>");

            out.println("<b>제목: "+multi.getParameter("title")+"<br>");

            out.println("<b>파일명: "+fileName);

        }

    }

}

 

 

<완성된 화면>

<로그인 페이지>

 

 

<로그인했을때>

 

 

 

  • Dynamic Web Project로 ServletGuest라는 프로젝트 만들기. Generate web.xml에 체크하기

 

 

  • WebContent에 guestbook이라는 폴더 만들고, insert.jsp 만들기 (폼태그)

  • Java Resources-src-com.guest.model 패키지 만들고 GuestDTO.java 만들기 (getter, setter)

    • Preferences에 getter body가 다음과 같이 설정되어야 함

 

    • num은 정수형 변수이므로 getNum()은 return num;으로만 설정

 

  • WEB-INF 폴더의 lib 폴더안에 jstl-1.2.jar 파일, json-simple-1.1.1.jar파일을 붙여넣는다.

 


 

<데이터베이스>

  • 오라클 SQL 디벨로퍼 열고 scott계정에 guestbook 테이블 생성

 

  • num에 해당하는 시퀀스 생성

 


  • com.guest.model패키지에 GuestDAO.java 만들기 (디비셋팅, 추가, 전체보기, 상세보기 등)

    • 디비셋팅할때 DataSource의 lookup 메소드 인자를 jdbc/guest로 수정

    • 전 프로젝트의 META-INF의 context.xml을 복사해서 현재 프로젝트 META-INF폴더 안에 복사해놓고 name="jdbc/guest"로 수정

 

<GuestDAO.java>

package com.guest.model;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.sql.DataSource;

public class GuestDAO {

    //디비셋팅

    private static GuestDAO instance=new GuestDAO();

    public static GuestDAO getInstance() {

        return instance;

    }

    private Connection getConnection() throws Exception{

        Context initCtx=new InitialContext();

        Context envCtx=(Context) initCtx.lookup("java:comp/env");

        DataSource ds=(DataSource) envCtx.lookup("jdbc/guest"); //context.xml의 name을 jdbc/guest로 바꾸기

        return ds.getConnection();

    }

    

    //추가

    public void guestInsert(GuestDTO guest) {

        Connection con=null;

        PreparedStatement ps=null;

        

        try {

            con=getConnection();

            String sql="insert into guestbook(num, name, content, grade, created, ipaddr)"

                    + "values (guestbook_seq.nextval,?,?,?,sysdate,?)";

            ps=con.prepareStatement(sql);

            ps.setString(1, guest.getName());

            ps.setString(2, guest.getContent());

            ps.setString(3, guest.getGrade());

            ps.setString(4, guest.getIpaddr());

            ps.executeUpdate();

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con,ps);

        }

    }

    

    //전체보기 페이징

    public ArrayList<GuestDTO> guestList(int startRow, int endRow){

        Connection con=null;

        PreparedStatement ps=null;

        ResultSet rs=null;

        ArrayList<GuestDTO> arr=new ArrayList<GuestDTO>();

        

        try {

            con=getConnection();

            StringBuilder sb=new StringBuilder();

            sb.append("select * from");

            sb.append(" (select aa.*, rownum rn from");

            sb.append(" (select * from guestbook order by num desc) aa");

            sb.append(" where rownum<=?) where rn>=?");

            ps=con.prepareStatement(sb.toString());

            ps.setInt(1, endRow);

            ps.setInt(2, startRow);

            rs=ps.executeQuery();

            while(rs.next()) {

                GuestDTO dto=new GuestDTO();

                dto.setNum(rs.getInt("num"));

                dto.setContent(rs.getString("content"));

                dto.setCreated(rs.getString("created"));

                dto.setGrade(rs.getString("grade"));

                dto.setIpaddr(rs.getString("ipaddr"));

                dto.setName(rs.getString("name"));

                arr.add(dto);

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, ps, rs);

        }

        return arr;

    }

    

    //검색 전체보기 페이징

    public ArrayList<GuestDTO> guestList(String field, String word, int startRow, int endRow){

        Connection con=null;

        PreparedStatement ps=null;

        ResultSet rs=null;

        ArrayList<GuestDTO> arr=new ArrayList<GuestDTO>();

        

        try {

            con=getConnection();

            StringBuilder sb=new StringBuilder();

            sb.append("select * from");

            sb.append(" (select aa.*, rownum rn from");

            sb.append(" (select * from guestbook where "+field+" like '%"+word+"%'");

            sb.append(" order by num desc) aa");

            sb.append(" where rownum<=?) where rn>=?");

            ps=con.prepareStatement(sb.toString());

            ps.setInt(1, endRow);

            ps.setInt(2, startRow);

            rs=ps.executeQuery();

            while(rs.next()) {

                GuestDTO dto=new GuestDTO();

                dto.setNum(rs.getInt("num"));

                dto.setContent(rs.getString("content"));

                dto.setCreated(rs.getString("created"));

                dto.setGrade(rs.getString("grade"));

                dto.setIpaddr(rs.getString("ipaddr"));

                dto.setName(rs.getString("name"));

                arr.add(dto);

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, ps, rs);

        }

        return arr;

    }

    

    

    //전체보기

    public ArrayList<GuestDTO> guestList(){

        Connection con=null;

        Statement st=null;

        ResultSet rs=null;

        ArrayList<GuestDTO> arr=new ArrayList<GuestDTO>();

        

        try {

            con=getConnection();

            st=con.createStatement();

            String sql="select * from guestbook order by num desc";

            rs=st.executeQuery(sql);

            while(rs.next()) {

                GuestDTO dto=new GuestDTO();

                dto.setNum(rs.getInt("num"));

                dto.setContent(rs.getString("content"));

                dto.setCreated(rs.getString("created"));

                dto.setGrade(rs.getString("grade"));

                dto.setIpaddr(rs.getString("ipaddr"));

                dto.setName(rs.getString("name"));

                arr.add(dto);

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, st, rs);

        }

        return arr;

    }

    

    //상세보기

    public GuestDTO guestView(int num) {

        Connection con=null;

        Statement st=null;

        ResultSet rs=null;

        GuestDTO guest=null;

        try {

            con=getConnection();

            st=con.createStatement();

            String sql="select * from guestbook where num="+num;

            rs=st.executeQuery(sql);

            if(rs.next()) {

                guest=new GuestDTO();

                guest.setNum(rs.getInt("num"));

                guest.setContent(rs.getString("content"));

                guest.setCreated(rs.getString("created"));

                guest.setGrade(rs.getString("grade"));

                guest.setIpaddr(rs.getString("ipaddr"));

                guest.setName(rs.getString("name"));

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, st, rs);

        }

        return guest;

    }

    

    //평가 리스트 개수 출력

    public int guestCount() {

        Connection con=null;

        Statement st=null;

        ResultSet rs=null;

        int count=0;

        

        try {

            con=getConnection();

            String sql="select count(*) from guestbook";

            st=con.createStatement();

            rs=st.executeQuery(sql);

            if(rs.next()) {

                count=rs.getInt(1);

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, st, rs);

        }

        return count;

    }

    

    //검색 평가 리스트 개수 출력

        public int guestCount(String field, String word) {

            Connection con=null;

            Statement st=null;

            ResultSet rs=null;

            int count=0;

            String sql="";

            try {

                con=getConnection();

                st=con.createStatement();

                if(word.equals("")) {

                    sql="select count(*) from guestbook";

                }else {

                    sql="select count(*) from guestbook where "+field+" like '%"+word+"%'";

                }

                rs=st.executeQuery(sql);

                if(rs.next()) {

                    count=rs.getInt(1);

                }

            } catch (Exception e) {

                e.printStackTrace();

            } finally {

                closeConnection(con, st, rs);

            }

            return count;

        }

    

    //삭제

    public void guestDelete(int num) {

        Connection con=null;

        Statement st=null;

        try {

            con=getConnection();

            String sql="delete from guestbook where num="+num;

            st=con.createStatement();

            st.executeUpdate(sql);

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, st, null);

        }

    }

        

    //로그인체크 (비밀번호 오류: 2, 회원아님: -1, 관리자: 1, 일반회원: 0)

    public int guestLoginCheck(String userid, String pwd) {

        Connection con=null;

        Statement st=null;

        ResultSet rs=null;

        int flag=-1;

        

        try {

            con=getConnection();

            String sql="select pwd, admin from jmember where userid='"+userid+"'";

            st=con.createStatement();

            rs=st.executeQuery(sql);

            if(rs.next()) { //id 맞음

                if(rs.getString("pwd").equals(pwd)) { //비번 일치

                    flag=rs.getInt("admin");

                }else { //비번 오류

                    flag=2;

                }

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            closeConnection(con, st, rs);

        }

        return flag;

    }

    

    //닫기 closeConnection

        private void closeConnection(Connection con, PreparedStatement ps) {

            try {

                if(ps!=null) ps.close();

                if(con!=null) con.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

        private void closeConnection(Connection con, Statement st, ResultSet rs) {

            try {

                if(st!=null) st.close();

                if(con!=null) con.close();

                if(rs!=null) rs.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

}

 

 


<GuestDTO.java>



package com.guest.model;

public class GuestDTO {

    private int num;

    private String name;

    private String content;

    private String grade;

    private String created;

    private String ipaddr;

    

    public int getNum() {

        return num;

    }

    public void setNum(int num) {

        this.num = num;

    }

    public String getName() {

        return name == null ? "" : name.trim();

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getContent() {

        return content == null ? "" : content.trim();

    }

    public void setContent(String content) {

        this.content = content;

    }

    public String getGrade() {

        return grade == null ? "" : grade.trim();

    }

    public void setGrade(String grade) {

        this.grade = grade;

    }

    public String getCreated() {

        return created == null ? "" : created.trim();

    }

    public void setCreated(String created) {

        this.created = created;

    }

    public String getIpaddr() {

        return ipaddr == null ? "" : ipaddr.trim();

    }

    public void setIpaddr(String ipaddr) {

        this.ipaddr = ipaddr;

    }

}

 


 

<insert.jsp>

  • submit전송 버튼을 누르면 create.gb로 가도록 함.

  • com.guest.action이란 패키지안에 서블릿으로 GuestInsertAction.java 생성하여 액션 실행. (서블릿의 경로는 guestbook/create.gb)

  • com.guest.model에 들어있는 GuestDAO.java파일에서 guestInsert()메소드를 호출하도록 함

  • GuestInsertAction.java에서 guestInsert를 실행하고나면 list.gb로 가도록 함.

  • 이름과 내용에 글자수를 표시하도록 자바스크립트 함수 생성.

  • 상세보기 하게끔 fview() 자바스크립트 함수를 생성. (getJSON 사용. 콜백함수에서 결과 출력) 

  • 검색영역 생성 <form name="search" id="search">

 

 

<insert.jsp+ajax>

  • insert.jsp에서 내용을 입력하면 listResult.jsp로 넘어가지 말고 입력칸 바로 밑에 결과들이 뜨게 하고 싶다면? (댓글쓰기 처럼) ajax 비동기 방식으로 값을 뿌려주면 됨.

 

  • 검색찾기 버튼을 클릭하면 getData()함수를 호출함 (전체보기 함수) 단, 함수 호출 시 페이지 번호, field, word 값을 들고 가야함. getData(페이지 번호, field, word)로 함수 수정하기

  • count 함수도 수정

  • 검색결과의 페이징을 위해 pageUtil에 filed, word 변수 선언. 

  • 검색결과의 페이지가 제대로 안넘어간다? listResult.jsp에서 getData의 변수로 오는 field와 word는 문자열이니까 따옴표 혹은 홑따옴표로 감싸야함.

  • 삭제실행 추가

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

<meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>

<script>

$(document).ready(function(){

    getData(1, "", ""); //페이지 로드 시 전체 리스트 보기

    

    $("#btnSearch").on("click", function(){//검색버튼 클릭

        getData(1, $("#field").val(), $("#word").val());

        

    })//btnSearch

    

    $("#send").click(function(){ //전송버튼 클릭

        if(${sessionScope.login==null}){

            alert("로그인 필요");

            return false;

        }

        var name=$("#name").val();

        var content=$("#content").val();

        var grade=$("input:radio[name=grade]:checked").val();

        var postString="name="+name+"&content="+content+"&grade="+grade;

        $.ajax({

            type:   "post",

            url :   "create.gb",

            data:   postString,

            success:function(d){

                $("#result").html(d);

            },

            beforeSend: showRequest, //빈칸 확인

            error: function(e){

                alert("error:"+e);

            }

        })//ajax

    })//send

})//document

//전체보기 함수

function getData(pageNum, field, word){

    $.get("list.gb",

            {"pageNum":pageNum, "field":field, "word":word},

            function(d){

            $("#result").html(d);

    })

}//getData

//빈칸 확인

function showRequest(){

    if($("#name").val()==""){

        alert("이름을 입력하세요");

        $("#name").focus();

        return false;

    }

    if($("#content").val()==""){

        alert("내용을 입력하세요");

        $("#content").focus();

        return false;

    }

    if($("input:radio[name=grade]:checked").length==0){

        alert("평가를 해주세요");

        return false;

    }

    return true;

}//showRequest

//글자수 초과 함수

function textCount(obj,target){ //target: nameCount, contentCount

    var len=$("#"+obj.id).val().length;

    if(obj.size==len){

        alert("글자수 초과");

        return false;

    }

    $("#"+target).text(len);

}//textCount

//상세보기 함수

function fview(num){

    $.getJSON ("view.gb", {"num": num}, function(data){

                var htmlStr="<table align='center' border='1'>";

                    htmlStr+="<tr>";

                    htmlStr+="<th>번호</th>";

                    htmlStr+="<td>"+data.num+"</td>";

                    htmlStr+="</tr>";

                    htmlStr+="<tr>";

                    htmlStr+="<th>글쓴이</th>";

                    htmlStr+="<td>"+data.name+"</td>";

                    htmlStr+="</tr>";

                    htmlStr+="<tr>";

                    htmlStr+="<th>내용</th>";

                    htmlStr+="<td>"+data.content+"</td>";

                    htmlStr+="</tr>";

                    htmlStr+="<tr>";

                    htmlStr+="<th>평가</th>";

                    htmlStr+="<td>"+data.grade+"</td>";

                    htmlStr+="</tr>";

                    htmlStr+="<th>작성일</th>";

                    htmlStr+="<td>"+data.created+"</td>";

                    htmlStr+="</tr>";

                    htmlStr+="<tr>";

                    htmlStr+="<th>ip주소</th>";

                    htmlStr+="<td>"+data.ipaddr+"</td>";

                    htmlStr+="</tr>";

                    htmlStr+="</table>";

                $("#view").html(htmlStr);

            }//콜백함수

    )

} //fview

//삭제 함수

function fdelete(num, name){

    if(confirm("["+name+"]의 게시물을 삭제할까요?")){

        $.get ("delete.gb?num="+num, function(data){

            $("#result").html(data);

        })

    }

}

</script>

</head>

<body>

<c:if test="${sessionScope.login==null}">

    <a href="login.jsp">로그인</a>

</c:if>

<c:if test="${sessionScope.login!=null}">

    ${login}님 반갑습니다.

    <a href="logout.gb">로그아웃</a>

</c:if>

<br/><br/>

<form action="create.gb" method="post">

<table align="center" width=900px>

    <tr>

        <td align="center">글쓴이</td>

        <td>

            <input type="text" size="20" maxlength="20" id="name" name="name" onKeyup="textCount(this,'nameCount')">

            *20글자이내 (<span id="nameCount" style="color:red">0</span>)

        </td>

    </tr>

    <tr>

        <td align="center">내용</td>

        <td>

            <input type="text" size="70" maxlength="70" id="content" name="content" onKeyup="textCount(this,'contentCount')">

            *70글자이내 (<span id="contentCount" style="color:red">0</span>)

        </td>

    </tr>

    <tr>

        <td align="center">평가</td>

        <td>

            <input type="radio" name="grade" value="excellent">아주잘함(excellent)

            <input type="radio" name="grade" value="good">잘함(good)

            <input type="radio" name="grade" value="normal">보통(normal)

            <input type="radio" name="grade" value="fail">노력(fail)

        </td>

    </tr>

    <tr>

        <td colspan="2">

            <input type="submit" value="submit전송">

            <input type="button" value="ajax버튼 전송" id="send">

        </td>

    </tr>

</table>

</form>

<br/><br/>

<div align="center">

<form name="search" id="search">

    <select name="field" id="field">

        <option value="name">이름</option>

        <option value="content">내용</option>

    </select>

    <input type="text" name="word" id="word">

    <input type="button" value="찾기" id="btnSearch">

</form>

</div>

<br/><br/>

<div id="result" align="center"></div>

<hr>

<div id="view"></div>

</body>

</html>

 


<GuestInsertAction.java>

 

package com.guest.action;

import java.io.IOException;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.guest.model.GuestDAO;

import com.guest.model.GuestDTO;

/**

 * Servlet implementation class GuestInsertAction

 */

@WebServlet("/guestbook/create.gb")

public class GuestInsertAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public GuestInsertAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        RequestDispatcher rd=request.getRequestDispatcher("insert.jsp");

        rd.forward(request, response);

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        GuestDTO guest=new GuestDTO();

        guest.setName(request.getParameter("name"));

        guest.setContent(request.getParameter("content"));

        guest.setGrade(request.getParameter("grade"));

        guest.setIpaddr(request.getRemoteAddr());

        

        GuestDAO dao=GuestDAO.getInstance();

        dao.guestInsert(guest);

        response.sendRedirect("list.gb");

    }

}




<listResult.jsp>

  • list.gb는 GuestListAction.java 서블릿의 경로인데 여기서 guestList()메소드를 호출.

  • 메소드로 인해 불러온 값들은 listResult.jsp에 뿌려짐.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>   

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

<meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>

  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>

</head>

<body>

<h5>평가 리스트(<span id="cntSpan">${count}</span>)</h5>

<table class="table table-hover">

    <thead>

        <tr>

            <th>번호</th>

            <th>seq</th>

            <th>글쓴이</th>

            <th>평가</th>

            <th>작성일</th>

            <c:if test="${sessionScope.login!=null}">

            <th>삭제</th>

            </c:if>

        </tr>

    </thead>

    <tbody>

        <c:forEach items="${guest}" var="guest" varStatus="st">

        <tr>

            <td>${rowNo-st.index}</td>

            <td>${guest.num}</td>

            <td><a href="javascript:fview(${guest.num})">${guest.name}</a></td>

            <td>${guest.grade}</td>

            <td>${guest.created}</td>

            <c:if test="${sessionScope.login!=null}">

                <td><a href="javascript:fdelete(${guest.num},'${guest.name}')">삭제</a></td>

            </c:if>

        </tr>

        </c:forEach>

    </tbody>

</table>

<div align="center">

    <c:if test="${pu.startPage>pu.pageBlock }"> <!-- 이전 -->

        <a href="javascript:getData(${pu.startPage-pu.pageBlock},'${pu.field}','${pu.word}')">[이전]</a>

    </c:if>

    <c:forEach begin="${pu.startPage}" end="${pu.endPage}" var="i"><!-- 페이지 출력 -->

        <c:if test="${i==pu.currentPage}"> <!-- 현재 페이지 -->

            <c:out value="${i}"/>

        </c:if>

        <c:if test="${i!=pu.currentPage}"> <!-- 현재 페이지 아닌 경우 링크 부여-->

            <a href="javascript:getData(${i},'${pu.field}','${pu.word}')">${i}</a>

        </c:if>

    </c:forEach>

    <c:if test="${pu.endPage<pu.totPage}"> <!-- 다음-->

        <a href="javascript:getData(${pu.endPage+1},'${pu.field}','${pu.word}')">[다음]</a>

    </c:if>

</div>

</body>

</html>

 


<GuestListAction.java>

 

package com.guest.action;

import java.io.IOException;

import java.util.ArrayList;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.guest.model.GuestDAO;

import com.guest.model.GuestDTO;

import com.guest.model.PageUtil;

/**

 * Servlet implementation class GuestListAction

 */

@WebServlet("/guestbook/list.gb")

public class GuestListAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public GuestListAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        GuestDAO dao=GuestDAO.getInstance();

        

        String pageNum=request.getParameter("pageNum")==null? "1":request.getParameter("pageNum");

        int currentPage=Integer.parseInt(pageNum);

        int pageSize=5;

        int startRow=(currentPage-1)*pageSize+1;

        int endRow=currentPage*pageSize;

                

        int count=0;

        String field=request.getParameter("field")==null?"":request.getParameter("field");

        String word=request.getParameter("word")==null?"":request.getParameter("word");

        count=dao.guestCount(field, word);

        //총페이지 수

        int totPage=(count/pageSize)+(count%pageSize==0?0:1);

        int pageBlock=3;

        int startPage=((currentPage-1)/pageBlock)*pageBlock+1;

        int endPage=startPage+pageBlock-1;

        if(endPage>totPage) endPage=totPage;

        

        PageUtil pu=new PageUtil();

        pu.setCurrentPage(currentPage);

        pu.setEndPage(endPage);

        pu.setPageBlock(pageBlock);

        pu.setStartPage(startPage);

        pu.setTotPage(totPage);

        pu.setField(field);

        pu.setWord(word);

        

        ArrayList<GuestDTO> arr=null;

        if(word.equals("")) {

            arr=dao.guestList(startRow,endRow);

        }else {

            arr=dao.guestList(field, word, startRow,endRow);

        }

        

        

        int rowNo=count-((currentPage-1)*pageSize); //매 페이지의 시작번호

        

        request.setAttribute("rowNo", rowNo);

        request.setAttribute("pu", pu);

        request.setAttribute("guest", arr);

        request.setAttribute("count", count);

        

        RequestDispatcher rd=request.getRequestDispatcher("listResult.jsp");

        rd.forward(request, response);

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);

    }

}


<PageUtil.java>

  • 리스트의 페이지를 나타내고 싶으면? PageUtil.java 파일을 생성하여 페이지 수 표시에 관련된 변수 선언. getter setter.

 

package com.guest.model;

public class PageUtil {

    private int currentPage;

    private int endPage;

    private int startPage;

    private int totPage;

    private int pageBlock;

    private String field;

    private String word;

    

    public String getField() {

        return field == null ? "" : field.trim();

    }

    public void setField(String field) {

        this.field = field;

    }

    public String getWord() {

        return word == null ? "" : word.trim();

    }

    public void setWord(String word) {

        this.word = word;

    }

    public int getCurrentPage() {

        return currentPage;

    }

    public void setCurrentPage(int currentPage) {

        this.currentPage = currentPage;

    }

    public int getEndPage() {

        return endPage;

    }

    public void setEndPage(int endPage) {

        this.endPage = endPage;

    }

    public int getStartPage() {

        return startPage;

    }

    public void setStartPage(int startPage) {

        this.startPage = startPage;

    }

    public int getTotPage() {

        return totPage;

    }

    public void setTotPage(int totPage) {

        this.totPage = totPage;

    }

    public int getPageBlock() {

        return pageBlock;

    }

    public void setPageBlock(int pageBlock) {

        this.pageBlock = pageBlock;

    }

}

 

 


<view.gb>

  • GuestViewAction.java의 경로는 guestbook/view.gb. JSON 형태로 값을 출력

  • GuestDAO.java에서는 guestView()메소드 완성

 

package com.guest.action;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.ArrayList;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;

import org.json.simple.JSONObject;

import com.guest.model.GuestDAO;

import com.guest.model.GuestDTO;

/**

 * Servlet implementation class GuestViewAction

 */

@WebServlet("/guestbook/view.gb")

public class GuestViewAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public GuestViewAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    //void라서 리턴값이 없다. 그래서 JSON형태로 바꿔서 콜백함수를 통해 값을 돌려주는 것

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        int num=Integer.parseInt(request.getParameter("num"));

        GuestDAO dao=GuestDAO.getInstance();

        GuestDTO guest=dao.guestView(num);

        //자바 Object을 JSON형태로 바꿔야 한다..

        JSONObject obj=new JSONObject();

        obj.put("name", guest.getName());

        obj.put("content", guest.getContent());

        obj.put("created", guest.getCreated());

        obj.put("grade", guest.getGrade());

        obj.put("ipaddr", guest.getIpaddr());

        obj.put("num", guest.getNum());

        response.setContentType("text/html;charset=utf-8");

        PrintWriter out=response.getWriter();

        out.println(obj.toString());

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    

    }

}

 


 

<delete.gb>

  • GuestDeleteAction.java의 경로 guestbook/delete.gb. 

  • $.get 함수를 사용하여 insert.jsp에서 delete.gb 호출

  • delete.gb에서 guestDelete()메소드를 부르고 GuestDAO.java에서 메소드 완성

package com.guest.action;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.guest.model.GuestDAO;

/**

 * Servlet implementation class GuestDeleteAction

 */

@WebServlet("/guestbook/delete.gb")

public class GuestDeleteAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public GuestDeleteAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        int num=Integer.parseInt(request.getParameter("num"));

        GuestDAO dao=GuestDAO.getInstance();

        dao.guestDelete(num);

        response.sendRedirect("list.gb");

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);

    }

}


<login.jsp>

  • 로그인 기능 구현. ajax 콜백이 아닌 다른 페이지로 넘어감

  • GuestLoginAction.java의 경로는 guestbook/login.gb.

  • GuestDAO.java에서 guestLoginCheck()메소드 완성 (아이디와 비밀번호가 테이블에 있는지 확인하여 검사)

  • 회원이면 insert.jsp로, 회원이 아니면 다시 login.jsp로 가도록

 

 

  • session 값인 login이 있으면 삭제가 보이도록, session 값인 login이 없으면 삭제가 보이지 않도록 함. (sessionScope.login!=null)

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

<form action="login.gb" method="post">

  <label for="userid">ID</label>

  <input type="text" id="userid" name="userid">

  <label for="pwd">PW</label>

  <input type="password" id="pwd" name="pwd">

  <input type="submit" value="로그인">

  <span style="color:red">${errMsg}</span>

</form>

</body>

</html>


<GuestLoginAction.java>

 

package com.guest.action;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import com.guest.model.GuestDAO;

/**

 * Servlet implementation class GuestLoginAction

 */

@WebServlet("/guestbook/login.gb")

public class GuestLoginAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public GuestLoginAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        RequestDispatcher rd=request.getRequestDispatcher("login.jsp");

        rd.forward(request, response);

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        String userid=request.getParameter("userid");

        String pwd=request.getParameter("pwd");

        GuestDAO dao=GuestDAO.getInstance();

        int flag=dao.guestLoginCheck(userid, pwd); //jmember테이블 사용

        String path="";

        if(flag==0 || flag==1) {

            HttpSession session=request.getSession();

            session.setAttribute("login", userid);

            path="insert.jsp";

        }else if(flag==-1) { //회원 아님

            request.setAttribute("errMsg", "회원이 아닙니다.");

            path="login.jsp";

        }else if(flag==2) { //비번 오류

            request.setAttribute("errMsg", "비밀번호 오류");

            path="login.jsp";

        }

        RequestDispatcher rd=request.getRequestDispatcher(path);

        rd.forward(request, response);

    }

}

<GuestLogoutAction.java>

 

package com.guest.action;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

/**

 * Servlet implementation class GuestLogoutAction

 */

@WebServlet("/guestbook/logout.gb")

public class GuestLogoutAction extends HttpServlet {

    private static final long serialVersionUID = 1L;

      

    /**

     * @see HttpServlet#HttpServlet()

     */

    public GuestLogoutAction() {

        super();

        // TODO Auto-generated constructor stub

    }

    /**

     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession session=request.getSession();

        session.invalidate();

        response.sendRedirect("insert.jsp");

    }

    /**

     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);

    }

}

 

 

 

 

  • mainTest.html (메인페이지). 자유형식으로 만들기

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>메인페이지</title>

    <link rel="stylesheet" href="mainTest.css">

</head>

<body>

    <div id="container">

    <nav>

        <ul>

            <li><a href="mainTest.html">Home</a></li>

            <li><a href="aboutme.html">About me</a></li>

            <li><a href="#contact">Contact</a></li>

            <li><a href="#lyrics1">Lyrics</a></li>

        </ul>

    </nav>

    <header></header>

    <section>

            <a href="https://c11.kr/h0uk"><img src="images/mrok.jpg" width="100px" height="100px" ></a>

            <a href="https://amongthestar.tistory.com"><img src="images/mrok.jpg" width="100px" height="100px" ></a>

        <article id="contact">

            <p><i>email</i>  </p>

            <p><i>phone</i>  +82 10 1234 5678</p>

            <p><i>homepage</i>  amongthestar.tistory.com</p>

        </article>

        <article id="bgc">

        <article id="lyrics1">

            <p><i>Coffee & TV</i></p>

            <p>Do you feel like a chain store?<br> Practically floored<br> One of many zeros<br> Kicked around, bored<br> Your ears are full but you're empty<br> Holding out your heart<br> To people who never really<br> Care how you are<br> So give me coffee and TV, peacefully<br> I've seen so much, I'm going blind<br> And I'm brain-dead virtually<br> Sociability<br> Is hard enough for me<br> Take me away from this big, bad world<br> And agree to marry me<br> So we can start over again<br> Do you go to the country?<br>

            It isn't very far<br> There's people there who will hurt you<br> 'Cause of who you are</p>

        </article>

        <article id="lyrics2">

            <p>Your ears are full of their language<br> There's wisdom there you're sure<br> 'Til the words start slurring<br> And you can't find the door<br> So give me coffee and TV, peacefully<br> I've seen so much, I'm going blind<br> And I'm brain-dead virtually<br> Sociability<br> Is hard enough for me<br> Take me away from this big bad world<br> And agree to marry me<br> So we can start over again<br> So give me coffee and TV, peacefully<br> I've seen so much, I'm going blind<br> And I'm brain-dead virtually<br> Sociability<br> Is hard enough for me<br> Take me away from this big bad world<br> And agree to marry me<br> So we can start over again<br> Oh, we can start over again<br> Oh, we can start over again<br> Oh, we can start over again<br> Oh, we can start over again</p>

        </article>

        </article>

    </section>

    <footer>

        <p>ⓒ</p>

        <p>amongthestar.tistory.com</p>

    </footer>

    </div>

</body>

</html>

 

  • mainTest.css

 

@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300&family=Recursive:wght@300;400&display=swap');

body{

    font-family: 'Noto Sans KR', sans-serif;

}

#container{

    width: 950px;

    margin: 0 auto;

    border: 1px solid rgb(172, 172, 172);

}

header{

    width: 960px;

    height: 600px;

    background-image: url(images/1.JPG);

    background-repeat: no-repeat;

}

header:hover{

    opacity: 0.8;

}

nav ul{

    list-style: none;

}

nav ul li{

    display: inline;

    font-size: 0.9em;

    padding: 15px;

}

nav ul li a{

    color:rgb(93, 93, 93);

    text-decoration: none;

}

#contact{

    float: right;

    margin: 20px 20px;

    padding: 20px;

    width: 400px;

    height: auto;

    font-size: 0.9em;

    color: #666;

    text-align: right;

    border: 1px dotted #ccc;

}

#bgc{

    display: inline-block;

    width: 100%;

    height: auto;

    background-color: rgb(246, 246, 246);

}

#lyrics1{

    position: absolute;

    margin: 120px 80px;

}

#lyrics1 p{

    line-height: 1.8;

    padding: 20px;

    text-align: left;

    border: 1px dotted #ccc;

    color: #666;

}

#lyrics2{

    float: right;

    margin: 120px 80px;

    line-height: 1.8;

    padding: 20px;

    text-align: left;

    border: 1px dotted #ccc;

    color: #666;

} 

section img{

    position: relative;

    top: 50px;

    left: 50px;

    padding-right: 20px;

}

section img:hover{

    -webkit-filter: grayscale(100%); filter: gray;

}

article i{

    color: #ccc;

}

footer{

    clear: both;

    width: 100%;

    height: 80px;

    background-color: bisque;

    color: #666;

    font-size: 0.8em;

    text-align: center;

    margin: 0 auto;

    padding-top: 5px;

}

 

 


 

네비게이터에서 About me 클릭할 경우 이력서 페이지(aboutme.html)로 이동

 

  • aboutme.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>이력서</title>

    <link rel="stylesheet" href="aboutme.css">

</head>

<body>

    <div id="container">

    <header>

        <h2></h2>

        <h6></h6>

        <img src="images/ice.jpg" width="100" height="100">

    </header>

    <nav>

        <ul>

            <li><a href="#ac1">Who am I</a></li>

            <li><a href="#ac2">Experience</a></li>

            <li><a href="#ac3">Skills</a></li>

            <li><a href="#ac4">Education</a></li>

            <li><a href="join.html">Join</a></li>

        </ul>

    </nav>

    <section>

        <article id="ac1">

            <h3>Who am I?</h3>

            <p><i>phone</i> +82 10 1234 5678</p>

            <p><i>email</i> </p>

            <p><i>assignment</i></p>

        </article>

        <article id="ac2">

            <h3>Experience</h3>

            <p>경력사항</p>

        </article>

        <article id="ac3">

            <h3>Skills</h3>

            <p>Java, javascript, CSS, HTML, SQL</p>

        </article>

        <article id="ac4">

            <h3>Education</h3>

            <p></p>

        </article>

    </section>

    <footer>

        <p>ⓒ</p>

        <p>amongthestar.tistory.com</p>

    </footer>

    </div>

</body>

</html>

 

  • aboutme.css

@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300&family=Recursive:wght@300;400&display=swap');

body{

    font-family: 'Noto Sans KR', sans-serif;

}

#container{

    width: 90%;

    margin: 0 auto;

    border: 1px solid rgb(172, 172, 172);

}

header{

    width: 100%;

    height: 200px;

    background-image: url(images/photo.png);

    background-size: 150px 150px;

    background-repeat: no-repeat;

    background-position: 5% 50%;

    background-color: blanchedalmond;

}

header img{

    position: absolute;

    top: 60px;

    right: 120px;

    border-radius: 10px;

}

header h2{

    position: relative;

    margin: 0 auto;

    padding: 30px;

    text-align: center;

    font-size: 2em;

    color: rgb(56, 56, 56);

}

header h6{

    position: relative;

    margin: 0 auto;

    text-align: center;

    font-size: 1em;

    color: rgb(56, 56, 56);

}

nav{

    width: 100%;

    height: auto;

    background-color: rgb(255, 255, 255);

    border-bottom: 1px solid #ccc;

    color: white;

    display: inline-block;

}

nav ul{

    list-style: none;

}

nav ul li{

    display: inline;

    font-size: 1em;

}

nav ul li a{

    color:rgb(93, 93, 93);

    text-decoration: none;

    padding: 5px 25px 5px 25px;

}

section{

    margin: 0 auto;

}

article{

    float: left;

    width: 330px;

    height: 200px;

    border: 1px dotted rgb(175, 175, 175);

    padding: 10px;

    margin: 20px;

}

article p{

    font-size: 0.9em;

    margin: 20px;

}

article h3{

    width: 90%;

    margin: 10px auto;

    background-color: #eee;

    color: rgb(56, 56, 56);

    font-size: 0.9em;

    text-align: center;

    padding-top: 10px;

    height: 30px;

}

footer{

    clear: both;

    width: 100%;

    height: 80px;

    background-color: blanchedalmond;

    color: rgb(56, 56, 56);

    font-size: 0.8em;

    text-align: center;

    margin: 0 auto;

    padding-top: 5px;

}

 

 

 


 

네비게이터에서 Join 클릭할 경우 회원가입 페이지(join.html)로 이동

 

  • join.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>회원가입</title>

    <link rel="stylesheet" href="join.css">

</head>

<body>

    <div id="container">

    <h1>회원 가입</h1>

    <form action="#">

        <fieldset>

            <legend>로그인 정보</legend>

            <ul id="login-info">

                <li>

                    <label for="userid" class="field">아이디</label>

                    <input type="text" id="userid" placeholder="4~8글자 입력" required onchange="checkId()">

                </li>

                <li>

                    <label for="user-pw1" class="field">비밀번호</label>

                    <input type="password" id="user-pw1" placeholder="8자리 이상" required onchange="checkPw()">

                </li>

                <li>

                    <label for="user-pw2" class="field">비밀번호 확인</label>

                    <input type="password" id="user-pw2" required onchange="comparePw()">

                </li>

            </ul>

        </fieldset>

        <fieldset>

            <legend>개인 정보</legend>

            <ul id="personal-info">

                <li>

                    <label for="name" class="field">이름</label>

                    <input type="text" id="name" required>

                </li>

                <li>

                    <label for="email" class="field">메일 주소</label>

                    <input type="email" id="email" required>

                </li>

                <li>

                    <label for="tel" class="field">연락처</label>

                    <input type="tel" id="tel" required>

                </li>

                <li>

                    <label for="blog" class="field">블로그/홈페이지</label>

                    <input type="url" id="blog">

                </li>

            </ul>

        </fieldset>

        <div id="buttons">

            <button type="submit">가입하기</button>

            <button type="reset">취소</button>

        </div>

    </form>

    </div>

    <script src="join.js"></script>

</body>

</html>

 

  • join.css

#container{

    width: 70%;

    margin: 0 auto;

}

ul{

    list-style: none;

}

ul li{

    clear: both;

}

.field {

    float: left;

    width: 30%;

    line-height: 40px;

    text-align: right;

    margin-right: 15px;

}

input[type="text"],input[type="email"],input[type="password"], input[type="tel"],input[type="url"]{

    float: left;

    width: 35%;

    border: 1px solid #666;

    border-radius: 2px;

    padding: 5px;                 

    margin: 8px 0;

}

#buttons{

    clear: both;

    margin: 0 auto;

    width: 100%;

    text-align: center;

    padding-top: 15px;

}

button{

    width: 280px;

    height: 50px;

    border: 1px solid #ccc;

    background: #eee;

    font-size: 0.9em;

    border-radius: 2px;

}

button[type=submit]{

    background-color: blanchedalmond;

    color: #666;

}

 

  • join.js

function openJoin(){

    var newWin=window.open("join.html", "", "");

    if(newWin==null){

        alert("팝업이 차단되어 있습니다. 차단을 해제하고 새로고침을 하세요.");

    }

}



var userId=document.querySelector("#userid");

var pw1=document.querySelector("#user-pw1");

var pw2=document.querySelector("#user-pw2");



userId.onChange=checkId;

pw1.onChange=checkPw;

pw2.onChange=comparePw;



function checkId(){

    if(userId.value.length<4 || userId.value.length>8){

        alert("4~8자리 영문과 숫자 사용");

        userId.focus();

    }

}``

function checkPw(){

    if(pw1.value.length<8){

        alert("비밀번호는 8글자 이상이어야 합니다.");

        pw1.value="";

        pw1.focus();

    }

}

function comparePw(){

    if(pw1.value != pw2.value){

        alert("비밀번호가 일치하지 않습니다.");

        pw2.value="";

        pw2.focus();

    }

}

 

 

 

 

 

 

 

 

 

 

'Learning > HTML&JavaScript' 카테고리의 다른 글

Post 방식으로 페이지 이동하기  (0) 2021.03.30
반응형 웹 디자인  (0) 2020.08.04
DOM, BOM  (0) 2020.08.04
자바스크립트 함수 2  (0) 2020.08.03
자바스크립트 함수 1  (0) 2020.07.31
  • 반응형 웹 디자인: 웹 사이트의 내용을 유지하면서 다양한 화면 크기에 맞게 웹 사이트 표시

  • 뷰포트(viewport): 실제 내용이 표시되는 영역. 

  • 그리드 시스템: 화면을 여러 개의 칼럼을 나누고 필요할때마다 칼럼들을 묶어 배치하는 방법

  • 가변 그리드 레이아웃: 전체를 감싸는 요소의 너비를 %로 변환

 

 

 

  • 고정 그리드 레이아웃

<!doctype html>

<html lang="ko">

<head>

<meta charset="utf-8">

<title>Fixed Grid Layout</title>

<style>

    #wrapper{

        width: 960px;

        margin: 0 auto;

    }

    header{

        width: 960px;

        height: 120px;

        background-color: aqua;

        border-bottom: 1px solid black;

    }

    .header-text{

        font-size: 40px;

        color: white;

        text-align: center;

        line-height: 120px;

    }

    .content{

        float: left;

        width: 600px;

        height: 400px;

        padding: 15px;

        background-color: yellow;

    }

    .right-side{

        float: right;

        width: 300px;

        padding: 15px;

        height: 400px;

        background-color: thistle;

    }

    footer{

        clear: both;

        height: 120px;

        background-color: yellowgreen;

    }

</style>

</head>



<body>

    <div id="wrapper">

        <header>

            <h1 class="header-text">고정 그리드 레이아웃</h1>

        </header>

        <section class="content">

            <h4>본문</h4>

        </section>

        <aside class="right-side">

            <h4>사이드바</h4>

        </aside>

        <footer>

            <h4>푸터</h4>

        </footer>

    </div>

</body>

</html>

 

 

 


 

  • 가변 그리드 레이아웃

 

<!doctype html>

<html lang="ko">

<head>

<meta charset="utf-8">

<title>Fluid Grid Layout</title>

<meta name="viewport" content="width=device-width, initial-scale=1">

<style>

    #wrapper{

        width: 96%;

        margin: 0 auto;

    }

    header{

        width: 100%;

        height: 120px;

        background-color: teal;

        border-bottom: 1px solid black;

    }

    .header-text{

        font-size: 32px;

        color: white;

        text-align: center;

        line-height: 120px;

    }

    .content{

        float: left;

        width: 62.5%;

        height: 400px;

        padding: 1.5625%;

        background-color: violet;

    }

    .right-side{

        float: right;

        width: 31.25%;

        height: 400px;

        padding: 1.5625%;

        background-color: thistle;

    }

    footer{

        clear: both;

        height: 120px;

        background-color: yellowgreen;

    }

</style>

</head>



<body>

    <div id="wrapper">

        <header>

            <h1 class="header-text">가변 그리드 레이아웃</h1>

        </header>

        <section class="content">

            <h4>본문</h4>

        </section>

        <aside class="right-side">

            <h4>사이드바</h4>

        </aside>

        <footer>

            <h4>푸터</h4>

        </footer>

    </div>

</body>

</html>

 

 


 

  • 가변 이미지

.content img{

        max-width: 100%;

        height: auto;

    }

 

 

 


 

 

  • 문서 객체 모델(Document Object Model, DOM)

  • 객체를 사용해 문서를 해석. 웹 문서의 요소를 부모/자식으로 구분. 

 

 

  • 인터넷 상품 페이지 (작은 사진 클릭하면 크게 보이기, 상세 설명 보기)

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <link rel="stylesheet" href="css/dom.css">

</head>

<body>

    <div id="container">

        <h1 id="heading">에디오피아 게뎁</h1>

        <div id="prod-pic">

            <img src="images/coffee-pink.jpg" alt="에디오피아 게뎁" id="cup" width="200" height="200">

            <div id="small-pic">

                <img src="images/coffee-pink.jpg" class="small">

                <img src="images/coffee-blue.jpg" class="small">

                <img src="images/coffee-gray.jpg" class="small">

            </div>

        </div>

        <div id="desc">

            <ul>

                <li>상품명: 에디오피아 게뎁</li>

                <li class="bluetext">판매가: 9,000원</li>

                <li>배송비: 3,000원<br>(50,000원 이상 구매 시 무료)</li>

                <li>적립금: 180원(2%)</li>

                <li>로스팅: 2019.06.17</li>

                <button>장바구니 담기</button>

            </ul>

            <a href="#" id="view">상세 설명 보기</a>

        </div>

        <div id="detail">

            <hr>

            <h2>상품 상세 정보</h2>

            <ul>

                <li>원산지: 에디오피아</li>

                <li>지  역: 이르가체프 코체레</li>

                <li>농  장: 게뎁</li>

                <li>고  도: 1,950~2,000</li>

                <li>품  종: 지역 토착종</li>

                <li>가공법: 워시드</li>

            </ul>

            <h3>Information</h3>

            <p>2차 세계대전 이후 설립된 게뎁 농장은 유기농 인증 농장으로 여성의 고용 창출과 지역사회 발전에 기여하며 3대째 이어져 내려오는 오랜 역사를 가진 농장입니다. 게뎁 농장은 SCAA 인증을 받은 커피 품질관리 실험실을 갖추고 있어 철저한 관리를 통해 스페셜티 커피를 생산 합니다.</p>

            <h3>Flavor Note</h3>

            <p>은은하고 다채로운 꽃향, 망고, 다크 첼리, 달달함이 입안 가득.</p>

        </div>

    </div>

    <script src="js/dom.js"></script>

</body>

</html>

 

 

  • dom.css

 

#container{

    width: 600px;

    margin: 0 auto;

}

#prod-pic, #desc{

    float: left;

}

#prod-pic{

    margin: 20px 20px auto 10px;

    padding: 0;

}

#cup{

    box-shadow: 1px 1px 2px #eee;

    outline: 1px dashed #ccc;

    outline-offset: -7px;

}

.small{

    width: 60px;

    height: 60px;

}

#small-pic{

    list-style: none;

    margin-top: 20px;

    padding: 0;

}

#small-pic>li{

    float: left;

    margin-right: 10px;

}

#small-pic img:hover{

    cursor: pointer;

}

#desc{

    width: 300px;

    padding-top: 20px;

    margin-bottom: 50px;

}

.bluetext{

    color: blue;

    font-weight: bold;

}

#desc button{

    margin-top: 20px;

    margin-bottom: 20px;

    width: 100%;

    padding: 10px;

}

#desc ul{

    list-style: none;

}

#desc li{

    font-size: 0.9em;

    line-height: 1.8;

}

#desc a{

    text-decoration: none;

    font-size: 0.9em;

    color: blue;

    padding-left: 40px;

}

hr{

    clear: both;

    border: 1px dashed #f5f5f5;

}

#detail{

    padding-top: 10px;

    display: none;

}

#detail li{

    font-size: 0.9em;

    line-height: 1.4;

}

h1{

    font-size: 2em;

}

h2{

    font-size: 1.5em;

    color: #bebebe;

    font-weight: normal;

}

h3{

    font-size: 1.1em;

    color: #222;

}

p{

    font-size: 0.9em;

    line-height: 1.4;

    text-align: justify;

}

 

 

  • dom.js

var bigPic=document.querySelector("#cup"); //큰 이미지 가져오기

var smallPic=document.querySelectorAll(".small"); //작은 이미지 가져오기



for(var i=0;i<smallPic.length;i++){

    // var newPic=this.src; //클릭 이벤트가 발생한 대상의 src 속성 저장

    // bigPic.setAttribute("src", newPic); //newPic 값을 큰 이미지의 src 속성에 할당

    // smallPic[i].onclick=changePic;



    smallPic[i].addEventListener("click", changePic);

}



function changePic(){

    var newPic=this.src;

    bigPic.setAttribute("src",newPic);

}



var isOpen=false;

var view=document.querySelector("#view");

view.addEventListener("click",function(){

    if(isOpen==false){

        document.querySelector("#detail").style.display="block";

        view.innerText="상세 설명 닫기"

        isOpen=true;

    }else{

        document.querySelector("#detail").style.display="none";

        view.innerText="상세 설명 보기"

        isOpen=false;

    }

});

 

 

 

 


 

  • 브라우저 객체 모델 (Browser Object Model, BOM)

  • Window, Navigator, history, location, screen

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script>

        var info=navigator.userAgent.toLowerCase();

        var osImg=null;



        if(info.indexOf('windows')>=0){

            osImg="windows.png";

        }else if(info.indexOf('macintosh')>=0){

            osImg="macintosh.png";

        }else if(info.indexOf('iphone'>=0)){

            osImg="iphone.png";

        }else if(info.indexOf('android')>=0){

            osImg="android.png";

        }

        document.write("<img src=\"../0803/images/"+osImg+"\">","<br>");

        var scr=screen;

        var sc_w=scr.width;

        var sc_h=scr.height;



        document.write("모니터 해상도 너비:"+sc_w+"px","<br>");

        document.write("모니터 해상도 높이:"+sc_h+"px","<br>");

    </script>

</head>

<body>

</body>

</html>

 

 


 

  • 팝업창 뜨도록 함

  • bom2.html

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <p>이 문서가 열리면 자동으로 팝업 창이 표시 됩니다.</p>

</body>

    <script src="js/pop.js"></script>

</html>

 

 

  • pop.js

function openPop(){

    var newWin=window.open("popup.html","","width=400, height=400");

    if(newWin==null){

        alert("팝업이 차단되어 있습니다. 차단을 해제하고 새로고침을 하세요.");

    }

}

window.onload=openPop;

 

  • popup.html

 

<!DOCTYPE html>



<html lang="ko">

<head>

    <meta charset="utf-8" />

    <title>location 객체</title>   

    <link rel="stylesheet" href="css/popup.css">     

</head>

<body>

    <div id="content">

        <h1>공지사항</h1>

        <p>팝업 창에 표시되는 내용</p>

        <p>팝업 창에 표시되는 내용</p>

        <p>팝업 창에 표시되는 내용</p>

        <p>팝업 창에 표시되는 내용</p>

        <p>팝업 창에 표시되는 내용</p>

        <button id="detail"><a href="#">자세히 보기</a></button>   

        <p id="close"><a href="javascript:window.close();">창닫기</a></p>

    </div>

</body>

</html>

 

 

 

 

 

 

  • return 값이 있는 경우 함수

 

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script>

        function addNum(a,b){

            var sum=a+b;

            return sum;

        }

        var num1=parseInt(prompt("첫번째 숫자?"));

        var num2=parseInt(prompt("두번째 숫자?"));

        var result=addNum(num1,num2);

        alert("두 수를 더한 값은 "+result+" 입니다.");

    </script>

</head>

<body>

    

</body>

</html>

 


 

  • return값이 없는 함수

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script>

        var myVal=100; //전역변수

        test();

        document.write("myVal is"+myVal);



        function test(){

            var myVal=50; //지역변수

        }

    </script>

</head>

<body>

    

</body>

</html>

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <script>

        var myVal=100; //전역변수

        test();

        document.write("myVal is"+myVal);



        function test(){

            // var myVal=50; //지역변수

            myVal=50;

        }

    </script>

</head>

<body>

    

</body>

</html>

 

 


  • 사진 위에 버튼을 누르면 설명 보기, 닫기 버튼 누르면 설명 닫기

 

  • fun_event.html

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>민들레</title>

    <link rel="stylesheet" href="css/event.css">

    <script src="js/event.js"></script>

</head>

<body>

    <div id="item">

        <img src="images/flower1.jpg" alt="민들레 꽃">

        <button class="over" id="open" onclick="showDetail()">상세 설명 보기</button>

        <div id="desc" class="detail">

            <h4>민들레</h4>

            <p>어디서나 매우 흔하게 보이는 잡초로써 바닥에 딱 붙어서 꽃봉오리 하나가 쏙 올라온다.톱니 모양의 입새와 눈에 확 띄는 노란 꽃이 인상적이다. 특히 꽃이 지고나면 솜털모양의 깃을 가진 씨앗들이 나오는데 바람을 타고 날아가서 널리 퍼진다.</p>

            <button id="close" onclick="hideDetail()">상세 설명 닫기</button>

        </div>

    </div>

</body>

</html>

 

 

  • event.css

#item{

    position: relative;

    width: 500px;

    height: auto;

    padding: 15px 20px;

    margin: auto;

}

button{

    background-color: rgba(255, 255, 255, 0.7);

    padding: 5px;

    border: 1px solid #ccc;

    font-size: 0.8em;

}

.over{

    position: absolute;

    left: 30px;

    bottom: 30px;

}

.detail{

    width: 400px;

    text-align: left;

    line-height: 1.8em;

    display: none;

}

 

 

  • event.js

function showDetail(){

    document.querySelector('#desc').style.display="block";

    document.querySelector('#open').style.display="none";

}



function hideDetail(){

    document.querySelector('#desc').style.display="none";

    document.querySelector('#open').style.display="block";

}

 

 

 

 


 

  • 두 수를 입력받고 더 큰 수를 알림 창에 표시

 

<!DOCTYPE html>

<html lang="ko">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>연습문제 2</title>

    <script>

        function compare(a,b){

            if(a>b){

                alert(a+"(이)가 "+b+"보다 큽니다.")

            }else if(a==b){

                alert(a+"(이)가 "+b+"와 같습니다.")

            }else if(a<b){

                alert(b+"(이)가 "+a+"보다 큽니다.")

            }

        }

        var num1=parseInt(prompt("첫번째 수"));

        var num2=parseInt(prompt("두번째 수"));

        compare(num1, num2);

    </script>

</head>

<body>

    

</body>

</html>


 

  • date객체 활용하여 기념일 달력 만들기

 

<script> 표시할 내용

  • 오늘날짜 Date객체

  • 처음 만난 날 Date 객체

  • 오늘 날짜를 밀리초로 변경

  • 처음 만난 날 밀리초로 변경

  • 두 밀리 초 사이의 차이 계산

  • 결과 값을 날짜 수로 변경

  • 화면에 결과 표시

 

 

  • date_obj.html

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>기념일 달력</title>

    <link rel="stylesheet" href="css/d-day.css">

</head>

<body>

    <div class="container">

        <div class="day1">

            <h3>우리 만난 지</h3>

            <p id="accent" class="accent"><span style="font-size: 0.6em">며칠?</span></p>

        </div>

        <div class="bar">기념일 계산</div>

        <div class="day2">

            <ul>

                <li class="item-title">100일</li>

                <li class="item-date" id="date100"> </li>

            </ul>

            <ul>

                <li class="item-title">200일</li>

                <li class="item-date" id="date200"> </li>

            </ul>

            <ul>

                <li class="item-title">1년</li>

                <li class="item-date" id="date365"> </li>

            </ul>

            <ul>

                <li class="item-title">500일</li>

                <li class="item-date" id="date500"> </li>

            </ul>

        </div>

    </div>

    <script src="js/d-day.js"></script>

</body>

</html>

 

 

  • d-day.css

 

*{

    box-sizing: border-box;

}

.container{

    width: 450px;

    margin: 0 auto;

    border: 1px solid #ccc;

    border-radius: 2%;

    box-shadow: 2px 2px 5px #ccc;

}

.day1{

    padding-top: 20px;

    text-align: center;

}

.day1 h3{

    font-size: 1.2em;

    color: #666;

}

.accent{

    margin-left: 10px;

    margin: 10px;

    font-weight: bold;

    font-size: 3em;

    color: #666;

}

.bar{

    width: 100%;

    height: 40px;

    margin: 60px auto 0 auto;

    background: #666;

    padding-left: 15px;

    font-size: 1.2em;

    color: #fff;

    line-height: 40px;

}

.day2{

    width: 420px;

    margin: 20px auto 20px auto;

}

.day2 ul{

    list-style: none;

    border-bottom: 1px dashed #ccc;

    height: 60px;

}

.item-title{

    float: left;

    width: 160px;

    font-weight: bold;

    font-size: 1.5em;

    line-height: 60px;

}

.item-date{

    float: left;

    margin-left: 60px;

    font-size: 1.2em;

    color: #222;

    text-align: right;

    line-height: 60px;

}



  • d-day.js

 

var now=new Date(); //오늘 날짜 정보를 date객체의 인스턴스 now객체로 만듦

var firstDay=new Date("2020-05-22"); //처음 만난 날



var toNow=now.getTime(); //오늘 날짜를 밀리초로 변경

var toFirst=firstDay.getTime(); //처음 만난 날을 밀리초로 변경



var passedTime=toNow-toFirst; //처음 만난 날과 오늘 날짜의 차이 (밀리초)

var passedDay=Math.round(passedTime/(1000*60*60*24)); //밀리초를 일로 변환 후 반올림



document.querySelector('#accent').innerText=passedDay+"일";



calcDate(100);

calcDate(200);

calcDate(365);

calcDate(500);



function calcDate(days){

    var future=toFirst+days*(1000*60*60*24); //처음 만난 날에 밀리초를 날로 바꾸어서 더함

    var someday=new Date(future); //future값을 사용한 Date 객체의 인스턴스

    var year=someday.getFullYear(); //연도

    var month=someday.getMonth()+1; //월

    var date=someday.getDate(); //일

    document.querySelector("#date"+days).innerText=year+"년 "+month+"월 "+date+"일";

}

 

 

 


 

 

'Learning > HTML&JavaScript' 카테고리의 다른 글

반응형 웹 디자인  (0) 2020.08.04
DOM, BOM  (0) 2020.08.04
자바스크립트 함수 1  (0) 2020.07.31
자바스크립트 객체  (0) 2020.07.31
자바스크립트 제어문  (0) 2020.07.31
  • 전역변수와 지역변수

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 함수 </title>

<script>

    var num=100;

    function menu(){

        num+=100;

        alert(num);

    }

    menu();



    function menu(){

        alert(num);

    }

    

</script>

</head>

<body>

</body>

</html>

 

처음엔 200, 두번째엔 100이 출력됨

 


 

 

  • 익명 함수 선언

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 함수 </title>

<script>

    var count = 0;

    myFunc();



    function myFunc(){ //정상적인 함수 정의

        count++;

        document.write("hello"+count,"<br>");

    }



    myFunc();



    var theFunc=function(){ //익명 함수 선언

        count++; 

        document.write("bye"+count,"<br>");

    }



    theFunc();

</script>

</head>

<body>

</body>

</html>

 


 

  • 배경색 바꾸기

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 함수 </title>

<script>

    var color=["white", "yellow", "aqua", "purple"];

    var i=0;

    function changeColor(){

        i++;

        if(i>color.length) {

            i=0;

        }

        var bodyTag=document.getElementById("theBody");

        bodyTag.style.backgroundColor=color[i];

    }

</script>

</head>

<body id="theBody">

  <button onclick="changeColor();">배경색 바꾸기</button>

</body>

</html>

 


 

 

 

'Learning > HTML&JavaScript' 카테고리의 다른 글

DOM, BOM  (0) 2020.08.04
자바스크립트 함수 2  (0) 2020.08.03
자바스크립트 객체  (0) 2020.07.31
자바스크립트 제어문  (0) 2020.07.31
자바스크립트  (0) 2020.07.24
  • 객체 종류

    • 내장 객체: String, Date, Array, Math...

    • 브라우저 객체 모델: window, screen, location, history, navigator...

    • 문서 객체 모델: html, head, body...


  • 객체 메소드 호출

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 배열객체 </title>

<script>

    var tv=new Object();

    tv.color="white";

    tv.price=300000;

    tv.info=function(){

        document.write("tv색상:"+this.color,"<br>");

        document.write("tv가격:"+this.price,"<br>");

    }

    var car={

        color:'black',

        price:500000,

        info: function(){

            document.write("car색상:"+this.color,"<br>");

            document.write("car가격:"+this.price,"<br>");

        }

    }

    document.write("<h1>tv객체 메서드 호출</h1>");

    tv.info();



    document.write("<h1>car객체 메서드 호출</h1>");

    car.info();

</script>

</head>

<body>

</body>

</html>

 


 

  • 수학객체

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 수학객체 </title>

<script>

    var num = 2.1234;

    minNum=Math.min(10,4,5,6,20);

    roundNum=Math.round(num);

    floorNum=Math.floor(num);

    ceilNum=Math.ceil(num);

    rndNum=Math.random();

    piNum=Math.PI;



    document.write(minNum+"<br>");

    document.write(roundNum+"<br>");

    document.write(floorNum+"<br>");

    document.write(ceilNum+"<br>");

    document.write(rndNum+"<br>");

    document.write(piNum+"<br>");

</script>

</head>

<body>

</body>

</html>

 


 

  • 날짜 정보 객체

 

<!DOCTYPE html>

<html lang="ko">

<head>

    <meta charset = "UTF-8">

    <title> 날짜 정보 객체 </title>

    <script>

        var today=new Date();

        var nowMonth=today.getMonth(); //현재 월

        nowDate=today.getDate(); //현재 날짜

        nowDay=today.getDay(); //현재 요일

        document.write("<h1>오늘 날짜 정보</h1>")

        document.write(nowMonth+1+"월 ");

        document.write(nowDate+"일 ");

        var strDay="";

        switch(nowDay){

            case 1:strDay="월요일"; break;

            case 2:strDay="화요일"; break;

            case 3:strDay="수요일"; break;

            case 4:strDay="목요일"; break;

            case 5:strDay="금요일"; break;

            case 6:strDay="토요일"; break;

            case 7:strDay="일요일"; break;

        }

        document.write(strDay);

    </script>

</head>

<body>

</body>

</html>


 

  • 컴퓨터가 랜덤으로 내는 가위, 바위, 보 맞추기

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 수학객체 </title>

<script>

    document.write("<h1>컴퓨터 가위, 바위, 보 맞추기</h1>");

    var game=prompt("가위, 바위, 보 중에 선택", "가위");

    var gameNum=0;

    switch(game.trim()){

        case "가위": gameNum=1; break;

        case "바위": gameNum=2; break;

        case "보": gameNum=3; break;

        default : alert("잘못 입력"); location.reload();

    }

    var comNum=Math.ceil(Math.random()*3);

    document.write("<image src=\images/math_img_"+comNum+".jpg\>");

    if(gameNum==comNum){

        document.write("<image src=\images/game_1.jpg\>");

    }else{

        document.write("<image src=\images/game_2.jpg\>");

    }

</script>

</head>

<body>

</body>

</html>

 


 

 

  • 배열객체 값 가져오기

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 배열객체 </title>

<script>

   var arr=[30, "따르릉", true];

   document.write("<h3>배열값 가져오기</h3>");

   document.write(arr[0],"<br>");

   document.write(arr[1],"<br>");

   document.write(arr[2],"<br>");



   document.write("<h3>배열값 가져오기-2</h3>");

   for(var i=0;i<arr.length;i++){

        document.write(arr[i],"<br>");

   }

   document.write("<h3>배열값 가져오기-3</h3>");

   for(i in arr){

        document.write(arr[i],"<br>");

   }



</script>

</head>

<body>

</body>

</html>

 


 

  • 배열객체

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 배열객체 </title>

<script>

    var arr_1 = ["사당", "교대", "방배", "강남"];

    var arr_2 = ["신사", "압구정", "옥수"];

    var greenArr=["교대", "방배", "강남"];

    var yellowArr=["미금", "정자", "수서"];



    var result=arr_1.join("-"); //지정값으로 문자열 연결

    document.write(result,"<br>");



    result=arr_1.concat(arr_2); //배열 연결

    document.write(result,"<br>"); 



    result=arr_1.slice(1,3);

    document.write(result,"<br>");



    arr_1.sort(); //오름차순 정렬

    document.write(arr_1,"<br>"); 



    arr_2.reverse(); //거꾸로 정렬

    document.write(arr_2,"<br>"); 



    greenArr.splice(2,1,"서초","역삼"); //2번부터 하나만 삭제하고 서초와 역삼을 추가

    document.write(greenArr,"<br>");



    var data1=yellowArr.pop();

    document.write(data1,"<br>");



    var data2=yellowArr.shift(); //맨 앞의 값 삭제

    document.write(yellowArr);

</script>

</head>

<body>

</body>

</html>


 

  • 문자객체

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset = "UTF-8">

<title> 문자 객체 </title>

<script>

    var name=prompt("이름을 영어로 입력");

    var tel=prompt("전화번호 입력");

    var upperName=name.toUpperCase();

    document.write(upperName,"<br>");



    var result_tel=tel.substring(0, tel.length-4)+"****";

    document.write(result_tel);

</script>

</head>

<body>

</body>

</html>

 

 

'Learning > HTML&JavaScript' 카테고리의 다른 글

자바스크립트 함수 2  (0) 2020.08.03
자바스크립트 함수 1  (0) 2020.07.31
자바스크립트 제어문  (0) 2020.07.31
자바스크립트  (0) 2020.07.24
CSS3 선택자  (0) 2020.07.24

 

  • if else문

 

 

 

 

 


 

  • if else문과 confirm 객체

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> else문 </title>

<script>

    var result=confirm("정말 탈퇴를 하겠습니까?");

    if(result){

        document.write("탈퇴 처리 완료");

    }else{

        document.write("탈퇴 취소");

    }

</script>

</head>

<body>

</body>

</html>

 

확인버튼=true

 

 

 

 

취소버튼=false

 

 


 

  • 처리 조건이 여러개일때 if else문

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> else if문 </title>

<script>

    var mon = prompt("현재는 몇 월입니까?", "0");

    if(mon>=9 && mon<=11){

        document.write("가을입니다.");

    }else if(mon>=6 && mon<=8){

        document.write("여름입니다.");

    }else if(mon>=3 && mon<=5){

        document.write("봄입니다.");

    }else if(mon==12 || mon<=2){

        document.write("겨울입니다.");

    }

    if(mon>12){

        document.write("1~12 사이만 입력가능");

    }

</script>

</head>

<body>

</body>

</html>

 

 

 

 

 

 

 

 

 


 

 

  • 중첩 if 문

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> 중첩 if문 </title>

<script>

    var id = "easy1004";

    var pw = "112233";



    var usr_id=prompt("아이디: ", "");

    var usr_pw=prompt("비밀번호: ","");



    if(usr_id==id){

        if(usr_pw==pw){

            document.write("로그인 성공");

        }else{

            alert("비밀번호 불일치");

            location.reload(); //브라우저 새로고침

        }

    }else{

        alert("해당 아이디가 없음");

        location.reload(); //브라우저 새로고침

    }

</script>

</head>

<body>

</body>

</html>

 

=>>경고창이 뜬 후 다시 아이디 입력

 

 

=========================================================

 

 

=>>경고창이 뜬 후 다시 아이디 입력

 

==========================================================

 

 


  • switch문

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> 선택문 </title>

<script>

    var site = prompt("네이버, 다음, 네이트, 구글 중 \

    즐겨 사용하는 포털 검색 사이트는?", "");

    var url;



    switch(site){

        case "구글": url="www.google.com"; break;

        case "다음": url="www.daum.net"; break;

        case "네이버": url="www.naver.com"; break;

        case "네이트": url="www.nate.com"; break;

        default : alert("해당 사이트 url 누락");

    }

    if(url){

        location.href="http://"+url;

    }

    

</script>

</head>

<body>

</body>

</html>

 

 

 

 


 

  • 반복문 while

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> while문 </title>

<script>

        var i = 1;

        while(i<=10){

            document.write("안녕"+i,"<br>");

            i++;

        }

        document.write("==== The End ====");

</script>

</head>

<body>

</body>

</html>

 

 


 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> while문 </title>

<script>

        var i = 1;

        do{

            document.write("안녕"+i,"<br>");

            i++;

        }while(i<=10)

        document.write("==== The End ====");

</script>

</head>

<body>

</body>

</html>

 

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> while문 </title>

<script>

        var i = 1;

        for(i=1;i<=10;i++){

            document.write("안녕"+i, "<br>");

        }

        document.write("==== The End ====");

</script>

</head>

<body>

</body>

</html>

 


 

  • 20~10까지 짝수면 파랗게, 홀수면 빨간 글씨로 출력

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <style>

        .red{

            color: red;

        }

        .blue{

            color: blue;

        }

    </style>

</head>

<body>

    <script>

        var i=20;

        while(i>=10){

            if(i%2==0){

                document.write("<p class='blue'>"+i+"</p>");

            }else{

                document.write("<p class='red'>"+i+"</p>");

            }

            i--;

        }

    </script>

</body>

</html>

 

 


 

  • 5의 배수는 파란색, 7의 배수는 빨간색, 5와 7의 공배수는 초록색 글씨로 표시

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

    <style>

        .blue{

            color: blue;

        }

        .red{

            color: red;

        }

        .green{

            color: green;

        }

    </style>

</head>

<body>

    <script>

        for(var i=1;i<=100;i++){

            if(i%5==0 && i%7!=0){

                document.write("<p class='blue'>"+i+"</p>");

            }else if(i%7==0 && i%5!=0){

                document.write("<p class='red'>"+i+"</p>");

            }else if(i%5==0 && i%7==0){

                document.write("<p class='green'>"+i+"</p>");

            }

        }

    </script>

</body>

</html>

 

 


 

  • break: 반복문을 강제로 종료

  • continue: 반복문의 처음으로 돌아감

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> break문 </title>

<script>

    for(var i=1;i<100;i++){

        if(i==6){

            break;

        }

        document.write(i,"<br>");

    }

    document.write("=== The End ===");

</script>

</head>

<body>

</body>

</html>

 


 

  • 1에서 100까지 홀수만 출력 (break사용)

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> break문 </title>

<script>

    for(var i=1;i<100;i++){

        if(i%2==0) continue;

        document.write(i,"<br>");

    }

    document.write("=== The End ===");

</script>

</head>

<body>

</body>

</html>

 

 


 

  • 중첩 for 문

 

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title> 중첩for문 </title>

<script>

    for(var i=1;i<=3;i++){

        for(var j=1;j<=2;j++){

            document.write(i+"행"+j+"열");

        }

        document.write("<br>");

    }

</script>

</head>

<body>

</body>

</html>

 


 

  • 구구단 출력

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <script>

        var dan=prompt("단 입력", "");

        for(var i=1;i<=9;i++){

            document.write(dan+" X "+i+"="+i*dan+"<br>");

        }

    </script>

</body>

</html>

 

 

 


 

  • 이중 for문으로 5행 5열 테이블 출력

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <script>

        var n=1;

        var t="<table border=1>";

        for(var i=1;i<=5;i++){

            t+="<tr>";

            for(var j=1;j<=5;j++){

                t+="<td>"+n+"</td>";

                n++;

            }

            t+="</tr>";

        }

        t+="</table>";

        document.write(t);

    </script>

</body>

</html>

 

 

'Learning > HTML&JavaScript' 카테고리의 다른 글

자바스크립트 함수 1  (0) 2020.07.31
자바스크립트 객체  (0) 2020.07.31
자바스크립트  (0) 2020.07.24
CSS3 선택자  (0) 2020.07.24
HTML 멀티미디어  (0) 2020.07.24

+ Recent posts