Angular doesn't set databinding - angularjs

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);

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.

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

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.

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.

How to create div and assign object to dataset dynamically using Angularjs

I have below div (class name 'sp') which I would like to dynamically create based on the sk from a dataset object.
div code
<div style="" class="swindow">
<div class="sp" style="">
<div class="svis" style="">
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
</div>
</div>
While searching for similar examples, I came across ng-repeat in Angular js and I thought it might suit for this kind of objective.
But am very new to Angular js and not sure how to assign the data to my dyndata variable dynamically and create new div (class=sp) for each of the given id.
Here is the lookup object
[
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
When I input the id's as a set [12,26,57] - Three divs (each for #sp) should get created one for each of ids. In those, each div should have the dyndata assigned with the respective 'st' from above javascript object.
I could create div's in jquery using .append function to the container (#swindow) each time when I need. But am not sure how to assign sk as input to dyndata dataset for each div that gets created.
Could you please share how this can be achieved using Angular js ?
Here is the angular js code I used -
<script>
var app = angular.module('ExampleApp', ['ui.plot']);
app.controller('PlotCtrl', function ($scope) {
$scope.dyndata={};
});
</script>
I'm not exactly sure what you're trying to do but I think it should look something like this. Here is a plnkr..
Controller:
app.controller('PlotCtrl', function($scope) {
$scope.items = [
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
});
HTML:
<body ng-controller="PlotCtrl">
<div style="" class="swindow">
<div class="sp" style="" ng-repeat="item in items">
<div class="svis" style="">
<strong>{{item.id}}:</strong>
<div>-{{item.st[0].label}}</div>
<div>-{{item.st[1].label}}</div>
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
<br>
</div>
</div>
</div>
</body>

Issue with angular-based codepen not loading my inline templates using ng-include

I am trying to load angular inline templates as follows:
<ng-include src="templateId"></ng-include>
Here is the inlined template:
<script type="text/ng-template" id="needs.html">
<div class="form-group">
<div class="col-lg-6">
<div ng-repeat="need in needs" class="hidden-radios">
<input type="radio" id="{{need}}" name="needs" ng-required="true" ng-model="advertisement.need" ng-value="need"/>
<label for="{{need}}" class="col-lg-6">
<span class="block-span">
{{ need }}
</span>
</label>
</div>
</div>
</div>
</script>
and the relevant portion from the controller:
$scope.focusNeed = function(){
console.log('focusNeed');
$scope.templateId='needs.html';
};
See codepen here: http://codepen.io/balteo/pen/ogBBXZ?editors=101
The issue I have is that the app tries to load the template by issuing request on the server instead of looking at the inline templates.
Can anyone please help?
That is because your template is out of scope. Place <script type="text/ng-template" id="needs.html"> inside ng-app and it will work.
In real world ng-app is on the body. Butin codepen you cannot do that. That is why you'd better use plunker.

Resources