6

के लिए प्रकट नहीं होता है I Angular Datetime PickerAngular Formly इनपुट प्रकार के रूप में उपयोग करने का प्रयास कर रहा हूं। मुझे यह काम मिल गया है कि मैं एक मूल्य को संपादित और सेट कर सकता हूं जो बाध्य मॉडल में सही ढंग से जोड़ा गया है।प्रमाणीकरण त्रुटि संदेश कस्टम डेटपिकर कोणीय फॉर्मूली फ़ील्ड

हालांकि, मुझे नियमित इनपुट फ़ील्ड की तरह प्रदर्शित करने के लिए सत्यापन त्रुटि संदेश प्राप्त नहीं हो सकते हैं।

JS Bin with what I've got so far। जैसा कि आप देख सकते हैं कि जब आप फ़ील्ड से बाहर निकलते हैं तो लाल रंग दिखाई नहीं देता है, केवल तभी जब आप सबमिट करने का प्रयास करते हैं। और त्रुटि संदेश कभी दिखाई नहीं देता है।

formly कॉन्फ़िग:

formlyConfigProvider.setType({ 
    name: 'datepicker', 
    templateUrl: "custom-template.html", 
    overwriteOk: true, 
    wrapper: ['bootstrapHasError'], 
    defaultOptions: function defaultOptions(options) { 
    return { 
     templateOptions: { 
     validation: { 
      show: true 
     } 
     } 
    }; 
    } 
}); 

formlyConfigProvider.setWrapper({ 
    name: 'validation', 
    types: ['input', 'datepicker'], 
    templateUrl: 'error-messages.html' 
}); 

फील्ड्स

vm.fields = [ 
    { 
    key: 'text', 
    type: 'input', 
    templateOptions: { 
     label: 'Text', 
     placeholder: 'Write something', 
     required: true 
    }, 
    }, 
    { 
    key: 'date', 
    type: 'datepicker', 
    templateOptions: { 
     label: 'Date', 
     placeholder: 'Pick a date', 
     required: true 
    }, 
    } 
]; 

टेम्पलेट्स

<script type="text/ng-template" id="custom-template.html"> 
    <div class="form-group"> 

     <label class="control-label" for="{{::id}}">{{to.label}} {{to.required ? '*' : ''}}</label> 
     <div class="dropdown"> 
      <a class="dropdown-toggle" id="dropdown-{{options.key}}" role="button" data-toggle="dropdown"> 
      <div class="input-group"> 
       <input id="{{::id}}" name="{{::id}}" type="text" data-date-time-input="YYYY-MM-DD" class="form-control" data-ng-model="model[options.key]"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span> 
      </div> 
     </a> 
     <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> 
      <datetimepicker 
       data-ng-model="model[options.key]" 
       data-datetimepicker-config="{ dropdownSelector: '#dropdown-' + options.key, minView: 'day', startView: 'year', modelType: 'YYYY-MM-DDTHH:mm:ssZ'}"/> 
     </ul> 
     </div> 
    </div> 

</script> 

<script type="text/ng-template" id="error-messages.html"> 
    <formly-transclude></formly-transclude> 
    <div ng-messages="fc.$error" ng-if="form.$submitted || options.formControl.$touched" class="error-messages"> 
    <div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc.$viewValue, fc.$modelValue, this)}}</div> 
    </div> 
</script> 
+0

आप मुद्दा व्याख्या कर सकते हैं थोड़ा और अगर मैं लेबल "पाठ" के साथ पहली बार पाठ बॉक्स क्लिक करें और अगले पाठ बॉक्स "अधिक पाठ" पर क्लिक करें के बाद से, पहला टेक्स्टबॉक्स क्रोम में एक सत्यापन त्रुटि दिखाता है। लेकिन यह "तिथि" के लिए नहीं हो रहा है। क्या यह मुद्दा है? – Aruna

+0

हां, यह समस्या –

