How to move up and down items using angular js? - javascript

http://jsfiddle.net/Nidhin/xd3Ab/
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.roles = [
{roleId: 1, roleName: "Administrator"},
{roleId: 2, roleName: "Super User"}
];
$scope.user = {
userId: 1,
username: "JimBob",
roles: [$scope.roles[0]]
};});myApp.directive('multiSelect', function($q) {return {
restrict: 'E',
require: 'ngModel',
scope: {
selectedLabel: "#",
availableLabel: "#",
displayAttr: "#",
available: "=",
model: "=ngModel"
},
template: '<div class="multiSelect">' +
'<div class="leftms fL ">' +
'<label class="control-label fL" for="multiSelectSelected">{{ availableLabel }} ' +
'({{ available.length }})</label>'+'<div class="clear"></div>'+
'<select id="multiSelectAvailable" ng-model="selected.available" multiple ' +
'class="pull-left mselect " ng-options="e as e[displayAttr] for e in available"></select>' + '<div class="clear"></div>'+
'</div>' +
'<div class=" width10p fL" >' +
'<button class="btn mover left" ng-click="add()" title="Add selected" ' +
'ng-disabled="selected.available.length == 0">' +
'<i class="icon-arrow-right clrblk">></i>' +
'</button>' +
'<button class="btn mover right" ng-click="remove()" title="Remove selected" ' +
'ng-disabled="selected.current.length == 0">' +
'<i class="icon-arrow-left clrblk"><</i>' +
'</button>' +
'</div>' +
'<div class="leftms fL">' +
'<label class="control-label fL" for="multiSelectSelected">{{ selectedLabel }} ' +
'({{ model.length }})</label>' +'<div class="clear"></div>'+
'<select id="currentRoles" ng-model="selected.current" multiple ' +
'class="pull-left mselect fL" ng-options="e as e[displayAttr] for e in model">' +
'</select>' + '<div class="clear"></div>'+
'</div>' +
'<div class=" width10p fL" >' +
'<button class="btn mover left" ng-click="up()" title="Add selected" ' +
'ng-disabled="selected.current.length == 0">' +
'<i class="fa fa-angle-up clrblk"></i>' +
'</button>' +
'<button class="btn mover right" ng-click="down()" title="Remove selected" ' +
'ng-disabled="selected.current.length == 0">' +
'<i class="fa fa-angle-down clrblk"></i>' +
'</button>' +
'</div>' +
'</div>', link: function(scope, elm, attrs) {
scope.selected = {
available: [],
current: []
};
/* Handles cases where scope data hasn't been initialized yet */
var dataLoading = function(scopeAttr) {
var loading = $q.defer();
if(scope[scopeAttr]) {
loading.resolve(scope[scopeAttr]);
} else {
scope.$watch(scopeAttr, function(newValue, oldValue) {
if(newValue !== undefined)
loading.resolve(newValue);
});
}
return loading.promise;
};
/* Filters out items in original that are also in toFilter. Compares by reference. */
var filterOut = function(original, toFilter) {
var filtered = [];
angular.forEach(original, function(entity) {
var match = false;
for(var i = 0; i < toFilter.length; i++) {
if(toFilter[i][attrs.displayAttr] == entity[attrs.displayAttr]) {
match = true;
break;
}
}
if(!match) {
filtered.push(entity);
}
});
return filtered;
};
scope.refreshAvailable = function() {
scope.available = filterOut(scope.available, scope.model);
scope.selected.available = [];
scope.selected.current = [];
};
scope.add = function() {
scope.model = scope.model.concat(scope.selected.available);
scope.refreshAvailable();
};
scope.remove = function() {
scope.available = scope.available.concat(scope.selected.current);
scope.model = filterOut(scope.model, scope.selected.current);
scope.refreshAvailable();
};
scope.update = function() {
scope.model = scope.model.concat(scope.selected.current);
//scope.model = filterOut(scope.model, scope.selected.current);
scope.refreshAvailable();
};
scope.up = function() {
var $op = $('#currentRoles option:selected');
if($op.length){
$op.first().prev().before($op);
}
$('#currentRoles').find('option').attr('selected','selected');
//scope.update();
scope.refreshAvailable();
};
scope.down = function() {
var $op = $('#currentRoles option:selected');
if($op.length){
$op.last().next().after($op);
}
//scope.add();
scope.refreshAvailable();
scope.apply();
};
$q.all([dataLoading("model"), dataLoading("available")]).then(function(results) {
scope.refreshAvailable();
});
}};})// JavaScript Document
on this link you will find two select box Available Role & Current role, I have to move item from Available Role to Current role Then Move the item Up and down in Current role Select box
--- Moving Item from available role to Current role I have used angular js
--- For Moving item UP and down in Current role I have used Jquery But when I am posting the value order of item is not passing in same format which is in Current role selectbox.
Pls use the fiddle.

