Angular JS expressions not evaluating - javascript

I've the following simple Angular JS trail, which contains the basic CRUD operations:
<html>
<head>
<title>CRUD</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
</head>
<body>
<div ng-app>
Simple Expression Evaluator:<br/>
<input ng-model="calculator"/><br/>
{{calculator + "=" + $eval(calculator)}}
</div>
<h3>CRUD - Comments</h3>
<div ng-app="commentapp">
<ul ng-controller="commentController">
<li ng-repeat="user in users">
{{user.name}} wrote "{{user.comment}}"
<br/>Delete
Edit
</li>
<li>
<input id="name" ng-model="current.name" value="{{current.name}}" />
<input id="name" ng-model="current.comment" value="{{current.comment}}" />
</li>
<li>
<button ng-click="save(current)">
Save
</button>
<button ng-click="addNew(current)">
Add New User
</button>
</li>
</ul>
</div>
<script>
var app = angular.module("commentapp", []);
app.controller("commentController", function($scope) {
$scope.users = [{
"name": "Qwe",
"comment": "Great!"
}];
$scope.current = {};
$scope.addNew = function(user) {
$scope.users.push(user);
};
$scope.edit = function(user) {
$scope.current = user;
};
$scope.save = function(user) {
$scope.current = {};
};
$scope.remove = function(user) {
var index = $scope.users.indexOf(user);
$scope.users.splice(index, 1);
};
});
</script>
</body>
</html>
However the output shows:
So, the expression evaluator works perfectly, which means Angular JS is tied up correctly. But the rest of the components don't work at all. Instead of Qwe, I get the expression {{user.name}}. What am I doing wrong here?

Hi I tried your script and seem working when I remove the first ng-app
nov the html part is like this
<h3>CRUD - Comments</h3>
<div ng-app="commentapp">
<ul ng-controller="commentController">
<li ng-repeat="user in users">
{{user.name}} wrote "{{user.comment}}"
<br/>Delete
Edit
</li>
<li>
<input id="name" ng-model="current.name" value="{{current.name}}" />
<input id="name" ng-model="current.comment" value="{{current.comment}}" />
</li>
<li>
<button ng-click="save(current)">
Save
</button>
<button ng-click="addNew(current)">
Add New User
</button>
</li>
</ul>
</div>
look at this fiddle
hope this help

Related

How can i replace multiple chars in string in ng repeat in angularjs?

