티스토리 뷰

반응형

toast grid로 엔터키를 치지 않고 한글이 입력될때 초성이든 중성이든 종성이든 들어오면 입력모드로 변환하도록 코드를 짜는 것에 집중하고 있다.

영문, 숫자, 한글 등 입력이 되면 Enter키를 치지 않고 하는 방법을 일단 toast Grid에서는 제공하지 않는다.

꼭 엔터키를 치고 값을 입력하는게, 실무에서 일하는 분들에겐 이미 우리가 'Excel'이라 지구상 가장 훌륭하다고 생각하는 프로그램에 익숙해서 보통 셀을 이동하고 바로 입력값을 넣으면 알아서 편집모드로 들어가는 것....

이걸 자바스크립트로 구현하려고 하니, 찾아볼 것도 많고 고난도의 프로그램으로 들어가는 느낌이었지만,

하나하나 만들어보다 보면, 프로그램의 구조나 기타 내가 몰랐던 기능들을 맞딱들이게 된다.

한글 입력 감지 (초성, 중성, 종성 포함) - 화면 출력 코드 연구해서 얻어낸 결과다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성, 중성, 종성 포함) - 화면 출력</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <input type="text" id="outputField" readonly>
  <script>
    const inputField = document.getElementById('inputField');
    const outputField = document.getElementById('outputField');

    let compositionData = '';

    inputField.addEventListener('compositionstart', (event) => {
      compositionData = event.data;
    });

    inputField.addEventListener('compositionupdate', (event) => {
      compositionData = event.data;
      outputField.value = `한글 입력 감지: ${compositionData}`;
    });

    inputField.addEventListener('compositionend', (event) => {
      compositionData = event.data;
      outputField.value = `한글 입력 감지: ${compositionData}`;
    });

  </script>
</body>
</html>

 

실제 동작을 해봤는데 잘된다.

초성 'ㅎ'만 입력한 경우 감지해서 화면에 나온다. 이걸 찾느라 정말 많은 것들을 검색하고 chatGPT에게도 많이 질문했다. 

거의 chatGPT로 이걸 얻으려고 10회이상 질문한 것 같다.

그 과정도 함께 담아보려고 한다. 질문하는 질문을 이해하지 못하고 다른 답을 주는 경우가 종종있으니, 유의하시기 바란다.

참고로 chatGPT-4 (유료버전)으로 질문해서 얻은 결과다.

첫 질문
class CustomTextEditor { constructor(props) { const el = document.createElement('input'); const { maxLength } = props.columnInfo.editor.options; el.type = 'text'; el.maxLength = maxLength; el.value = String(props.value); this.el = el; } getElement() { return this.el; } getValue() { return this.el.value; } mounted() { this.el.select(); } } 위의 함수에서 input중에 방향키를 누르면 input상태에서 빠져나가서 grid다음셀로 이동하는 방법은?
답변 :
방향키를 눌렀을 때 input 상태에서 빠져나와서 다음 셀로 이동하려면, CustomTextEditor 클래스에 keydown 이벤트 리스너를 추가해야 합니다. 이벤트 리스너에서는 ArrowUp, ArrowDown, ArrowLeft, ArrowRight 키에 대한 처리를 구현합니다. 아래 코드는 CustomTextEditor 클래스에 keydown 이벤트 리스너를 추가하는 방법을 보여줍니다.

 

class CustomTextEditor {
  constructor(props) {
    const el = document.createElement('input');
    const { maxLength } = props.columnInfo.editor.options;

    el.type = 'text';
    el.maxLength = maxLength;
    el.value = String(props.value);

    this.el = el;
    this.props = props;
    this.el.addEventListener('keydown', this.onKeyDown.bind(this));
  }

  onKeyDown(event) {
    const { key } = event;
    const { rowKey, columnName } = this.props;

    if (key === 'ArrowUp' || key === 'ArrowDown' || key === 'ArrowLeft' || key === 'ArrowRight') {
      event.preventDefault();
      event.stopPropagation();

      this.props.grid.finishEditing();
      this.navigateNextCell(key, rowKey, columnName);
    }
  }

