Can't access data from ion-content in ion-footer - angularjs

Update
I get it. I just need to put a
$scope.get = {}
outside my save function and change
<button ng-click="save(get)"></button>
to this
<button ng-click="save()"></button>
Thanks to this thread.
I have a simple problem that related to access data from ion-content in the button placed on ion-footer. It returns undefined.
<ion-content>
<input type="text" ng-model="get.name" />
</ion-content>
<ion-footer>
<button ng-click="save(get)"></button>
</ion-footer>
js file
$scope.save = function(get){
alert(get);
}

JS Code
$scope.get = {'Id':1,Name:'Test'};
$scope.save = function (get) {
alert(get.Name);
};
HTML Code
<ion-view>
<ion-content>
<input type="text" ng-model="get.Name"/>
</ion-content>
</ion-view>
<ion-footer>
<button ng-click="save(get)">Save</button>
</ion-footer>
This code will work and alert the Name.

Related

Implementing a script in Ionic Typescript

I would like to implement dynamically added buttons to my Ionic app. I found that I can use the following code for this task.
The first part of the code I placed into the home.html file inside html body.
<div ng-controller="MyCtrl">
<div class="list list-inset">
<div class="item-input" ng-repeat="input in inputs">
<label class="item-input-wrapper">
<input type="text" placeholder="Type something" ng-model="input.value" />
</label>
<button class="button button-small button-balanced" ng-if="$index == inputs.length - 1" ng-click="addInput()">
<i class="icon ion-plus"></i>
</button>
<button class="button button-small button-assertive" ng-if="$index != inputs.length - 1" ng-click="removeInput($index)">
<i class="icon ion-minus"></i>
</button>
</div>
</div>
The second part of the code I placed to the home.ts file. I tried to place this code in the main class.
var app = angular.module('myApp', []);
app.controller("MyCtrl", function($scope) {
$scope.inputs = [{
value: null
}];
$scope.addInput = function() {
console.log("new input");
$scope.inputs.push({
value: null
});
}
$scope.removeInput = function(index) {
$scope.inputs.splice(index, 1);
}
});
Unfortunately, I cannot define a variable:
var app = angular.module('myApp', []);
Because I am getting a "Typescript error". Unfortunately, I don't know how to solve this problem. I hoped that some of you will know a solution and can help me with this problem.
The second part of the code I placed to the home.ts file
This statement suggests that you have created an ionic 2+ project(currently Ionic 3.x). This does not use angularjs (v 1.x) and uses angular 5.x instead.
If you want to start an ionic v1 project,
you need to set the type in your start command.
ionic start myApp blank --type=ionic1
Or you need to read up on latest angular docs here if you need to start an ionic v3 project.

Filter in ng-repeat not applying

