### necessary ( 필수 ) ###

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- JQUERY -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
 
<!-- JQUERY-UI -->
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
 
<!-- bootstrap.min.css -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
 
<!-- bootstrap-theme.min.css -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
 
<!-- bootstrap.min.js -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
cs

jquery-ui 는 모달을 드래그 하기 위해 필요하다.

 

### Modal CSS ###

1
2
3
.modal { top:60px; z-index: unset; position: relative!important; }
.modal-dialog { position: fixed; left: 0; right: 0; top: 100; margin: 70; padding: 10px;}
.modal-backdrop.in{opacity: 0;}
cs

 

### HTML (EJS) ###

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<button type='button' data-toggle="modal" data-target="#first_modal">첫번쨰 모달 열기</button>
<button type='button' data-toggle="modal" data-target="#second_modal">두번쨰 모달 열기</button>
<button type='button' data-toggle="modal" data-target="#third_modal">세번쨰 모달 열기</button>
 
<!--first_modal-->
<div class="modal fade bs-example-modal-lg" id="first_modal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog modal-lg" role="document">
   <div class="modal-content">
     <div class="modal-header">
       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      
       <ol class="breadcrumb" style='background-color: white;'>
         <li><a href="#">모달</a></li>
         <li class="active">첫번쨰 모달</li>
       </ol>
     </div>
   </div>
</div>
</div>
 
<!--second_modal-->
<div class="modal fade bs-example-modal-lg" id="second_modal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog modal-lg" role="document">
   <div class="modal-content">
     <div class="modal-header">
       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      
       <ol class="breadcrumb" style='background-color: white;'>
         <li><a href="#">모달</a></li>
         <li class="active">두번쨰 모달</li>
       </ol>
     </div>
   </div>
</div>
</div>
 
<!--third_modal-->
<div class="modal fade bs-example-modal-lg" id="third_modal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog modal-lg" role="document">
   <div class="modal-content">
     <div class="modal-header">
       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      
       <ol class="breadcrumb" style='background-color: white;'>
         <li><a href="#">모달</a></li>
         <li class="active">세번쨰 모달</li>
       </ol>
     </div>
   </div>
</div>
</div>
cs

1. 각 모달의 id 값을 설정해준다. 필자는 first_modal, second_modal, third_modal 이렇게 3개의 모달을 준비함.

2. button에 data-toggle="modal" data-target="#first_modal" 구문을 추가한다. data-target="#first_modal"처럼 각 모달의 id 값을 넣어준다.

3. data-backdrop="static" 와 같이 static 값을 넣어주면 모달 영역 밖을 클릭했을때 모달이 닫히지 않는다.

 

### Modal Draggable & Priority when clicking modal ###

*모달 드래그 방법

*여러개의 모달이 열려있을 경우 사용자가 클릭한 모달이 화면 가장 앞으로 오게 하는 방법.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
    // 모달 위치 초기화 - 모달 창이 열리기 전에 실행
    $(document).on('show.bs.modal''.modal'function(){
        // 화면에 보여지는 모달수 추적
        if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' ) {
            $('body').data( 'fv_open_modals'0 );
        }
 
        // 이 모달의 z-index 속성이 정해져 있다면 무시
        if ($(this).hasClass('fv-modal-stack')) {
            return;
        }
 
        $(this).addClass('fv-modal-stack');
        $('body').data('fv_open_modals', $('body').data('fv_open_modals' ) + 1 );
        $(this).css('z-index'1040 + (10 * $('body').data('fv_open_modals' )));
        $('.modal-backdrop').not('.fv-modal-stack').css('z-index'1039 + (10 * $('body').data('fv_open_modals')));
        $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack'); 
        
        // 모달 위치 초기화
        $(this).find($('.modal-dialog')).css('top',100);
        $(this).find($('.modal-dialog')).css('right',0);
        $(this).find($('.modal-dialog')).css('left',0);
 
        // 모달창 드래그 기능
        $(this).find($('.modal-dialog')).draggable({ handle: ".modal-header" });
 
    })
    
    // 모달창이 완전히 사라진 후 호출
    $(document).on('hidden.bs.modal''.modal'function(e){
        $(this).removeClass( 'fv-modal-stack' );
        $('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
    });
 
    // 클릭한 모달의 화면 우선순위
    $(document).on('click''.modal'function(){
        $(this).css('z-index'1040 + (10 * $('body').data('fv_open_modals' )));  
        $('body').data('fv_open_modals', $('body').data('fv_open_modals' ) + 1 ); 
        
        if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' ) {
            $('body').data( 'fv_open_modals'0 );
        }
    });
