Reputation: 17940
I have a form directive that injects some bootstrap classes and adds ng-messages
to a form. Once i upgraded to angular 1.4 it breaks.
I was able to pinpoint the problem to this method:
var setupDom = function ( element ) {
var input = element.querySelector( 'input,textarea,select' );
var label = element.querySelector( 'label' );
var type = input.getAttribute( 'type' );
var name = input.getAttribute( 'name' );
//checkbox and radio need a different class
if ( type !== 'checkbox' && type !== 'radio' ) {
input.classList.add( 'form-control' );
}
element.classList.add( 'form-group' );
return name;
};
The html element that this code runs on looks like this:
<input type="url" name="{{'videoLink' + $index}}" id="{{'videoLink' + $index}}"
ng-model="item.videoLink" placeholder="Youtube or Vimeo video link"/>
The problem is in var name
, since it gets the non-compiled version {{'videoLink' + $index}}
instead of videoLink0 , videoLink1... as it used to in 1.3.
Any idea why is it happening and how to overcome this problem?
UPDATE:
here is the entire directive code:
'use strict';
(function ( module ) {
var setupDom = function ( element, scope ) {
var input = element.querySelector( 'input,textarea,select' );
var label = element.querySelector( 'label' );
var type = input.getAttribute( 'type' );
var name = scope.$eval(input.getAttribute( 'name' ));
//checkbox and radio need a different class
if ( type !== 'checkbox' && type !== 'radio' ) {
input.classList.add( 'form-control' );
}
element.classList.add( 'form-group' );
return name;
};
var addMessages = function ( form , element , name , $compile , scope ) {
var messages = '<div class="help-block am-fade-and-scale" ' + 'ng-messages=" ' + form.$name + '.' + name + '.$error' + '" ' + 'ng-show="' + form.$name + '.' + name + '.$dirty">' + '<div ng-messages-include="/assets/angular-client/app/html/common/forms/message.html"></div></div>';
element.append( $compile( messages )( scope ) );
};
var watcherFor = function ( form , name ) {
return function () {
if ( name && form[ name ] ) {
return form[ name ].$invalid;
}
};
};
var updaterFor = function ( element ) {
return function ( hasError ) {
if ( hasError ) {
element.removeClass( 'vl-success' ).addClass( 'vl-error' );
} else {
element.removeClass( 'vl-error' ).addClass( 'vl-success' );
}
};
};
var link = function ( $compile ) {
return function ( scope , element , attr , formCtrl ) {
var name = setupDom( element[ 0 ] ,scope );
addMessages( formCtrl , element , name , $compile , scope );
scope.$watch( watcherFor( formCtrl , name ) , updaterFor( element ) );
};
};
var forminput = /*ngInject*/
function ( $compile ) {
return {
restrict : 'A' ,
require : '^form' ,
link : link( $compile )
};
};
forminput.$inject = [ '$compile' ];
module.directive( 'vlForminput' , forminput );
}( angular.module( 'html.common' ) ));
Upvotes: 2
Views: 108
Reputation: 11
I encountered the same issue and addressed it using the replace method.
HTML:
<input type="text" ng-model="carrierBillingRateException.rate" name="rate{{$index}}" required />
Angular Directive:
var setupDOM = function (element, scope) {
var input = element[0].querySelector("input, textarea, select");
var type = input.getAttribute("type");
var name = input.getAttribute("name").replace('{{$index}}', scope.$index);
return name;
};
Upvotes: 1
Reputation: 552
Why not try using something like the following:
var app = angular.module('html.common', []);
app.directive('vlFormInput', function () {
return {
restrict: 'EA',
templateUrl: 'path/to/html/file/with/ng-repeat.html',
link: {
post: function(scope,elem,attr){
scope.setUpDom = function(){
var input = angular.element( 'input,textarea,select' );
var label = angular.element( 'label' );
var type = input.getAttribute( 'type' );
var name = input.getAttribute( 'name' );
}
}
}
};
});
I honestly have not tested this code but it should point you in the right direction. By using a post: function the values should be compiled when you go looking for them.
Upvotes: 0