Anuglar JS 공부<*> - my directive

Posted by lib oimb
2019. 2. 21. 22:22 AngularJS



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>




이 댓글을 비밀 댓글로