ng-repeat: prevent changing of information in previous panels - javascript

So, the issue is:
I have an HTML structure here:
<div class="container-fluid" ng-click="goto(item.title)" ng-repeat="item in someResponse" data-toggle="collapse" data-parent="accordion"
data-target="#collapseone_{{ $index }}" aria-expanded="false" aria-controls="#collapseone">
<div class="panel-group" id="accordion">
<div class="panel panel-info">
<div class="panel-heading">
<div class="wrap">
<img class="img" ng-src="{{item.img_url}}">
<p>{{item.title}}</p>
<p>{{item.price | currency}}</p>
<p>{{item.summary}}</p>
</div>
</div>
<div id="collapseone_{{ $index }}" class="panel-collapse collapse" ng-model="collapsePanel">
<div class="panel-body">
<div>
<p>{{IdResponse.price | currency}}</p>
<p>{{IdResponse.title}}</p>
<img class="img" ng-src="{{IdResponse.img_url}}">
<p>{{IdResponse.summary}}</p>
<p>Bathrooms:{{IdResponse.bathroom_number}}</p>
<p>Bedrooms:{{IdResponse.bedroom_number}}</p>
<input type="button" value="favourites" ng-click="goto1()">
</div>
</div>
</div>
</div>
</div>
And its controller:
angular
.module('PropertyCross')
.controller('searchResultsCtrl', ['$scope', '$http', '$location', 'myService',
function ($scope, $http, $location, myService) {
$scope.someResponse = myService.getData();
console.log($scope.someResponse);
$scope.goto = function (id) {
myService.setID(id);
console.log(id);
$scope.IdResponse = myService.getID();
console.log($scope.IdResponse);
};
$scope.goto1 = function () {
myService.setFav($scope.IdResponse);
}
}
]);
When I click on one collapse panel I have the right data coming from the back, but the problem appears when I try to open two or more panels. As a result I have the same things on all opened panels.
How can I prevent the changing of information in previous panels?

You could have the service push the data back into to the someResponse model. That way all of the price and detail information just extends the general listing. and since it is living within your ng-repeat the two-way binding will render the info.
Just change this code to this.. I'm not sure if the id below is a unique id from a database or the id within the array which is part of the response. if you have both you can use this code...
$scope.goto = function (id, arrayIndex) {
myService.setID(id);
console.log(id);
$scope.someResponse[arrayIndex].IdResponse = myService.getID();
console.log($scope.someResponse[arrayIndex].IdResponse);
};
So, you are storing the information into an object within the original model. What you were doing was storing everything in one data model. So, whenever you updated it, the two way binding updated and cascaded to the two references (in both expanded panels).
Next, you would update your ng-repeat and ng-click to this:
<div class="container-fluid"
ng-click="goto(item.title, index)"
ng-repeat="(index, item) in someResponse"
data-toggle="collapse" data-parent="accordion"
data-target="#collapseone_{{ $index }}"
aria-expanded="false" aria-controls="#collapseone">
and finally update the curly braces in the panels to something like this:
<div id="collapseone_{{ $index }}"
class="panel-collapse collapse" ng-model="collapsePanel">
<div class="panel-body">
<div ng-show="item.IdResponse">
<p>{{item.IdResponse.price | currency}}</p>
<p>{{item.IdResponse.title}}</p>
<img class="img" ng-src="{{item.IdResponse.img_url}}">
<p>{{item.IdResponse.summary}}</p>
<p>Bathrooms:{{item.IdResponse.bathroom_number}}</p>
<p>Bedrooms:{{item.IdResponse.bedroom_number}}</p>
<input type="button" value="favourites" ng-click="goto1()">
</div>
</div>
</div>
And I added an ng-show="item.IdResponse" so that the formatting wont show up until there is an object returned from the server.
I hope this answers your question.

Related

How to call a html <div> from <a href> link on the same html file

