ion-content won't resize when keyboard appears - angularjs

I have an application with a chat functionality which works great, except for one part, when the keyboard appears, the ion-content won't resize to a proper height, so I am stuck when I want to scroll to the top and the header disappears completely. The view has a header, content and footer and what I want is the footer to appear above the keyboard and the content to resize so it fits between the header and the footer-bar. The view I have created is as followed:
<ion-view id="userMessagesView" cache-view="true" flow-init flow-name="imageTemp.imageTemp" ng-if="!inChatSettings">
<div class="loader-center" ng-if="!doneLoading">
<div class="loader">
<i class="icon ion-loading-c"></i>
</div>
</div>
<div class="loader-center" ng-if="errorLoading">
<div class="loader">{{'error_loading_messages'|translate}}</div>
</div>
<ion-content class="has-header has-footer" has-bouncing="true" delegate-handle="userMessageScroll" style="background:red;">
<ion-refresher pulling-text="{{'pull_load_earlier'|translate}}" on-refresh="loadMore()"></ion-refresher>
<div ng-repeat="message in messageThread.messages | orderBy : 'postDate'" class="message-wrapper">
<div class="chat-bubble" ng-class="{ false: 'left', true:'right'}[{{message.postedBy|isCurrentUser}}]">
<div class="message-detail">
<span class="bold">{{message.postedBy.name}}</span>
</div>
<div class="message" ng-bind-html="message.message | nl2br" autolinker></div>
<img ng-src="{{message.imageUrl}}" ng-if="message.imageUrl"/>
<small am-time-ago="message.postDate">{{message.postDate|timeago}}</small>
</div>
<div class="cf"></div>
</div>
</ion-content>
<ion-footer-bar class="bar-light message-footer">
<button class="button button-icon icon icon-upload" flow-btn flow-file-added="imageUploaded($file)" flow-name="imageTemp.imageUrlTemp"></button>
<label class="item-input-wrapper" for="newmessage">
<textarea focus-me="input.focusInput" id="newmessage" ng-model="input.message" value="" required minlength="1" maxlength="1500" msd-elastic></textarea>
</label>
<button class="button button-clear" type="submit" ng-disabled="!input.message || input.message === ''" ng-click="sendMessage()" translate="send"></button>
</ion-footer-bar>
</ion-view>
I tried adding the keyboard-attach attribute to the ion-footer-bar, but the footer only gets bigger when I add this. Plus the footer already stays on top of the keyboard, so it appears unneeded. I have the following situation, it also appears that when I type something, the view goes up a little more.
This is when the keyboard is shown:
This is when the keyboard is hidden:
Does any of you know how to resize the ion-content to a normal height when the keyboard appears?

I have tried some things and the problem seemed to disappear, yet I don't think the solution is the right one or if this is actually the thing what solved the issue. So if anyone got a better solution, please share. First thing I had to do was including the Ionic keyboard plugin to get events based on the keyboard.
Inside the CSS, I have added:
.message-footer { min-height: 44px; }
Inside my controller I added the following code:
$scope.$on('taResize', function (e, ta) {
if(!ta || !footerBar) return;
var taHeight = ta[0].offsetHeight + 10;
var newHeight = (taHeight < 44) ? 44 : taHeight;
scroller.style.bottom = newHeight + 'px';
footerBar.style.height = newHeight + 'px';
});

Related

Angular Material swipe gesture works hardly