  navigateNextCell(key, rowKey, columnName) {
    const grid = this.props.grid;
    const { rowKey: newRowKey, columnName: newColumnName } = grid.getFocusedCell();

    switch (key) {
      case 'ArrowUp':
        newRowKey = Math.max(newRowKey - 1, 0);
        break;
      case 'ArrowDown':
        newRowKey = Math.min(newRowKey + 1, grid.getRowCount() - 1);
        break;
      case 'ArrowLeft':
        newColumnName = grid.prevColumnName(columnName);
        break;
      case 'ArrowRight':
        newColumnName = grid.nextColumnName(columnName);
        break;
    }

    if (newRowKey !== rowKey || newColumnName !== columnName) {
      grid.focus(newRowKey, newColumnName);
      grid.startEditing(newRowKey, newColumnName);
    }
  }

  getElement() {
    return this.el;
  }

  getValue() {
    return this.el.value;
  }

  mounted() {
    this.el.select();
  }
}
위의 코드에서는 onKeyDown 메서드를 추가하여 방향키에 대한 처리를 구현하고 있습니다. onKeyDown 메서드에서는 방향키를 눌렀을 때 이벤트의 기본 동작과 버블링을 중단한 다음, 편집을 종료하고 navigateNextCell 메서드를 호출하여 다음 셀로 이동하도록 합니다. navigateNextCell 메서드에서는 새로운 행 키(newRowKey)와 열 이름(newColumnName)을 계산하여 해당 셀에 포커스를 주고 편집을 시작하도록 합니다.
이렇게 함으로써, 사용자가 방향키를 누르면 입력 상태에서 벗어나 다음 셀로 이동하게 됩니다. 다만, 이 예제에서는 grid.prevColumnName()과 grid.nextColumnName() 메서드가 미리 구현되어 있다고 가정하였습니다.
두번째 질문:
키보드로 한글 입력이 되었을때 알아내는 법 자바스크립트로 코드짜줘
답변 :
키보드로 한글 입력이 되었을 때를 감지하기 위해, 아래 예제와 같이 'input' 이벤트 리스너를 사용할 수 있습니다. 'input' 이벤트는 사용자가 입력 요소에 값을 입력하거나 변경할 때 발생합니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <script>
    const inputField = document.getElementById('inputField');

    inputField.addEventListener('input', (event) => {
      const inputValue = event.target.value;
      const lastChar = inputValue.slice(-1);

      const isKorean = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0xAC00 && unicode <= 0xD7A3;
      };

      if (isKorean(lastChar)) {
        console.log('한글 입력 감지:', lastChar);
      }
    });
  </script>
</body>
</html>
위의 예제에서는 'inputField' 입력 요소에 'input' 이벤트 리스너를 추가하고 있습니다. 이벤트가 발생할 때마다 입력 요소의 값을 가져와 마지막 문자를 확인합니다. 마지막 문자가 한글인지 확인하기 위해
isKorean
함수를 사용하며, 이 함수는 입력받은 문자의 유니코드 값이 한글 범위인지 확인합니다. 만약 마지막 문자가 한글이라면 콘솔에 "한글 입력 감지" 메시지와 함께 해당 문자를 출력합니다.

 

질문 :
한글의 초성만 입력해도 인식하도록 코드 수정해줘
한글의 초성만 입력해도 인식하도록 코드를 수정하려면, 초성 범위를 확인하는 함수를 추가해야 합니다. 아래 예제에서는isKoreanChosung 함수를 사용하여 입력받은 문자가 초성인지 확인합니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성 포함)</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <script>
    const inputField = document.getElementById('inputField');

    inputField.addEventListener('input', (event) => {
      const inputValue = event.target.value;
      const lastChar = inputValue.slice(-1);

      const isKorean = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0xAC00 && unicode <= 0xD7A3;
      };

      const isKoreanChosung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1100 && unicode <= 0x1112;
      };

      if (isKorean(lastChar) || isKoreanChosung(lastChar)) {
        console.log('한글 입력 감지:', lastChar);
      }
    });
  </script>
