Front-End

[Vue.js + vuetify.js] 토글 버튼(v-btn-toggle)혹은 버튼(v-btn) 동적으로 생성하기 : 토글 버튼 여러개를 선택하는 방법

뷰티파이의 토글 버튼(v-btn-toggle) 과 버튼(v-btn)을 동적으로 생성하는 방법에 대해 알아봅니다. 서버에서 가져온 JSON 타입의 데이터 부분은 생략합니다.

아래의 스니펫과 같이 vue파일에 하드코딩하는 방식으로 대부분의 태그를 사용하게 됩니다.

<v-btn
	small
	rounded
	dark
	depressed
	color="#00ACC1"
	@click="getFilter('a1')"  v-show="false">
	서울지역
</v-btn>
        
      
<script>
import moment from 'moment';

export default {
  name: 'TestActHist',
  props: {
    keyId: { type: String },
    companyId: { type: String },
  },
  data: () => ({
    page: {
      totCnt: 0, // 리스트 전체 갯수
      perPage: 10, // 최초 가지고 올 데이터 갯수
      currPage: 1, // 현재 페이지
    },
    act: {
      isUse: true,
      color: '#00BCD4',
      class: 'test-btn-more-round',
    },
    testHistList: [],
    testOriginHistList: [],
    data: {
      startDate: moment(new Date()).format('YYYY-MM-DD'),
      endDate: '',
      selectedDate: '',
      isShow: false,
    },
    toggle_val: [],
  }),
  created() {
    this.selectedDate = moment(new Date()).format('YYYY-MM-DD');
    console.log(`##call created  ====  ${this.selectedDate}`);
  },
  mounted() {
  },
} 
</script>

 <v-btn> 태그 안에서 버튼의 색상이나 컬러를 지정할 때 , 데이터 변수에서 가져와서 처리하는 경우에는 콜론을 찍고 color 혹은 class 값으로 변수를 대입하게 됩니다.

<v-btn
	small
	rounded
	dark
	depressed
	:color="act.color"
    :class="act.class"
@click="getFilterSelect('a1')"  v-show="false">
서울지역
</v-btn>

본론으로 들어가서 동적으로 토글버튼이나 버튼을 생성해봅니다. <v-btn-toggle> 태그에 v-model 디렉티브를 사용하여 toggle_val 변수를 바인딩 처리합니다.  그리고 반드시 @click 이벤트가 아닌 @change 이벤트를 사용해서 처리합니다. 

multiple 옵션을 사용하게 되면 여러개의 토글 버튼을 클릭하여 선택되게 할 수 있어요.

  <v-btn-toggle v-model="toggle_val"
		  multiple
		  class="test-item-btn-toggle"
		  color="#00ACC1"
		  dense
		  small
		  rounded
	 @change="fnGetFilterList">
	  <v-btn v-for="(item, i) in ItemList" :key="i" :value="item.ITEM_NM"
		class="test-item-btn-toggle v-btn"
		small
		>{{item.ITEM_NM}}</v-btn>
  </v-btn-toggle>

[CSS]

.test-item-btn-toggle {
	display: inline-block;
	font-size: 0;
	border-radius: 5px;
}
.test-item-btn-toggle .v-btn{
	background: rgb(217, 217, 217) !important;
	color: #050505;
	border: 0px solid #00BCD4 !important;
	height: 32px !important;
	min-width: 53px !important;
	margin-left: -1px;
	margin-top: 3px;
}

.test-item-btn-toggle .v-btn.v-btn--active {
	background: #2f5597 !important;
	color: #fff !important;
}


@media only screen and (min-width:768px){
	.test-item-btn-toggle.block {
		width: 100%;
	}
	.test-item-btn-toggle.block .v-btn {
		width: 50%;
	}
	.test-item-btn-toggle.ubs-btn-toggle-three.block .v-btn {
		width: 33.3%;
	}	
}

CSS 수정시 색상값 위에 마우스 커서를 올리면 아래 이미지 처럼 색상 고르는 창이 뜨네요. 색상을 선택하면 자동으로 값이 변경됩니다.  신세계네요. 이런건 처음입니다. CSS까지 함께 개발해 본적이 없는데………………..비주얼스튜디오 코드의 기능인지 어떤 플러그인을 설치해서 그런지는 잘 모르겠네요.