How can i replace multiple chars in string in ng repeat in angularjs ?
Here Is My Code and its not working.
i want to replace the #,_,. from the string.How can i replace multiple chars in string.Here Is My Code.
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>Type a letter in the input field:</p>
<p><input type="text" ng-model="test"></p>
<ul>
<li type="1" ng-repeat="x in names | filter:test">
{{ x.replace(/#|_/./g,'') }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = [
"Jana#ai.mkv",
'Car.l.mkv',
'Mar##gareth.mkv',
'Hege.mkv',
'Jo_e.mkv',
'G__ustav.mkv',
'Birgit.mkv',
'Mary.mkv',
'Kai.mkv'
];
});
</script>
</body>
You can use a function and apply the logic to replace the # inside the function.
DEMO
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.getText = function(obj){
return obj.replace(/#|_|\./g, '');
};
$scope.names = [
"Jana#ai.mkv",
'Car.l.mkv',
'Mar##gareth.mkv',
'Hege.mkv',
'Jo_e.mkv',
'G__ustav.mkv',
'Birgit.mkv',
'Mary.mkv',
'Kai.mkv'
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>Type a letter in the input field:</p>
<p><input type="text" ng-model="test"></p>
<ul>
<li type="1" ng-repeat="x in names | filter:test">
{{ getText(x) }}
</li>
</ul>
</div>
Correct your regex first. Looks like it should be
/#|_|\./g
Write a method inside the controller and call it inside the mustach template. For instance
angular.module('App', [])
.controller('Ctrl', function() {
var vm = this;
vm.names = [
"Jana#ai.mkv",
'Car.l.mkv',
'Mar##gareth.mkv',
'Hege.mkv',
'Jo_e.mkv',
'G__ustav.mkv',
'Birgit.mkv',
'Mary.mkv',
'Kai.mkv'
];
vm.replace = function(value) {
return value.replace(/#|_|\./g, '');
};
});
<div ng-app="App" ng-controller="Ctrl as vm">
<p>Type a letter in the input field:</p>
<p><input type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in vm.names | filter: test">
{{ vm.replace(x) }}
</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>

AngularJS dynamic search box on same page

I am new in AngularJS but I have basic HTML and JavaScript knowledge.
I have a list of links on page, and a search box. I want to filter list elements dynamically according to the text typed in the box. I have found some example but they use external lists- not a list typed on same html file.
Exactly this: https://code.ciphertrick.com/demo/angularajaxsearch/
As you guess I cannot make filtered elements visible/unvisible like this. How can I filter them (all html codes must be in 1 page so we cannot call another js file, controller or etc.)
<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div class="bar">
<input type="text" class="search" ng-model="searchString" />
</div>
<ul class="data-ctrl">
<li ng-repeat="i in berkay | searchFor:searchString">
</li>
</ul>
<ul name="berkay">
<li>google</li>
<li>bbc</li>
<li>microsoft</li>
</ul>
</body>
</html>
Note: If there is a way with just Javascript or etc. without using angular js, it is welcome as well.
Last Edit: All 3 answers are correct and working fine right now.
Could you try this. I hope it works for you :)
<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $filter) {
$scope.searchString=[{Text:"https://google.com"},{Text:"https://bbc.com"},{Text:"https://microsoft.com"}];
$scope.searchString2=$scope.searchString;
$scope.$watch('search', function(val)
{
$scope.searchString= $filter('filter')($scope.searchString2, val);
});
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="bar">
<input type="text" class="search" ng-model="search" />
</div>
<ul>
<li ng-repeat="item in searchString">
<a href="{{item.Text}}">{{item.Text}}</>
</li>
</ul>
</div>
</body>
</html>
Please check this updated answer. It will redirect when you click on it.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var app = angular.module("app", []);
app.controller("myCtrl", function($scope) {
$scope.berkay = [{
name: "google",
link: 'https://google.com'
}, {
name: "bbc",
link: 'https://bbc.com'
}, {
name: "microsoft",
link: 'https://microsoft.com'
}];
});
</script>
<div ng-app="app" ng-controller="myCtrl">
<div class="bar">
<!--
1. If you want to search everything(both link and name), just use searchString
<input type="text" class="search" ng-model="searchString">
2. If you want to search only name change searchString to searchString.name
<input type="text" class="search" ng-model="searchString.name">
3. If you want to search only link change searchString to searchString.link
<input type="text" class="search" ng-model="searchString.link">
-->
<input type="text" class="search" ng-model="searchString" />
</div>
<ul class="data-ctrl">
<li ng-repeat="i in berkay | filter:searchString">
{{i.name}}
</li>
</ul>
</div>
You can add javascript inside HTML itself
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var app = angular.module("app", []);
app.controller("myCtrl", function($scope) {
$scope.berkay = [{
name: "google",
link: 'https://google.com'
}, {
name: "bbc",
link: 'https://bbc.com'
}, {
name: "microsoft",
link: 'https://microsoft.com'
}];
});
</script>
<div ng-app="app" ng-controller="myCtrl">
<div class="bar">
<!--
1. If you want to search everything(both link and name), just use searchString
<input type="text" class="search" ng-model="searchString">
2. If you want to search only name change searchString to searchString.name
<input type="text" class="search" ng-model="searchString.name">
3. If you want to search only link change searchString to searchString.link
<input type="text" class="search" ng-model="searchString.link">
-->
<input type="text" class="search" ng-model="searchString" />
</div>
<ul class="data-ctrl">
<li ng-repeat="i in berkay | filter:searchString">
{{i.name}}
</li>
</ul>
</div>

Angular: Async push to recursively generated array

A quick explanation: this is a simple app meant to recreate Reddit, so each comment on a post (which I'm calling a "node") contains an array of comments (nodeList), and each comment can have any number of nodes in this list. What I want to do is push an added comment into the current ng-repeat object's "nodeList", so that I can add the comment without refreshing.
This recursive template works, but only when I refresh the page, so it isn't being pushed into the current scope of the ng-repeat. I've done some research about $index, but because it's recursively generated there is no way of knowing how deep down the tree of nested arrays you could be.
What I tried was $scope.x.nodeList = [] and then pushing a new "node" into that, thinking that each instance of "x" is a new $scope within the ng-repeat, but this is not working.
Controller:
redditLite.controller('post', function($routeParams, $scope, $http) {
var postId = $routeParams.id;
var controller = this;
var postComment = {};
var node = {};
$scope.show = true;
$scope.addComment = {};
$scope.post = {};
$scope.x = {};
$scope.x.nodeList = [];
controller.comment = function(parentId) {
postComment.comment = $scope.addComment.body;
postComment.parentId = parentId;
postComment.rootPostId = $scope.post.id;
$http.post('add-comment',postComment, config).then(function(response) {
node = response.data;
$scope.x.nodeList.push(node);
});
}
});
HTML:
<script type="text/ng-template" id="postTree">
<div class="username">
{{x.username}}
</div>
<div class="body">
{{x.body}}
</div>
<div class="metrics">
<ul>
<li>
Likes: {{x.likes}}
<br>
<button class="like-button" ng-click="controller.likeNode(x.nodeId); x.likes = x.likes + 1">Like</button>
</li>
<li>
Comments: {{x.cmmnts}}
<br>
<button class="comment-button" ng-click="show = !show" ng-show="show">Comment!</button>
<div class="comment-field" ng-hide="show">
<input type="text" placeholder="Enter a comment." ng-model="addComment.body">
<br>
<button ng-click="controller.comment(x.nodeId); show = !show">Submit</button>
<br>
<button ng-click="show = !show">Cancel</button>
</div>
</li>
<li>
Date: {{x.submit_date}}
</li>
</ul>
</div>
<div class="nodes">
<ul ng-if="x.nodeList" ng-model="x.nodeList">
<li ng-repeat="x in x.nodeList" ng-include="'postTree'"></li>
</ul>
</div>
</script>
<div class="post">
<div class="username">
{{post.username}}
</div>
<div class="body">
{{post.body}}
</div>
<div class="metrics">
<ul>
<li>
Likes: {{post.likes}}
<br>
<button class="like-button" ng-click="controller.like(post.id); post.likes = post.likes + 1">Like</button>
</li>
<li>
Comments: {{post.cmmnts}}
<br>
<button class="comment-button" ng-click="show = !show" ng-show="show">Comment!</button>
<div class="comment-field" ng-hide="show">
<input type="text" placeholder="Enter a comment." ng-model="addComment.body">
<br>
<button ng-click="controller.comment(post.id); show = !show">Submit</button>
<br>
<button ng-click="show = !show">Cancel</button>
</div>
</li>
<li>
Date: {{post.submit_date}}
</li>
</ul>
</div>
</div>
<ul class="master-list">
<li ng-repeat="x in post.nodeList" ng-include="'postTree'"></li>
</ul>
There is some missing logic that needs to be handled, but for now I'm trying to get this working to push an object into an array no matter how deeply nested that array is within other objects.
Edit: I've included an image of the JSON structure as a referencece, and it can be seen that each node object can contain an array of node objects, so this is the array that I am attempting to push a new node into.
I've done recursive templating like this successfully several times. If I recall, having the ng-repeat and ng-include on the same html tag is problematic. Try wrapping the contents of your script in a div, remove the ng-include attribute from your li elements, and instead add an ng-include element inside of your li elements. Also, you have basically added your template twice, once for the root item, then again to add recursive behavior. You should be able to only have 1 template (the script one) if you wrap your post variable inside of an array in your markup.
<script type="text/ng-template" id="postTree">
<div>
...
<div class="nodes">
<ul ng-if="x.nodeList" ng-model="x.nodeList">
<li ng-repeat="x in x.nodeList">
<ng-include src="'postTree'"></ng-include>
</li>
</ul>
</div>
</div>
</script>
<ul class="master-list">
<li ng-repeat="x in [ post ]">
<ng-include src="'postTree'"></ng-include>
</li>
</ul>
Update:
When comment is clicked, send the parent to the function instead of just the parent id. This way, you can push the child onto it's parent after the $http post completes.
JS:
angular
.module('redditLite', [])
.controller('post', function($scope, $http) {
var controller = this;
$scope.show = true;
$scope.post = {
id: 1,
parentId: null,
username: 'jeff',
body: 'my fantastic comment',
likes: 152,
submit_date: new Date(),
nodeList: []
};
$scope.comment = function(parent) {
var postComment = {
id: 2,
parentId: parent.id,
username: 'jeff',
body: parent.addComment,
likes: 0,
submit_date: new Date(),
nodeList: []
};
console.log('adding comment', postComment, parent)
$http.post('add-comment',postComment, config).then(function(response) {
var node = response.data;
parent.nodeList.push(node);
});
}
});
HTML
<script type="text/ng-template" id="postTree">
<div>
<div class="username">
{{x.username}}
</div>
<div class="body">
{{x.body}}
</div>
<div class="metrics">
<ul>
<li>
Likes: {{x.likes}}
<br>
<button class="like-button" ng-click="controller.likeNode(x.nodeId); x.likes = x.likes + 1">Like</button>
</li>
<li>
Comments: {{x.nodeList.length}}
<br>
<button class="comment-button" ng-click="show = !show" ng-show="show">Comment!</button>
<div class="comment-field" ng-hide="show">
<input type="text" placeholder="Enter a comment." ng-model="x.addComment">
<br>
<button ng-click="comment(x); show = !show">Submit</button>
<br>
<button ng-click="show = !show">Cancel</button>
</div>
</li>
<li>
Date: {{x.submit_date}}
</li>
</ul>
</div>
<div class="nodes">
<ul ng-if="x.nodeList" ng-model="x.nodeList">
<li ng-repeat="x in x.nodeList">
<ng-include src="'postTree'"></ng-include>
</li>
</ul>
</div>
</div>
</script>
<ul class="master-list">
<li ng-init="x = post">
<div ng-include="'postTree'"></div>
</li>
</ul>
Plunker:
https://plnkr.co/edit/X40JoHduKYy12QPuLBCo?p=preview
You might be getting hurt by lexical scope. Basically:
$http.post('add-comment',postComment, config).then(function(response) {
node = response.data;
$scope.x.nodeList.push(node); //this $scope is not actually your $scope
});
Try doing:
var vm = this;
$http.post('add-comment',postComment, config).then(function(response) {
node = response.data;
vm.$scope.x.nodeList.push(node); //should be the right scope.
})
If this doesn't work, try double checking your bindings. A value not updating normally means the binding is not correct.
Try using $scope.x.nodeList.concat([node]); instead of pushing the value, like this avoid mutations in the object.

Opening specific list in angular JS

I'm using the following code to try ng-repeat in angular. I need to show the list which I click. But when I click on the symbol ~, it is showing all the lists.
How can I specify such conditions when using ng-repeat?
HTML
<div ng-app='myapp' ng-controller='cntrl'>
<input ng-model="addy" />
<button ng-click="add()" class="w3-btn w3-padding w3-blue">Add</button>
<span ng-show='span' style='color:red'>The TeXt Is AlReAdY In ThE LiSt</span>
<ul class="w3-ul">
<li ng-repeat="x in names" class="w3-padding-hor-16">
<span ng-click="expand()">~{{x}}
<ul ng-show='show'>
<li ng-repeat="Y in features[$index]">{{Y}}</li>
</ul>
</span>
</li>
</ul>
</div>
Angular JS
<script>
var app = angular.module('myapp',[]);
app.controller('cntrl', function($scope){
$scope.names = ['Fruits', 'Veggies', 'Cars'];
$scope.show= false ;
$scope.features=[['Apple','Mango','Lemon','Grapes'], ['Tomato', 'Carrot', 'Cucumber'], ['Porsche', 'Aston', 'Dodge']];
$scope.expand=function(){
$scope.show = !$scope.show;
}
$scope.add = function(){
$scope.span = false
if($scope.names.indexOf($scope.addy) === -1)
$scope.names.push($scope.addy);
else
$scope.span = true;
}
});
</script>
Pls check it out
var app = angular.module('myapp',[]);
app.controller('cntrl', function($scope){
$scope.names = ['Fruits', 'Veggies', 'Cars'];
$scope.show= false ;
$scope.features=[['Apple','Mango','Lemon','Grapes'], ['Tomato', 'Carrot', 'Cucumber'], ['Porsche', 'Aston', 'Dodge']];
$scope.expand=function(index){
$scope.expanded = ($scope.expanded != index)?index:-1;
}
$scope.add = function(){
$scope.span = false
if($scope.names.indexOf($scope.addy) === -1)
$scope.names.push($scope.addy);
else
$scope.span = true;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myapp' ng-controller='cntrl'>
<input ng-model="addy" />
<button ng-click="add()" class="w3-btn w3-padding w3-blue">Add</button>
<span ng-show='span' style='color:red'>The TeXt Is AlReAdY In ThE LiSt</span>
<ul class="w3-ul">
<li ng-repeat="x in names" class="w3-padding-hor-16">
<span ng-click="expand($index)">~{{x}}
<ul ng-show='expanded == $index'>
<li ng-repeat="Y in features[$index]">{{Y}}</li>
</ul>
</span>
</li>
</ul>
</div>

Unable to fetch data from controller in Angular.js

I'm pretty much new to AngularJS. In fact, this is my first day. What I'm trying to do here is to fetch data from a controller I made and show it in the view. But I don't know why, it's not simply working.
My data is a list of students. All I'm trying to do is to show the list of students in a list order and filter the list according to the name entered in a textbox.
My code is pretty simple:
<!DOCTYPE html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
</head>
<body>
<h1>Hello!</h1>
Student Name:
<br />
<input type="text" ng-model="sname" /> {{ sname }}
<div id="mvvm_communication" class="container" data-ng-controller="simpleController">
<ul>
<li ng-repeat="stud in students | filter:sname | orderBy:'firstname'" >{{stud.firstname | lowercase }}, {{stud.lastname| uppercase }}</li>
</ul>
</div>
<script>
function simpleController($scope)
{
$scope.students=[
{firstname:'Jordan',lastname:'Rains'},
{firstname:'Michael',lastname:'Jordan'},
{firstname:'John',lastname:'Doe'},
{firstname:'John',lastname:'Smith'},
{firstname:'Simcha',lastname:'Michelle'},
{firstname:'Sydney',lastname:'Rivers'},
{firstname:'Summer',lastname:'Rose'},
{firstname:'Georgia',lastname:'Schubert'},
{firstname:'Rosalie',lastname:'Fayadh'}
];
}
</script>
</body>
</html>
Here's a fiddle.
You need to register your controller!
var myApp = angular.module('myApp',[]);
myApp.controller('simpleController', ['$scope', simpleController]);
And then you also need to put a name into ng-app.
<html ng-app="myApp">
I've updated your JSFiddle:
HTML:
<div ng-app="app">
<div ng-controller="simpleController">
<h1>Hello Student!</h1> Student Name:<br/>
<input type="text" ng-model="sname" /> {{ sname }}
<div id="mvvm_communication" class="container">
<ul>
<li ng-repeat="stud in students | filter:sname | orderBy:'firstname'" >{{stud.firstname | lowercase }}, {{stud.lastname| uppercase }}</li>
</ul>
</div>
</div>
</div>
Angular:
var app = angular.module('app', []);
app.controller('simpleController', function($scope) {
$scope.students=[
{firstname:'Jordan',lastname:'Rains'},
{firstname:'Michael',lastname:'Jordan'},
{firstname:'John',lastname:'Doe'},
{firstname:'John',lastname:'Smith'},
{firstname:'Simcha',lastname:'Michelle'},
{firstname:'Sydney',lastname:'Rivers'},
{firstname:'Summer',lastname:'Rose'},
{firstname:'Georgia',lastname:'Schubert'},
{firstname:'Rosalie',lastname:'Fayadh'}
];
});
you need to define an angular module:
angular.module('app', []).controller('simpleController', simpleController);
see jsFiddle

Categories

Resources