Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[이형준]sprint4 #115

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion css/login.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,26 @@ input {
}

input:focus {
outline: 2px solid var(--brand-blue);
outline: 1px solid var(--brand-blue);
}

.error-input,
.error-input:focus {
outline: 1px solid var(--error-red);
}

.password-input {
position: relative;
}

.error-message {
margin-top: 8px;
margin-left: 16px;
font-size: 15px;
font-weight: 600;
color: var(--error-red);
}

.visibility-button {
width: 24px;
height: 24px;
Expand Down
25 changes: 25 additions & 0 deletions js/button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// validitiy checker (boolean)
import { emailIsValid, nicknameIsValid, pwIsValid, pwRetypeIsValid } from './input.js';

const loginButton = document.querySelector('#login-button');
const signupButton = document.querySelector('#signup-button');

// every input is valid -> button disable=false
export function buttonDisableChecker(event) {

if(loginButton !== null) {
if(emailIsValid && pwIsValid) {
loginButton.disabled = false;
} else {
loginButton.disabled = true;
}
}
Comment on lines +10 to +16
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위 코드를 아래처럼 바꿀 수 있어요!

  1. 동일하게 동작하는데, 중복코드를 줄일 수 있어요.
  2. 유효성 검사 하는 함수를 별도로 분리해서 재사용성도 높일 수 있습니다.
/**
 * 로그인 버튼 유효성 검사
 * @returns {boolean}
 */
function isLoginButtonValid() {
  return emailIsValid && pwIsValid;
}

/**
 * 회원가입 버튼 유효성 검사
 * @returns {boolean}
 */
function isSignupButtonValid() {
  return emailIsValid && pwIsValid && nicknameIsValid && pwRetypeIsValid;
}

export function buttonDisableChecker(event) {
  if (loginButton) {
    loginButton.disabled = !isLoginButtonValid();
  }

  if (signupButton) {
    signupButton.disabled = !isSignupButtonValid();
  }
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가적으로 함수를 작성했을 때, 타입스크립트를 아직 사용하지 않다보니 아래처럼 JSDoc을 통해 주석을 추가해주시면 좋아요.

/**
 * 로그인 버튼 유효성 검사
 * @returns {boolean}
 */
function isLoginButtonValid() {
  return emailIsValid && pwIsValid;
}

관련 링크는 남겨놓을게요!
https://jsdoc.app/about-getting-started


if(signupButton !== null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 if 문 안에서 !== null 대신 truthy 값을 사용하여 조건을 단순화할수 있어요

if (signupButton) {
  signupButton.disabled = !isSignupButtonValid();
}

if(emailIsValid && pwIsValid && nicknameIsValid && pwRetypeIsValid) {
signupButton.disabled = false;
} else {
signupButton.disabled = true;
}
}
}
86 changes: 86 additions & 0 deletions js/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// password valid condition
const PW_MIN_LENGTH = 8;

// for button disable toggle
export let emailIsValid = false;
export let nicknameIsValid = false;
export let pwIsValid = false;
export let pwRetypeIsValid = false;

// email validitiychecker
export function emailInputCheck(event) {
const target = event.target;
const errorMessage = document.querySelector('#email-error-message');

if (target.value === "") {
target.classList.add('error-input');
errorMessage.textContent = '이메일을 입력해주세요.';
emailIsValid = false;
}
// checkValidity() : true ("" or type match), false (different type)
if (!target.checkValidity()) {
target.classList.add('error-input');
errorMessage.textContent = '잘못된 이메일 형식입니다.';
emailIsValid = false;
}
if (target.checkValidity() && target.value !== "") {
target.classList.remove('error-input');
errorMessage.textContent = '';
emailIsValid = true;
}
}
Comment on lines +11 to +31
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emailInputCheck 함수 외에도 아래에 있는 validation 역할을 해주는 함수들 중 중복 코드들이 보여요.

이를 해결하기 위해, classList.toggle 사용해서 가독성 있게 해결 해볼 수 있어요.

아래 방법을 nicknameInputCheck, pwInputCheck, pwRetypeInputCheck 함수에 똑같이 적용해주시면 됩니다.

/**
 * 에러 메시지 설정 및 클래스 토글 함수
 * @param {HTMLElement} target
 * @param {HTMLElement} errorMessage
 * @param {string} message
 * @param {boolean} isValid
 */
function setErrorMessage(target, errorMessage, message, isValid) {
  target.classList.toggle('error-input', !isValid);
  errorMessage.textContent = message;
}

export function emailInputCheck(event) {
  const target = event.target;
  const errorMessage = document.querySelector('#email-error-message');

  if (!target.value) {
    setErrorMessage(target, errorMessage, '이메일을 입력해주세요.', false);
    emailIsValid = false;
  } else if (!target.checkValidity()) {
    setErrorMessage(target, errorMessage, '잘못된 이메일 형식입니다.', false);
    emailIsValid = false;
  } else {
    setErrorMessage(target, errorMessage, '', true);
    emailIsValid = true;
  }
}

https://developer.mozilla.org/ko/docs/Web/API/Element/classList


// nickname validitiychecker
export function nicknameInputCheck(event) {
const target = event.target;
const errorMessage = document.querySelector('#nickname-error-message');

if (target.value === "") {
target.classList.add('error-input');
errorMessage.textContent = '닉네임을 입력해주세요.';
nicknameIsValid = false;
} else {
target.classList.remove('error-input');
errorMessage.textContent = '';
nicknameIsValid = true;
}
}

// password validitiychecker
export function pwInputCheck(event) {
const target = event.target;
const errorMessage = document.querySelector('#password-error-message');

if (target.value.length === 0) {
target.classList.add('error-input');
errorMessage.textContent = '비밀번호를 입력해주세요.';
pwIsValid = false;
}
if (target.value.length < PW_MIN_LENGTH && target.value.length > 0) {
target.classList.add('error-input');
errorMessage.textContent = '비밀번호를 8자 이상 입력해주세요.';
pwIsValid = false;
}
if (target.value.length >= PW_MIN_LENGTH) {
target.classList.remove('error-input');
errorMessage.textContent = '';
pwIsValid = true;
}
}

// retype password validitiychecker
export function pwRetypeInputCheck(event) {
const target = event.target;
const pwInput = document.querySelector('#password-input');
const errorMessage = document.querySelector('#password-retype-error-message');

if (target.value !== pwInput.value) {
target.classList.add('error-input');
errorMessage.textContent = '비밀번호가 일치하지 않습니다.';
pwRetypeIsValid = false;
} else {
target.classList.remove('error-input');
errorMessage.textContent = '';
pwRetypeIsValid = true;
}
}
32 changes: 32 additions & 0 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { emailInputCheck,nicknameInputCheck, pwInputCheck, pwRetypeInputCheck } from './input.js';
import { buttonDisableChecker } from './button.js';
import { pwVisibleToggle } from './pw_visibility.js';

const emailInput = document.querySelector('#email-input');
const pwInput = document.querySelector('#password-input');
const pwRetypeInput = document.querySelector('#password-retype-input');
const nicknameInput = document.querySelector('#nickname-input');

const pwVisibleBtn = document.querySelector('#password-visibility-button');
const pwRetypeVisibleBtn = document.querySelector('#password-retype-visibility-button');

// login page event
emailInput.addEventListener('focusout', emailInputCheck);
pwInput.addEventListener('focusout', pwInputCheck);

emailInput.addEventListener('focusout', buttonDisableChecker);
pwInput.addEventListener('focusout', buttonDisableChecker);

pwVisibleBtn.addEventListener('click', pwVisibleToggle);


// additional event for signup page
if (pwRetypeInput && nicknameInput) {
nicknameInput.addEventListener('focusout', nicknameInputCheck);
pwRetypeInput.addEventListener('focusout', pwRetypeInputCheck);

nicknameInput.addEventListener('focusout', buttonDisableChecker);
pwRetypeInput.addEventListener('focusout', buttonDisableChecker);

pwRetypeVisibleBtn.addEventListener('click', pwVisibleToggle);
}
17 changes: 17 additions & 0 deletions js/pw_visibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
let visibleMode = false;

export function pwVisibleToggle(event) {
const img = event.target;
const input = img.parentElement.parentElement.firstElementChild;

if (visibleMode) {
img.src = "/images/btn_visibility_off.png";
input.type = "password";
visibleMode = false;
} else {
img.src = "/images/btn_visibility_on.png";
input.type = "text";
visibleMode = true;
}
}

22 changes: 15 additions & 7 deletions pages/login/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<link rel="stylesheet" href="/css/base/global.css" />
<link rel="stylesheet" href="/css/login.css" />
</head>

<body>
<header>
<div class="logo-block">
Expand All @@ -26,30 +27,33 @@
<div class="content">
<div>
<h3>이메일</h3>
<input type="email"
<input type="email" id="email-input"
placeholder="이메일을 입력해주세요"
onfocus="this.placeholder=''"
onblur="this.placeholder='이메일을 입력해주세요'"
/>
<p id="email-error-message" class="error-message"></p>
</div>
<div>
<h3>비밀번호</h3>
<div class="password-input">
<input type="password"
<input type="password" id="password-input"
placeholder="비밀번호를 입력해주세요"
onfocus="this.placeholder=''"
onblur="this.placeholder='비밀번호를 입력해주세요'"
/>
/>
<a>
<img
class="visibility-button"
src="/images/btn_visibility_off.png"
alt="비밀번호 표시 옵션"
id="password-visibility-button"
class="visibility-button"
src="/images/btn_visibility_off.png"
alt="비밀번호 표시 옵션"
/>
</a>
<p id="password-error-message" class="error-message"></p>
</div>
</div>
<button>로그인</button>
<button id="login-button" onclick="location.href='/pages/items'" disabled="true">로그인</button>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disabled 만 적어주셔도 됩니다! 기본 값이 true 이기 때문이에요~

<div class="simple-login">
<p>
간편 로그인하기
Expand All @@ -70,4 +74,8 @@ <h3>비밀번호</h3>
</div>
</main>
</body>

<script type="module" src="/js/main.js"></script>
<script type="module" src="/js/input.js"></script>
<script type="module" src="/js/pw_visibility.js"></script>
</html>
33 changes: 22 additions & 11 deletions pages/login/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<link rel="stylesheet" href="/css/base/global.css" />
<link rel="stylesheet" href="/css/login.css" />
</head>

<body>
<header>
<div class="logo-block">
Expand All @@ -26,55 +27,61 @@
<div class="content">
<div>
<h3>이메일</h3>
<input type="email"
<input type="email" id="email-input"
placeholder="이메일을 입력해주세요"
onfocus="this.placeholder=''"
onblur="this.placeholder='이메일을 입력해주세요'"
/>
<p id="email-error-message" class="error-message"></p>
</div>
<div>
<h3>닉네임</h3>
<input type="text"
<input type="text" id="nickname-input"
placeholder="닉네임을 입력해주세요"
onfocus="this.placeholder=''"
onblur="this.placeholder='닉네임을 입력해주세요'"
/>
<p id="nickname-error-message" class="error-message"></p>
</div>
<div>
<h3>비밀번호</h3>
<div class="password-input">
<input type="password"
<input type="password" id="password-input"
placeholder="비밀번호를 입력해주세요"
onfocus="this.placeholder=''"
onblur="this.placeholder='비밀번호를 입력해주세요'"
/>
<a>
<img
class="visibility-button"
src="/images/btn_visibility_off.png"
alt="비밀번호 표시 옵션"
id="password-visibility-button"
class="visibility-button"
src="/images/btn_visibility_off.png"
alt="비밀번호 표시 옵션"
/>
</a>
<p id="password-error-message" class="error-message"></p>
</div>
</div>
<div>
<h3>비밀번호 확인</h3>
<div class="password-input">
<input type="password"
<input type="password" id="password-retype-input"
placeholder="비밀번호를 다시 한 번 입력해주세요"
onfocus="this.placeholder=''"
onblur="this.placeholder='비밀번호를 다시 한 번 입력해주세요'"
/>
<a>
<img
class="visibility-button"
src="/images/btn_visibility_off.png"
alt="비밀번호 표시 옵션"
id="password-retype-visibility-button"
class="visibility-button"
src="/images/btn_visibility_off.png"
alt="비밀번호 표시 옵션"
/>
</a>
<p id="password-retype-error-message" class="error-message"></p>
</div>
</div>
<button>회원가입</button>
<button id="signup-button" onclick="location.href='./'" disabled>회원가입</button>
<div class="simple-login">
<p>
간편 로그인하기
Expand All @@ -95,4 +102,8 @@ <h3>비밀번호 확인</h3>
</div>
</main>
</body>

<script type="module" src="/js/main.js"></script>
<script type="module" src="/js/input.js"></script>
<script type="module" src="/js/pw_visibility.js"></script>
</html>
Loading