<v-btn> 태그 안에서 v-for 문을 사용하여 버튼을 동적으로 생성해줍니다. 이때 value 값으로 키값 혹은 키값으로 사용되는 이름(text) 등으로 값을 지정합니다.  그렇게 하면 토글 버튼을 클릭할 때 마다 fnGetFilterList() 함수를 호출하게 되며, toggle_val 배열에 토글을 선택한 값의 value값이 자동으로 push되며, 선택을 해제하면 자동으로 pop처리합니다.

fnGetFilterList()함수 호출시에 toogle_val에 선택한 배열 값들을 반복문처리하여 서버사이드에서 데이터를 조회하여 오거나 혹은 필터링 처리를 할 수 있어요.

<script>
import moment from 'moment';

export default {
  name: 'TestActHist',
  props: {
    keyId: { type: String },
    companyId: { type: String },
  },
  data: () => ({
    testHistList: [],
    testOriginHistList: [],
    data: {
      startDate: moment(new Date()).format('YYYY-MM-DD'),
      endDate: '',
      selectedDate: '',
      isShow: false,
    },
    toggle_val: [],
  }),
  created() {
    this.selectedDate = moment(new Date()).format('YYYY-MM-DD');
  },
  mounted() {
  },
  methods: {
  	fnGetFilterList() {
    	console.log(`clicked: ${this.toggle_val}`);
    },
  },
} 
</script>

fnGetFilterList() 함수를 하나 만들었어요. 페이지 시작시 모든 자료를 조회한 후 토글버튼을 클릭하여 다중선택하여 해당 값이 존재하는 경우 필터처리 하여 리스트로 되돌려 주는 코드입니다. 쌩으로 코딩하다보니 문득…….

filter()함수를 사용했으면 되지 않았을까?????? 라는 생각이 들었네요. 그러나 이미 코드는 완성되었고, 다시 필터함수를 사용하여 코드를 변경하기엔 해야할 일이 많네요. 나중에 할일 없을 때 해보자!!!!

fnGetFilterList() {      
	const TempList = [];
	for (let j = 0; j < this.toggle_val.length; j += 1) {
	  const choice = this.toggle_val[j];
		for (let i = 0; i < this.testlOriginHistList.length; i += 1) {
		  const row = this.testlOriginHistList[i];
		  if (row.ITEM_NM.indexOf(choice) > -1) {
			// console.log(`## 포함된 데이터 : row.ITEM_NM : ${row.ITEM_NM}  choice = ${choice}`);
			// 임시 배열 테이블 중복 체크
			let isExist = false;
			for (let h = 0; h < TempList.length; h += 1) {
				const lastRow = TempList[h];
				// console.log(`## ${lastRow.KEY_ID} : ${row.KEY_ID}`);
				if (lastRow.KEY_ID === row.KEY_ID) {
				  isExist = true;
				  break;
				}
			}
			if (!isExist) TempList.push(row);
		  }
		}
	}
	
	this.testlHistList = [];
	// 필터를 모두 해제한 경우와 선택한 경우에 대한 처리
	if (this.toggle_val.length > 0) {
	// console.log(`## TempList.length : ${TempList.length}`);
	this.sortArrayList(TempList, 'START_TIME', false);// desc 정렬
	this.testlHistList = TempList;
	} else this.testlHistList = this.testlOriginHistList;
},

다음 스니펫은 배열을 오름차순 혹은 내림차순으로 정렬하는 스크립트입니다. 

sortArrayList(obj, id, boolean) {
  const clsRow = obj;
  clsRow.sort((a, b) => {
	let rtnVal = 0;
	if (boolean) {
	  rtnVal = a[id] < b[id] ? -1 : 1;
	} else {
	  rtnVal = a[id] < b[id] ? 1 : -1;
	}
	return rtnVal;
  });
},

 

[REFERENCE]

https://vuetifyjs.com/en/components/button-groups/#misc

https://vuetifyjs.com/en/api/v-btn-toggle/

 

 

Leave a Reply

error: Content is protected !!