I want to build a directive that allows me to use a twitter bootstrap component in one tag:
The tag looks like this:
<bootstrapinput
model="lastName"
key="lastName"
localized="Surname"
formpath="playerForm.lastName"
required>
</bootstrapinput>
The directive looks like this
.directive('bootstrapinput', function () {
return {
restrict:'E',
compile:function (tElement, tAttrs, transclude) {
var type = tAttrs.type || 'text';
var required = tAttrs.hasOwnProperty('required') ? 'required' : '';
var ngClazz = tAttrs.hasOwnProperty('formpath') ? 'ng-class="{error: ' + tAttrs.formpath + '.$invalid}"' : '';
var html = '<div class="control-group" ' + ngClazz + '>' +
'<label class="control-label" for="' + tAttrs.key + '">' + tAttrs.localized + '</label>' +
'<div class="controls">' +
'<input ng-model="'+tAttrs.model+'" type="' + type + '" id="' + tAttrs.key + '" name="' + tAttrs.key + '" placeholder="' + tAttrs.localized + '" ' + required + ' />' +
'</div>' +
'</div>';
tElement.replaceWith(html);
}
}
});
The tag is embedded in a Controller. But if I access the model in the controller via scope, the model is empty. Moreover the ng-class attribute is not evaluated, i.e. The CSS is not assigned as it should be.
EDIT The access to the model does now work. But the ng-class attribute still is not evaluated properly.
Use $compile. transclude is imho not necessary:
app.directive("bootstrapinput", function($compile) {
return {
restrict: 'E',
scope: {
model: '='
},
link: function(scope, element, attrs) {
var type = attrs.type || 'text';
var required = attrs.hasOwnProperty('required') ? 'required' : '';
var ngClazz = attrs.hasOwnProperty('formpath') ? 'ng-class="{error: ' + attrs.formpath + '.$invalid}"' : '';
var htmlTemplate = '<div class="control-group" ' + ngClazz + '>' + '<label class="control-label" for="' + attrs.key + '">' + attrs.localized + '</label>' + '<div class="controls">' + '<input ng-model="' + attrs.model + '" type="' + type + '" id="' + attrs.key + '" name="' + attrs.key + '" placeholder="' + attrs.localized + '" ' + required + ' />' + '</div>' + '</div>';
console.log(htmlTemplate);
var compiled = $compile(htmlTemplate)(scope);
element.replaceWith(compiled);
}
};
});
OK, finally I have the solution
I've just wrapped the div control-group in a further div. Now it works.
'<div><div class="control-group" ...>...</div></div>'
see also http://jsfiddle.net/JNgN2/6/