view code:
<ion-view class="forms-view" ng-init="loadall()">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-title>
<span>List</span>
</ion-nav-title>
<ion-content>
<ion-scroll direction="xy" on-scroll="addMoreItem()">
<ion-list ng-controller="card">
<div class="item item-input-inset">
<label class="item-input-wrapper">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" ng-model="input.filterUser" placeholder="Search" style="height:48px;">
</label>
</div>
<ion-item class="item-avatar item-icon-right" ng-repeat="cardlists in cardlist | filter:input.filterUser" ui-sref="app.details({card_id:cardlists.card_id,xyz:0})">
<img src="{{cardlists.avatar}}" >
<h2>{{cardlists.name}}</h2>
<p>{{cardlists.card_id}} </p>
<i class="icon ion-plus-round custom-icon" ng-show="!cardlists.isShow" ng-click="addTo(cardlists.card_id);cardlists.isShow = true"></i>
<i class="icon ion-checkmark-round" ng-show="cardlists.isShow"></i>
</ion-item>
</ion-list>
</ion-scroll>
</ion-content>
</ion-view>
controller code:
controller('boardCtrl', function ($scope, $http, $cordovaSQLite, $localStorage, $state,$rootScope,$ionicPlatform,$ionicPopup,$timeout,$filter,$ionicNavBarDelegate) {
$rootScope.limit_list=10;
$scope.addMoreItem=function()
{
if($scope.cardlist.length >= $rootScope.limit_list)
{
$rootScope.limit_list+=5;
}
$scope.loadall();
}
$scope.loadall=function()
{
$rootScope.cardlist = [];
var query2 = "SELECT * FROM abc LIMIT "+$rootScope.limit_list;
$cordovaSQLite.execute(db, query2, []).then(function (res) {
if (res.rows.length > 0) {
for (var j = 0; j < res.rows.length; j++) {
var name = res.rows.item(j).name;
$rootScope.cardlist.push({
name: name,
age: res.rows.item(j).age,
card_id: res.rows.item(j).card_id,
avatar: "img/avatar5.png"
});
}
}
}
}
}
I want to display a list whenever view is loaded and its working fine.The only change what i want to make is to display only 10 names by default and once i scroll down the page i want to load 10 more and so on.The above code is working perfectly fine but only in x direction i.e horizontal scroll.I want it load more name once i scroll down side i.e vertical scroll.Can any one tell me what is the issue with above code.It will be helpful.
How to set checked/default radio button value in IONIC?
I have code like below:
<ul>
<li ng-repeat="quest in Questions">
{{quest.question}}
<div ng-repeat="choice in quest.jawaban" ng-init="answer[quest.no]='A'">
<input
type="radio"
ng-model="answer[quest.no]"
ng-value="'{{choice.pil}}~{{choice.jawaban}}'"
name="{{quest.no}}">
{{choice.jawaban}}
</div>
<br>
</li>
</ul>
ng-init="answer[quest.no]='A'"
I need replace 'A' to "selected" value from database simulate like below
$scope.Questions = [{"no":"1","qus_id":"AI1a","question":"Pilih buah kesukaan:","selected":"A","jawaban":[{"pil":"A","jawaban":"Pepaya"},{"pil":"B","jawaban":"Mangga"},{"pil":"C","jawaban":"Pisang"},{"pil":"D","jawaban":"Jambu"}]},{"no":"2","qus_id":"AI1b","question":"Warna Favorit:","selected":"B","jawaban":[{"pil":"A","jawaban":"Merah"},{"pil":"B","jawaban":"Kuning"},{"pil":"C","jawaban":"Hijau"},{"pil":"D","jawaban":"Biru"}]}];
};
To set default/checked radio button.
More details are available at http://play.ionic.io/app/6d698853ef09
just change your input line with the following code.
<input type="radio" ng-model="answer[quest.no]" value="{{choice.pil}}" name="{{quest.no}}">
ng-init="answer[quest.no]='A'"
You are using it wrong, value is actually different than A its A~Merah, so you should use it like
ng-init="answer[quest.no]='A~Merah'"
or best way is
<input type="radio" ng-model="answer[quest.no]" ng-value="'{{choice.pil}}'" name="{{quest.no}}">
In Ionic 2:
Project src directory: src => app => pages => home => home.ts
open home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { AlertController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
num1:number;
num2:number;
sum:string;
// deafult value checked
rdValue:string = "mPlus";
constructor(public alertCtrl: AlertController) {
}
doSum():void {
if(typeof this.num1 !== 'number' || typeof this.num2 !== 'number') {
this.presentAlert();
} else {
var localNum1 = parseInt(this.num1);
var localNum2 = parseInt(this.num2);
//this.sum = parseInt(this.num1) + parseInt(this.num2);
var copyValue = this.rdValue;
switch(copyValue) {
case 'mPlus':
this.sum = localNum1 + localNum2;
break;
case 'mMinus':
this.sum = localNum1 - localNum2;
break;
case 'mMulti':
this.sum = localNum1 * localNum2;
break;
case 'mDivide':
this.sum = localNum2 / localNum1;
break;
}
}
}
presentAlert() {
let alert = this.alertCtrl.create({
title: 'Warnning',
subTitle: 'Only Enter Integer',
buttons: ['OK']
});
alert.present();
}
}
home.html
<ion-header>
<ion-navbar color="primary">
<ion-title>MCalculator</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding="0">
<ion-item>
<ion-label color="primary">Number 1:</ion-label>
<ion-input type="text" placeholder="Enter First Number" [(ngModel)]="num1"></ion-input>
</ion-item>
<ion-item>
<ion-label color="primary">Number 2:</ion-label>
<ion-input type="text" placeholder="Enter Second Number" [(ngModel)]="num2"></ion-input>
</ion-item>
<ion-list radio-group class="btn-margin m-font-size" [(ngModel)]="rdValue">
<ion-list-header>
<p>Arithmetic Options<p>
</ion-list-header>
<ion-item>
<ion-label>Addition</ion-label>
<ion-radio checked="true" value="mPlus"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Subtraction</ion-label>
<ion-radio value="mMinus"></ion-radio>
</ion-item>
<ion-item>
<ion-label>Multiplication</ion-label>
<ion-radio value="mMulti">Multiplication</ion-radio>
</ion-item>
<ion-item>
<ion-label>Addition</ion-label>
<ion-radio value="mDivide"></ion-radio>
</ion-item>
</ion-list>
<ion-item>
<ion-label color="primary">Result:</ion-label>
<ion-input type="text" placeholder="Result" [(ngModel)]="sum"></ion-input>
</ion-item>
<button ion-button full large class="btn-margin" (click)="doSum()">Submit Operation</button>
</ion-content>
<!-- <ion-footer>
<ion-toolbar color="primary">
<ion-title></ion-title>
</ion-toolbar>
</ion-footer> -->
I'm using Ionic with a tabbed interface. Tab 1 has some basic data, Tab 2 has some more detailed data.
I'm using a db insert like this:
$scope.insert = function(date_in, basic_data1, basic_date2, detail1, detail2, detail3) {
db.transaction(function(tx){
tx.executeSql("INSERT OR REPLACE INTO 'stats' (date, age, gender, val1, val2, val3) VALUES (?,?,?,?,?,?)", [date_in, basic_data1, basic_date2, detail1, detail2, detail3);
},function(e){
$log.log("ERROR: " + e.message);
});
}
This works to insert the data from the tab you are on. Here is the ng-click:
ng-click="insert(currentDate, userage, usergender, user_detail1, user_detail2, user_detail3)"
And the form elements:
<label class="item item-input">
<i class="icon ion-clock"></i>
<span class="input-label smalltext"> Age</span>
<input type="number" ng-model="userage">
</label>
I'm looking at the webSQL DB in the Chrome dev console. The insert works, and it overwrites like it should. But it only saves the portion of the DB from the tab you are on.
E.g. If I save from Tab 1 the date, age and gender save. If I save from Tab 2 the date and detail1, 2 and 3 save. This overwrites the other part of the data with "undefined", even thought going back to the other tab shows that the data is still in the fields.
The reason the date works is there is a date picker on both tabs bound to the same model - currentDate.
How can I get the data from both tabs to be handled by my function every time? I never had this issue using jQM...
This is the code in the controller:
.controller('SettingsCtrl', function($scope, $rootScope, $localstorage, $log, $ionicPopup, $ionicActionSheet, $timeout, $cordovaDatePicker) {
$scope.insert = function(date_in, weight_in, heartrate_in, sysbp_in, diabp_in, neck_in, chest_in, biceps_in, waist_in, forearms_in, thighs_in, calves_in) {
console.log(date_in, weight_in, heartrate_in, sysbp_in, diabp_in, neck_in, chest_in, biceps_in, waist_in, forearms_in, thighs_in, calves_in);
db.transaction(function(tx){
tx.executeSql("INSERT OR REPLACE INTO 'stats' (date, weight, heartrate, sysbp, diabp, neck, chest, biceps, waist, forearms, thighs, calves) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", [date_in, weight_in, heartrate_in, sysbp_in, diabp_in, neck_in, chest_in, biceps_in, waist_in, forearms_in, thighs_in, calves_in]);
console.log("The inserted weight is", weight_in);
console.log("The inserted date is", date_in);
console.log("The inserted neck is", neck_in);
console.log("The inserted chest is", chest_in);
},function(e){
$log.log("ERROR: " + e.message);
});
}
$scope.data = {};
$scope.select = function(date) {
db.transaction(function(tx){
tx.executeSql("SELECT date, weight, heartrate, sysbp, diabp, chest, biceps, waist, forearms, thighs, calves FROM stats where date =?", [date, weight, heartrate, sysbp, diabp, chest, biceps, waist, forearms, thighs, calves]);
console.log("The inserted weight is", y);
},function(e){
$log.log("ERROR: " + e.message);
});
}
$scope.usergender = $localstorage.get('storeGender');
$scope.userage = parseInt($localstorage.get('storeAge'));
$scope.userheight = parseInt($localstorage.get('storeHeight'));
$scope.userunits = $localstorage.get('storeUnits');
$scope.userdate = $localstorage.get('storeDate');
$scope.useranalytics = $localstorage.get('storeAnalytics');
$scope.changeVal = function(storeName, val){
$localstorage.set(storeName,val);
console.log(storeName + " is now " + val);
}
// Date converter UK or US //
Date.prototype.dateConvertUK = function() {
function two(n) {
return (n < 10 ? '0' : '') + n;
}
return two(this.getDate()) + '/' + two(this.getMonth() + 1) + '/' + this.getFullYear();
};
Date.prototype.dateConvertUS = function() {
function two(n) {
return (n < 10 ? '0' : '') + n;
}
return two(this.getMonth() + 1) + '/' + two(this.getDate()) + '/' + this.getFullYear();
};
var dateTypeUK = true;
// Set todays date
var d = new Date();
console.log("New Date is", d);
if(dateTypeUK===true){
today = d.dateConvertUK();
console.log("Today (coverted UK) is", today);
}else{
today = d.dateConvertUS();
console.log("Today (coverted US) is", today);
}
$scope.currentDate = today;
//Convert date to string
$scope.dateToString = function(date){
return date.toString();
}
var options = {
date: new Date(),
mode: 'date', // or 'time'
minDate: new Date() - 10000,
allowOldDates: true,
allowFutureDates: false,
doneButtonLabel: 'DONE',
doneButtonColor: '#F2F3F4',
cancelButtonLabel: 'CANCEL',
cancelButtonColor: '#000000'
};
$scope.popupDate = function(){
console.log("in the popup");
$cordovaDatePicker.show(options).then(function(date){
$scope.currentDate = date;
console.log("processed date is", date);
});
}
});
And the code in the html is:
<ion-view view-title="Vitals">
<ion-nav-buttons side="secondary">
<button class="button smalltext" ng-click="popupDate()">
<i class="icon ion-calendar"></i> {{currentDate}}
</button>
</ion-nav-buttons>
<ion-content class="padding" has-bouncing="false">
<div class="list">
<label class="item item-input">
<i class="icon ion-podium"></i>
<span class="input-label smalltext">Weight (<span id="weightunit">kg</span>)</span>
<input type="number" ng-model="data.userweight" placeholder="0">kg
</label>
<div class="item item-button-right smalltext">
Your BMI is: high
<button class="button button-stable button-clear">
<i class="icon ion-help-circled"></i>
</button>
</div>
</div>
<div class="list">
<label class="item item-input">
<i class="icon ion-heart"></i>
<span class="input-label smalltext">Heart Rate (bpm)</span>
<input type="number" ng-model="data.userheartrate" placeholder="0">
</label>
<div class="item item-button-right smalltext">
Your Heart Rate is:
<button class="button button-stable button-clear">
<i class="icon ion-help-circled"></i>
</button>
</div>
</div>
<div class="list">
<div class="item item-divider smalltext">
<i class="icon ion-stats-bars"></i> Blood Pressure
</div>
<div class="row">
<div class="col noPadding">
<label class="item item-input">
<i class="icon ion-arrow-up-b"></i>
<span class="input-label smalltext">Systolic</span>
<input type="number" placeholder="0" ng-model="data.usersysbp">
</label>
</div>
<div class="col noPadding">
<label class="item item-input">
<i class="icon ion-arrow-down-b"></i>
<span class="input-label smalltext">Diastolic</span>
<input type="number" placeholder="0" ng-model="data.userdiabp">
</label>
</div>
</div>
<div class="item item-button-right smalltext">
Your Blood Pressure is:
<button class="button button-stable button-clear">
<i class="icon ion-help-circled"></i>
</button>
</div>
</div>
<button class="button button-mygreen button-full" ng-click="insert(currentDate, data.userweight, data.userheartrate, data.usersysbp, data.userdiabp, data.userneck, data.userchest, data.userbiceps, data.userwaist, data.userforearms, data.userthighs, data.usercalves)">
<i class="icon ion-android-archive"></i> Save
</button>
</ion-content>
</ion-view>
Since each tab is included in an ng-if, each tab creates it's own scope. So each tab only has on it's scope the properties that it has input tags for. When you call the insert method (which I assume is created on the parent scope of the tabs, only the properties that are on the tab will be defined.
To fix, create an object on the same scope as your insert function that holds the data, and modify your inputs on your tabs to reference that data:
So, the controller for the parent of your tabs would be:
.controller('tabmanager', function($scope) {
$scope.insert = function(date_in, basic_data1, basic_date2, detail1, detail2, detail3) {
db.transaction(function(tx){
tx.executeSql("INSERT OR REPLACE INTO 'stats' (date, age, gender, val1, val2, val3) VALUES (?,?,?,?,?,?)", [date_in, basic_data1, basic_date2, detail1, detail2, detail3);
},function(e){
$log.log("ERROR: " + e.message);
});
}
$scope.data = {}; //an empty object to hold your model data in this scope
})
Your markup changes to:
<label class="item item-input">
<i class="icon ion-clock"></i>
<span class="input-label smalltext"> Age</span>
<input type="number" ng-model="data.userage">
</label>
....
....
<button ng-click="insert(data.currentDate, data.userage, data.usergender, data.user_detail1, data.user_detail2, data.user_detail3)">Save</button>
I think basically the issue is that each tab has its own data model, and the data that is defined in another tab is not available to this tab, so when you use gender in tab 2 it is undefined.
I'm pretty new to angular and its conventions but is there anything stopping you from also passing the $rootScope to the controller, like this:
.controller('TabxCtrl', function ($scope, $rootScope) {
and having both tab controllers share this $rootScope?
Then you can just use $rootScope.data to define values that are set in either tab, so that when you do the database INSERT none of the values are undefined.
Not sure how the rest of your application is structured, but you could leverage the
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ ... })
event to make sure you save the latest field values to the $rootScope.data variable before you navigate away from the tab. Or you can just update the $rootScope.data variable whenever any field value is changed or updated.
I have used jQM in the past so I understand how you feel. I'm in the same boat wondering if the advantages outweigh new learning curve lol.
Good luck!
I am writing a small AngularJS/Ionic/Cordova application where I have a list of contacts. When the user taps on a contact, I navigate to a new page where details about the contact are shown (first name, last name, phone number). Here, the user can update details about the contact, or delete the contact. The problem I have is when the user deletes the contact the list still shows the deleted item after navigating back.
Right now I am storing the list of contacts in localStorage, but I do plan on eventually persisting these values in SQLite and/or a web service.
I am using two controllers, two html templates, and a factory. Why is the first list not updating when I make changes to a detail item? I am very new to AngularJS so please bear with me.
List Controller
angular
.module('app')
.controller('contactListCtrl', ['$scope', 'Contacts',
function($scope, Contacts) {
$scope.contacts = Contacts.get();
}
])
List Template
<ion-content scroll="false" class="padding-horizontal" has-header="true">
<div class="row padding-vertical">
<div class="col col-center text-center">
<span class="small-text primary-text-color">Contact List</span>
</div>
</div>
<div class="row" >
<div class="col col-center">
<ul class="list">
<li class="item" ng-repeat="contact in contacts" ui-sref="contactListEdit({id: $index})">
{{contact.fName}} {{contact.lName}}
</li>
</ul>
</div>
</div>
</ion-content>
Detail Controller
angular
.module('app')
.controller('editContactCtrl', ['$scope', '$stateParams', 'Contacts',
function($scope, $stateParams, Contacts) {
var contactId = false;
if ($stateParams.id !== 'undefined') {
contactId = $stateParams.id;
}
$scope.contact = Contacts.get(contactId);
$scope.contactId = contactId;
$scope.delete = function(index) {
Contacts.removeContact(index);
window.history.back();
};
}
])
Detail Template
<ion-content scroll="false" class="padding-horizontal" has-header="true">
<div class="row padding-vertical">
<div class="col col-center text-center">
<span class="medium-text primary-text-color">Edit contact</span>
</div>
</div>
<div class="list">
<label class="item item-input">
<input type="text" placeholder="First Name" ng-model="contact.fName">
</label>
<label class="item item-input">
<input type="text" placeholder="Last Name" ng-model="contact.lName">
</label>
<label class="item item-input">
<input type="text" placeholder="Phone" ng-model="contact.mobile">
</label>
<label class="item item-input">
<input type="text" placeholder="Email" ng-model="contact.email">
</label>
<button ng-click="save()" class="button button-full button-positive">
Save
</button>
<button ng-click="delete(contactId)" class="button button-full button-assertive">
Delete
</button>
</div>
</ion-content>
Contacts Factory
angular
.module('app')
.factory('Contacts', ['$http',
function($http) {
return {
get: function(index) {
var contacts;
try {
contacts = JSON.parse(window.localStorage.getItem("contacts"));
if (index >= 0) {
return contacts[index];
}
return contacts;
} catch (e) {
console.log("error parsing json contacts");
return false;
}
},
removeContact: function (index) {
var contactList = this.get();
if (index !== -1) {
contactList.splice(index, 1);
}
console.log(contactList);
this.saveContacts(contactList);
},
setDefaultContacts: function() {
var self = this;
return $http.get('./mock_data/contacts.json').then(function(response) {
// contacts already exist, don't set.
if (window.localStorage.getItem("contacts")) {
return false;
} else {
self.saveContacts(response.data);
return true;
}
});
},
saveContacts: function(contactList) {
window.localStorage.setItem("contacts", JSON.stringify(contactList));
},
};
}
])
I think you will find that the contactListCtrl is not being setup again when you navigate back to it (after a delete). I believe this is because Ionic caches views for you.
What you need to do is listen to $ionicView.beforeEnter event and load your contacts list into your ContactListCtrl scope whenever you receive this event.
So.. Try adding something like this to your controller:
$scope.$on('$ionicView.beforeEnter', function() {
$scope.contacts = Contacts.get();
}
);
Check out: http://ionicframework.com/blog/navigating-the-changes/