Show different buttons matching array values - javascript

So here's my problem, i'm using AngularJS and i'm getting JSON from PHP, and displaying all my data with ng-repeat. I already have done this.
Now I want to check if some data is in "Array1" and if it is, change the correspndent data from the ng-repeat. I know it sounds really weird, but let me put an example with code:
Here's array1 values
{
"23",
"48",
"51"
}
So when i get the data, it's something like this:
{
id : "23",
name: "example"
}
And for every JSON object i'm using ng-repeat to display them all like this:
<div ng-model="data.posts" ng-repeat="post in posts | orderBy:'-' | unique: 'id'">
...
<button>This button will show if "id" matches</button>
<button>This button will show if "id" not matches</button>
</div>
I want to compare if an id of array1 matches an id from the JSON data and if it matches show one button and if not show other.
I'm on this like 2 weeks, and i can't get the problem solved, and i don't see any way to get it.
Thx for reading at least and sorry for my bad english!

Your array1 should be an array and can add a function in controller to check match id.
in controller:
$scope.array1 = ["23","48","51"];
$scope.checkInArray1 = function(id) {
var index = $scope.array1.indexOf(id);
if(index < 0){
return false;
} else {
return true;
}
};
and in your html:
<button ng-if="checkInArray1(post.id)">This button will show if "id" matches</button><br>
<button ng-if="!checkInArray1(post.id)">This button will show if "id" not matches</button>

Making the assumption that {"23","48","51"} should be a array ["23","48","51"]
You could do something like this:
Working Fiddle: http://jsfiddle.net/ravenous52/rgyom4yd/
myApp.controller('MyCtrl', ['$scope',
function($scope) {
$scope.knownIds = ["23", "48", "51"];
$scope.data = {
posts: [{
id: "23",
name: "example23"
}, {
id: "51",
name: "example51"
}, {
id: "99",
name: "example99"
}]
}
}
]);
<section ng-controller="MyCtrl">
<div ng-repeat="post in data.posts">
<button ng-show="knownIds.indexOf(post.id) >-1">This button will show if "id" matches</button>
<button ng-hide="knownIds.indexOf(post.id) >-1">This button will show if "id" not matches</button>
</div>
</section>

https://jsfiddle.net/alair016/4wc44on1/
<div ng-app='myApp' ng-controller="MyCtrl">
<div ng-model="data.posts" ng-repeat="post in data.posts">
<button ng-if="array1.indexOf(post.id) >-1">{{post.name}} id matches</button>
<button ng-if="array1.indexOf(post.id) == -1">{{post.name}} id does not match</button>
</div>
</div>
var myApp = angular.module('myApp',[])
.controller('MyCtrl', ['$scope', function($scope) {
$scope.array1 = ["23","48","51"];
$scope.data = {
posts : [
{
id : "23",
name: "example"
},
{
id: "24",
name:"second example"
}
]
};
}]);

Related

Angular, connect objects and display right information

I'm creating an angular webapp, listing different cars in a sidebar and some information about the specific car in a informationbox.
The purpose is to show the right information in the box when clicking the different cars.
I have two different arrays(two API-endpoints), where the first array lists the car name, and the other one got the information about the car. But I have no idea how to connect the objects with the primary key and the foreign key, and how I'm supposed to output the right information after clicking the car.
app.js:
angular.module('myApp', [])
.controller('MyController', function($scope, $http) {
function fetch() {
$http({method : 'GET',url : 'http://*cars*'})
.success(function(data) {
$scope.cars = data;
});
$http({method : 'GET',url : 'http://*information*'})
.success(function(data) {
$scope.information = data;
});
}
fetch();
})
html:
<div id="sidebar">
<ul>
<li ng-repeat="name in cars">{{ name.displayName }}</li>
</ul>
</div>
For now all I have done is that I've fetched the data and outputed the cars in the sidebar. But now I've been googling and trying to connect the cars to the information with loops and functions for hours, but stil clueless.
Yes, I'm new to this. Any kind of help would be great! Thanks
You can deal with this with the ng-route. You can do something like :
In your route definition:
.when(/cars/:Id), {
name: 'cars',
templateUrl : 'ayourtemplate.html',
controller : 'yourCtrl'
})
In your html:
<div id="sidebar">
<ul>
<li ng-repeat="name in cars">{{ name.displayName }}</li>
</ul>
</div>
The Id will be your key tou will just have to match the right key in your $scope.information
It depends on what information those arrays contains.
If you're sure, that every element corresponds to other, you can just use $index in the html.
<li ng-repeat="name in cars">
{{ name.displayName }}
<p>{{ information[$index] }}</p>
</li>
However, if elements in array aren't ordered, you will have to check primary keys of objects in arrays. Let's assume, that data in arrays looks like this:
cars:
[
{ id: "1", name: "Carrera GT" },
{ id: "2", name: "DB 11" },
... and so on
]
information:
[
{ id: "2", info: "Lorem ipsum" },
{ id: "1", info: "Dolor sit amet" },
...
]
Then I'd suggest using loops and constructing new array using ids.
var carinfo = [];
cars.forEach(car => {
obj["id"] = car.id;
obj["name"] = car.name;
obj["info"] = ""; // Placeholder
info.forEach(c => {
if (c.id === car.id) {
obj["info"] = c.info;
}
});
carinfo.push(obj);
});
$scope.carInfo = carinfo;
Then you can use $scope.carInfo in the html file.
<li ng-repeat="car in carInfo">
{{ car.name }}
<p>{{ car.info }}</p>
</li>