</body>
</html>
위의 예제에서는 isKoreanChosung 함수를 사용하여 입력받은 문자가 초성인지 확인하고 있습니다. 이 함수는 입력받은 문자의 유니코드 값이 초성 범위인지 확인합니다. 만약 마지막 문자가 한글이거나 초성이라면 콘솔에 "한글 입력 감지" 메시지와 함께 해당 문자를 출력합니다. 이렇게 하면 한글의 초성만 입력해도 인식할 수 있습니다.
질문 :
콘솔로 결과를 나타내지말고, 화면에 text창이나 input창으로 나오게 수정해줘
콘솔 대신 화면에 text창이나 input창에 결과를 출력하려면, 아래와 같이 추가로 입력 요소를 생성하고 출력할 값을 설정하면 됩니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성 포함) - 화면 출력</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <input type="text" id="outputField" readonly>
  <script>
    const inputField = document.getElementById('inputField');
    const outputField = document.getElementById('outputField');

    inputField.addEventListener('input', (event) => {
      const inputValue = event.target.value;
      const lastChar = inputValue.slice(-1);

      const isKorean = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0xAC00 && unicode <= 0xD7A3;
      };

      const isKoreanChosung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1100 && unicode <= 0x1112;
      };

      if (isKorean(lastChar) || isKoreanChosung(lastChar)) {
        outputField.value = `한글 입력 감지: ${lastChar}`;
      } else {
        outputField.value = '';
      }
    });
  </script>
</body>
</html>
위의 예제에서는 outputField 라는 새로운 input 요소를 추가하였습니다. 이 input 요소는 readonly
속성을 가지고 있어 사용자가 직접 수정할 수 없도록 하였습니다. 이후, 한글이나 초성을 감지했을 때
outputField.value 에 결과를 출력하도록 코드를 수정하였습니다. 이렇게 하면 한글 입력이 감지되었을 때 화면에 출력되도록 할 수 있습니다.
질문 :
여전히 한글 'ㅎ', 'ㅏ' 등 초성이 입력되는 것을 찾아내지 못하는데
한글의 완성형이 아닌 초성, 중성, 종성을 찾아내려면 다음과 같이 코드를 수정하여 각각의 범위를 확인할 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성, 중성, 종성 포함) - 화면 출력</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <input type="text" id="outputField" readonly>
  <script>
    const inputField = document.getElementById('inputField');
    const outputField = document.getElementById('outputField');

    inputField.addEventListener('input', (event) => {
      const inputValue = event.target.value;
      const lastChar = inputValue.slice(-1);

      const isKorean = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0xAC00 && unicode <= 0xD7A3;
      };

      const isKoreanChosung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1100 && unicode <= 0x115F;
      };

      const isKoreanJungsung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1160 && unicode <= 0x11A7;
      };

      const isKoreanJongsung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x11A8 && unicode <= 0x11FF;
      };

      if (isKorean(lastChar) || isKoreanChosung(lastChar) || isKoreanJungsung(lastChar) || isKoreanJongsung(lastChar)) {
        outputField.value = `한글 입력 감지: ${lastChar}`;
      } else {
        outputField.value = '';
      }
    });
  </script>
</body>
</html>
위의 예제에서는 isKoreanChosung , isKoreanJungsung , isKoreanJongsung 함수를 사용하여 각각 초성, 중성, 종성 범위를 확인합니다. 이렇게 하면 완성형 한글뿐만 아니라 초성, 중성, 종성 단독 입력도 감지할 수 있습니다.
질문 :
문제는 inputField.addEventListener('input', (event) => { 이 문장에서 한글의 'ㅎ'가 입력되었을때 이벤트를 발생시키지 않는 것 같아
죄송합니다. 이해했습니다. 한글 초성 입력을 처리하려면 'compositionstart'와 'compositionend' 이벤트를 사용해야 합니다. 이 이벤트들은 IME (Input Method Editor)를 통해 문자가 완성되기 전과 후에 발생합니다. 한글 초성 입력을 처리하는 코드를 다음과 같이 수정할 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성, 중성, 종성 포함) - 화면 출력</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <input type="text" id="outputField" readonly>
  <script>
    const inputField = document.getElementById('inputField');
    const outputField = document.getElementById('outputField');

    let compositionData = '';

    inputField.addEventListener('compositionstart', (event) => {
      compositionData = event.data;
    });

    inputField.addEventListener('compositionupdate', (event) => {
      compositionData = event.data;
    });

    inputField.addEventListener('compositionend', (event) => {
      compositionData = event.data;
      const lastChar = compositionData.slice(-1);

      const isKorean = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0xAC00 && unicode <= 0xD7A3;
      };

      const isKoreanChosung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1100 && unicode <= 0x115F;
      };

      const isKoreanJungsung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1160 && unicode <= 0x11A7;
      };

      const isKoreanJongsung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x11A8 && unicode <= 0x11FF;
      };

      if (isKorean(lastChar) || isKoreanChosung(lastChar) || isKoreanJungsung(lastChar) || isKoreanJongsung(lastChar)) {
        outputField.value = `한글 입력 감지: ${lastChar}`;
      } else {
        outputField.value = '';
      }
    });

  </script>