+0

है क्या आप मेरा नीचे जवाब देख सकते हैं? – Aruna

उत्तर

3

इस गहरी जांच के बाद, मैं देख सकता हूं कि आपने Angular Datetime Picker पर नियंत्रण को Angular Formly के साथ पूरी तरह से संगत नहीं किया है।

यही कारण है यह AngularJS के ngModelController.$render() विधि को अधिलेखित है और इसलिए अन्य इनपुट नियंत्रण की तरह $touched के लिए मूल्य की स्थापना नहीं है कि के कारण है।

अपने कोड में एक और कारण है, config और टेम्पलेट error-messages.htmlfc.$touched, fc.$error और fc.$viewValue जबकि DatePicker तत्वों (सरणी) के समूह के रूप में प्रदर्शित हो रहा है साथ ही तत्व के रूप में कस्टम नियंत्रण इलाज कर रहे हैं।

इन सभी मुद्दों से छुटकारा पाने के लिए, आप के रूप में नीचे $touched स्थापित करने के लिए एक कस्टम निर्देश हो सकता है

app.directive('setTouched', function MainCtrl() { 
    return { 
     restrict: 'A', // only activate on element attribute 
     require: '?ngModel', // get a hold of NgModelController 
     link: function(scope, element, attrs, ngModel) { 
     if (!ngModel) return; // do nothing if no ng-model 
     element.on('blur', function() { 
      var modelControllers = scope.$eval(attrs.setTouched); 
      if(angular.isArray(modelControllers)) { 
       angular.forEach(modelControllers, function(modelCntrl) { 
       modelCntrl.$setTouched(); 
       }); 
      }    
     }); 
     } 
    }; 
    }); 

और custom-template.html में,

<div class="input-group"> 
    <input set-touched="options.formControl" id="{{::id}}" name="{{::id}}" type="text" data-date-time-input="YYYY-MM-DD" class="form-control" data-ng-model="model['date1']"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span> 
</div> 

और नीचे विन्यास में fc[0].$touched जोड़ने खेतों की सरणी का ख्याल रखने के लिए,

app.run(function run(formlyConfig, formlyValidationMessages) { 
    formlyConfig.extras.errorExistsAndShouldBeVisibleExpression = 'form.$submitted || fc.$touched || fc[0].$touched'; 
    formlyValidationMessages.addStringMessage('required', 'This field is required'); 
}); 

और भी क्षेत्रों की सरणी की देखभाल करने के error-messages.html में अनुभाग के नीचे जोड़ने के लिए,

<div ng-messages="fc[0].$error" ng-if="form.$submitted || options.formControl[0].$touched" class="error-messages"> 
    <div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc[0].$viewValue, fc[0].$modelValue, this)}}</div> 
</div> 

यह परिवर्तन इस मुद्दे को ठीक होगा।

आप जो आगे नीचे प्रदर्शित किया जाता है त्रुटि संदेश के साथ डिजाइन मुद्दे का एक सा देख सकते हैं,

आप div आवरण <div class="form-group"> को हटाने के द्वारा के रूप में नीचे custom-template.html बदल सकते हैं,

<script type="text/ng-template" id="custom-template.html"> 
    <label class="control-label" for="{{::id}}" 
      uib-popover="{{options.templateOptions.desc}}" 
      popover-trigger="mouseenter" 
      popover-placement="top-left" 
      popover-popup-delay="500" 
      popover-append-to-body="true">{{to.label}} {{to.required ? '*' : ''}}</label> 

      <div class="dropdown"> 
       <a class="dropdown-toggle" id="dropdown-{{options.key}}" role="button" data-toggle="dropdown"> 
       <div class="input-group"> 
        <input set-touched="options.formControl" id="{{::id}}" name="{{::id}}" type="text" data-date-time-input="YYYY-MM-DD" class="form-control" data-ng-model="model['date1']"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span> 
       </div> 
      </a> 
      <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> 
       <datetimepicker 
        data-ng-model="model[options.key]" 
        data-datetimepicker-config="{ dropdownSelector: '#dropdown-' + options.key, minView: 'day', startView: 'year', modelType: 'YYYY-MM-DDTHH:mm:ssZ'}"/> 
      </ul> 
      </div> 

    </script> 