AngularJS access further details by matching ids

This must be simple and Angular probably has an inbuilt directive to do this but I cant think of how to do without looping through the Array.
I have a array of options i.e.
$scope.colors=[
{id:"0",label:"blue"},
{id:"1",label:"red"},
{id:"2",label:"green"}
]
And then my data object that stores the id of a color option i.e.
$scope.data={
color:"1",
otherproperty:""
}
But when I display the data to the user I want to show the label rather than the id, so is there a easy(angular) way to do this?:
{{data.color.label}}
The Angular way would be using ng-repeat & filter, your still essentially looping over the Array but all options would require some sort of loop i.e.
<div ng-repeat="color in colors | filter:{ 'id': data.color}:true">
{{ color.label }}
</div>
Setting the Filter strict comparison to 'true' as above will only select the id with an exact match
https://jsfiddle.net/sjmcpherso/wztunyr5/
The following will return the object where the id matches $scope.data.color:
var pickedColor = $scope.colors.filter(function( obj ) {
return obj.id === $scope.data.color;
});
pickedColor.label will be the label string.
Look at other way, hope it will help you.
https://jsfiddle.net/kkdvvkxk/.
We can also use $filter under controller.
Controller :
var myApp = angular.module('myApp', []);
function MyCtrl($scope, $filter) {
$scope.colors = [{
id: "0",
label: "blue"
}, {
id: "1",
label: "red"
}, {
id: "2",
label: "green"
}]
$scope.data = {
color: "1",
otherproperty: ""
}
$scope.getLabel = function(colorId) {
return $filter('filter')($scope.colors, { id: colorId }[0].label;
}
}
HTML :
{{ getLabel(data.color)}}

Dynamically access an array using ng-repeat

I need to access different arrays based on the users choice and then run through the array with a ng-repeat.
Controller:
$scope.allbooks={
book1:{price:"3.00",type:"non-fiction",chapters:book1chapters},
book2:{price:"4.00",type:"fiction",chapters:book2chapters},
};
$scope.pick = function(selectedBook) {
$rootScope.choice = selectedBook;
}
$scope.book1chapters=[
{title:"it begins"},
{title:"another one"}
];
$scope.book2chapters=[
{title:"hello"},
{title:"calling from the otherside"}
];
HTML:
<button ng-click="pick(allbooks.book1)">Book 1</button>
<button ng-click="pick(allbooks.book2)">Book 2</button>
<div ng-repeat:"m in choice.chapters"><-----this does not work
Chapter: {{m.title}}
</div>
This is a very simplified example just to make it easier to look at :) I don't know how t reference another array from inside an array. Thanks
It seems you did not define book1chapters and book1chapters for collection allbooks, instead you defined them in $scope which is not correct. Also change $rootScope to $scope since rootScope is not injected. The following code is working:
var book1chapters = [{
title: "it begins"
}, {
title: "another one"
}];
var book2chapters = [{
title: "hello"
}, {
title: "calling from the otherside"
}];
$scope.allbooks = {
book1: {
price: "3.00",
type: "non-fiction",
chapters: book1chapters
},
book2: {
price: "4.00",
type: "fiction",
chapters: book2chapters
},
};
$scope.pick = function(selectedBook) {
$scope.choice = selectedBook;
}
The code on plunker: http://plnkr.co/edit/83Ujp4R8BjIe39ROmp6n?p=preview
Short Answer
Basically you have incorrect ng-repeat syntax. It should have = instead of : before writing expression in front of ng-repeat directive like we do for value attribute
Markup
<div ng-repeat="m in choice.chapters"><-----this does not work
Chapter: {{m.title}}
</div>
Suggestions
You should not pollute $rootScope for sharing variables. For that you could create a shareable service which can share a data among-est various components of your app like controllers, directives, service, etc.
HTML
<button ng-click="sharableData.choice = 'book1'">Book 1</button>
<button ng-click="sharableData.choice = 'book2'">Book 2</button>
<div ng-repeat = "m in allbooks[sharableData.choice].chapters">
Chapter: {{m.title}}
</div>
Service
app.service('sharableData', function(){
var sharableData = this;
sharableData.sharedData = {
choice: undefined
};
});
Controller
app.controller('myCtrl', function($scope, sharableData){
//you other controller code
//add this additional line to expose service variable on html
$scope.sharableData = sharableData;
});

updating text on view from ng-repeat

