1. layer 열고 닫기
/*
* directive - 다른 레이어 view 또는 레이어 닫기 기능
*
* layerShow : 현재 닫으려는 pop-up의 show의 scope 변수명
* input : 현재 닫으려는 pop-up input의 모델 객체 명 (ex object.model => object를 적음됨)
* layer : 현재 새로 열려는 pop-up scope 변수명 (열려는 pop-up)없을수도 있음 )
* form : 현재 닫으려는 form name
*/
inquiry_controller.directive('layerShow',['$parse',function($parse){
return {
priority:'2',
restrict: 'AE',
scope : {
layerShow :'=',
input : '=',
layer : '=',
form : '='
},
link : function(scope,element,attrs){
element.on('click',function(){
scope.$apply(function(){
// [1] 현재 pop-up 닫기
scope.layerShow = false;
// [2] 현재 pop-up input값 초기화
angular.forEach(scope.input,function(inp,idx){
scope.input[idx]='';
});
// [3] form을 최초의 순정상태로 돌림 (invalid message를 없애기위함)
if(attrs.form != null && attrs.form != undefined){
scope.form.$setPristine(true);
}
// [4] 새로운 pop-up을 열려한다면 true로 변경 typeof
if(attrs.layer != undefined && attrs.layer != null){
scope.layer = true;
}
})
});
}
}
}])
<a href="#none" layer-show="layer.is_x_popup" input="form" layer="layer.is_y_popup" form="formArea">x</a>
2. match - 비밀번호 일치 확인
/*
* directive - 비밀번호 일치 확인 디렉티브
*
* match : 매칭 시키고 싶은 password의 ngModel 값
* $setValidity : match라는 새로운 validate를 생성한다. 조건이 true -> valid false -> invalid
* $parsers : ngModelController에 함수를 등록 한다.
*/
layer_controller.directive('match',function(){
return {
restrict : 'A',
scope:{
match : '='
},
require: "ngModel",
link: function(scope,element,attrs,ctrl){
function matchValidation(value){
scope.$watch(scope.match,function(newValue){
var strMatch = newValue || "";
ctrl.$setValidity('match',value==strMatch);
})
return value;
}
ctrl.$parsers.push(matchValidation);
}
}
})
<input type="password" name="joinPwd" ng-model="join_form.join_pwd">
<input type="password" name="joinMatchPwd" match="join_form.join_pwd" ng-model="join_form.join_match_pwd" >
3. 파일 업로드 + 추가 및 삭제
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<style type="text/css">
.upload-file{top: 0;left: 0;width: 100%;height: 100%;opacity: 0;z-index: 301;cursor: pointer; position: absolute;}
.button-upload{display: inline-block;padding: 14px 26px;color: #dcdcdc;font-size: 15px;line-height: 2px;vertical-align: top;background-color: #fdfdfd;cursor: pointer;border: 1px solid #dcdcdc;border-bottom-color: #e2e2e2;border-radius: 2px;font-weight: bold;color: #8c8c8c;letter-spacing: -0.5px;height: 0px; border-top-left-radius: 0;border-bottom-left-radius: 0;position: absolute;z-index: 300;top: -1px;right: -1px;}
.label-upload{color: #333;white-space: nowrap;opacity: .5;vertical-align: top;font-size: 12px;display: inline-block;overflow: hidden; width: 100%}
.upload-file-array{ display: inline-block;text-align: left;width: 356px;position: relative;border-radius: 2px;padding: 8px 10px;color: #999;font-size: 12px;line-height: normal;vertical-align: middle;background-color: #f5f5f5;cursor: pointer;border: 1px solid #dcdcdc;border-radius: 2px;font-weight: bold;color: #8c8c8c;letter-spacing: -0.5px;height: 12px;border-top-right-radius: 0;border-bottom-right-radius: 0;box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1) inset;-webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1) inset;-moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1) inset;margin-left: 0px;margin-bottom: 15px;margin-top: 15px;}
.add-btn{display: inline-block; cursor: pointer;}
.remove-btn {display: inline-block; cursor: pointer;}
.upload-file-array-area{width: 500px;height: 30px; margin-bottom: 8px}
</style>
</head>
<body ng-app="app" >
<div ng-controller="Con">
<form name ='testForm' novalidate>
<!-- <div multi-file ng-repeat="upload_file in upload_file_array" ng-if="upload_file.is_use"> -->
<div class="upload-file-array-area" multi-file ng-repeat="upload_file in upload_file_array" add="add" remove="remove" upload-file-array="upload_file_array">
<div class="upload-file-array" >
<input file-model="upload_file_name" type='file' name="uploadFile" class="upload-file" ng-model="upload_file" ng-required="true" >
<span class='button-upload'>찾아보기</span>
<label ng-if="upload_file_name==null" class='label-upload'>파일을 첨부해주세요</label>
<label ng-if="upload_file_name!=null" class='label-upload'>{{upload_file_name}}</label>
<label ng-if="false" class='label-upload' ng-bind='upload_file_save'></label>
</div>
<a class="add-btn" ng-click="add($index)" ng-if="$last">add</a>
<a class="remove-btn" ng-click="remove($index,upload_file)" ng-if="!$first">remove</a>
</div>
<button type="submit" ng-click="click()" style="margin-top: 20px">click</button>
</form>
</div>
</body>
<script>
var app = angular.module("app",[]);
app.controller("Con",["$scope",function($scope){
$scope.upload_file_array = [{'is_use':true}];
$scope.file_list = [];
$scope.click = function(){
for(var i=0 ; i<document.getElementsByClassName('upload-file').length;i++){
if(document.getElementsByClassName('upload-file')[i].value !=null && document.getElementsByClassName('upload-file')[i].value !=''){
$scope.file_list.push(document.getElementsByClassName('upload-file')[i].files[0]);
}
}
console.log($scope.file_list);
}
}])
angular.module("app").directive("multiFile", function() {
return {
scope:{
add : '=',
remove : '=',
upload_file_array : '=uploadFileArray'
},
link: function (scope,elem,attrs) {
scope.add = function(index){
scope.upload_file_array.push({});
//scope.upload_file_array.push({'is_use' :false});
}
scope.remove = function(index,upload_file){
// 아래 2가지 방식중 하나 선택
scope.upload_file_array.splice(index,1);
//upload_file.is_use=false;
}
}
}
})
angular.module("app").directive('fileModel', function() {
return {
scope : {
upload_file_name : '=fileModel'
},
require: "ngModel",
link : function(scope, element, attrs,ctrl) {
// 동적으로 이벤트를 달아주는경우 ModelOptions를 수정 해줘야함
ctrl.$overrideModelOptions({
updateOn:'change click'
,debounce: 0
})
// 클릭시 이미 등록된 파일이 삭제되므로 view도 삭제된 모습을 보여줘야함
element.on('click',function(){
scope.$apply(function(){
clear();
})
})
// 파일 등록시
element.on('change',function(){
scope.$apply(function(){
if(element[0].files[0]!=null && element[0].files[0]!='' && element[0].files[0] != undefined){
if(!validateFile()){
return false;
}
ctrl.$setViewValue(element[0].files[0]);
scope.upload_file_name=element[0].files[0].name;
}
})
})
// 파일관련 객체와 변수들을 초기화
var clear = function() {
element[0].value=null;
ctrl.$setViewValue(element[0].files[0]);
}
// 파일 확장자
var splitExtension = function(fileName){
fileName = fileName.split('.');
extension = fileName[fileName.length-1];
return extension;
};
//파일 검증 로직
var validateFile= function() {
if(typeof element[0].files[0] != 'undefined' && element[0].files[0] != null ){
var fileType=splitExtension(element[0].files[0].name).toUpperCase();
if(element[0].files[0].size > 20971520){
clear();
alert("파일의 크기가 너무 큽니다. 20mb이하로 올려주세요.");
return false;
}
if(element[0].files[0].name=='' || element[0].files[0].name == null){
clear();
alert("파일을 첨부해주세요.");
return false;
}/*else if(fileType!="TXT"){
clear();
$window.alert("적절한 파일 타입이 아닙니다.");
return false;
}*/
}else{
clear();
alert("파일을 첨부해주세요.");
return false;
}
return true;
}
}
}
});
</script>
</html>
4. popup + callback
<a href="#" class="normal-type-btn purple" popup="url" dimensions="dimensions" callback="setTemplate" >템플릿</a>
/*
* 팝업 창 Controller에서 자신을 연창(부모) Controller에 있는 callback 함수를 호출
*/
$scope.selectTemplate = function(template){
$window.opener.callback(template);
$window.close();
};
/*
* popup directive
* url : 이동할 url
* dimensions : 팝업 속성값
* callback : 콜백 함수
*/
inquiry_controller.directive("popup", function($window){
return {
restrict: "AE",
scope: {
popup: "=",
dimensions: "=",
callback : "="
},
link: function(scope, element){
$window.callback = function(template){
scope.callback(template);
};
element.on("click", function(e){
var authwindow = $window.open(scope.popup,"_blank", scope.dimensions);
authwindow.focus();
});
}
};
});
5. checkbox + all check
// inquiryTypeAll - 체크박스 전체 or 선택한 박스만 체크 됨 part : part[0] = 체크박스 리스트 part[1] = checked
inquiry_controller.directive('checkBoxAll', ['$parse', function($parse) {
return function(scope, element, attrs) {
var parts = attrs.checkBoxAll.split('&');
// 전체 버튼 토글여부
element.bind('change', function() {
scope.$apply(function() {
var setValue = element[0].checked;
angular.forEach(scope.$eval(parts[0]), function(v) {
v[parts[1]] = setValue;
})
})
})
// 부분 버튼 클릭에 따른 전체 버튼 토글 여부
scope.$watch(parts[0], function(val) {
var hasTrue = false, hasFalse = false;
angular.forEach(val, function(v) {
if (v[parts[1]]) {
hasTrue = true;
} else {
hasFalse = true;
}
});
if (hasTrue && hasFalse) {
var get = $parse(attrs.ngModel);
get.assign(scope, false);
} else {
var get = $parse(attrs.ngModel);
get.assign(scope, hasTrue);
}
}, true);
}
} ])
<span>
<input type="checkbox" id="all_status" check-box-all="check_box.inquiry_status_list&checked" ng-model="check_box.inquiry_status_all">
<label for="all_status">전체</label>
</span>
<span ng-repeat="inquiry_status in check_box.inquiry_status_list">
<input type="checkbox" id="{{inquiry_status.CODE}}" ng-model="inquiry_status.checked"
class="inquiry-status" value="{{inquiry_status.CODE}}" >
<label for="{{inquiry_status.CODE}}">{{inquiry_status.NAME}}</label>
</span>
자바 스크립트 - 객체 복사 (0) | 2019.03.14 |
---|---|
Anuglar JS 공부 <6> - $apply(), $watch() 변화 감지 그리고 $eval(),$parse() (0) | 2019.03.04 |
Anuglar JS 공부 <5> - 상속 (0) | 2019.02.20 |
Anuglar JS 공부 <4> - module.directive (0) | 2019.02.19 |
Anuglar JS 공부 <3> - 양,단 방향 바인딩 (0) | 2019.02.18 |