I have 3 columns. The first lists a list of subjects from an array. Within that array, each subject has it's particular courses listed within, and within that, the rest of the course information.
Can I have the ng-repeat "function" operate properly if it is placed using a .innerHTML function?
I could be using the wrong identifiers to try and call content from the array, which could also be causing my problems.
scope:
$scope.subjects = [
{text:'English', courses:[
{coursesub:'English 1', coursedata:[
{coursedesc:'test'}
]
}
]
},
{text:'Mathematics'},
{text:'Science'}
];
$scope.showDetail = function (todo) {
document.getElementById("courselistings").innerHTML = '<a ng-repeat="course in subject.courses" class="list-group-item" target="#courseinformation" ng-click="showDetail(course)">{{courses.coursesub}}</a>';
};
html + angularjs:
<div class="col-md-3" id="subjects">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Subjects</h3>
</div>
<div class="panel-body">
<div class="list-group">
<a ng-repeat="subject in subjects" class="list-group-item" target="#courselistings" ng-click="showDetail(subject)">
{{subject.text}}
</a>
</div>
</div>
</div>
</div>
<div class="col-md-3" id="courselisting">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Courses</h3>
</div>
<div class="panel-body">
<div class="list-group" id="courselistings">
test
</div>
</div>
</div>
</div>
<div class="col-md-6" id="courseinfo">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Course Info</h3>
</div>
<div class="panel-body">
<div class="list-group" id="courseinformation">
</div>
</div>
</div>
</div>
I haven't done the courseinfo panel stuff yet, I just included it so that the columns would align properly.
No, it won't work.
You need to use template or directive.
http://docs.angularjs.org/guide/directive
You simple move innerHTML string to directive template
.directive('myCustomer', function() {
return {
scope: {
subject: '='
},
template: '<string here>'
};
});
And use it like
<my-customer subject="xxx"/>
A directive is a better answer for you. DOM manipulation should be done in directives, not controllers.
That said, it is possible using Angular's $compile which makes Angular aware of new HTML.
Just as a proof of concept- here's that function (and a working fiddle):
$scope.showDetail = function (todo) {
var html= '<div><a ng-repeat="course in subjects['+todo+'].courses" class="list-group-item" target="#courseinformation" ng-click="showDetail(course)">{{course.coursesub}}</a></div>';
var innerHTML =$compile(html)($scope)
var currente = angular.element(document.getElementById("courselistings"));
currente.replaceWith(innerHTML);
}
In order for this to work we also need to pass in the index of the course you want to show -- ng-click="showDetail($index)". This is because the $compile will compile this against the controller scope, not the one inside the ngRepeat.
As you can see it takes jumping through a number of hoops to make this work- which is part of why a directive is better.
Related
I've a HTML structure which looks like this :
<div class="row">
<div class="md-4">1</div>
<div class="md-4">2</div>
<div class="md-4">3</div>
</div>
<div class="row">
<div class="md-4">4</div>
<div class="md-4">5</div>
<div class="md-4">6</div>
</div>
<div class="row">
<div class="md-4">7</div>
<div class="md-4">8</div>
<div class="md-4">9</div>
</div>
and I've JS :
var abc = [1,2,3,4,5,6,7,8,9]
currently as per my structure I can't directly run ng-repeat as after every 3 records I want starts and ends
I want something similar like
<div ng-repeat="val in abc" class="row" ng-if="$index%3==0">
<div>{{val}}</div>
</div>
but above codes don't work and I know its incorrect way but I want something similar to that
please try with this code:
<div ng-repeat="val in abc track by $index" class="row" ng-if="$index%3==0">
<div>{{val}}</div>
</div>
If you've used lodash before
var arr = _.chunk(abc,3);
//makes your array like [[1,2,3],[4,5,6],[7,8,9]]
<div ng-repeat = "a in arr" class = "row">
<div ng-repeat="b in a" class="md-4">{{b}}</div>
</div>
you can lookup lodash here
I am trying to access the parameter which is passed to the JavaScript function and alert the value. but when i alert the value i am getting undefined in alert. what is wrong i have done here.
html
<div ng-app="plusminusApp" ng-controller="categorylist">
<div class="whitescreen" id="buttons-overlay">
<div class="icons-container">
<div class="icons-inside-container">
<div ng-repeat="category in categories" value="{{category.picture}}" class="category-icon-thumbnail" onclick="setCategory(this.value);">
<img value="{{category.category}}" src="{{category.picture}}">
</div>
</div>
</div>
</div>
</div>
app.js
function setCategory(category){
alert(category)
document.getElementById('buttons-overlay').style.display = 'none';
}
If you want to pass a angular's scope value to a function, it must be ng- prefixed event. You can't pass scope variable to a function outside of angular context.
<div ng-repeat="category in categories" value="{{category.picture}}" class="category-icon-thumbnail" ng-click="setCategory(category.picture)">
and the function must be in the scope of the controller that means you need to define $scope.setCategory = function(val){}
HTML:
<div ng-app="plusminusApp" ng-controller="categorylist">
<div class="whitescreen" id="buttons-overlay">
<div class="icons-container">
<div class="icons-inside-container">
<div ng-repeat="category in categories"class="category-icon-thumbnail" >
<img value="{{category.category}}" src="{{category.picture}}" ng-click="setCategory(category.picture);">
</div>
</div>
</div>
</div>
JS:
$scope.setCategory = function(val){
console.log(val)
}
Assuming this to be your json
$scope.categories = [{
'category': 'ABC',
'picture': 'https://randomuser.me/api/portraits/men/22.jpg'
}, {
'category': 'ced',
'picture': 'https://randomuser.me/api/portraits/men/13.jpg'
}]
Use the below code
$scope.setCategory =function(category) {
$scope.something=category;
document.getElementById('buttons-overlay').style.display = 'none';
}
<div ng-app="plusminusApp" ng-controller="categorylist">
<p>Hello!</p>
<div class="whitescreen" id="buttons-overlay">
<div class="icons-container">
<div class="icons-inside-container">
<div ng-repeat="category in categories" value="{{category.picture}}" class="category-icon-thumbnail">
<button ng-click="setCategory(category.category)"> {{category.category}}
</button>
<img value="{{category.category}}" src="{{category.picture}}">
</div>
</div>
</div>
</div>
</div>
For simplicity and understanding purpose I have changed the click event from div to button.
LIVE DEMO
Navbar (main.html):
<nav class="navbar navbar-dark bg-primary">
<button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#collapseEx2">
<i class="fa fa-bars"></i>
</button>
<div class="container" ng-controller="UpComingGamesCtrl">
<div class="collapse navbar-toggleable-xs" id="collapseEx2">
<a class="navbar-brand" href="#/">VideoGame Releases</a>
<form ng-submit="searchGame()">
<input type="text" id="form1" class="form-control" ng-model="gameToSearch">
</form>
</div>
</div>
</nav>
Controller:
...
$scope.games = [];
$scope.searchGame = function () {
if ($scope.gameToSearch) {
console.log('entered with text');
getUpcomingGames.getGame($scope.gameToSearch).get({}, function (data) {
$scope.games = data.results;
});
}
}
upcoming_games_template.html:
<div class="row" ng-repeat="games in games | chunkBy:3">
<div class="col-md-4" ng-repeat="game in games">
<div class="card">
<div class="view overlay hm-white-slight card-image">
<img src="{{game.image.screen_url}}" class="img-fluid" alt="">
<a href="#/">
<div class="mask waves-effect waves-light"></div>
</a>
</div>
<div class="card-block">
<h4 class="card-title">{{game.name}}</h4>
<p class="card-text">{{(game.original_release_date | limitTo: 10) || getFutureReleaseDate(game) }}</p>
Read more
</div>
</div>
</div>
</div>
I am trying to create a search function on my navbar in my main.html file and when the user presses the enter key, I get the info from an external API using that search and update the upcoming_games template. Now, I know I enter the function "searchGame" because it logs to console and I know the data I get back is good. But when i try to change the variable "$scope.games = data.results;", the view does not update.
Now if I create the same search bar form inside the upcoming_games_template.html it works perfectly.
Why does this happen ? I'm declaring the controller in my main.html file, so it should work the same, right ?
I also don't think I need the $scope.$apply() in this situation.
Thank you.
Probably you're using two different controllers, so you're filling the $scope.games variable of a controller while you would fill the $scope.games variable of the other controller. If you provide a jsfiddle it could be simpler. If you want a fast solution you should try to use a $rootScope.games variable and repeat over the same rootscope variable :
<div class="row" ng-repeat="games in $root.games | chunkBy:3">
<!-- Content -->
</div>
This is not the better solution but it should works.
I have a record that is returned from an angular $resource promise like below.
The record is an array and within each array of record there another variable array. I try displaying in my view like below.
div(ng-repeat="category in categories")
h6
img(src="{{category.ImageUrl}}")
|{{category.Name}}
ul(class="list-unstyled")
li(item in category.CategoryItems)
a(href="#") {{item.Item}} (0)
The problem is , category.CategoryItems returned undefined and empty as a result even though its actually an array of objects. Please how do i print those? Each category has category items of an array type. How do i best achieve this pls?
You didn't use ng-repeat the second time. Try this:
div(ng-repeat="category in categories")
h6
img(src="{{category.ImageUrl}}")
|{{category.Name}}
ul(class="list-unstyled")
li(ng-repeat="item in category.CategoryItems") //ng-repeat added
a(href="#") {{item.Item}} (0)
I used nested ng-repeat in my project some time ago. In my project the requirement was to show all blogs like in snapshot:
To achieve this you can use ng-repeat like in below code:
<div class="panel ">
<div class="panel-body">
<div class="col-sm-12 " ng-repeat="blogBlock in blogs" >
<h2 class="hot-topics-heading">{{blogBlock.year}}</h2>
<div class="blog-year>
<div class="col-sm-6" ng-repeat="months in blogBlock.data">
<span class="hot-topics-heading">{{months.monthName}}</span>
<div class="blog-month" >
<ul class="hot-topics-ul" >
<li class="blogTitle" ng-repeat="blog in months.data">
{{blog.title}}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
In the above code ng-repeat inside the ng-repeat and also inside the ng-repeat.
<div ng-repeat="blogBlock in blogs" >
<div ng-repeat="months in blogBlock.data">
<ul>
<li ng-repeat="blog in months.data"></li>
</ul>
</div>
</div>
Hi I am working on requirement where my filter object is keep getting changed and because of that i have to change ng-repeat on div.
html code :
<div class="col-md-6" ng-repeat="model in models | filter:{ModelText : '!All models', ModelId: '!FilteredModelIds'}:true">
<div class="well">
<div class="media">
<div class="media-object small"><i class="pp-car"></i></div>
<div class="media-body">
<div class="text-box">
<h3>{{model.ModelText}}</h3><span class="hr-small"></span>
</div>
<div class="dashboard-control clearfix">
<div class="simple-metric text-left sub-metric">
<div class="metric-title">Satisfaction score</div>
<div class="metric-number text-red">{{model.SatisfactionAvg}}</div>
</div>
<div class="simple-metric text-left sub-metric">
<div class="metric-title">Total interviews</div>
<div class="metric-number">{{model.TotalInterviews}}</div>
</div>
</div>
<ul class="list-standard">
<li> View interviews</li>
</ul>
</div>
</div>
</div>
</div>
here is the angular js code:
function getModelId() {
dataFactory.getModelIdByFilter($scope.region, $scope.subregion).success($scope.handleSuccess).then(function (result) {
$scope.FilteredModelIds = result.data;
});
}
Model json :
[{"ModelId":0,"ModelText":"All models","Sequence":0,"TotalInterviews":0,"SatisfactionAvg":0.000000},{"ModelId":1,"ModelText":"A3","Sequence":20,"TotalInterviews":2062,"SatisfactionAvg":9.637245},{"ModelId":2,"ModelText":"A4","Sequence":30,"TotalInterviews":3106,"SatisfactionAvg":9.743721},{"ModelId":3,"ModelText":"A5","Sequence":40,"TotalInterviews":1863,"SatisfactionAvg":9.694041},{"ModelId":4,"ModelText":"A6","Sequence":50,"TotalInterviews":280,"SatisfactionAvg":9.642857},{"ModelId":5,"ModelText":"A8","Sequence":70,"TotalInterviews":46,"SatisfactionAvg":11.217391},{"ModelId":9,"ModelText":"Q5","Sequence":110,"TotalInterviews":3176,"SatisfactionAvg":9.503778},{"ModelId":10,"ModelText":"Q7","Sequence":120,"TotalInterviews":1355,"SatisfactionAvg":9.685608},{"ModelId":11,"ModelText":"R8","Sequence":130,"TotalInterviews":31,"SatisfactionAvg":10.064516},{"ModelId":12,"ModelText":"TT","Sequence":140,"TotalInterviews":408,"SatisfactionAvg":9.764705},{"ModelId":13,"ModelText":"A1","Sequence":10,"TotalInterviews":1087,"SatisfactionAvg":10.097516},{"ModelId":14,"ModelText":"A7","Sequence":60,"TotalInterviews":263,"SatisfactionAvg":10.190114},{"ModelId":15,"ModelText":"Q3","Sequence":105,"TotalInterviews":1045,"SatisfactionAvg":9.542583}]
on page load its showing proper data with filter. but on change of filtered object in my case FilteredModelIds, its not getting updated. any help is appreciated.
please let me know if i am worng here.
Thanks.