मैं इन परिवर्तनों के साथ अपने JSBin को अपडेट किया है।

स्निपेट:

/* global angular */ 
 
(function() { 
 
    
 
    'use strict'; 
 

 
    var app = angular.module('formlyExample', ['formly', 'formlyBootstrap', 'ngAnimate', 'ngMessages', 'ui.bootstrap.datetimepicker', 'ui.dateTimeInput'], function config(formlyConfigProvider) { 
 
    
 
    formlyConfigProvider.setType({ 
 
     name: 'datepicker', 
 
     templateUrl: "custom-template.html", 
 
     overwriteOk: true, 
 
     wrapper: ['bootstrapHasError'], 
 
     defaultOptions: function defaultOptions(options) { 
 
      return { 
 
       templateOptions: { 
 
        validation: { 
 
         show: true 
 
        } 
 
       } 
 
      }; 
 
     } 
 
    }); 
 
    
 
    formlyConfigProvider.setWrapper({ 
 
     name: 'validation', 
 
     types: ['input', 'datepicker'], 
 
     templateUrl: 'error-messages.html' 
 
    }); 
 

 
    }); 
 
    
 
    
 
    
 
    app.run(function run(formlyConfig, formlyValidationMessages) { 
 
    formlyConfig.extras.errorExistsAndShouldBeVisibleExpression = 'form.$submitted || fc.$touched || fc[0].$touched'; 
 
    formlyValidationMessages.addStringMessage('required', 'This field is required'); 
 
    }); 
 
    
 

 
    app.directive('setTouched', function MainCtrl() { 
 
    return { 
 
     restrict: 'A', // only activate on element attribute 
 
     require: '?ngModel', // get a hold of NgModelController 
 
     link: function(scope, element, attrs, ngModel) { 
 
     if (!ngModel) return; // do nothing if no ng-model 
 
     element.on('blur', function() { 
 
      var modelControllers = scope.$eval(attrs.setTouched); 
 
      if(angular.isArray(modelControllers)) { 
 
       angular.forEach(modelControllers, function(modelCntrl) { 
 
       modelCntrl.$setTouched(); 
 
       }); 
 
      }    
 
     }); 
 
     } 
 
    }; 
 
    }); 
 
    
 

 
    app.controller('MainCtrl', function MainCtrl(formlyVersion) { 
 
    var vm = this; 
 
    
 
    vm.onSubmit = onSubmit; 
 
    vm.model = {}; 
 
    vm.options = {}; 
 
     vm.env = { 
 
     angularVersion: angular.version.full, 
 
     formlyVersion: formlyVersion 
 
    }; 
 
    
 
    vm.fields = [ 
 
     { 
 
     key: 'text', 
 
     type: 'input', 
 
     templateOptions: { 
 
      label: 'Text', 
 
      placeholder: 'Write something', 
 
      required: true 
 
     }, 
 
     }, 
 
     { 
 
     key: 'moretext', 
 
     type: 'input', 
 
     templateOptions: { 
 
      label: 'More Text', 
 
      placeholder: 'Write something else', 
 
     }, 
 
     }, 
 
     { 
 
     key: 'date', 
 
     type: 'datepicker', 
 
     templateOptions: { 
 
      label: 'Date', 
 
      placeholder: 'Pick a date', 
 
      required: true 
 
     }, 
 
     } 
 
    ]; 
 
    
 

 
    vm.originalFields = angular.copy(vm.fields); 
 

 
    // function definition 
 
    function onSubmit() { 
 
     if (vm.form.$valid) { 
 
     vm.options.updateInitialValue(); 
 
     alert(JSON.stringify(vm.model), null, 2); 
 
     } 
 
    } 
 
    }); 
 

 
})();
body { 
 
    margin: 20px 
 
} 
 

 
.formly-field { 
 
    margin-bottom: 30px; 
 
} 
 

 
.error-messages { 
 
    position: relative; 
 
} 
 

 
.error-messages, .message { 
 
    opacity: 1; 
 
    transition: .3s linear all; 
 
} 
 

 
.message { 
 
    font-size: .8em; 
 
    position: absolute; 
 
    width: 100%; 
 
    color: #a94442; 
 
    margin-top: 4px; 
 
} 
 

 
.error-messages.ng-enter.ng-enter-active, 
 
