In angular js How to do an edit option? - javascript

I am trying to do an edit field in angular js but I don't know how to do that one help me
below is my Crud operation code
var app = angular.module('myApp', [])
app.controller('myCtrl', ['$scope', function($scope) {
$scope.products = ["venu", "balaji", "suresh"];
$scope.addItem = function() {
$scope.errortext = "";
if (!$scope.addMe) {
return;
}
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe)
} else {
$scope.errortext = "The item is already in your names list.";
}
}
$scope.removeItem = function(x) {
$scope.errortext = "";
$scope.products.splice(x, 1);
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="x in products">{{x}}<span ng-click="removeItem($index)">×</span>
</li>
</ul>
<input ng-model="addMe">
<button ng-click="addItem()">ADD</button>
<p>{{errortext}}</p>
<p>Try to add the same name twice, and you will get an error message.</p>
</div>
</div>
I am doing crud operations in angular js. i have done Delete and Add but I dont know how to do Edit operation in angular js

var app = angular.module('myApp', [])
app.controller('myCtrl', ['$scope', function($scope) {
$scope.products = ["venu", "balaji", "suresh"];
$scope.addItem = function() {
$scope.errortext = "";
if (!$scope.addMe) {
return;
}
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe)
} else {
$scope.errortext = "The item is already in your names list.";
}
$scope.addMe = "";
}
$scope.removeItem = function(x) {
$scope.errortext = "";
$scope.products.splice(x, 1);
}
$scope.edit = function(index){
$scope.addMe = $scope.products[index];
$scope.products.splice(index, 1);
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="x in products">{{x}}
<span ng-click="removeItem($index)">×</span>
<span style="color:blue;cursor:pointer;" ng-click="edit($index)">Edit</span>
</li>
</ul>
<input ng-model="addMe">
<button ng-click="addItem()">ADD</button>
<p>{{errortext}}</p>
<p>Try to add the same name twice, and you will get an error message.</p>
</div>
</div>
Try this.

The solution is here:
HTML
<li ng-repeat="x in products" ng-click="preEdit(x, $index)">{{x}}<span ng-click="removeItem($index)">×</span></li>
<input ng-model="addMe">
<button ng-if="isAdd" ng-click="addItem()">ADD</button>
<button ng-if="!isAdd" ng-click="editItem()">EDIT</button>
JS
$scope.isAdd = true;
$scope.preEdit = preEdit;
var index = '';
function preEdit(x, i){
$scope.addMe = x;
index = i;
$scope.isAdd = false;
}
$scope.editItem = editItem ;
function editItem (){
$scope.products[index] = $scope.addMe;
$scope.isAdd = true;
$scope.addMe = '';
index = '';
}
Look my solution in filddle: https://jsfiddle.net/tfx8njw6/

At first you need to add a edit option on the <li> say,
<ul>
<li ng-repeat="x in products">{{x}}
<span ng-click="removeItem($index)">×</span>
<span ng-click="editItem($index)">Edit</span>
</li>
</ul>
Then add a controller function for edit editItem() like
$scope.editItem= function(index) {
$scope.addMe = $scope.products[index];
//this variable will allow you to check whether the operation is an edit or add
$scope.editIndex = index;
}
You can then reuse your addItem() function like this
$scope.addItem = function() {
$scope.errortext = "";
if (!$scope.addMe) {
return;
}
if(angular.isDefined($scope.editIndex)){
$scope.products[$scope.editIndex] = $scope.addMe;
//reset the variable to undefined after using it
$scope.editIndex = undefined;
}else{
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe);
} else {
$scope.errortext = "The item is already in your names list.";
}
}
}

If you want to take it to the "next level", check out xeditable. :)
https://vitalets.github.io/angular-xeditable/#text-simple
Good luck!

For Edit what you can do:
0.Pass the id on edit click and get data of that id and assign to the same variable you have used for add and hide add button and show update button.
1.Either use the same text field which you are using for add and show/hide button add/update accordingly.
2.You can use separately div which includes one text box and button to update.Show/hide as per you action.

Related

Angular List color change based ng-click

I am using angularjs I have two list when I click first one I will push the value into another scope and bind the value to second list. Now my requirement is when first list values which are moved to second list, I need to change the color of moved values in list1
Here I attached my fiddle
Fiddle
You can use findIndex and ng-class together to check if the second list contains the same item as first. If present apply css class to the first list item.
JS:
$scope.checkColor = function(text) {
var index = $scope.linesTwos.findIndex(x => x.text === text);
if (index > -1) return true;
else return false;
}
HTML:
<li ng-click="Team($index,line.text)" ng-class="{'change-color':checkColor(line.text)}">{{line.text}}</li>
Working Demo: https://jsfiddle.net/7MhLd/2659/
You can do something like this:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.lines = [{
text: 'res1'
},
{
text: 'res2'
},
{
text: 'res3'
}
];
$scope.linesTwos = [];
$scope.Team = function(index, text) {
var obj = {};
obj.text = text;
$scope.linesTwos.push(obj)
}
$scope.Team2 = function(index, text2) {
$scope.linesTwos.splice(index, 1)
}
$scope.containsObj = function(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (angular.equals(list[i], obj)) {
return true;
}
}
return false;
};
}
.clicked {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul ng-repeat="line in lines">
<li ng-class="{'clicked': containsObj(line,linesTwos)}" ng-click="Team($index,line.text)">{{line.text}}</li>
</ul>
<ul>
<li>__________</li>
</ul>
<ul ng-repeat="line in linesTwos">
<li ng-click="Team2($index,line.text)">{{line.text}}</li>
</ul>
</div>
you have to achieve it using ng-class and create a dynamic class style for pushed data please check my working example fiddle
JS fiddle sample
in HTML nedd to do these changes
<li ng-click="Team($index,line.text,line)" ng-class="{'pushed':line.pushed}">
<li ng-click="Team2($index,line.text,line)">
In css
.pushed{color:red;}
In Controller
`$scope.Team=function(index,text,line){
var obj={};
obj = line;
$scope.linesTwos.push(obj)
line.pushed = true;
}`
`scope.Team2 = function(index,text2,line){
$scope.linesTwos.splice(index,1)
line.pushed = false;
}
`
its because angular two way binding

Angularjs How to Toggle div's in ng-repeat?

I am working in angularjs and I need to toggle div in ng-repeat but its not working fine. jQuery click is also not working on this. On click of pregroupMem() anchor tag I am calling this function. and data id coming from this function and I am using this as membersList in listdiv div. I need to toggle this div on click of "custom-cn" anchor tag.There are multiple lists and in each of these lists there are there multiple listdivs . I need to toggle the particular div on the click of anchor tag of list.
This is my js to get all groups of members.
localStorageService.set('grpOpen', grps.openGroups);
localStorageService.bind($scope, 'grpOpen');
grs.init = init;
function init()
{
getMyData();
}
$scope.data = null;
DataService.getMyData().then(function successCallback(response)
{
$scope.data = response.data.results;
$scope.grpOpen.length = 0;
$scope.grpOpen.push({'data': response.data.results});
},function errorCallback(response) {
});
This is js to get all members list of a group.I have updated this according to your
$scope.open = -1;
$scope.pregroupMem = function(index,id,e){
$rootScope.membersList = '';
// $rootScope.membersList.length = 0;
$scope.loading= true;
DataService.getGrpMem(id).success(function (data) {
$rootScope.membersList = data.results;
$scope.data[index].shown = !$scope.data[index].shown;
if( $scope.open >= 0 && $scope.data[$scope.open] ){
$scope.data[$scope.open].shown = !$scope.data[$scope.open].shown;
}
if( $scope.open !== index ){
$scope.data[index].shown = !$scope.data[index].shown;
}
$scope.open = index;
}).catch(function (err) {
// Log error somehow.
})
.finally(function () {
// Hide loading spinner whether our call succeeded or failed.
$scope.loading = false;
});
}
<ul>
<li ng-repeat="groupsw in grpOpen[0].data track by $index">
<a ng-click="pregroupMem($index,groupsw.grpId,$event)" class="custom-cn" href="javascript:;">{{ groupsw.grpName }}</a>
<div class="listdiv">
<ul class="userlist">
<li ng-repeat="mymembers in membersList">
<a class="add_user" href="javascript:;"><i class="fa fa-user-plus"></i></a>
<div class="userlist">
<span class="usnermalissval" ng-if="mymembers.Name != null">{{mymembers.Name}}</span>
</div>
</li>
</ul>
</div>
</li>
</ul>
You can do it in following way:
angular
.module('app', [])
.controller('MyController', function($scope) {
$scope.data = [
{grpId: 1, grpName: 'One'},
{grpId: 2, grpName: 'Two'},
{grpId: 3, grpName: 'Three'},
{grpId: 4, grpName: 'Four'},
{grpId: 5, grpName: 'Five'}
]
$scope.open = -1;
$scope.pregroupMem = function(index, id, e) {
e.preventDefault();
if( $scope.open >= 0 && $scope.data[$scope.open] ){
$scope.data[$scope.open].shown = !$scope.data[$scope.open].shown;
}
if( $scope.open !== index ){
$scope.data[index].shown = !$scope.data[index].shown;
}
$scope.open = index;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<ul ng-controller="MyController">
<li ng-repeat="groupsw in data">
<a ng-click="pregroupMem($index, groupsw.grpId, $event)" class="custom-cn" href="javascript:;">{{ groupsw.grpName }}</a>
<div class="listdiv" ng-show="groupsw.shown">
<ul class="userlist">
This is a child div of grpId: {{groupsw.grpId}}
</ul>
</div>
</li>
</ul>
</div>

Synching arrays in AngularJS

I am looking for a way to synchronize arrays within an AngularJS controller.
Example:
var input = [1];
var synchArray = DatabindToModifiedInput()
// synchArray is something like this:
// [{name:someObject}, {name:inputElement, Id:1}]
input.push(2);
// synchArray should be updated automatically:
// [{name:someObject}, {name:inputElement, Id:1}, {name:inputElement, Id:2}]
Obviously i could register $watches and modify synchArray when input changes but that doesn't feel very angular-like.
Question:
I am tempted to write a filter which i can apply to the input-array. However this still feels like i am missing some obvious way to bind the data together within a controller/service.
Is there some way to utilize ngRepeat or some databinding-mechanism for this? Or should i maybe approach this in a completely different way?
You should likely make an extended array object as demonstrated in this post by Jacob Relkin.
That way you could do more than just one array or event when something happens.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.myClonedArray = [];
$scope.myExtendedArray;
// Extended array type
function EventedArray(handler) {
this.stack = [];
this.mutationHandler = handler || function() {};
this.setHandler = function(f) {
this.mutationHandler = f;
};
this.callHandler = function(event, obj) {
if (typeof this.mutationHandler === 'function') {
this.mutationHandler(event, obj);
}
};
this.push = function(obj) {
this.stack.push(obj);
this.callHandler('push', obj);
};
this.pop = function() {
var obj = this.stack.pop();
this.callHandler('pop', obj);
return obj;
};
this.getArray = function() {
return this.stack;
}
}
var handler = function(event, item) {
console.log(event, item);
if (event === 'push') {
$scope.myClonedArray.push(item);
} else if (event === 'pop') {
$scope.myClonedArray.pop();
}
};
$scope.myExtendedArray = new EventedArray(handler);
//or
// $scope.myExtendedArray = new EventedArray();
// $scope.myExtendedArray.setHandler(handler);
$scope.addItem = function() {
$scope.myExtendedArray.push($scope.inputValue);
};
$scope.popItem = function() {
$scope.myExtendedArray.pop();
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp">
<body ng-controller="MyCtrl">
<input type="text" ng-model="inputValue" />
<button ng-click="addItem()">Add</button>
<button ng-click="popItem()">Pop</button>
<p>Custom Array</p>
<ul>
<li ng-repeat="item in myExtendedArray.stack track by $index">
{{item}}
</li>
</ul>
<p>Cloned Array</p>
<ul>
<li ng-repeat="item in myClonedArray track by $index">
{{item}}
</li>
</ul>
</body>
</html>

Calling one controller from another in Angular.js

I'm having trouble understanding some of the basics. Here are 2 controllers I have:
<form ng-controller="NewList" id="form" ng-submit="submit()">
<input name="title" ng-model="formData.title" placeholder="{{placeholders.title}}" />
<button type="submit">Generate</button>
<p ng-show="loading == 1">Loading...</p>
<p ng-show="loading == 2">Response: {{response}}</p>
</form>
<div id="lists" ng-controller="GetLists">
<ul>
<li ng-show="loading">Loading...</li>
<li class="list" ng-repeat="list in lists">
<b>{{list.id}}</b> : {{list.title}}
</li>
</ul>
</div>
JS:
function NewList($scope, $http) {
$scope.formData = { };
$scope.placeholders = { "title" : "List title" };
$scope.loading = 0;
$scope.submit = function() {
$scope.loading = 1;
$http.post(window.apiBase + 'lists/create', this.formData)
.success(function(response) {
$scope.response = response;
$scope.loading = 2;
});
}
}
function GetLists($scope, $http) {
$scope.loading = true;
$http.get(window.apiBase + 'lists/all').success(function(response) {
$scope.lists = response.lists;
$scope.loading = false
});
}
What I'm trying to achieve, is upon form submit, refresh the lists. Meaning, when .success() hits in NewList, call GetList and make it happen again. How do I achieve this?

AngularJS: Hitting a strange issue with $scope variables

In the following code, whenever you delete an item from the delete link in the list, it will only delete the item from the list, but it will not delete the currently selected item. (The item displaying once you click on it). However, if you click on the delete link next to the currently selected item, it will delete from both places.
To replicate what I'm seeing:
Add a bunch of items by typing in the text box and hitting enter a few times.
Select one of the items from the list.
Click delete next to the item when it displays below.
This is the correct behavior.
Select another item you created earlier.
Now click the delete link next to the item in the list.
The item is removed from the list, but not the currently displayed item.
When I step into the code $scope.currentUser is undefined when I click on the delete link in the list.
Why is this happening?
<html ng-app="myApp">
<head>
<script src="http://code.angularjs.org/1.0.1/angular-1.0.1.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.config(function($routeProvider) {
$routeProvider.when('/User/:id', {
controller: UserCtrl,
template: '<h1>{{currentUser.name}}</h1> <a ng-click="deleteUser(currentUser.id)">delete me</a>'
});
});
app.factory('userSvc', function(){
return new UserService();
});
function UserCtrl($scope, $routeParams, $location, userSvc) {
var currUser = userSvc.getUser($routeParams.id);
$scope.currentUser = currUser;
$scope.users = userSvc.getAllUsers();
$scope.addUser = function () {
var user = {
id: userSvc.nextId(),
name: $scope.addUserName
};
userSvc.addUser(user);
$scope.addUserName = '';
$location.url('/User/' + user.id);
};
$scope.deleteUser = function(id) {
if($scope.currentUser != null && $scope.currentUser.id == id) {
$scope.currentUser = null;
}
userSvc.delete(id);
};
};
function UserService() {
var users = [{id: 1, name: 'Ben' }];
this.delete = function(id) {
for(var i = 0; i < users.length; i++) {
var user = users[i];
if(user.id == id) {
users.splice(i,1);
}
}
};
this.addUser = function(user) {
users.push(user);
};
this.getAllUsers = function() {
return users;
};
this.getUser = function(id) {
for(var i = 0; i < users.length; i++) {
var user = users[i];
if(user.id == id) {
return user;
}
}
};
this.nextId = function() {
var maxId = 0;
for(var i = 0; i < users.length; i++) {
var user = users[i];
maxId = Math.max(maxId, user.id);
};
return maxId + 1;
};
}
</script>
</head>
<body>
<div ng-controller="UserCtrl">
<form ng-submit="addUser()">
<input ng-model="addUserName" type="text"/>
<input type="submit" value="Add"/>
</form>
<ul>
<li ng-repeat="user in users">{{user.name}} <a ng-click="deleteUser(user.id)">delete</a></li>
</ul>
</div>
<div ng-view></div>
</body>
</html>
It turns out that selecting a user from the list actually also created a brand new scope that was seperate from the one used to bind the list.
Thanks to Gloopy's comment above to check out Batarang, I was able to see this happen. If this happens to help you, please +1 his comment.
According to the documentation on Scopes some directives will actually cause a new scope to be created. I'm assuming that clicking a link that is being handled by the $routeProvider also results in the creation of a whole new scope tree, likely because it's creating another instance of that controllor.

Categories

Resources