cs

### RESULT ###

1.) 8자리 년월일 => 10자리로 변경(ex. 20200824 => 2020-08-24)

1
2
var YYMMDD = '20200824';
YYMMDD = YYMMDD.replace(/(\d{4})(\d{2})(\d{2})/'$1-$2-$3');
cs

2.) 전화번호 '-' 추가하기

1
2
var phone = "01012345678";
phone.replace(/(\d{3})(\d{4})(\d)/"$1-$2-$3");
cs

3.) 이메일 체크 ( 사용가능한 문자와  '@'와 '.' 이 들어가 있는지 확인 )

1
2
3
var email_check = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/g; 
var text = "uznam8x@gmail.com"
email_check.test(text);
cs

4.) 숫자, 영어, 한글 체크

1
2
3
/^[0-9]+$/g.test(1234);    // 숫자만 가능
/^[a-zA-Z]+$/g.test("abcd"); // 영어만 가능
/^[가-힣]+$/g.test("가나다라");    // 한글만 가능
cs

5.) ',' (콤마) 제거

1
2
var value = '100,000,000';
value = value.replace(/,/g,'');
cs

6. 3자리 단위로 ','(콤마) 추가하기

1
2
var money = 10000000;
money = String(money).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
cs

 

크롬의 alert창 스타일과 같은 심플한 팝업창이 필요해서 구글링 하던중

dialog element demo

라는 방법을 알았다.

https://demo.agektmr.com/dialog/

 

dialog element demo

The HTML dialog element provides in-page dialog box functionality. A dialog exists in the DOM tree and can be styled using ordinary CSS.

demo.agektmr.com

내가 자주 사용하는 dialog [style]

1
2
dialog { border: 1px solid rgba(0, 0, 0, 0.3); border-radius: 6px; box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); }
dialog::backdrop { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); }
 

주의 할 점

Internet explorer, edge 에서는 작동 안함 => 아래의 bluebird.js 를 사용하면 Internet explorer 에서 작동됨

 

axios 설치 명령어(터미널에서)

1
npm install axios
 

[App.js]

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
31
32
33
34
35
36
37
38
import React from 'react';
import axios from 'axios';
import Movie from './Movie';
class App extends React.Component{    
  state={              
   isLoading: true,
   movies: []
  };
 
  getMovies = async () =>{      // async는 비동기를 말하며 await는 axios함수가 끝날떄 까지 기달리라는 뜻을 가진다.
    const {data : {data : {movies}}} = await axios.get('https://yts-proxy.now.sh/list_movies.json?sort_by=rating');
    // movies.data.data.movies로 써도 되지만 es6에서는 {data : {data : {movies}}}같은 방법으로도 사용 가능하다.
    this.setState({ movies, isLoading:false });
  }
  componentDidMount(){
   this.getMovies();
  }
 
  render(){
    const {isLoading, movies} = this.state;
    return (
      <div>{isLoading ? "Loading..." : movies.map(movie => (
        <Movie
          key={movie.id}
          id={movie.id} 
          title={movie.title} 
          year={movie.year} 
          summary={movie.summary} 
          poster={movie.poster}
        />
      ))}
      </div>
      
    );    
  } 
}
 
export default App;
 
 

[Movie.js]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React from 'react';
import PropType from 'prop-types';
 
function Movie({id, title, year, summary, poster}){
    return <h4>{title}</h4>
}
 
Movie.PropType = {
    id: PropType.number.isRequired,
    title: PropType.string.isRequired,
    year: PropType.number.isRequired,
    summary: PropType.string.isRequired,
    poster: PropType.string.isRequired
}
 
export default Movie;
 