I'm working on a Ionic project which has a view that shows a scrollable list with a search input that filters the displayed results, this view is located in a template that is loaded into another view.
We noticed the search input would move with the content when the scrolling began, disappearing making it a problem when you had scrolled and wish to filter the results.
I tried to workaround this by pulling the search input outside the template and placing it above where it is loaded in the parent view.
While this renders the search input at a fixed location, even though I specified the controller that handles its logic, the filter isn't applied on the list.
Here is how my code looks on the parent view:
<ion-popover-view id="popfecha" class="fit" >
<ion-view view-title="Nuevo ReSAT">
<ion-content class="padding" data-ng-hide="activity.state.notes || activity.state.reasonShow || activity.state.product_lineShow || activity.state.account || activity.state.contact " >
<form name="form" data-ng-submit="submitForm()">
<!-- A long form -->
</form>
</ion-content>
<ion-view class="wrapper" data-ng-show="activity.state.account" >
<!-- Filter section -->
<div data-ng-controller="AccountCatalogueCtrl" class="item item-input filterSearch bar-header popupBorder borderFirstItemPopup">
<label class="item-input-wrapper">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" placeholder="Search" class="form-control"
ng-model="filterText.name">
</label>
</div>
<!-- ./Filter section -->
<ion-content class="padding" data-ng-show="activity.state.account" >
<div data-ng-controller="AccountCatalogueCtrl" ng-include="'templates/account-catalogue.html'"></div>
</ion-content>
</ion-view>
<ion-content class="padding" data-ng-show="activity.state.notes" >
<div data-ng-controller="ActivityNotesCtrl" ng-include="'templates/activity-notes.html'"></div>
</ion-content>
<ion-content class="padding" data-ng-show="activity.state.reasonShow" >
<div data-ng-controller="ReasonCatalogueCtrl" ng-include="'templates/reason-catalogue.html'"></div>
</ion-content>
<ion-content class="padding" data-ng-show="activity.state.product_lineShow" >
<div data-ng-controller="ProductLineCatalogueCtrl" ng-include="'templates/product-line-catalogue.html'"></div>
</ion-content>
<ion-content class="padding" data-ng-show="activity.state.contact" >
<div data-ng-controller="ContactCatalogueCtrl" ng-include="'templates/contact-catalogue.html'"></div>
</ion-content>
</ion-view>
</ion-popover-view>
As you can see, I'm specifying the controller AccountCatalogueCtrl to the div that holds the search input and to the div that loads the template account-catalogue.html.
Here's my template:
<ion-list>
<ion-radio class="item-avatar popupBorder borderLastItemPopupIterator whiteBackground" ng-repeat="acc in accountCatalogue | orderBy:'-name' : true | filter:filterText track by acc._id"
type="item-text-wrap" ng-value="acc.name" ng-if="!acc.isDivider" ng-click="select(acc); go()" >
<img src="img/account.png">
<h2>{{acc.name}}</h2>
</ion-radio>
</ion-list>
<ion-infinite-scroll
ng-if="canLoadAccounts"
on-infinite="loadAccounts()"
distance="5%">
</ion-infinite-scroll>
I even placed a watch on the filterText object to see it was being updated, the watch did show me that the property name was changing.
This is my controller:
var mod = angular.module('starter.controllers');
mod.controller('AccountCatalogueCtrl', ['$scope', '$rootScope', '$location', '$timeout', function ($scope, $rootScope, $location, $timeout) {
$scope.select = function(acct){
$rootScope.activity.accountId = acct._id;
};
$scope.go = function ( ) {
$timeout(function(){
$scope.$emit('HideAccount');
},150);
};
// Added the lines below to see if the filter was changing
// Since in the beginning filterText doesn't exist undefined is returned
// Later when a value is placed in the input then the filterText object is created
$scope.$watch('filterText.name', function(n, o){
console.log('filter updated ' + JSON.stringify(n) + ' ' + JSON.stringify(o));
});
}]);
If I place the search input inside my template, the filter is applied, but when placed outside the filter isn't applied. Am I doing something wrong in my implementation? How can I make sure the filter applies even if the component that received it is outside the template that makes use of the filter?
I solved this issue by removing the controller from the search input, so it looked like this:
<!-- Filter section -->
<div class="item item-input filterSearch bar-header popupBorder borderFirstItemPopup">
<label class="item-input-wrapper">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" placeholder="Search" class="form-control"
ng-model="filterText.name">
</label>
</div>
<!-- ./Filter section -->
I saw that I could access to filterText on my controller AccountCatalogueCtrl due to the component that shows the catalogue has access to the scope variables from the parent component that it is holding it. This way I could change the value outside AccountCatalogueCtrl and affect the filter inside the list.

Angular doesn't set databinding

I have a problem with Angular, it seems to not do the two way binding.
I'm pretty new on this stuff, so I might just look over something.
Here is my code.
View:
<ion-view view-title="Update challenge">
<ion-content>
<ion-list>
<ion-item>
Current total
<span class="item-note">
{{challengeProgress.current_total_reps}}
</span>
</ion-item>
<ion-item>
Ultimate goal
<span class="item-note">
{{challengeProgress.total_reps}}
</span>
</ion-item>
<ion-item>
Todays goal
<span class="item-note">
{{todaysReps}}
</span>
</ion-item>
<ion-item>
Left for today
</ion-item>
<ion-item>
<label class="item item-input">
<input type="text" placeholder="Performed reps" ng-model="reps">
</label>
</ion-item>
<div class="button button-calm button-block" ng-click="updateProgress()">Update!</div>
Reps {{reps}}
</ion-list>
Controller:
$scope.reps;
$scope.updateProgress = function(reps){
console.log(reps);
SendToAPI.updateChallenge(u_id, c_id, toAdd);
}
reps seems to be undefined and the {{reps}} doesn't get updated either.
There is no need to pass reps as parameter.You can have access in the $scope.updateProgress function as $scope.reps.
HTML :
<div class="button button-calm button-block" ng-click="updateProgress()">Update!</div>
JS :
$scope.updateProgress = function(){
console.log($scope.reps);
//SendToAPI.updateChallenge(u_id, c_id, toAdd);
}
Please check Plunker
This appears to be a combination of issues related to the ionic framework.
The first issue is that ion-item elements actually create a child scope, and because reps is a primitive rather than an object, it isn't visible in other scopes due to prototype inheritance. This is easily fixed by ensuring that the reps is inside the same ion-item as the function that will be consuming it, though it could also be solved by making an object on $scope, $scope.workout.reps for example, that does not have the same issues with inheritance.
The second issue seems to be that the function itself is never actually firing. On the surface, this appears to be some sort of issue with the CSS in ionic, but it is easily fixed by changing the div to an ion-item instead.
The following shows the working changes to the view:
<ion-item>
<label class="item item-input">
<input type="text" placeholder="Performed reps" ng-model="reps">
</label>
<ion-item class="button button-calm button-block"
ng-click="updateProgress(reps)">Update!</ion-item>
Reps {{reps}}
</ion-item>
http://codepen.io/Claies/pen/EPEBZN
Note in the codepen, I log both the passed in reps and $scope.reps, to prove that there is an inheritance issue.
Bas dont seem like you have 1. declared an app and 2. wrapped your html with an ng-controller. Without a controller there is no link between you HTML and your controller. As you can see with 2 way binding there is no need for a ng-click as it is updated into HTML as well as your controller
Here is a basic working example of your code:
https://plnkr.co/edit/w2B7iRcaoTiOCdL1JJTX?p=preview
<!DOCTYPE html>
<html ng-app="plunker">
<head>
</head>
<body ng-controller="MainCtrl">
<h1>Hello Plunker!</h1>
<label class="item item-input">Label</label>
<input type="text" placeholder="Performed reps" ng-model="name" />
// BUTTON NOT NEEDED for update but can used for some other event
<button class="button button-calm button-block" ng-click="updateProgress()">Update!</button>
<p>Hello {{name}}!</p>
</div>
</body>
</html>
Script:
(function(angular) {
'use strict';
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.name = "Hello World";
$scope.updateProgress = function(val){
console.log(reps);
$scope.name = val;
};
}]);
})(window.angular);

