Passing data to ionic popover in ng-repeat - angularjs

I want to add ionic Popover to my application and place in under ng-repeat however I am struggling a bit with this.
How can I pass a parameter to it?
<p ng-repeat="query in ctrl.timesheet">query.Name<button ng-click="openPopover($event)">Open Popover</button></p>
<script id="my-popover.html" type="text/ng-template">
<ion-popover-view>
<ion-header-bar>
<h1 class="title">My Popover Title</h1>
</ion-header-bar>
<ion-content>
<button ng-click="ctrl.delete(index)">Delete</button>
</ion-content>
</ion-popover-view>
</script>
So in short I want a list of buttons and whenever i click the popover for the button than there is a option to delete the element.

See this demo: http://play.ionic.io/app/eb32466d892c
You can pass scope of your controller to pop over, so whatever you have in parent controller will be available in pop over. Pass a parameter index in openpopover funtion : ng-click = "openPopover($event, pass-index-here)"> and bind it to $scope.index before you open popup, See this:
$ionicPopover.fromTemplateUrl('my-popover.html', {
scope: $scope
}).then(function(popover) {
$scope.popover = popover;
});
$scope.openPopover = function($event,index) {
$scope.index = {'value' : index}; //i am using object, because simple variable shows binding problem some time
$scope.popover.show($event);
};
Now this $scope.index will be available in popover, and will contain latest index of item, which you have clicked because we update its value before opening popover :
<button ng-click="ctrl.delete(index.value)">Delete</button>

Related

Angular 1.5 Binding ng-repeat created controls?

Angular 1.5
In an ng-repeat I create a button that will display a Bootstrap popup with anchor links.
How do I bind the onAction call so that it calls my $scope.onAction() function ? (onAction() is not bound to $scope.onAction().)
<div ng-repeat="item in model.Holdings track by $index" bs-popover>
<button class="popoverBtn"
data-content="<a ng-click='onAction(1)'>Buy</a>...and more"
click me to show popup
</button>
</div>
Here's my directive that turns the Bootstrap popover on:
app.directive('bsPopover', function () {
return function (scope, element, attrs) {
element.find(".popoverBtn").popover({ placement: 'auto', html: 'true' });
????COMPILE GOES HERE???////
};
});
It sounds like you want the onAction method to take an item identifier.
Perhaps something like <a ng-click='onAction(item.id)'>Buy</a> ??
From what I recall, you are in the scope of the controller that stores the data. If you have nested ng-repeats, look into $parent.
If you are looking to pass the index value of an item into your function on a click event, you need only pass it $index instead of an explicit value. For example:
<div ng-repeat="item in model.Holdings track by $index">
<button class="btn btn-primary"
data-content="<a ng-click='onAction($index)'>Buy</a>...and more">
click me to show popup
</button>
</div>
UI-Bootstrap project seems to have simple to use controls for Angular + Bootstrap.
https://angular-ui.github.io/bootstrap/
This worked

Reset Angular dropdown option in Ionic - won't reset after value is changed from initial value

