[js] Summernote Custom Button & styleTags

florentyoon·2021년 4월 7일
0

js

목록 보기
8/12
post-thumbnail

썸머노트는 위지윅으로 코드 몇줄만 붙여오면 내 게시판에 에디터를 추가할 수 있는 아주 유용한 오픈소스다.

Summernote

특히 사용자가 원하는대로 기능을 추가하는 것도 간편하다.

먼저 적용할 수 있는 기술은 styleTags이다.

styleTags

아래는 기존에 사용하고 있는 썸머노트 코드.

styleTags 프로퍼티는 사용자가 지정한 태그를 바로 적용할 수 있게 도와주는 기능이다.

//# summerNote
        $('.summernote').summernote({
            toolbar: [
                ['style', ['borderBtn', 'style']],
                ['font', ['bold', 'underline', 'clear']],
                ['fontsize', ['fontsize']],
                ['height', ['height']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['table', ['table']],
                ['insert', ['link']],
                ['view', ['fullscreen', 'codeview', 'help']],
                ['image', ['picture', 'resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],
                ['float', ['floatLeft', 'floatRight', 'floatNone']],
                ['remove', ['removeMedia']],
            ],
            styleTags: [ 
                {
                    title: '제목',
                    tag: 'h1',
                    className: 'titleFont',
                    value: 'h1'
                },
                {
                    title: '일반(숫자)',
                    tag: 'p',
                    className: 'normalFont',
                    value: 'p'
                },
                {
                    title: '서브',
                    tag: 'p',
                    className: 'subFont',
                    value: 'p'
                },
            ],
            buttons: {
                borderBtn: borderBtn,
            },
            height: 350,
            lang: 'ko-KR',
            lineHeights: ['0.2', '0.3', '0.4', '0.5', '0.6', '0.8', '1.0', '1.2', '1.4', '1.5', '2.0', '3.0'],
            callbacks: {
                onImageUpload: function(files){
                    uploadSummernoteImageFile(files[0], this, 'community');
                },
                onPaste: function (e) {
                    var clipboardData = e.originalEvent.clipboardData;
                    if (clipboardData && clipboardData.items && clipboardData.items.length) {
                        var item = clipboardData.items[0];
                        if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
                            e.preventDefault();
                        }
                    }
                }
            }
        })

사진처럼 해당 태그가 출력되는걸 볼수 있다.

styleTags 사용은 아래처럼 title,tag,className,value를 지정할 수 있고, 혹은 styleTags: ['p', 'h1', 'h6' ] 식으로 열거해서 쓸 수 있다.

다만 이렇게 styleTags를 사용하는 방법은 p, pre, h1, h2 등과 같이 태그 자체를 출력해주기 때문에 p태그 안에 인라인 style을 적용하는 방법 등은 제한이 된다.

물론 className을 지정해서 별도의 css를 쓸 수 있지만, 현재 상황은 관리자 모드에서 작성한 글을 클라이언트 화면에 보여지도록 하고 있다.
관리자 환경에선 부트스트랩을 사용하며, 프론트는 리액트를 쓰고 있다.
이 두 차이로 인해 최대한 썸머노트에 저장된 html코드를 건드리지 않고 전달하는 inline style을 사용하고 싶다.

buttons

위와 같이 태그 자체를 생성해주는 styleTags 말고, 다른 방법으로 내가 inline style까지 지정한 태그를 붙여주는 방법은 없을까 고민했다. 결과적으로 summernote는 custom buttons 생성이 가능하다. 그리고 각 버튼에 대해 자유롭게 생성할 수 있기 때문에 이를 활용해보기로 한다.

위에 올린 summernote 코드 중간에 "buttons" 란 이름으로 프로퍼티가 들어간게 보인다. 이걸 활용한다.

 buttons: {
                borderBtn: borderBtn,
            },

또한, summernote의 툴바가 인식할 수 있도록 toolbar에도 방금 작성한 borderBtn을 써준다.

                ['style', ['borderBtn', 'style']],

그리고 아래 함수를 작성해주면 된다.

 var borderBtn = function() {
            var ui = $.summernote.ui;
            var button = ui.button({
                contents: '<i class="fa fa-pencil"/> 테두리',
                tooltip: '테두리 생성',
                click: function() {
                    const selection = window.getSelection();
                    const newRange = selection.getRangeAt(0);
                    let node = document.createElement('span');

                    selection.addRange(newRange);
                    node.innerHTML = '<p style="border:1px solid #f1a417; text-align: center; padding: 40px 0 40px 0;"> 내용 </p>';
                    node.innerHTML += '<br><br>';
                    newRange.deleteContents();
                    newRange.insertNode(node);
                }
            });
            return button.render();
        }

이 함수가 동작하는 것은 click 메소드 부터인데, 버튼을 클릭하는 순간 실행된다.
내용은 selection이라는 이름으로 커서 위치를 가져오고, 새 커서 위치를 저장.
사용자가 원하는 위치에 커서를 놓으면 그곳에 테두리를 생성하게 된다. (엄밀히 따지면, 생성보다는 innerHTML로 인해 내용이 입력되는 것이라 할 수 있다.)

그럼 사진 맨 위 상단에 "테두리"라는 버튼이 생성되었고, 이것을 누르면 textarea에 테두리가 생긴다.

이렇게 원하는 태그를 넣을 수 있다.

.

참조

[summernote custom button](https://codepen.io/qwe001/pen/VJaWoR) [자바스크립트 커서 위치 가져오기](https://webisfree.com/2020-11-18/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%BB%A4%EC%84%9C-%EC%9C%84%EC%B9%98-%EB%B0%8F-%EC%84%A0%ED%83%9D-%EC%98%81%EC%97%AD%EC%97%90-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%B0%8F-%EC%97%98%EB%A6%AC%EB%A8%BC%ED%8A%B8-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0)
profile
florentyoon의 IT 세상

0개의 댓글