Get value from ng-repeat outside of ng-repeat

I got a header bar outside of ng-repeat:
<ion-header-bar class="headerView" ng-show="!hideAll">
<button id="shareImage" class="button button-icon icon ion-share" style="color:#fff" ng-click="shareImageTo({{originalImageSource}})"></button>
<button class="button button-outline button-light close-btn" ng-click="closeModal()">{{::actionLabel}}</button>
</ion-header-bar>
And a slidebox where images are shown:
<ion-slide ng-repeat="single in slides track by $index">
<div class="item item-image gallery-slide-view">
<img ng-src="{{single.original}}">
<input type="text" ng-model="originalImageSource" value="{{single.original}}">
</div>
</ion-slide>
{{single.original}} is an URL to an image. But this URL is not placed in the input field. It is shown when I´m deleting this ng-model statement.
If a user clicks the button #shareImage the ShareImageTo(URL) function is executed. But with an undefined value for {{originalImageSource}}.
Any thoughts on how i could pass the URL in {{single.original}} to this ShareImageTo() function?
With $ionicSlideBoxDelegate you can get the current slide index via currentIndex(). That enables you to get the URL by $scope.slides[$ionicSlideBoxDelegate.currentIndex()].original in your ShareImageTo()-method like that:
$scope.ShareImageTo = function() {
var URL = $scope.slides[$ionicSlideBoxDelegate.currentIndex()].original;
//your logic
};
Another approach would be to use ion-slide-box's directive on-slide-changed.
Template:
<ion-slide-box on-slide-changed="slideHasChanged($index)">
...
</ion-slide-box>
Controller:
$scope.slideHasChanged = function(index) {
$scope.originalImageSource = $scope.slides[index].original;
//.. some more logic
}
Just create a div that wrap around both your navbar and your slidebox, and place your ng-repeat in that div :)

how to clear modals in ionic angular todo example

I've noticed that in the ionic todo app example the stale/old todo information remains on the modal if I cancel the modal and open it back up again. What's the best place to clear/reset the old modal data so that it always has fresh blank fields after I cancel or submit the modal form fields?
Should I null or clear the task object somehwere? Reset the fields manually on close and create? Add a handler to some sort of on hide event?
Here's the angular/ionic example:
http://ionicframework.com/docs/guide/building.html
and a relevant snippet of code
// Called when the form is submitted
$scope.createTask = function(task) {
$scope.tasks.push({
title: task.title
});
$scope.taskModal.hide();
task.title = "";
};
// Open our new task modal
$scope.newTask = function() {
$scope.taskModal.show();
};
// Close the new task modal
$scope.closeNewTask = function() {
$scope.taskModal.hide();
};
and the modal
<div class="modal">
<!-- Modal header bar -->
<ion-header-bar class="bar-secondary">
<h1 class="title">New Task</h1>
<button class="button button-clear button-positive" ng-click="closeNewTask()">Cancel</button>
</ion-header-bar>
<!-- Modal content area -->
<ion-content>
<form ng-submit="createTask(task)">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="What do you need to do?" ng-model="task.title">
</label>
</div>
<div class="padding">
<button type="submit" class="button button-block button-positive">Create Task</button>
</div>
</form>
</ion-content>
I've had the same problem. I first tried to clear my form data by clearing the model-object upon closing my modal window, just like you, but that only worked for when I submitted the form, it seems. When cancelling, it doesn't work! (Even if you explicitly clear the object before hiding the popup, it will not work)
I eventually fixed it by doing this:
$scope.newTask = function() {
$scope.task = {};
$scope.taskModal.show();
};
This way, every time the window is loaded, you clear the model. So the trick is not to do it when submitting data, but when opening the modal window. That did it for me at least.
Btw, I also needed an edit function for this same modal window, so I do this:
$scope.editTask = function(task) {
$scope.task = task;
$scope.taskModal.show();
};
The accepted answer is definitely correct but there is another way to achieve the same goal.
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
$scope.task = {};
});

Resources