ng-include height displays as 0 in ionic - angularjs

Update:
Using ng-include height is 0. I've provided a totally simplified example below. I need to know how to fix this and make it so the page says Hello.
<ion-view title="Page">
<ion-content padding="true" class="has-header">
<div ng-include="'templates/page30'"></div>
</ion-content>
</ion-view>
Where the templates/page30 file is
<p>Hello</p>
Original Post:
I need to figure out how to get my ng-include to be shown within an ng-switch. Currently the code does not work. Two things aren't happening as expected. The outer button is way small and the ng-included sub-forms are not showing as their height is 0. Please keep in mind I am using Ionic which means I do not have access to *.height().
NOTE: I'm only showing step 1 of the ng-switch otherwise this would be too bulky.
<ion-view title="Some Template" hide-nav-bar="true">
<ion-content padding="true" class="has-header">
<div ng-controller="someCtrl">
<ng-switch on="step">
<div ng-switch-when="1">
<div height-bind height-value="containerHeight">
<ng-include src="'templates/somepage.html'"></ng-include>
</div>
</div>
</ng-switch>
</div>
</ion-content>
</ion-view>
I have built a directive that looks like the following:
llApp.directive('heightBind', function() {
return {
scope: {
heightValue: '='
},
link: function($scope, $element) {
$scope.$watch(function() {
$scope.heightValue = $element.prop('offsetHeight');
});
}
}
});
The template called by ng-include is the following:
<ion-view title="Services" hide-nav-bar="true">
<ion-content padding="true" class="has-header">
<div class="page-header">
<h1>
<span>Lawncare</span>Services</h1>
</div>
<ul class="list">
<li class="item item-checkbox">
Mow Lawn
<label class="checkbox">
<input type="checkbox">
</label>
</li>
<li class="item item-checkbox">
Trim Plants
<label class="checkbox">
<input type="checkbox">
</label>
</li>
</ul>
</ion-content>
</ion-view>
One last thing. The controller someCtrl looks like the following: (actual controller reference is missing because I'm currently working within ionic creator)
function($scope, $stateParams) {
// Set the step initially to 1 every time this controllwer is instantiated.
// Usually on ng-switch button update the
// step value via the setStep function provided
$scope.step = 1;
$scope.setStep = function(step) {
$scope.step = step;
}
$scope.containerHeight = 0;
}
Some of the other things I've looked at to solve this. I have looked at:
http://stackoverflow.com/questions/25108780/height-of-container-with-ng-repeat-directive-is-zero
As well as this plunker:
Plunker

You are setting the height to 0 in the controller:
$scope.containerHeight = 0;

Related

How to clear input field onclick?

I have done a lot to fix this, but it's not working. I am using Ionic's searchbar.
My input field gets the class ng-empty when nothing is filled in (so this is the default state). The input field gets a ng-not-empty class when it's filled in.
So, I could fix this with jQuery or something, but I saw that Angular has ways to do this. This is the HTML:
<ion-view view-title="Testing">
<ion-header-bar align-title="center" class="bar">
</ion-header-bar>
<ion-content class="scrollBar">
<ion-searchbar class="searchBar" ng-app="myApp">
<label>
<input class="searchField" type="search" ng-model="itemsSearch"/>
<a class="clear" data-ng-click="saveParentComment()">X</a>
<i class="icon ion-search placeholder-icon"></i>
</label>
</ion-searchbar>
</ion-content>
</ion-view>
I've added this to my controller:
myApp.controller('SearchController', function ($http, $scope, $state) {
$scope.saveParentComment = function () {
$scope.itemsSearch = "";
};
Yet, this is not working and I don't get why. Am I doing something wrong? If so, how can I fix it? I have seen a lot of questions regarding this one, but no answer worked for me. I don't see any errors in the console either...
The only thing I see, is that the anchor gets a new class "activated" when I click on it.
In the angular,every directive create new scope.
itemsSearch is bind to the directive scope and its not visible to controller.
Use it as part of object defined on $scope in controller.
myApp.controller('SearchController', function ($http, $scope, $state) {
$scope.objItem = {itemsSearch : ""};
$scope.saveParentComment = function () {
$scope.objItem.itemsSearch = "";
};
HTML :
<input class="searchField" type="search" ng-model="objItem.itemsSearch"/>
Try this out :-
<input type="text" class="form-control" data-ng-model="searchAll"></input>
<a class="clear" href="" data-ng-click="clearSearch()">X</a>
app.controller("SearchController", function ($scope) {
$scope.searchAll = "";
$scope.clearSearch = function () {
$scope.searchAll = "";
};
});
I don't see anywhere in your view you have put SearchController Also ng-model should work with a dot operator
Try,
<ion-view view-title="Testing" ng-app="myApp" ng-controller="SearchController">
<ion-header-bar align-title="center" class="bar">
</ion-header-bar>
<ion-content class="scrollBar">
<ion-searchbar class="searchBar">
<label>
<input class="searchField" type="search" ng-model="myObj.itemsSearch"/>
<a class="clear" data-ng-click="saveParentComment()">X</a>
<i class="icon ion-search placeholder-icon"></i>
</label>
</ion-searchbar>
</ion-content>
</ion-view>
In controller:
myApp.controller('SearchController', function ($http, $scope, $state) {
$scope.myObj = {};
$scope.saveParentComment = function () {
$scope.myObj.itemsSearch = "";
};
Can you please make sure that you put SearchController,
Can you please try with this
<ion-view view-title="Testing" ng-app="myApp" ng-controller="SearchController">
<ion-header-bar align-title="center" class="bar">
</ion-header-bar>
<ion-content class="scrollBar">
<ion-searchbar class="searchBar">
<label>
<input class="searchField" type="search" ng-model="itemsSearch"/>
<a class="clear" data-ng-click="saveParentComment()">X</a>
<i class="icon ion-search placeholder-icon"></i>
</label>
</ion-searchbar>
</ion-content>
And Function:
$scope.saveParentComment = function () {
console.log("clear");
$scope.itemsSearch = null;
};
If you see clear in console log than you are sure that your function is working fine. And you can set initial value also in controller like for itemSearch like.
$scope.itemsSearch = "Search Here";
I think there is a problem with your controller. First try in console for function is working or not
$scope.saveParentComment = function () {
console.log("working");
};

localStorage AngularJS does not save anything

I want to create a text area where if i add some text and click on save, the text should be saved in localStorage. So if i open the text area again, i can see it still there.
HTML
<ion-view view-title="CWIN 2016 - Votre avis">
<ion-content>
<div class="list card user-infos-card">
<div class="item aw-dark-blue"> <h2 class="activity-name"></h2> Notes</div>
<textarea ng-model="note" rows="20" cols="50"></textarea>
<div class="item tabs tabs-secondary tabs-icon-left aw-dark-blue" ng-click="saveNote()" ng-model="note">Enregistrer vos notes</div>
<div ng-show="error">
<p class="form-error-message">Veuillez saisir des notes</p>
</div>
</div>
</ion-content>
</ion-view>
JS
angular.module('companion.noteBookController', ['LocalStorageModule'])
.controller('noteBookController', function ($scope, localStorageService){
$scope.note=localStorageService.get('note');
$scope.saveNote=function() {
localStorageService.set('note', $scope.note);
}
});
I don't underdstand the problem. Besides I don't have any errors.
Change this line
<div class="item tabs tabs-secondary tabs-icon-left aw-dark-blue" ng-click="saveNote(note)">Enregistrer vos notes</div>
and in js
angular.module('companion.noteBookController', ['$localStorage'])
.controller('noteBookController', function ($scope, $localStorage){
$scope.saveNote=function(note_val) {
console.log(note_val);
$localStorage.note = note_val;
}
});
if you want to get value then you can use this
var my_note = $localStorage.note;

bind controller on dynamic HTML

I have a HTML page with different sections, which are loaded with AJAX. I have created a controller for each of the sections.
How is possible to bind the controller on a section which has been dynamically added on HTML?
I have found very complicated solutions, which i don't even know if they apply.
I need the most basic, easiest solution, something similiar with ko.applyBindings($dom[0], viewModel) for the ones who worked with KnockoutJs.
Index html
<div class="row" ng-app="app">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li>
Profile
</li>
</ul>
</div>
<div class="col-xs-9">
<div id="container"><!-- load dynamic HTML here --></div>
</div>
</div>
Dynamic HTML
<div ng-controller="profile">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
Javascript:
var app = angular.module('app', []);
app.controller('profile', function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
// load new HTML
// normally this is triggered by a link / button
$(function () {
$.get("/EditProfile/Profile", function (data, status) {
$("#container").html(data);
});
});
Don't use jQuery to embed html to your container. If you use jQuery, AngularJS can't track DOM manipulations and trigger directives. You can use ng-include directive of AngularJS.
In index.html file:
...
<div id="container">
<div ng-include="'/EditProfile/Profile'"></div>
</div>
...
If you want you can make that conditional:
...
<div id="container">
<div ng-if="profilePage" ng-include="'/EditProfile/Profile'"></div>
</div>
...
With that example, if you set profilePage variable to true, profile html will be load and render by ng-include.
For detailed info take a look to ngInclude documentation.
By the way, best practice to include views to your layout by triggering same link clicks is using routers. You can use Angular's ngRoute module or uiRouter as another popular one.
If you use ngRoute module, your index.html looks like that:
<div class="row" ng-app="app">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li>
Profile
</li>
</ul>
</div>
<div class="col-xs-9">
<div id="container" ng-view><!-- load dynamic HTML here --></div>
</div>
</div>
And with a router configuration like below, profile html will be automatically loaded and rendered by ngRoute inside ngView directive:
angular.module('myapp', []).config(function($routeProvider) {
$routeProvider
.when('/profile', {
templateUrl: '/EditProfile/Profile',
controller: 'ProfileController'
});
});

Angular scope confusion across templates

I started using Angular and Ionic recently and sounds like I am missing something basic about scope that should be obvious but don't understand what that is.
I have two Ionic templates/pages. The corresponding states belong to the same controller and both display a list. The states are defined as below
.state('app.group', {
url: '/group',
views: {
'menuContent':{
templateUrl: 'templates/group.html',
controller: 'GroupController',
}
},
onEnter: function($){
console.log("Entered Group State");
}
})
.state('app.search', {
url: '/pickGroup',
views: {
'menuContent':{
templateUrl: 'templates/groups/pickGroup.html',
controller: 'GroupController' }
},
onEnter: function(){
console.log("Entered Pick Group State");
}
})
The first template is
<ion-view title="My Groups">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-nav-buttons side="right">
<button class="right button button-icon icon ion-plus" ng-click="pickGroup()"></button>
</ion-nav-buttons>
<ion-content>
<div class="list card">
<span>My Group Names</span>
<div ng-repeat="item in list" class="item">
{{item.name}}
</div>
</div>
</ion-content>
</ion-view>
And the second template is
<ion-view title="Pick Groups">
<ion-nav-buttons side="secondary">
<button class="right button button-positive" ng-click="gotoCreateGroup()">Create Group</button>
</ion-nav-buttons>
<ion-content has-header="true">
<span>In Pick Group</span>
<div class="list card">
<span>Groups In My Viscinity </span>
<input type="text" ng-model="searchTxt.name" placeholder="Enter Group Name to Search">
<div ng-repeat="item in list | filter:searchTxt" class="item">
{{item.name}}
</div>
</div>
</ion-content>
</ion-view>
The controller has the following code
$scope.list = [
{name:"G1-1"},
{name:"G1-2"},
{name:"G1-3"}
];
$scope.pickGroup = function(){
$scope.list = [ {name:"G2-1"},
{name:"G2-2"},
{name:"G2-3"}
];
$location.path("/app/pickGroup");
console.log('PickGroup called');
}
When the first template loads the G1 groups show up as expected. When I click on the button in first template that calls pickGroup to go to the second template with updated groups, the G2 groups replace G1 groups in template one before the transition and the second template shows up but with G1 groups. When I go back to the first template through the back button the G2 groups are there.
I was expecting the G2 groups to show up in second template as well since I am updating the $scope.list in the pickgroup function but for some reason they don't. Sounds like I don't fully understand the scope here.
Appreciate your helping me understand this better.
Thanks,
Sanjay.
When u switch to state 'app.search', angular will re-create a instance of controller, the scope you defined is new one, so you can't get the list data which init in state 'app.group'.
if u want share data, u can use 'Service'.

How to insert a variable has html to ionic & angular template file?

I have an ionic & angular based project. I get variable node from a service. node's body value is HTML. But when I print {{node.body.und[0].value}} with ionic, it prints HTML codes with tags like <ul><li><strong>Title:</strong> some text</li><ul>
Controller and service part of the code:
.controller('NodeCtrl', function($scope, $stateParams, Node) {
$scope.node = Node.get({nid: $stateParams.nid});
});
.factory('Node', function ($resource) {
return $resource('some-domain.com/api/node/:nid'+'.json');
})
Ionic template:
<ion-view view-title="{{node.title}}">
<ion-content>
<div class="list card">
<div class="item">
<h2>{{node.title}}</h2>
</div>
<div class="item item-body">
{{node.body.und[0].value}}
</div>
</div>
</ion-content>
</ion-view>
How can I make ionic print {{node.body.und[0].value}} as HTML instead of with HTML tags like <ul><li><strong>Title:</strong> some text</li><ul>?
All Credits to Will.Harris!!
ng-bind-html, is what you are looking for.
From the Docs, use the ng-bind-html in the view as:
<div ng-controller="ExampleController">
<p ng-bind-html="myHTML"></p>
</div>
and in the controller, assign the scope variable with the html content as:
angular.module('bindHtmlExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', function($scope) {
$scope.myHTML =
'I am an <code>HTML</code>string with ' +
'links! and other <em>stuff</em>';
}]);

Resources