I'm trying to figure out why I can't seem to wrangle a simple angular dropdown reset.
When the view loads, you hit the button "Reset", and it changes whatever value is selected to a different one, based on what the functionality in the controller dictates. This works fine on page load, but if you change the value in the dropdown THEN click "Reset", it does nothing. It doesn't reset the dropdown as specified in the function and I can't figure it out.
Steps to reproduce:
Page loads
Click "Reset" button
Dropdown value changes to "Japanese"
Change the value back to "English"
Click "Reset" button
Nothing. It should change the value back to English, but doesn't.
I've boiled everything down to the most basic example using an extremely basic ionic example in my Codepen:
http://codepen.io/starshock/pen/EPdXpz
Basically, here is my controller code:
.controller('DropdownController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Dropdown Reset';
$scope.reset = function() {
$scope.selectedOption = $scope.languages[0];
}
$scope.languages = [
{ name: "English"},
{ name: "Japanese"}
];
$scope.selectedOption = $scope.languages[1];
}]);
And here is my template:
<script id="entry.html" type="text/ng-template">
<ion-nav-bar animation="nav-title-slide-ios7"
type="bar-positive"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back">
</ion-nav-bar>
<ion-view title="{{navTitle}}" class="bubble-background">
<ion-content has-header="true" padding="true">
<div class="item item-input item-select" href="#">
<label>
<div class="input-label">
Select language
</div>
<select
data-ng-options="language.name for language in languages"
data-ng-model="selectedOption">
</select>
</label>
</div>
<button class="button button-positive" ng-click="reset()">Reset</button>
</ion-content>
</ion-view>
</script>
I've been struggling with this problem for months and I have a number of instances that utilize similar code. Any Angular masters have any thoughts? :D
You need to change your controller slightly to reference the same object each time (see https://stackoverflow.com/a/17607794/360067 and the answer referenced i.e. https://stackoverflow.com/a/14049482/360067 for the basics).
Assuming the default value you want is English (if it's Japanese, just change the index to 1 in both places)
$scope.reset = function() {
$scope.filter.selectedOption = $scope.languages[0];
}
...
$scope.filter = {
selectedOption: $scope.languages[0]
};
and in your HTML
<select
data-ng-options="language.name for language in languages"
data-ng-model="filter.selectedOption">
</select>
CodePen - http://codepen.io/anon/pen/KVGqOG

Ng-click does not work first time - but works afterwards

I have two states/views called bookmark and bookmarked.
The bookmark view has a button which passes an url into a function called setURL. This function sets the src for the iframe on the bookmarked view.
<ion-view view-title="Bookmarks">
<ion-content>
<button class="button" ui-sref="myLearning.bookmarked" ng-click="setURL('SOMEURL')">Bookmark</button>
</ion-content>
<div class="bar bar-footer bar-assertive"></div>
</ion-view>
The bookmarked view has an iframe whose src is set by the button on the previous view. The src is currently set to nothing because I would never navigate to this view unless I've clicked the bookmark button which would pass in an url.
<ion-view view-title="Bookmarked">
<ion-content>
<iframe id="learningFrame" src="" width="100%" height="100%" seamless></iframe>
</ion-content>
</ion-view>
When I run the app and navigate to the bookmark view and click on the bookmark button, it navigates to the bookmarked view but it displays a blank page in the iframe (src="") rather than using the url passed in from the function. However, from this blank page if I navigate to the bookmarks view and click on the bookmark button the second time, the actual url loads.
Why does it the view not use the url that I have passed in through setURL, on the first load?
This is what the function looks like:
.controller('bookmarkCtrl', function($scope){
$scope.setURL = function(currURL){
document.getElementById('learningFrame').src = currURL;
};
});
I don't know why it does not work the first time...
Any help would be appreciated, thank you.
Instead of doing DOM manipulation from the controller you could simply use ng-src that would have {{}} to have decide src attribute value.
Markup
<ion-view view-title="Bookmarked">
<ion-content>
<iframe id="learningFrame" ng-src="{{learningFrameUrl}}" width="100%" height="100%" seamless></iframe>
</ion-content>
</ion-view>
Controller
.controller('bookmarkCtrl', function($scope){
$scope.setURL = function(currURL){
$scope.learningFrameUrl = currURL;
};
});
Update
As you wanted to share data between you controllers then you could use service/factory component. Then you can use that service by injecting it inside your controller/directive wherever you wanted to use it.
Service
app.service('dataService', function(){
this.learningFrame = {
Url: ''
};
//..other stuff here..//
});
Controller
.controller('bookmarkCtrl', function($scope, dataService){
$scope.setURL = function(currURL){
//this can be available in other controller
//wherever you take value from learningFrameUrl
$scope.learningFrame = dataService.learningFrame;
dataService.learningFrame.Url = currURL;
};
});

How to show preloader inside button instead text Angular JS?

I use Angular JS library ngActivityIndicator.
I tried to show preloader inside element div instead text when button is pushed:
<div ng-activity-indicator="CircledDark">
<div ng-click="Add();" class="btn shareBtn">
<div ng-view></div>
<span>Text</span>
</div>
</div>
I posted <div ng-view></div> inside and have added directive ng-activity-indicator="CircledDark" to parent element.
When I click button, I call function that display preloader:
$activityIndicator.startAnimating();
But preloader is created outside of button:
<div ng-show="AILoading" class="ai-circled ai-indicator ai-dark-spin"></div>
This is official documantation, from here I have taken example:
https://github.com/voronianski/ngActivityIndicator#directive
How to show preloader inside button instead text Angular JS?
I think the only solution is to separate your ng-view and button, at least they do something similar in their sample page. So, in your markup you could do something like this:
<div ng-click="add()" class="btn btn-default" ng-activity-indicator="CircledDark">
<span ng-show="!AILoading">Add</span>
</div>
<div ng-view ng-show="!AILoading">{{ delayedText }}</div>
And in your controller:
$scope.delayedText = "";
$scope.add = function() {
$activityIndicator.startAnimating();
$timeout(function() {
$scope.delayedText = "Here we are!";
$activityIndicator.stopAnimating();
}, 3000);
};
Here is full Demo, you can play with CSS a little so the size of the button won't change when text is replaced by icon.

angular-ui bootstrap accordion: How do I properly $watch the is-open attribute?

I'm trying to perform an action when a specific accordion-section is openend. My use-case is almost identical to this question here, only I'm using statically defined 's instead of ng-each.
Somehow I can't get the $watch to fire when the is-open state changes, can anybody tell me why this doesn't work:
View:
<accordion close-others="false">
<accordion-group heading="group1" is-open="acc1open">
content 1
</accordion-group>
<accordion-group heading="group2" is-open="acc2open">
content 2
</accordion-group>
</accordion>
Controller:
$scope.acc1open = false;
$scope.acc2open = true;
$scope.$watch('acc1open', function(){
console.log("watch acc1:" +$scope.acc1open);
}, true);
Here's a plunker:
https://plnkr.co/edit/Ycms81?p=preview
It prints "watch acc1:false" a single time when the page is loaded, but nothing when the accordion group is opened.
Along with the plunker: plnkr.co/edit/1lnbTa?p=preview
I found this worked for an array:
JS
$scope.array = [object1,object2,object3,object4];
$scope.isOpen = [false,false,false,false];
$scope.$watch('isOpen', function() {
console.log("watch isOpen:" + $scope.isOpen);
}, true);
HTML(JADE)
accordion-group(ng-repeat='object in array',is-open="$parent.isOpen[$index]")
accordion-heading
h4 My Heading {{$index}}
p My content {{$index}}
I added a <span> inside the AccordionDemoCtrl div and changed the is-open to bind to $parent.acc1open
<accordion-group heading="group1" is-open="$parent.acc1open">
...
<span ng-click="acc1open = true">Click me to open group 1</span>
Directives have their own scope, and the variables are their own.

Resources