in my opinion, you should just modify the arrays within $scope to get the ordering right.
https://gist.github.com/jfornoff/db2bb5f0c35bc0364529
This is a gist of a bit of code that i used to modify array orders in a project that i worked on.
Basically what you would do is just grab your variable that points to the currently selected element,
and modify the corresponding array to suit what you are trying to do.
$scope.up = function(){
ArrayService.moveUp(correspondingArray, selected.current);
};
Hope that helps, cheers!

You can use Angular itself to move elements up and down too. If you reorder the elements in the array available and current the ui would automatically reorder the elements.
Use the array splice method to move element within the array. See this answer on how to move elements in an array.
Move an array element from one array position to another

Related

jQuery: function in dynamic generated list item doesn't work

I build a function to display a value in a HTML element for a
<input type="range">
object.
My function works fine:
var rangeValues = { "50": "Fifty" , "100": "Hundred" , "...": "..." };
$(function Skilllevel() {
$('#rangeText').text(rangeValues[$('#rangeInput').val()]);
$('#rangeInput').on('input change', function ()
{
$('#rangeText').text(rangeValues[$(this).val()]);
});
});
See example in jsfiddle
My problem now is the following:
I putted the function Skilllevel() into a $.each(result, function and into it, it doesn't work, because every entry from my second JSON file var urlBewerbungID = "json.php"; generated one separate list element in $("#ergebnisSkill").append(
The second JSON looks very simple, like this:
[
"item1",
"item2",
"item3"
]
My complete function:
//Skills selektieren
var rangeValues = {
"0": "Keine",
"33": "Anfänger",
"66": "Fortgeschritten",
"99": "Profi"
};
//Abfrage, welche Stelle gewählt wurde
$('#bewerbungID').on('change', function() {
var bewerbungID = ($('#bewerbungID').val());
console.log("BewerbungsID gewählt: " + bewerbungID);
//Zuerst das #HTML Element leeren
$("#ergebnisSkill").empty();
$(document).ready(function() {
var urlBewerbungID = "json.php";
$.getJSON(urlBewerbungID, function(result) {
console.log(result);
$.each(result, function(i, field) {
var skill = field;
//Skill liste erstellen
$(function Skilllevel() {
$('#rangeText').text(rangeValues[$('#rangeInput').val()]);
$('#rangeInput').on('input change', function() {
$('#rangeText').text(rangeValues[$(this).val()]);
});
});
//Jetzt HTML Element neu befüllen
$("#ergebnisSkill").append(
'<li>' +
'<div class="item-content">' +
'<div class="item-media"><i class="icon f7-icons">star</i></div>' +
'<div class="item-inner">' +
'<div class="item-title label">' + skill + '<br> <span id="rangeText"></span></div>' +
'<div class="item-input">' +
'<div class="range-slider">' +
'<input type="range" id="rangeInput" min="0" max="99" value="0" step="33">' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</li>'
);
});
});
});
});
Your code is inside out.
You need document.ready to wrap the event handlers.
Use class instead of IDs, IDs need to be unique
use delegation - currently you have a function per result which does not work.
You need the skills functionality assigned to each result but delegated - see how a click on the ergebnisSkill will be captured by the rangeInput:
//Skills selektieren
var rangeValues = {
"0": "Keine",
"33": "Anfänger",
"66": "Fortgeschritten",
"99": "Profi"
};
$(document).ready(function() {
//Skill liste erstellen
$("#ergebnisSkill").on('input change', ".rangeInput", function() { // delegation
$(this).closest("item-inner") // a parent div
.find('.rangeText') // the input field
.text(rangeValues[$(this).val()]);
});
//Abfrage, welche Stelle gewählt wurde
$('#bewerbungID').on('change', function() {
var bewerbungID = ($('#bewerbungID').val());
console.log("BewerbungsID gewählt: " + bewerbungID);
//Zuerst das #HTML Element leeren
$("#ergebnisSkill").empty();
var urlBewerbungID = "json.php";
$.getJSON(urlBewerbungID, function(result) {
console.log(result);
$.each(result, function(i, field) {
var skill = field;
//Jetzt HTML Element neu befüllen
$("#ergebnisSkill").append(
'<li>' +
'<div class="item-content">' +
' <div class="item-media"><i class="icon f7-icons">star</i></div>' +
' <div class="item-inner">' +
' <div class="item-title label">' + skill + '<br> <span class="rangeText"></span></div>' +
' <div class="item-input">' +
' <div class="range-slider">' +
' <input type="range" class="rangeInput" min="0" max="99" value="0" step="33">' +
' </div>' +
' </div>' +
' </div>' +
'</div>' +
'</li>'
);
});
});
});
});

How to render a List Element using VueJs from a json data

I have a javascript code which renders <ol><li></li></ol> , Using a json from the server . The code looks something like this
function loadWorkFlowRules() {
var wf_id = <?php echo $wf->id; ?>;
$.post("/api/wfengine/get_wf_rules/", {
wf_id: wf_id
}, function(result) {
var wf_rules = JSON.parse(result).data;
if (makeView(wf_rules)) {
toastr.success('The Rules are Successfully Loaded!');
} else
toastr.info('Welcome to Work Flow Editor');
});
}
function makeView(wf_rules) {
//console.log(wf_rules);
var html_str = '',
response = false;
$.each(wf_rules, function(key, value) {
if (value.length > 0) {
$.each(value, function(key1, value1) {
var ui_l1 = '<li class="alert mar" data-id="' + value1.id + '" data-name="' + value1.name + '" style=""><div class="dd-handle state-main">' + value1.name + '<span class="cust-close" data-dismiss="alert" aria-label="Close"><i class="fa fa-times"></i></span></div><ol>';
html_str = html_str + ui_l1;
if (value1.children.length > 0) {
$.each(value1.children, function(key2, value2) {
$.each(value2, function(key3, value3) {
var ui_l2 = '<li class="alert mar" data-id="' + value3.id + '" data-name="' + value3.name + '" style=""><div class="dd-handle state-main">' + value1.name + '<span class="cust-close" data-dismiss="alert" aria-label="Close"><i class="fa fa-times"></i></span></div><ol>';
html_str = html_str + ui_l2;
if (value3.children.length > 0) {
$.each(value3.children, function(key4, value4) {
if (value4.length > 0) {
var ui_l3 = '<li class="dd-item alert mar action" data-id="' + value4[0].id + '" data-name="' + value4[0].name + '" data-api="' + value4[0].api + '" data-url="' + value4[0].url + '" data-json="' + value4[0].json + '" style=""><div class="dd-handle">' + value4[0].name + '<span class="cust-close" data-dismiss="alert" aria-label="Close"><i class="fa fa-times"></i></span> <span class="edit cust-close" data-toggle="modal" data-target="#editAction" ><i class="fa fa-pencil"></i></span></div></li>';
html_str = html_str + ui_l3;
}
})
}
html_str = html_str + '</ol></li>';
});
})
}
html_str = html_str + '</ol></li>';
});
$('.contract_main').html(html_str);
response = true;
} else
response = false;
});
return response;
}
HTML
<div class="dd">
<ol class="dd-list simple_with_drop vertical contract_main">
</ol>
</div>
I got into a situation where Ill have to Bind the data element of the child <li> with an HTML MODAL popup , So that if the value in Modal is updated it shoud change in the Object/Dom also .
I was recommended to use VueJs.
I have went through! the basics of the VueJs , But that didn't cover how I ccan bind complete list from a Json ,
Any help in how I can do this would be great
Currently I don't see any structure of Vue.Js in your code and you are manipulating the JSON data and constructing the HTML in the JS code itself. You can do it in vue way, where you will create an Vue instance, do loading of data in Vue methods and use Vue syntax to iterate over data and other things. One Simple example you can see in this fiddle or in below code:
new Vue({
el: '#app',
data: {
jsonData: []
},
mounted () {
this.loadJsonData();
},
methods: {
loadJsonData(){
setTimeout(()=>{
this.jsonData = ["first", "Second", "Third", "And So On"]
}, 300)
}
}
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<ul>
<li v-for="data in jsonData">{{data}}</li>
</ul>
</div>
You can look at vue-hackernews to understand more about structuring of code, How to fetch data from remote APIs in JSON format and display it.

How to make a function in a controller access an argument that's inside a directive?

My directive:
'<tr ng-repeat="item in listGroup">' +
'<th scope="row">{{$index + 1}}</th>' +
'<td>{{item.name}}</td>' +
'<td ng-if="!listAll">{{item.users.length}}</td>' +
'<td ng-if="!listAll">_</td>' +
'<td>{{item.createdAt}}</td>' +
'<td><button type="submit" class="btn btn-default" ng-click="remove(item)">remove</button></td>' +
scope: {
listName: "#",
listGroup: "=",
listAll: "=",
submit: "&",
remove: "&"
HTML:
<table-list
list-name="users"
list-group="usersGroup"
list-all="usersAll"
submit="submit()"
remove="remove()">
</table-list
Controller:
$scope.remove = function(username) {
console.log(username);
/*
AV.Cloud.run('updateUserGroup', {
groupName: $scope.group.name,
users: _.pluck(selectedUsers, 'name'),
op: "add"
}, {
*/
I'm not very sure what to add in remove="remove()"> in the HTML it's supposed to receive an argument, but the argument is inside the directive.
How can I make remove() get the argument item.name?
Can pass the function name as reference to isolated scope using =
JS
scope: {
listName: "#",
listGroup: "=",
listAll: "=",
submit: "&",
remove: "="
HTML
<table-list
list-name="users"
list-group="usersGroup"
list-all="usersAll"
submit="submit()"
remove="remove"><!-- Note "()" deleted -->
</table-list>
Now you can pass arguments to the referenced function inside directive or in html
In Directive:
use: ng-click="remove({itemToRemove:item})"
In HTML:
<table-list
list-name="users"
list-group="mainAppCtrlAs.usersGroup"
list-all="usersAll"
submit="submit()"
remove="mainAppCtrlAs.remove(itemToRemove)">
In Controller:
self.remove = function(itemToRemoveIs)
{
alert("Remove This\nId: = " + itemToRemoveIs.id + "\nName = " + itemToRemoveIs.name);
}
Full Code:
<!doctype html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"> </script>
<script>
var appModule = angular.module('mainApp', []);
</script>
<html ng-app="mainApp">
<head>
<script src="mainAppCtrl.js"></script>
</head>
<body>
<h2>Todo</h2>
<div ng-controller="mainAppCtrl as mainAppCtrlAs">
<table-list
list-name="users"
list-group="mainAppCtrlAs.usersGroup"
list-all="usersAll"
submit="submit()"
remove="mainAppCtrlAs.remove(itemToRemove)">
</table-list>
</div>
</body>
</html>
Controller: mainAppCtrl.js
appModule.controller('mainAppCtrl', function() {
self = this;
self.userGrp1 = {};
self.userGrp1.id = '01';
self.userGrp1.name = 'Manager';
self.userGrp1.users = ['Ashish','Ravi'];
self.userGrp2 = {};
self.userGrp2.id = '02';
self.userGrp2.name = 'Developer';
self.userGrp2.users = ['krishan','Geeta','Ritu'];
self.usersGroup = [self.userGrp1,self.userGrp2];
self.remove = function(itemToRemoveIs)
{
alert("Remove This\nId: = " + itemToRemoveIs.id + "\nName = " + itemToRemoveIs.name);
}
});
appModule.directive('tableList', [function() {
return {
template: '<div ng-repeat="item in listGroup">' +
'<th scope="row">{{$index + 1}}</th>' +
'<td>{{item.name}}</td>' +
'<td ng-if="!listAll">{{item.users.length}}</td>' +
'<td ng-if="!listAll">_</td>' +
'<td>{{item.createdAt}}</td>' +
'<td><button type="submit" class="btn btn-default" ng- click="remove({itemToRemove:item})">remove</button></td>' +
'</div><br>',
scope: {
listName : "#",
listGroup: "=",
listAll: "=",
submit: "&",
remove: "&"
} //scope
}; //return
}]);

How to update the resolved array variable in customized directive of angularjs

I made a popup drop dow using AngularUI bootstrap $uibModal service to replace the original select form element.
http://jsfiddle.net/ehcj8wn7/17/
angular.module('myApp', [
'ui.bootstrap'])
.controller('myController', function ($scope) {
$scope.cities = ['Shanghai', 'Beijing'];
$scope.basicInfo = {
city: 'Shanghai'
};
$scope.updateCities1 = function () {
$scope.cities.pop();
$scope.cities.push('New York');
}
$scope.updateCities2 = function () {
$scope.cities = ['Taipei', 'Hong Kong'];
}
})
.directive('popupDropDown', ['$uibModal', function ($uibModal) {
var dropDownTemplate = '<div class="modal-header">' +
' <h3 class="modal-title">Please Select</h3>' +
'</div>' +
'<div class="modal-body">' +
' <button class="btn btn-block" ng-class="{\'btn-primary\': item===selected}" ng-repeat="item in items" ng-click="select(item)" ng-if="!cols">{{item}}</button >' +
' <div class="row no-padding" ng-if="cols===12">' +
' <div class="col-xs-1 text-center no-padding" ng-repeat="item in items">' +
' <button class="btn btn-lg no-padding" ng-class="{\'btn-primary\': item===selected}" ng-click="select(item)" >{{item}}</button >' +
' </div>' +
' </div>' +
' <div class="row no-padding" ng-if="cols===6">' +
' <div class="col-xs-2 text-center no-padding" ng-repeat="item in items">' +
' <button class="btn btn-lg no-padding" ng-class="{\'btn-primary\': item===selected}" ng-click="select(item)" >{{item}}</button >' +
' </div>' +
' </div>' +
' <div class="row no-padding" ng-if="cols===4">' +
' <div class="col-xs-3 text-center no-padding" ng-repeat="item in items">' +
' <button class="btn btn-lg no-padding" ng-class="{\'btn-primary\': item===selected}" ng-click="select(item)" >{{item}}</button >' +
' </div>' +
' </div>' +
' <div class="row no-padding" ng-if="cols===3">' +
' <div class="col-xs-4 text-center no-padding" ng-repeat="item in items">' +
' <button class="btn btn-lg no-padding" ng-class="{\'btn-primary\': item===selected}" ng-click="select(item)" >{{item}}</button >' +
' </div>' +
' </div>' +
' <div class="row no-padding" ng-if="cols===2">' +
' <div class="col-xs-6 text-center no-padding" ng-repeat="item in items">' +
' <button class="btn btn-lg no-padding" ng-class="{\'btn-primary\': item===selected}" ng-click="select(item)" >{{item}}</button >' +
' </div>' +
' </div>' +
'</div>' +
'<div class="modal-footer">' +
' <button class="btn btn-warning" type="button" ng-click="cancel();">Cancel</button>' +
'</div>';
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, controller) {
var popupDropDownAttribute = scope.$eval(attrs.popupDropDown);
var showPopupDropDown = function (evt) {
var dropDown = $uibModal.open({
animation: true,
template: dropDownTemplate,
resolve: {
items: function () {
return popupDropDownAttribute.items;
},
cols: function () {
return popupDropDownAttribute.cols;
},
selected: function () {
return element.val();
}
},
controller: function ($scope, $modalInstance, items, cols, selected) {
$scope.items = items;
$scope.cols = cols;
$scope.selected = selected;
$scope.select = function (v) {
$modalInstance.close(v);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
});
dropDown.result.then(function (v) {
controller.$setDirty();
controller.$setViewValue(v);
controller.$render();
});
};
element.attr('readonly', '');
element.addClass('dropdown');
element.on('click', showPopupDropDown);
}
};
}]);
This works fine for static items, and the items can be updated by poping or pushing (in function updateCities1), but when I change the content of items by direct assignment (in function updateCities2), the items in the popup drop down doesn't update.
Is there any way to watch the items in AngularJs directive so that the second way would work? Or when I want to change the items, do I have to use the first way to update them?
Is there any shortcut to clear and push multiple items into the original array?
Finally I figured it out.
There was a bug in the directive.
The popupDropDownAttrabute shoud be fetched when showing the modal, thus, the link should be:
link: function (scope, element, attrs, controller) {
var showPopupDropDown = function (evt) {
var popupDropDownAttribute = scope.$eval(attrs.popupDropDown);
var dropDown = $uibModal.open({
animation: true,
template: dropDownTemplate,
resolve: {
items: function () {
return popupDropDownAttribute.items;
},
cols: function () {
return popupDropDownAttribute.cols;
},
selected: function () {
return element.val();
}
},
controller: function ($scope, $modalInstance, items, cols, selected) {
$scope.items = items;
$scope.cols = cols;
$scope.selected = selected;
$scope.select = function (v) {
$modalInstance.close(v);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
});
dropDown.result.then(function (v) {
controller.$setDirty();
controller.$setViewValue(v);
controller.$render();
});
};
element.attr('readonly', '');
element.addClass('dropdown');
element.on('click', showPopupDropDown);
}

Directive is not acting the way i want to - AngularJS

I've created two custom directives, one parent and one child directive that communicate with each other through parent directive controller.
Parent Directive
app.directive('attrsCtrl', function ($compile) {
return {
restrict: 'E',
scope: {
attributes: '=array',
options: '='
},
controller: function ($scope, $element) {
$scope.attributes = [];
this.returnOptions = function(){
return $scope.options;
}
this.saySomething = function (obj) {
$scope.attributes.push(obj);
alert(obj.name + "/" + obj.type.name);
var newDirective = angular.element('<attributes> </attributes>');
$element.append(newDirective);
$compile(newDirective)($scope);
}
}
}})
Child Directive
app.directive('attributes', function ($compile) {
return {
restrict: 'E',
require: '^attrsCtrl',
template: '<div ng-class="classInput">' +
' <div class="col-md-6" style="padding-left: 0;">' +
' <label>Nome do Atributo</label>' +
' <input type="text" class="form-control input-sm" placeholder="Nome do Atributo" ng-model="attrname" ng-change="validation()" ng-disabled="afterSend">' +
' </div>' +
' <div class="col-md-4 " style="padding-left: 0;"> ' +
' <label>Tipo do Atributo</label> ' +
' <select class="form-control input-sm" ng-options="option.name for option in options" ng-model="attrtype" ng-disabled="afterSend"></select>' +
' </div> ' +
' <div class="col-md-2" style="padding-right: 0;"> ' +
' <label> </label>' +
' <button type="button" class=" btn btn-default pull-right" ng-click="changeButton()" style="margin-top: 1em;" ng-disabled="disabled"> Adicionar </button>' +
' </div> ' +
'</div>' +
'<div class="clearfix></div>',
link: function (scope, element, attrs, attrsCtrl) {
scope.classInput = 'form-group';
scope.disabled = true;
scope.afterSend = false;
scope.options = attrsCtrl.returnOptions();
scope.changeButton = function () {
scope.attr = {
name: scope.attrname,
type: scope.attrtype
};
attrsCtrl.saySomething(scope.attr);
scope.disabled = true;
scope.afterSend = true;
}
scope.validation = function () {
if (scope.attrname.length < 6) {
scope.classInput = 'form-group has-error';
} else {
scope.classInput = 'form-group has-success';
scope.disabled = false;
}
}
}
};})
HTML
<attrs-ctrl array="myAttributes" options="options" >
<attributes/>
</attrs-ctrl>
My issue is that after i click twice to create a directive, it automatically creates another directive but i can't type anything in it! This behavior was supposed to happen only after i click on "Adicionar" button.
There are two problems here
In above example, link function contains scope.disabled = true;, it should be changed to scope.disabled = false; I guess it is your typo while pasting the example here.
Secondly, I guess you have added the parent directive dependency explicitly as you want to create independent child directive. As per your code, the scope between parent and child directive is getting shared. So, scope of parent directive is being shared across all child directives and all fields are appearing disabled.
Add scope:{}, to your directive function as given below...
This will create separate child directive scope.
There is a nice article explaining scopes in details: https://github.com/angular/angular.js/wiki/Understanding-Scopes
app.directive('attributes', function ($compile) {
return {
restrict: 'E',
require: '^attrsCtrl',
scope: {},
template: '<div ng-class="classInput">' +
' <div class="col-md-6" style="padding-left: 0;">' +
' <label>Nome do Atributo</label>' +
' <input type="text" class="form-control input-sm" placeholder="Nome do Atributo" ng-model="attrname" ng-change="validation()" ng-disabled="afterSend">' +
' </div>' +
' <div class="col-md-4 " style="padding-left: 0;"> ' +
' <label>Tipo do Atributo</label> ' +
' <select class="form-control input-sm" ng-options="option.name for option in options" ng-model="attrtype" ng-disabled="afterSend"></select>' +
' </div> ' +
' <div class="col-md-2" style="padding-right: 0;"> ' +
' <label> </label>' +
' <button type="button" class=" btn btn-default pull-right" ng-click="changeButton()" style="margin-top: 1em;" ng-disabled="disabled"> Adicionar </button>' +
' </div> ' +
'</div>' +
'<div class="clearfix></div>',
link: function (scope, element, attrs, attrsCtrl) {
scope.classInput = 'form-group';
scope.disabled = false;
scope.afterSend = false;
scope.options = attrsCtrl.returnOptions();
scope.changeButton = function () {
scope.attr = {
name: scope.attrname,
type: scope.attrtype
};
attrsCtrl.saySomething(scope.attr);
scope.disabled = true;
scope.afterSend = true;
}
scope.validation = function () {
console.log("validate");
if (scope.attrname.length < 6) {
scope.classInput = 'form-group has-error';
} else {
scope.classInput = 'form-group has-success';
scope.disabled = false;
}
}
}
};})

Categories

Resources