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>
Related
I have some collapseable panels and i want to add a resize button. For this i've made this javascript code:
function myFunction () {
$(".elementoGrafico").click(function () {
$(this).toggleClass("col-md-12");
$(this).toggleClass("col-md-6");
});
};
the html code is:
<div class="col-md-12 ui-state-default elementoGrafico">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading ">
<h4 class="panel-title">
<a data-toggle="collapse" href="#collapse1" class="component-button max-min-button more-less glyphicon glyphicon-chevron-up"></a>
Gráfico 1
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in elemento"> <canvas class="chart" id="myChart"></canvas>
</div>
</div>
</div>
</div>
But it doesn't work properly. Sometimes i have to click more than one time and some times the chart inside don't resizes like the div. (i want a code that works for all elements, not just one, so i want to do it using class, not id.)
I could use angularjs too.
Thank you.
Use this:
$(".elementoGrafico").each(function() {
let panel = this;
$(this).find(".resize-button").click(function() {
$(panel).toggleClass("col-md-12");
$(panel).toggleClass("col-md-6");
});
});
What this does is find the resize button for each panel and assign it a click handler which changes the panel itself.
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>
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.
I have a ng-repeat loop, which displays individual panels (one for each loop iteration). In each panel I have a 'mark as read' button that has a ng-click event. I want to be able to hide the panel that the mark as read button is clicked on, but so far I can only get all the panels to show and hide, not the individual selected panel.
How can I get the ng-click to hide the selected panel?
Thanks
Sorry here is some code of what I am doing now:
The panel section:
<section class="card" ng-repeat="item in notifications" ng-hide="msgRead">
<div class="item item-header notification wrap">
<h2>{{item.title}}</h2>
<div class="notification-content">
{{item.text}}
</div>
<button class="button button-block button-stable" ng-click="markAsRead(item.id)">
Mark As Read
</button>
</div>
</section>
And this is my controller function:
$scope.msgRead = true;
$scope.markAsRead = function (id) {
$scope.msgRead = $scope.msgRead === false ? true : false;
};
Stephen
You can write like:
<section class="card" ng-repeat="item in notifications" ng-hide="item.readonly">
<div class="item item-header notification wrap">
<h2>{{item.title}}</h2>
<div class="notification-content">
{{item.text}}
</div>
<button class="button button-block button-stable" ng-click="item.readonly = true">
Mark As Read
</button>
</div>
</section>
You don't need to write a scope method for this.
I am using Handlerbars.js and it gives me a dynamic template that is generated on the fly. When I do some Jquery events like click etc .. Jquery is not able to catch those events. Please help me out.
I want to trigger a event when the button with id hitUp is clicked
HandlerBar.js code
{{#each this}}
<div id="accordion2" class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a href="#{{log}}" data-parent="#accordion2"
data-toggle="collapse" class="btn-block" > <img
class="img-rounded" src="/assets/images/default-food.png" /> {{log}}
</a>
</h4>
</div>
<div class="panel-collapse collapse" id="{{log}}">
<div class="panel-body food-details">
<div class="bm pzero col-xs-12">
<div class="input-group spinner">
<input id="spinid" type="text"
name="demo_vertical2" class="form-control input-sm"
/> <span class="input-group-btn vertical">
<button id="hitUp"
class="btn btn-default bootstrap-touchspin-up"
type="button">
<i class="fa fa-caret-up"></i>
</button>
<button id="hitDown"
class="btn btn-default bootstrap-touchspin-down "
type="button">
<i class="fa fa-caret-down"></i>
</button>
</span>
</div>
HTML code
<div id="accordion2" class="panel-group">
</div>
Jquery code
Try1
$('body').on("click",'#hitUp',function(){
console.log("Functionclicked")
});
Try2
$('#hitUp').click(function(){
console.log("Functionclicked")
});
Try3
$( document ).ready(function( $('body').on("click",'#hitUp',function(){
console.log("Functionclicked")
});){})
I have tried the above Jquery methods but no use. Give me some solutions
Just like in the link that #adeno posted, jQuery event handlers need to be registered as the very last thing that happens when all the JavaScript files and libraries are loaded. Calling $(document).ready() does not mean that all JS files have been loaded, it just means that the DOM has been put in place and is ready for manipulation. If you're going to do more DOM manipulation with a library like Handlebars, you need to make sure that your event handlers are registered after all that dynamic generation has already happened.
So if this is my template:
<h1>{{title}}</h1>
<div>{{body}}</h1>
<br />
{{#each buttonIds}}
<input type="button" id="{{this}}" value="Click me" />
{{/each}}
And this is my javascript:
var data = {
title: 'The Title',
body: 'Document Body',
buttonIds: [ 'hitUp1', 'hitUp2', 'hitUp3' ]
};
var templateScript = $('#header').html();
var template = Handlebars.compile(templateScript);
$(document.body).append(template(data));
$('#hitUp1').on('click', function () { alert('clicked 1'); });
$('#hitUp2').on('click', function () { alert('clicked 2'); });
$('#hitUp3').on('click', function () { alert('clicked 3'); });
I'm waiting til very last to register the on click handlers, and they are each unique identifiers.
Here is a working fiddle to demonstrate what I'm saying.
was facing the same issue. use
$('body').on("change", '#amountType', function (){
});
this worked for me