I have problem with updating view by using ng-repeat.
When click on text, it doesnt update but it overwrites below. (I want have panel with names(links) and show its description on view)
I have searched everything and couldnt find answer or something useful what would help me.
html:
<body>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li><a ng-repeat="item in items" ng-click="getInfo(item)" > {{item.name}} <br> </a></li>
</ul>
</div>
<hr>
<div ng-controller="myInfo">
<div ng-repeat="info in item" >
<h3>Name: {{info.name}}</h3>
<p> ID: {{info._id}}</p>
<p> temp: {{info.temp}} </p>
</div>
</div>
</div>
</body>
js
var app = angular.module('myApp', [])
app.controller('myCtrl', function($scope, $http, shareDataService) {
$http.jsonp('data.json').success(function(data) {
$scope.items = data;
});
$scope.getInfo = function(item) {
shareDataService.addItem(item);
}
});
app.controller('myInfo', function( $scope, shareDataService ){
$scope.item = shareDataService.getItem();
});
app.service('shareDataService', function() {
var myItem = [];
var addItem = function(newObj) {
myItem.push(newObj);
}
var getItem = function(){
return myItem;
}
return {
addItem: addItem,
getItem: getItem
};
});
json
angular.callbacks._0([
{
"_id": 1,
"temp": "asdgdf",
"name": "name1"
},
{
"_id": 2,
"temp": "asdasdasd",
"name": "name2"
},
{
"_id": 3,
"temp": "asasdasdadgdf",
"name": "name3"
}
]);
Plunker: http://plnkr.co/edit/X65oH0yAkRnN8npKnFY2?p=preview
You have an error in your console. Just add track by to your ng-repeat:
<div ng-repeat="info in item track by $index">
ng-repeat needs a unique id to track the items in order to be able to update them. If you add the same item twice, ng-repeat sees the same item twice, ans loses its mind. Using $index (which is unique) resolves that issue.
Keep in mind that using $index is adequate here, but it's preferred to use a unique id from the object if you can.
EDIT:
If your issue is that you want to see only the one element you clicked on in your view, then the issue is that you are adding your item to an array, when you should just be setting a value in your service. And, obviously, no need of a ng-repeat in your view.
http://plnkr.co/edit/Wfg9KhCWKMDreTFtirhR?p=preview
JS:
app.controller('myCtrl', function($scope, $http, shareDataService) {
//[...]
$scope.getInfo = function(item) {
shareDataService.setItem(item);
}
});
app.controller('myInfo', function( $scope, shareDataService ){
$scope.$watch(function () {
return shareDataService.getItem();
}, function (value) {
$scope.info = value;
})
});
app.service('shareDataService', function() {
var myItem;
return {
setItem: function(newObj) {
myItem = newObj;
},
getItem: function(){
return myItem;
}
};
});
HTML:
<div ng-controller="myInfo" ng-show="info">
<h3>Name: {{info.name}}</h3>
<p> ID: {{info._id}}</p>
<p> temp: {{info.temp}} </p>
</div>
If you only want to display information of the item that you just have clicked, then we don't need the second ng-repeat (as jlowcs said).
We also don't have to defined myItem as a array, it's just unnecessary, I think.
Edit:
how embarrassing i am, my answer look exactly to same as jlowcs's. I guess I took to much time to figure out the answer.
One thing to add up:
Why do I need a $watch in myInfo controller?
Because at the first time, we use ng-repeat, this component do the watch part for us. Then when I remove ng-repeat, I need to watch for data changing by myself.

angularjs i am using multiple select tag how to clear its all option after saved in db

How to clear multiple select option after saving into DB, i am using ng-model to clear it. Its clearing in back-end but not in UI side.
In controller I am writing:
smsType = {};
smsType.smsTypeId = [];
HTML code:
<div class="form-group">
<select ng-model="smsType.smsTypeId" ui-jq="chosen" multiple
class="w-md"
ng-options="s.id as s.name for s in smsoption.name">
</select>
</div>
Its not reflecting in ui side
Please give me some suggestion i am new to angularjs
Please see demo below
you missed $scope here
smsType.smsTypeId = [];
should be
$scope.smsType.smsTypeId = [];
// Code goes here
angular.module("myApp", []);
angular.module("myApp").controller("SelectCtrl", ["$scope",
function($scope) {
$scope.smsoption = {
name: [{
"id": "122",
"name": "denmark"
}, {
"id": "123",
"name": "france"
}, {
"id": "124",
"name": "italy"
}]
};
$scope.saveit = function() {
console.log($scope.selectCenter);
$scope.smsType.smsTypeId = [];
}
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<h1>ngOption demo</h1>
<div ng-app="myApp">
<div ng-controller="SelectCtrl">
<select ng-model="smsType.smsTypeId" ui-jq="chosen" multiple class="w-md" ng-options="s.id as s.name for s in smsoption.name">
</select>
<hr/>You have chosen:
<span ng-repeat="type in smsType.smsTypeId">{{type}} | </span>
<button ng-click="saveit()">Save</button>
</div>
</div>
The model is the output, not the input. To clear it you need to clear smsoption. The model should reflect the options you have selected, not the other way around.
smsoption = [];
Should do it

Categories