'웹 프로그래밍 > ReactJS' 카테고리의 다른 글

state 사용법  (0) 2019.09.09
기초적인 prop 사용법  (0) 2019.09.09
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
import React from 'react';
import PropTypes from 'prop-types';
 
class App extends React.Component{    // App 컴포넌트는 return함수를 가지고 있지만 React 컴포넌트로 확장했기 때문에 render 함수를 사용해야 한다. 그 이유는 React 컴포넌트는 return함수를 가지고 있지 않기 때문이다.
  state={               // 변하는 데이터를 생성하고자 할때는 state 안에 넣어야 한다.
    count: 0            // state를 render안에 넣고자 한다면 {this.state.count}와 같은 형식으로 넣어야 한다.
  };
  add = () =>{
    console.log("add");
    this.setState({count: this.state.count + 1});           // 이 방법은 추천하지 않는다.
  };
  minus = () =>{
    console.log("minus");
    this.setState(current => ({count: current.count - 1}));   // 이 방법을 추천한다.
  };
  render(){
    const {count} = this.state;
 
    return (
      <div>
        <h1>Number is {count}</h1>
        <button onClick={this.add}>더하기</button>           
        <button onClick={this.minus}>빼기</button>
      </div>
    );    // 바닐라JS에서는 기본적으로 button에 addEventListener를 해야하지만 react에서는 기본적으로 onClick함수가 내장되어있다.
  } 
}
 
export default App;
 
 

'웹 프로그래밍 > ReactJS' 카테고리의 다른 글

axios 사용하기  (0) 2019.09.09
기초적인 prop 사용법  (0) 2019.09.09

58번째에 사용된 map()함수는 배열변수에서만 사용할 수 있고 기본적으로 forEach 기능을 가지고 있다.

안에 들어갈 파라미터로는 함수가 들어간다. 

예를 들면

iLikeFood.map(function(item){

 <Food />

});

위와 같은 기본적인 형식이면 아래의 코드로와 기능은 같다.

iLikeFood.map( item => <Food />); 

 

item은 오브젝트이며 iLikeFood 배열에 존재하는 각각의 아이템들에 해당한다.

 

map함수의 기능으로는 배열안에 들어있는 오브젝트의 값을  Food라는 함수의 결과 값으로 바꾸는 기능 가지고 있다.

예를들어 iLikeFood 배열이 [1,2,3,4,5]라고 하자. 또 Food라는 함수의 return 값은 0이라고 한다면

 

iLikeFood.map( item => <Food />); 의 결과값으로 console.log(iLikeFood)를 찍어본다면 [0,0,0,0,0]이 나올것이다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import React from 'react';
import PropTypes from 'prop-types';
 
const iLikeFood = [
  {
    id:1,
    name"김밥",
    image: "../images/1.jpg",
    rating: 4.5
  },
  {
    id:2,
    name"탕수육",
    image: "../images/2.jpg",
    rating: 4.0
  },
  {
    id:3,
    name"라조기",
    image: "../images/3.jpg",
    rating: 3.8
  },
  {
    id:4,
    name"동파육",
    image: "../images/4.jpg",
    rating: 4.3
  },
  {
    id:5,
    name"족발",
    image: "../images/5.jpg",
    rating: 5.0
  },
]
Food.propTypes = {
  name: PropTypes.string.isRequired,
  picture: PropTypes.string.isRequired,
  rating: PropTypes.number
};
 
function Food({name, picture, rating}){
  //console.log(props);
  //return (<h5>I have a {props.dessert}</h5>)
  return (
    <div>
      <h1>I like {name}</h1>
      <h4>{rating}/5.0</h4>
      <img src={picture} alt={name/>
    </div>
  )
}
 
function App() {
  return (
    <div className="App">
      Hello!!
      {iLikeFood.map(item => <Food key={item.id} name={item.name} picture={item.image} rating={item.rating} />)}
    </div>
  );
}
 
export default App;
 
 

 

'웹 프로그래밍 > ReactJS' 카테고리의 다른 글

axios 사용하기  (0) 2019.09.09
state 사용법  (0) 2019.09.09

+ Recent posts