</body>
</html>
위의 예제에서는 'compositionstart', 'compositionupdate', 'compositionend' 이벤트를 추가하여 한글 초성 입력을 처리하고 있습니다. 'compositionstart' 이벤트가 발생하면 이벤트 객체의 data 속성을 compositionData 변수에 저장합니다. 'compositionupdate' 이벤트가 발생하면 compositionData 변수를 업데이트하고, 'compositionend' 이벤트가 발생하면 한글 초성 입력이 완료된 것이므로, 한글 감지를 수행한 후 결과를 출력합니다. 이렇게 하면 한글 초성 입력을 정확하게 감지할 수 있습니다.
질문 :
한글의 초성,중성,종성 중 어떤 것이 입력되도 표시되도록 수정해줘
한글 초성, 중성, 종성 중 어떤 것이 입력되어도 표시되도록 수정한 코드는 다음과 같습니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성, 중성, 종성 포함) - 화면 출력</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <input type="text" id="outputField" readonly>
  <script>
    const inputField = document.getElementById('inputField');
    const outputField = document.getElementById('outputField');

    let compositionData = '';

    inputField.addEventListener('compositionstart', (event) => {
      compositionData = event.data;
    });

    inputField.addEventListener('compositionupdate', (event) => {
      compositionData = event.data;
      detectAndDisplayKorean(compositionData);
    });

    inputField.addEventListener('compositionend', (event) => {
      compositionData = event.data;
      detectAndDisplayKorean(compositionData);
    });

    function detectAndDisplayKorean(inputValue) {
      const lastChar = inputValue.slice(-1);

      const isKorean = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0xAC00 && unicode <= 0xD7A3;
      };

      const isKoreanChosung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1100 && unicode <= 0x115F;
      };

      const isKoreanJungsung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x1160 && unicode <= 0x11A7;
      };

      const isKoreanJongsung = (char) => {
        const unicode = char.charCodeAt(0);
        return unicode >= 0x11A8 && unicode <= 0x11FF;
      };

      if (isKorean(lastChar) || isKoreanChosung(lastChar) || isKoreanJungsung(lastChar) || isKoreanJongsung(lastChar)) {
        outputField.value = `한글 입력 감지: ${lastChar}`;
      } else {
        outputField.value = '';
      }
    }

  </script>
</body>
</html>
위 코드에서는 한글 입력 감지를 하는 코드를 detectAndDisplayKorean 함수로 추출하였습니다. 그리고  'compositionupdate' 및 'compositionend' 이벤트 리스너에서 해당 함수를 호출하여 입력된 한글을 감지하고 화면에 출력하도록 하였습니다. 이렇게 하면 한글 초성, 중성, 종성 중 어떤 것이 입력되어도 표시됩니다.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>한글 입력 감지 (초성, 중성, 종성 포함) - 화면 출력</title>
</head>
<body>
  <input type="text" id="inputField" placeholder="여기에 입력하세요">
  <input type="text" id="outputField" readonly>
  <script>
    const inputField = document.getElementById('inputField');
    const outputField = document.getElementById('outputField');

    let compositionData = '';

    inputField.addEventListener('compositionstart', (event) => {
      compositionData = event.data;
    });

    inputField.addEventListener('compositionupdate', (event) => {
      compositionData = event.data;
      outputField.value = `한글 입력 감지: ${compositionData}`;
    });

    inputField.addEventListener('compositionend', (event) => {
      compositionData = event.data;
      outputField.value = `한글 입력 감지: ${compositionData}`;
    });

  </script>
</body>
</html>
이제 위의 코드는 'compositionupdate' 및 'compositionend' 이벤트에서 compositionData 를 직접 출력하도록 수정하였습니다. 이렇게 하면 '하'의 경우 'ㅎ'만 입력했을 때도 'ㅎ'이 출력됩니다. 이 코드는 입력된 한글의 초성, 중성, 종성을 포함하여 모두 표시합니다.

 

위의 과정을 통해 최종코드가 나온것임을 꼭 기억하자~

반응형
댓글