.message.ng-enter.ng-enter-active { 
 
    opacity: 1; 
 
    top: 0; 
 
} 
 

 
.error-messages.ng-enter, 
 
.message.ng-enter { 
 
    opacity: 0; 
 
    top: -10px; 
 
} 
 

 
.error-messages.ng-leave, 
 
.message.ng-leave { 
 
    opacity: 1; 
 
    top: 0; 
 
} 
 

 
.error-messages.ng-leave-active, 
 
.message.ng-leave-active { 
 
    opacity: 0; 
 
    top: -10px; 
 
}
<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <!-- jQuery --> 
 
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> 
 
    
 
    <!-- Twitter bootstrap --> 
 
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet"> 
 
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
 
    
 
    <!-- apiCheck is used by formly to validate its api --> 
 
    <script src="//npmcdn.com/[email protected]/dist/api-check.js"></script> 
 
    <!-- This is the latest version of angular (at the time this template was created) --> 
 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script> 
 

 
    <!-- This is the latest version of formly core. --> 
 
    <script src="//npmcdn.com/[email protected]/dist/formly.js"></script> 
 
    <!-- This is the latest version of formly bootstrap templates --> 
 
    <script src="//npmcdn.com/[email protected]/dist/angular-formly-templates-bootstrap.js"></script> 
 

 
     <script src="https://rawgit.com/angular/bower-angular-messages/v1.4.4/angular-messages.js"></script> 
 
    <script src="https://rawgit.com/angular/bower-angular-animate/v1.4.4/angular-animate.js"></script> 
 
    
 
    <!-- Moment --> 
 
    <script src="https://cdn.rawgit.com/moment/moment/develop/min/moment-with-locales.min.js"></script> 
 
    
 
    <!-- Datetime picker --> 
 
    <script type="text/javascript" src="https://cdn.rawgit.com/dalelotts/angular-bootstrap-datetimepicker/master/src/js/datetimepicker.js"></script> 
 
    <script type="text/javascript" src="https://cdn.rawgit.com/dalelotts/angular-bootstrap-datetimepicker/master/src/js/datetimepicker.templates.js"></script> 
 
    <link href="https://cdn.rawgit.com/dalelotts/angular-bootstrap-datetimepicker/master/src/css/datetimepicker.css" rel="stylesheet"> 
 
    <script type="text/javascript" src="https://cdn.rawgit.com/dalelotts/angular-date-time-input/master/src/dateTimeInput.js"></script> 
 
    
 
    
 
    <title>Angular Formly Example</title> 
 
    </head> 
 

 
    <body ng-app="formlyExample" ng-controller="MainCtrl as vm"> 
 
    <div> 
 
     <form ng-submit="vm.onSubmit()" name="vm.form" novalidate> 
 
     <formly-form model="vm.model" fields="vm.fields" options="vm.options" form="vm.form"> 
 
      <button type="submit" class="btn btn-primary submit-button">Submit</button> 
 
      <button type="button" class="btn btn-default" ng-click="vm.options.resetModel()">Reset</button> 
 
     </formly-form> 
 
     </form> 
 
     <hr /> 
 
     <h2>Model</h2> 
 
     <pre>{{vm.model | json}}</pre> 
 
     <h2>Fields <small>(note, functions are not shown)</small></h2> 
 
     <pre>{{vm.originalFields | json}}</pre> 
 
     <h2>Form</h2> 
 
     <pre>{{vm.form | json}}</pre> 
 
    </div> 
 

 
    <!-- Put custom templates here --> 
 
    <script type="text/ng-template" id="custom-template.html"> 
 
    <label class="control-label" for="{{::id}}" 
 
      uib-popover="{{options.templateOptions.desc}}" 
 
      popover-trigger="mouseenter" 
 
      popover-placement="top-left" 
 
      popover-popup-delay="500" 
 
      popover-append-to-body="true">{{to.label}} {{to.required ? '*' : ''}}</label> 
 

 
      <div class="dropdown"> 
 
       <a class="dropdown-toggle" id="dropdown-{{options.key}}" role="button" data-toggle="dropdown"> 
 
       <div class="input-group"> 
 
        <input set-touched="options.formControl" id="{{::id}}" name="{{::id}}" type="text" data-date-time-input="YYYY-MM-DD" class="form-control" data-ng-model="model['date1']"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span> 
 
       </div> 
 
      </a> 
 
      <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> 
 
       <datetimepicker 
 
        data-ng-model="model[options.key]" 
 
        data-datetimepicker-config="{ dropdownSelector: '#dropdown-' + options.key, minView: 'day', startView: 'year', modelType: 'YYYY-MM-DDTHH:mm:ssZ'}"/> 
 
      </ul> 
 
      </div> 
 
    </script> 
 
    
 
    <script type="text/ng-template" id="error-messages.html"> 
 
     <formly-transclude></formly-transclude> 
 
     <div ng-messages="fc.$error" ng-if="form.$submitted || options.formControl.$touched" class="error-messages"> 
 
     <div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc.$viewValue, fc.$modelValue, this)}}</div> 
 
     </div> 
 
     <div ng-messages="fc[0].$error" ng-if="form.$submitted || options.formControl[0].$touched" class="error-messages"> 
 
     <div ng-message="{{ ::name }}" ng-repeat="(name, message) in ::options.validation.messages" class="message">{{ message(fc[0].$viewValue, fc[0].$modelValue, this)}}</div> 
 
     </div> 
 
    </script> 
 

 
    </body> 
 

 
