일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- APK
- 그누보드
- 웹 프로그래밍
- 코드이그나이터
- MSsql
- php
- config
- 안드로이드
- ajax
- 후크
- FCM
- 옵션표
- API
- 설정
- 라이렌
- rairen
- jquery
- Database
- 함수
- html
- 헬퍼
- phpDocumentor
- javascript
- CodeIgniter
- 영카트
- mysql
- jw player
- function
- codeigniter3
- CI3
Archives
- Today
- Total
프로그램 개발서
카드번호 마스킹 처리 html, js 예제 본문
2023.08.24 : 카드번호 위치 및 마스킹 표시 문자, 하이픈 표시여부, 하이픈 사용시 하이픈 위치 지정 설정 추가
2023.08.29 : 설정에 따라 다른 처리되는 것을 확인하기 위한 코드로 변경
카드번호 마스킹 처리 예제 코드
- html
<div class="container py-5">
<div class="card-group">
<div class="card">
<div class="card-header">
<h4 class="h4">카드번호 마스킹</h4>
</div>
<div class="card-body">
<div class="row justify-content-center">
<div class="col-auto">
<label>번호 길이[최소, 최대]</label>
<div class="input-group">
<input type="text" class="form-control onlyNumber" id="numberMaxLength" name="numberMaxLength" value="16" size="2">
</div>
</div>
<div class="col-auto vr px-0"></div>
<div class="col-auto">
<label>마스킹 시작자리</label>
<div class="input-group">
<input type="text" class="form-control onlyNumber" id="positionStart" name="positionStart" value="7" size="2">
</div>
</div>
<div class="col-auto vr px-0"></div>
<div class="col-auto">
<label>마스킹 처리길이</label>
<div class="input-group">
<input type="text" class="form-control onlyNumber" id="positionLength" name="positionLength" value="6" size="2">
</div>
</div>
<div class="col-auto vr px-0"></div>
<div class="col-auto ">
<label>실제 처리할 데이터 구분</label>
<div class="input-group">
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" id="procValueView" name="procValue" value="view" checked="">
<label class="form-check-label" for="procValueView">마스크 처리 후</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" id="procValueHide" name="procValue" value="hide">
<label class="form-check-label" for="procValueHide">마스크 처리 전</label>
</div>
</div>
</div>
<div class="col-auto vr px-0"></div>
<div class="col-auto ">
<label>하이픈(-) 사용여부</label>
<div class="input-group">
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" id="isHipenUseTrue" name="isHipenUse" value="true" checked="">
<label class="form-check-label" for="isHipenUseTrue">사용</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" id="isHipenUseFalse" name="isHipenUse" value="false">
<label class="form-check-label" for="isHipenUseFalse">사용안함</label>
</div>
</div>
</div>
</div>
<hr class="hr">
<div class="card-text">
<label for="view-card-number">사용자가 입력하고 마스킹 처리되는 입력란</label>
<input type="text" class="form-control" id="view-card-number" minlength="15" maxlength="16">
</div>
<div class="card-text">
<label for="hide-card-number">사용자가 입력한 번호 그대로 가지고 있는 입력란</label>
<input type="text" class="form-control" id="hide-card-number" readonly="">
</div>
<div class="card-text">
<label for="real-card-number">실제로 백단으로 보낼 입력란</label>
<input type="text" class="form-control" id="real-card-number" readonly="">
</div>
</div>
</div>
</div>
</div>
- javascript
function onlyNumber(className = 'onlyNumber'){
className = "." + className;
let onlyNumberEl = document.querySelectorAll(className);
onlyNumberEl.forEach(function(el, idx){
el.addEventListener('keydown', function (KeyboardEvent) {
if(KeyboardEvent.which >= 48 && KeyboardEvent.which <= 57){
return true;
}
else if(KeyboardEvent.which >= 96 && KeyboardEvent.which <= 105){
return true;
}
else{
KeyboardEvent.preventDefault();
KeyboardEvent.stopPropagation();
return false;
}
});
});
}
onlyNumber();
/**
* 카드번호 마스킹
*/
let [start, end] = [0, 0];// 입력 위치 확인하기위한 변수
let viewCardEl = document.querySelector('#view-card-number');//마스크 처리 된 값을 보여줄 요소
let hideCardEl = document.querySelector('#hide-card-number');//마스크 처리하기 전 사용자가 입력한 값을 보유할 요소
let realCardEl = document.querySelector('#real-card-number');//처리단으로 보낼 값을 보유한 요소
// 마스킹 설정
let maskRange = [7, 13]; // 마스킹 처리 범위[시작, 끝] ex) 4이후부터 8까지
let maskText = 'x'; // 마스킹 처리할 문자
let procValue = 'view'; // 어떤 값으로 처리하지 구분할 값 ['view', 'hide']
let isHipenUse = true; // 하이픈(-) 사용 여부
let hipenPosition = [5, 10, 15];// 하이픈 위치
let inputMinLength = 15; // 입력제한
let inputMaxLength = 16; // 입력제한
viewCardEl.setAttribute('minLength', inputMinLength);
viewCardEl.setAttribute('maxLength', inputMaxLength);
// 선택 시 해당 위치 저장
function valueSelect(e){
start = e.target.selectionStart;
end = e.target.selectionEnd;
}
// 중간 잘라내기
function valueSlice(str, start, end, midStr){
const front = str.slice(0, start);
const back = str.slice(end);
if (midStr) return front + midStr + back;
else return front + back;
}
// 입력 시 마스킹 처리하기
function maskCardNumber(e){
// 입력제한 있는 경우
if(typeof inputMaxLength !== 'undefined'){
// 하이픈 사용하고 하이픈 들어가는 개수가 있는 경우
if(typeof isHipenUse !== 'undefined' && isHipenUse === true && typeof hipenPosition !== 'undefined' && hipenPosition.length > 0){
e.target.setAttribute('maxLength', parseInt(inputMaxLength) + parseInt(hipenPosition.length));
}
else{
e.target.setAttribute('maxLength', parseInt(inputMaxLength));
}
}
const data = e.data; // 입력 데이터
const inputType = e.inputType;// 입력 방식
let position = e.target.selectionStart;// 입력 후 시작위치
// 삭제
if(inputType === 'deleteContentBackward'){
// 기본
if (start === end) {
hideCardEl.value = valueSlice(hideCardEl.value, position, position + 1);
}
// 드래그 삭제
else {
hideCardEl.value = valueSlice(hideCardEl.value, start, end);
}
}
// 입력
else if (parseInt(data) >= 0 && parseInt(data) <= 9){
if (start === end) {
hideCardEl.value = valueSlice(hideCardEl.value, position - 1, position - 1, data);
}
// 드래그 후 입력
else {
hideCardEl.value = valueSlice(hideCardEl.value, start, end, data);
}
// 위치저장
start = position;
end = position;
}
console.log(maskRange);
let tempMaskRange = maskRange;
// 하이픈 사용 시
// 마스크 처리 부분은
if (typeof isHipenUse !== 'undefined' && isHipenUse === true) {
if(hideCardEl.value !== ''){
// 하이픈 넣어주면서 생기는 커서 위치 pos 조정
hideCardEl.value = hideCardEl.value.replaceAll('-', '').match(/[0-9*]{1,4}/g)?.join('-');
}
// 하이픈 위치 저장 변수 체크하기 위해 반복
for(let i = 0; i < hipenPosition.length; i++){
// 입력 후 위치가 하이픈 넣을 위치면 하이픈 다음으로 옮겨주기 위헤
// 위치 값 + 1
if(position === hipenPosition[i]){
position = position + 1;
}
// 마스크 범위 수정
if((hipenPosition[i] - 1) === maskRange[0]){
tempMaskRange[0] = maskRange[0] + i + 1;
}
if((hipenPosition[i] - 1) === maskRange[1]){
tempMaskRange[1] = maskRange[1] + i + 1;
}
}
}
const value = hideCardEl.value;
const splitValue = value.split('');
const maskValue = splitValue.map((v, i) => {
if(typeof isHipenUse !== 'undefined' && isHipenUse === true){
if (i >= parseInt(tempMaskRange[0]) && i <= parseInt(tempMaskRange[1]) && v !== '-') return maskText;
else return v;
}
else{
if (i >= tempMaskRange[0] && i <= tempMaskRange[1]) return maskText;
else return v;
}
}).join('');
// 치환 값 넣기
e.target.value = maskValue;
// 바뀐 위치 원상복구
e.target.selectionStart = position;
e.target.selectionEnd = position;
// 어떤 값을 실제 처리단으로 넘길 값으로 할지 구분함.
if(typeof procValue !== 'undefined'){
switch (procValue) {
case 'view':
realCardEl.value = viewCardEl.value;
break;
case 'hide':
realCardEl.value = hideCardEl.value;
break;
}
}
else{
realCardEl.value = hideCardEl.value;
}
}
// 이벤트 바인딩
viewCardEl.addEventListener('input', maskCardNumber);// 입력 시
viewCardEl.addEventListener('select', valueSelect); // 선택 시
// 번호 최대길이
let numberMaxLengthEl = document.querySelector('#numberMaxLength');
numberMaxLengthEl.addEventListener('keyup', function(){
let maxLength = this.value;
inputMaxLength = maxLength;
viewCardEl.setAttribute('maxLength', maxLength);
});
// 마스크 위치
let positionStartEl = document.querySelector('#positionStart');
positionStartEl.addEventListener('keyup', function(){
let positionStartData = this.value;
if(isHipenUse !== true){
positionStartData = (positionStartData - 1);
}
maskRange[0] = parseInt(maskRange[0]);
});
// 마스크 길이
let positionLengthEl = document.querySelector('#positionLength');
positionLengthEl.addEventListener('keyup', function(){
let positionLengthData = this.value;
maskRange[1] = maskRange[0] + positionLengthData;
});
let isHipenUseEl = document.querySelectorAll('input[name="isHipenUse"]');
isHipenUseEl.forEach(function(el, idx){
el.addEventListener('click', function () {
isHipenUse = (this.value === 'true');
maskRange[0] = (this.value === 'true') ? parseInt(positionStartEl.value) : parseInt(positionStartEl.value) - 1;
maskRange[1] = maskRange[0] + parseInt(positionLengthEl.value) - 1;
});
});
let procValueEl = document.querySelectorAll('input[name="procValue"]');
procValueEl.forEach(function(el, idx){
el.addEventListener('click', function () {
procValue = this.value;
});
});
티스토리 삽입 예제
카드번호 마스킹
코드펜 예제
See the Pen Card Number Mask Script by rairen (@rairen) on CodePen.
반응형
'Javascript' 카테고리의 다른 글
그누보드5 이윰빌더 시즌4 CHEditor5에 에드온 이모티콘 삽입 (0) | 2024.06.24 |
---|---|
Javascript 함수 모음 (0) | 2023.08.29 |
pointer 이벤트를 통한 스크롤 처리 (0) | 2023.06.30 |
가볍게 table 을 select 처럼 사용해보자. (0) | 2021.07.28 |
sprintf php to javascript (0) | 2020.11.03 |