I have a text and when I click the text, it will call the .
My code is as follow.
<h5>Posted On: {{postedDate | date}} <a href="" style="float:right" >Table Plans</a></h5>
When I click Table Plans, it should call the div with id "tableImagesSliding".
<div id="tableImagesSliding" class="col-md-4 col-sm-4 col-xs-12">
<div class="inner-box">
<div class="mask-menu">
<ul class="images ">
<li class="display-inline" ng-repeat="tableImage in allTableImages">
<img ng-src="{{tableImage.url}}" width="600" height="400" />
</li>
</ul>
</div>
<ul class="triggers-menu slider-btn">
<li ng-repeat="cnt in tablemapcount"></li>
</ul>
</div>
</div>
How can I do that?
You can use the href attribute of an <a> tag to point to an element on the page with an id by using the hash symbol.
Jump to table plans
<div id="tableImagesSliding">
Table plans div
</div>
For more information on valid uses of href, you can read the MDN page about a#href and about the id attribute
However, It's a bit more involved when using Angular...
Angular's router will get involved, and if it doesn't recognise the route, will (probably - depending on your setup) redirect to the main route.
You can use the $anchorScroll service to get Angular to jump to the div for you.
Your HTML now contains an ng-click, and the controller uses $anchorScroll:
angular.module('so42186303', [])
.controller('so42186303Ctrl', ['$scope', '$location', '$anchorScroll', function($scope, $location, $anchorScroll) {
$scope.showTablePlans = function() {
$location.hash('tableImagesSliding');
$anchorScroll();
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="so42186303">
<div ng-controller="so42186303Ctrl">
<a ng-click="showTablePlans()">Click to jump to table plans</a>
<div style="height: 100vh; margin-top: 20px;">Content to jump past</div>
<div id="tableImagesSliding" style="height: 100vh;">
Table plans
</div>
</div>
</div>
If by call you mean scoll to the position of the div, the answer would be

$scope variable not updating in view

I have the following snippet of code,
<div ng-controller="GraphCtrl" ng-if="errorTracerouteResultsLength!=0">
<h5>Erroneous Traceroute Paths
<small>Sub-heading</small>
</h5>
<a href="#" ng-repeat="(key, val) in errorTracerouteResults" ng-click="loadTraceroutePath(val.metadata);">
S: {{val.source.ip}}
D: {{val.destination.ip}}
</a>
</div>
It works fine, loadTraceroutePath belongs to another controller,(lets call it X) but somehow ng-click works and console.log gets printed out with the correct metadata value.
However, in controller X, I have,
$scope.loadIndividualTraceroutePath = function (metadataKey) {
$scope.noOfResults = 1;
}
In the html, I have {{noOfResults}} all over the place. Some of it are able to display 1 while some can't. I have already attached the ng-controller directives and point to controller X, but {{noOfResults}} does not display.
How can I make {{noOfResults}} display in any section of the HTML?
Edit: I have added the HTML.
<div class="row">
<div class="col-lg-9">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-bar-chart-o fa-fw"></i> Visualisation
<div class="pull-right">
Layout
</div>
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="container" ng-controller="X">
<!--This does not work-->
{{noOfResults}}
</div>
<div>
<div ng-controller="IndividualTraceroutePathGraphCtrl" id="individual_traceroute_path_graph"></div>
</div>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
The ng click in the first part of this question is way below.
You have a extra ; at the end, also you are not using the object what you are passing as a parameter to the function, hence Change
From:
<a href="#" ng-repeat="(key, val) in errorTracerouteResults" ng-click="loadTraceroutePath(val.metadata);">
To:
<a href="#" ng-repeat="(key, val) in errorTracerouteResults" ng-click="loadTraceroutePath(val)">
Then,
$scope.loadIndividualTraceroutePath = function (metadataKey) {
$scope.noOfResults = 1;
}
EDIT
You don't need to mention so many controllers in the view, have one controller where the function is defined and remove the rest, here, Update like this,
<div class="container" >
<!--This does not work-->
{{noOfResults}}
</div>
<div>
<div id="individual_traceroute_path_graph"></div>
</div>
</div>

AngularJS - JQuery News Ticker - After moving news the javascript function doesn't get called

This is an awkward problem, which will be better explained by looking at the live demo. Basically I have a news box populated with ng-repeat using Angular. Then I am using a jquery plugin called news ticker which allows the news headlines to move around. The first time you land on the page the news items are in their proper spots and they call the function accordingly. After moving them up or down, they stop calling the function, set a breakpoint in the code and after moving the breakpoint is never hit.
Edit - After researching this further I have found that it is because the elements need to be compiled using $compile after they're re added. However following some examples I have not gotten this to work. I need a way of compiling after a move event with this plugin.
Live demo
Angular Script for with function that should be called.
$scope.UpdateNews = function (item,number) {
console.log(item + ' ' + number);
switch (item)
{
case 'General':
$scope.NewsCast.General.Body = $scope.News.GeneralNews[number].Text;
break;
}
};
What the HTML looks like with the news boxes
<script src="http://www.jqueryscript.net/demo/Responsive-jQuery-News-Ticker-Plugin-with-Bootstrap-3-Bootstrap-News-Box/scripts/jquery.bootstrap.newsbox.min.js" type="text/javascript"></script>
<div class="row">
<div class="col-md-6 col-lg-3">
<div class="panel panel-default">
<div class="panel-heading"> <span class="glyphicon glyphicon-list-alt logo-inverse pull-left"></span><b> General News</b></div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<ul class="demo1" style="overflow-y: hidden; height: 280px;" ng-model="Idk">
<li style="" class="news-item text-left" ng-repeat="item in News.GeneralNews"><strong>{{item.DateValue | date: "MMM dd yyyy"}}</strong> {{item.Preview}}<a class="FakeClickable" ng-click="UpdateNews('General',item.index)" data-target="#GeneralModal" data-toggle="modal">Read more...</a></li>
</ul>
<div ng-if="Width>768">
<div ng-include="'../pages/Modals/General/GENERAL_INLINE.html'"></div>
</div>
</div>
</div>
</div>
<div class="panel-footer"> </div>
</div>
</div>

Trigger event when uib-accordion is opened

I´m trying to trigger an event when the accordion is opened. The event should just get triggered when the accordion is getting opened, not when getting closed.
HTML:
<uib-accordion>
<uib-accordion-group is-open="status.open" ng-click="showList(status.open)"
ng-init="count=0">
<uib-accordion-heading>
I can have markup, too! <i class="pull-right glyphicon"
ng-class="{'glyphicon-chevron-down': status.open,
'glyphicon-chevron-right': !status.open}"></i>
</uib-accordion-heading>
{{count}}
</uib-accordion-group>
</uib-accordion>
App.js (inside the Controller)
$scope.showList = function (status){
if(status)
{
$scope.count = $scope.count + 1;
}
};
For the sake of simplicity the event just increments count by one. I just want to know how to trigger an event when the accordion is opened.
this is an old thread, but since I bumped into the same issue, here is the solution I came up with.
uib-accordion[-group] directive has toggleOpen() scoped function. so you cannot change that from outside controller.
let's override template - accordion takes template-url. take the original template from:
https://github.com/angular-ui/bootstrap/blob/master/template/accordion/accordion-group.html
and create your own
remove toggleOpen() from root <div> and <a> tags.
while you feeding uib-accordion-heading, bind click/key-press event with your controller function - ie) myToggleOpen(myIsOpenModel) make sure your heading covers whole section
in myToggleOpen, do what you need
html
<uib-accordion>
<div uib-accordion-group template-url="myTemplate.html" ng-repeat="item in items track by $index" is-open="item.isOpen">
<uib-accordion-heading>
<div ng-click="myToggleOpen(item)">Toggle!</div>
</uib-accordion-heading>
<div class="content">
Hello!
</div>
</div>
</uib-accordion>
js
scope.myToggleOpen = function (item) {
item.isOpen = !item.isOpen;
}
myTemplate.html (change more if needed)
<div role="tab" id="{{::headingId}}" aria-selected="{{isOpen}}" class="panel-heading">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" href aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}" tabindex="0" class="accordion-toggle" uib-accordion-transclude="heading" ng-disabled="isDisabled" uib-tabindex-toggle><span uib-accordion-header ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
</h4>
</div>
<div id="{{::panelId}}" aria-labelledby="{{::headingId}}" aria-hidden="{{!isOpen}}" role="tabpanel" class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" ng-transclude></div>
</div>

Angular JS binding working only once in the page

I have a page where I do multiple binding to the same object (item, item2, message, messageType)
Though I placed the binding in several part of the page it works only the first time i placed. The objects are filled with ajax calls that return correctly the value (I logged them in the console)
What sounds even strange to me is that the <infomessage> directive has been used in several other places in the app (twice in the same page) and worked perfectly.
Do you have any idea on why these bindings don't work?
I even tried to $watch the objects and they are properly changes but seems that the view use the updated value only the first time
<div class="container" ng-app="MyApp" >
<div class="row" ng-controller="MyCtrl" >
<div class="col-lg-10">
<h3>...</h3>
</div>
<div class="col-lg-10">
<infomessage type="{{messageType}}" message="{{message}}"></infomessage>
</div>
<div class="col-lg-10">
Item: {{item.idbene_ext}} / {{item.id}} / {{item.img}}<br>
Ubicazione: {{item2.id}} {{item2.code}}
</div>
</div>
<div class="row" style="margin-top:20px">
<div class="col-xs-1"></div>
<div class="col-xs-4" ng-class="{'ubiBox':true,'ausilio-enabled':(item!=null),'ausilio-disabled':(item==null), 'boxfocus':(item==null)}">
<div ng-show="item==null">
<div class="number">1</div>
<img src="assets/images/disabled-128.png" width="100" class="img_none"/>
<h4> {{item.idbene_ext}} Select an item</h4>
</div>
<div ng-show="ausilio!=null">
<h4>Item:{{item.idbene_ext}}</h4>
</div>
</div>
<div class="col-xs-2"></div>
<div class="col-xs-4" ng-class="{'ubiBox':true,'ubi-enabled':(item!=null),'ubi-disabled':(item==null),'boxfocus':(item!=null) }">
<div ng-show="item==null">
<div class="number">2</div>
<img src="assets/images/Office-disabled-128.png" width="100" class="img_none"/>
<h4> Select the second item</h4>
</div>
<div ng-show="item!=null">
<h4>Item2 {{item2.code}}</h4>
</div>
</div>
<div class="col-xs-1"></div>
</div>
<div class="row">
<div class="col-lg-10">
<infomessage type="{{messageType}}" message="{{message}}"></infomessage>
</div>
<div class="col-lg-10">
Item: {{item.idbene_ext}} / {{item.id}} / {{item.img}}<br>
Ubicazione: {{item2.id}} {{item2.code}}
</div>
</div>
Here's the angularJS code
MyApp.controller("MyCtrl",function($scope,$http,Config,BarcodeService){
$scope.iditem2=-1
$scope.iditem=-1
$scope.item2=null
$scope.item=null
$scope.message=""
$scope.messageType=""
$scope.$on(BarcodeService.handleitem2,function(){
$scope.message=""
$scope.messageType=""
if($scope.item==null){
$scope.message="select an item before"
$scope.messageType="error"
}
$scope.iditem2=BarcodeService.id
$http
.post(Config.aj,{call:"item2.getitem2",id:$scope.iditem2})
.success(function(data){
$scope.item2=data.payload
})
})
$scope.$watch("item",function(){
console.log("---->",$scope.item)
},true)
$scope.$on(BarcodeService.handleitem,function(){
$scope.message="loading item"
$scope.messageType="info"
$scope.iditem=BarcodeService.id
$http
.post(Config.aj,{call:"item.getArticoloByIdMin",id:BarcodeService.id})
.success(function(data){
$scope.message="item loaded!!"
$scope.item=data.payload
})
})
})
Ok guys, got it!
The problem was lying in the fact that I have two in my application but i placed the ng-controller only on the first one.
This caused all the binding in the second div to fail because they were outside the controller.
I moved the ng-controller in the parent div that contains both and now everything works like a charm.
Thanks anyway to #wachme and #ivarni for taking care of my question.
Happy coding to *

Categories