I am trying to add swipe functionality to a ng-repeated list of elements. However, the swiping works badly. Sometimes a swipe gestures (all on desktop) is recognized, but most of the times I'm click and swiping like a madman to achieve the expected result.
I am using Material Angular.
Code:
<div ng-repeat="link in Links | filter: { category: 'quick' }">
<div ng-show="!link.show" md-swipe-left="link.show = true">
<div class="lv-item ">
<span href="{{link.url}}" class="no-select" target="_blank" >
<div class="lv-title" class="no-select">{{link.title}}</div>
<small class="lv-small" class="no-select">{{link.description}}</small>
</span>
</div>
</div>
<div ng-show="link.show" md-swipe-right="link.show = false">
<div class="lv-item delete" >
<button ng-click="deleteLink(link.id)">Verwijder</button>
</div>
</div>
</div>
On the Angular Material swipe docpage (https://material.angularjs.org/latest/demo/swipe) it seems easy and it works like a charm. However my implementation of the directive doesn't seem to work as it should. It rather lets me select the text inside the element than swiping.
Also, I'd rather want the span to be a a href, but this only lets me drag the whole element out of space.
I believe that to assure a proper work of all material function you should use their containers and directives instead. So you should put all of that inside a md-content, and also use ng-ifs instead of ng-show on the swiped div. Which would result in something like that :
<md-content>
<div ng-repeat="link in Links | filter: { category: 'quick' }">
<div ng-if="!link.show" md-swipe-left="link.show = true">
<div class="lv-item ">
<span href="{{link.url}}" class="no-select" target="_blank" >
<div class="lv-title" class="no-select">{{link.title}}</div>
<small class="lv-small" class="no-select">{{link.description}}</small>
</span>
</div>
</div>
<div ng-if="link.show" md-swipe-right="link.show = false">
<div class="lv-item delete" >
<button ng-click="deleteLink(link.id)">Verwijder</button>
</div>
</div>
</div>
</md-content>
I used this kind of code snippet on some md-sidenav and it works. By the way, if you're using chrome and use mobile view, the md-swipe-left is always triggered, doesn't matter if you swipe left, right, top or bottom.
Hope this helps

How to pass parameter to another screen with ionic 1 and angular 1?

I created a multi-button screen much like this:
When I click on a button it would have an id and that id I get on its route, I did with list already, but several buttons passing parameter I still can not.
My question is how to pass that button id to another screen.
Avisos.html
<ion-view view-title="Avisos">
<ion-content style="background-color: #FF4500; background-size: cover;
background-position: center;">
<div class="row icon-row">
<div class="col text-center">
<button class="botao button button-positive" id="1">Icon</button>
<br>mais informaƧoes
</div>
<div class="col text-center">
<button class="botao button button-positive" id="2">Icon</button>
<br>Avisos
</div>
<div class="col text-center ">
<button class="botao button button-positive" id="3">Icon</button>
<br>Contato
</div>
</div>
</ion-content>
</ion-view>
In that part is where I get the id, How can I get in that part the id of the chosen button? And pass it on side.id?
site.html
<ion-view view-title="Site">
<ion-content>
<ion-list>
<ion-item ng-repeat="site in sites" href="#/app/conteudoDoSite/{{site.id}}">
<span ng-bind-html="site.title"></span><span class="badge badge-assertive">{{site.post_count}}</span>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
How to pass parameter to another screen with ionic1 and angular1? Can anybody help me? What I am trying to do is that when the user clicks one of these buttons the id is passed.
I would recommend using ui-sref instead of href in this situation as it allows you to use states instead of paths and also allows you to pass variables to the next view. Here is an example:
<ion-item ng-repeat="site in sites" href="app.conteudoDoSite({id: site.id})">
You also need to make sure that the state you are trying to pass the variable to is configured to receive parameters. Which would look something like this:
.state('app.conteudoDoSite', {
url: '/conteudoDoSite/:id',
templateUrl: '/* Fill in */',
controller: '/* Fill in */'
})
I attempted to guess the state by looking at your code, but please make sure that it is correct, before copying the examples.

Ionic switch between 2 footers

I have this in the footer :
<div class="bar bar-footer bar-assertive" ng-show="withdarawStatus">
<button class="button button-assertive" id="applyButton" ng-click="withdraw()">
Successfully Applied! Withdraw?
</button>
</div>
<div class="bar bar-footer bar-positive" ng-show="!withdarawStatus" >
<p id="applyButton" >Application Withdrawn</p>
</div>
I want to write a function that when I click withdraw() the footer changes to "Application Withdraw" footer.
I tried this but it didn't work, unless i reload the entire page.
$scope.withdraw = function() {
$scope.withdrawStatus = true;
}
You have a typo in your HTML ng-show="!withdarawStatus" should be ng-show="!withdrawStatus". That should fix the issue.
Edit: Here's a working codepen

ionic scroll: Prevent translate3d on parent element

I have template in my ionic app that looks something like this:
<ion-view>
<ion-content>
<div class="nav">
<span class="ion-chevron-left" ng-click="goToMonth('thisMonth', $event)"></span>
<span>{{ monthName }}</span>
<span class="ion-chevron-right" ng-click="goToMonth('nextMonth', $event)"></span>
</div>
<ion-scroll on-scroll="onScroll()" class="wide-as-needed" delegate-handle="calendarScroll" direction="x" paging="true" scrollbar-x="false" style="min-height: 215px" ng-style="scrollStyle">
...
the div with the class 'nav' contains two buttons that let the user switch between two months. The months are in the <ion-scroll> element.
This works as it should. The buttons scroll the <ion-scrol> element horizontally. But every time the buttons are used, the entire <ion-view> is scrolled vertically down by 20px - thus hiding the buttons.
I've tried changing the <ion-scroll>s inline css (with angular.element) to not include 3d transforms, but they just get re-added.
This is the function that gets called upon click - and my attempt to prevent the transform3d on the parent element
$scope.goToMonth = function(id, event){
$location.hash(id);
if(id == 'thisMonth'){
$scope.monthName = monthLabels[thisMonth];
}
else{
$scope.monthName = monthLabels[nextMonth];
}
var elm = angular.element(document.querySelector('.nav'));
var parent = angular.element(elm.parent());
console.log(parent[0].style.transform);
parent[0].style.transform = 'none';
$ionicScrollDelegate.anchorScroll(true);
};
EDIT: I've also tried using event.stopPropagation - this breaks the functionality of the <ion-scroll> element
Can anyone tell me how to prevent this behaviour?
Silly me. It turns out this was very simple to solve. I simply just needed to add scroll="false" to the <ion-content> element. No additional controller logic was needed.
So the html code above now looks like this:
<ion-view>
<ion-content scroll="false">// <-- Here I altered the html
<div class="nav">
<span class="ion-chevron-left" ng-click="goToMonth('thisMonth', $event)"></span>
<span>{{ monthName }}</span>
<span class="ion-chevron-right" ng-click="goToMonth('nextMonth', $event)"></span>
</div>
<ion-scroll on-scroll="onScroll()" class="wide-as-needed" delegate-handle="calendarScroll" direction="x" paging="true" scrollbar-x="false" style="min-height: 215px" ng-style="scrollStyle">
...

How can I generate title dynamically on ionic framework?

I use ionic pet template.
I have a question about pet-detail page, if I would like to have a dynamic title on header, it will not show anything until I reload the page (using web browser), but I think it doesn't make sense since I would like to make an app.
Does I miss anything? what can I do?
here is my code as below:
<ion-nav-bar class="bar-positive">
<div class="buttons" ng-controller="BackCtrl">
<a class="button button-icon icon ion-chevron-left" ng-click="$back()"></a>
</div>
<h1 class="title"> {{ current_pet.name }} </h1>
..
If you happen to be using ion-view, use this:
<ion-nav-title>
{{ PageTitle }}
</ion-nav-title>
And put it outside your ion-content.
In my app I've used this:
<ion-view title="{{Properties.Title}}">
Where Properties is a object on my scope(I have sort of a master controller) where I "override" on each "inner controller".
If you are using and you want to show a button in the header bar only when an input/textarea is filled (not empty), then you can do the following.
<ion-header-bar class="bar-light">
<h1 class="title">{{$root.Title}}</h1>
<div class="buttons">
<button class="button button-clear icon ion-checkmark-round" ng-click="" ng-if="$root.Title"></button>
</div>
</ion-header-bar>
and inside "ion-content" -
<div class="row>
<textarea placeholder="" rows="3" maxlength="100" ng-model="$root.Title" ng-trim="false"></textarea>
</div>
Otherwise just using ng-if="Title" in the header bar will not work.

Resources