</html>

+0

यह अधिकांश भाग के लिए काम करता है, हालांकि, त्रुटि संदेश सबमिट पर डेटपिकर फ़ील्ड पर प्रकट नहीं होता है। केवल इसे ध्यान में रखते हुए और फिर इसे छोड़कर। –

0

आप चाहिए में में templateOptions के मूल्य के रूप में इसे बिना validation। लौटें

validation: { 
    show: true 
} 

बजाय

templateOptions: { 
    validation: { 
     show: true 
    } 
} 

आपका formlyConfigProvider कुछ इस तरह दिखना चाहिए:

formlyConfigProvider.setType({ 
    name: 'datepicker', 
    templateUrl: "custom-template.html", 
    overwriteOk: true, 
    wrapper: ['bootstrapHasError'], 
    defaultOptions: function defaultOptions(options) { 
     return { 
       validation: { 
        show: true 
       }  
     }; 
    } 
}); 

Here काम कर कोड के लिए JSBin है।

+0

यह समस्या का समाधान नहीं करता है। डेटपिकर फ़ील्ड को टेक्स्ट फ़ील्ड की तरह काम करना चाहिए। जब आप किसी भी मूल्य दर्ज किए बिना मैदान से बाहर निकलते हैं तो इसे लाल रंग में बदलना चाहिए, इसे चुनने से पहले लाल नहीं होना चाहिए। और त्रुटि संदेश अभी भी फ़ील्ड के नीचे कभी नहीं दिखाई देता है। –

संबंधित मुद्दे