OnsenUI : Tabbar with badger notification - onsen-ui

I have this:
<ons-tabbar var="tabbar">
<ons-tabbar-item icon="search" label="Buscar" page="page2.html" active="true"><div class="badge-notification"><span class="notification">1</span></div></ons-tabbar-item>
<ons-tabbar-item icon="star-o" label="Revisões" page="page2.html">XXXXXXX<span class="notification">9</span></ons-tabbar-item>
<ons-tabbar-item icon="tag" label="Combinações" page="page2.html"><span class="notification">9</span></ons-tabbar-item>
<ons-tabbar-item icon="comments" label="Conversas" page="page2.html"><span class="notification">9</span></ons-tabbar-item> </ons-tabbar>
How I can put a badge-notification working? Like show (1) upside the button "Search"?... I can make this in CSS... But, i lost the use of tab-bar...
<div class="tab-bar">
<label class="tab-bar__item">
<input type="radio" name="tab-bar-screen2" data-role="none" checked>
<button class="tab-bar__button" data-role="none" >
<i class="tab-bar__icon fa fa-4x fa-search"></i>
<div class="tab-bar__label">Buscar</div>
</button>
</label>
<label class="tab-bar__item">
<input type="radio" name="tab-bar-screen2" data-role="none">
<button class="tab-bar__button" data-role="none" >
<i class="tab-bar__icon fa fa-4x fa-star-o"></i>
<div class="tab-bar__label">Revisões</div>
<span class="notification">8</span>
</button>
</label>
<label class="tab-bar__item">
<input type="radio" name="tab-bar-screen2" data-role="none">
<button class="tab-bar__button" data-role="none" >
<i class="tab-bar__icon fa fa-4x fa-tag"></i>
<div class="tab-bar__label">Combinações</div>
<span class="notification">9</span>
</button>
</label>
<label class="tab-bar__item">
<input type="radio" name="tab-bar-screen2" data-role="none" >
<button class="tab-bar__button" data-role="none" >
<i class="tab-bar__icon fa fa-4x fa-comments"></i>
<div class="tab-bar__label">Bate-Papo</div>
<span class="notification">10</span>
</button>
</label>
</div>
Anyone know too where I can find a good documentation?

Unfortunately, you cannot add badge to the tab item for the current version of OnsenUI. We will consider putting this in the next release.
However, it's possible if you use the CSS as shown in ur code above. But you can't use the function and transition of the OnsenUI framework anymore since now it's just simply OnsenUI CSS components. Therefore, you will need to write your own necessary function using JavaScript.

It's been a while since you posted your question, but since I recently had to deal with the exact same problem, here's my solution.
Onsen modifies the DOM for each ons-tab element. So, simple DOM modification (jQuery or not) didn't work because I couldn't reliably detect when the tabbar has been completely initialized.
What I did is I created a controller that sets up a function to execute every second (changeNotifications). In this function I add the notification once I have detected that tab bar has been initialized.
This is my index.html file:
<body ng-controller="MainCtrl">
<ons-tabbar var="tabbar" modifier="ios">
<ons-tab icon="ion-email" id="inbox-tab" label="{{ 'Inbox' | translate }}" page="inbox.html" active="true">
<!-- more tabs -->
</body>
In MainCtrl.js I have my "main" controller"
function _MainCtrl($scope,) {
function changeNotifications() {
var inboxTab = $('#inbox-tab');
if (!inboxTab.length) {
return; // not initialized yet
}
var notif = $('#inbox-notification');
if (!notif.length) {
$('#inbox-tab > button').append(
$('<div class="notification tabbar-notification" id="inbox-notification">5</div>'));
notif = $('#inbox-notification');
}
var numWhatever = 5;
if (numWhatever == 0) {
notif.remove();
} else {
notif.text(numWhatever);
}
}
function initNotifications() {
ons.ready(function() {
setInterval(changeNotifications, 1000);
});
}
initNotifications();
}
In addition to Onsen's notification style, I am adding the following by means of the tabbar-notification CSS class:
.tabbar-notification {
position: absolute;
margin-left: 10px;
margin-top: -44px;
min-width: 16px;
font-size: 16px;
line-height: 16px;
height: 16px;
}

Related

Tooltip for each option of dropdown

I want to show the tooltip for each option of using react-tooltip, I have tried below code which is working fine to show tooltip on mouseover, but on keydown and keyup arrow it not works because the focus never come to inner child div, which I have created as below...
Here, I updating options with tooltip div
updatedOptions = updatedOptions.map((option) => {
return {
value: option.value,
label: (
<>
<ReactTooltip
role="tooltip"
className="cb-select-tooltip"
type="info"
place="right"
effect="solid"
id={option?.value}
/>
<div
data-for={option?.value}
data-tip={option?.tooltipContent}
data-event="mouseover focus"
data-event-off="mouseout blur"
aria-label="option"
className="select-option"
ref={this.selectOption}
role="button"
tabIndex="0"
>
{option?.label}
</div>
</>
),
};
});
There is always a parent div creted,
`
<div role="listbox" id="react-select-2-menulist">
<div class="select__option css-3dmylm-option" id="react-select-2-option-0" tabindex="-1">
<div class="__react_component_tooltip place-right type-dark " id="" role="tooltip" data-id="tooltip"></div>
<div
data-for=""
data-event="mouseover focus keydown"
data-event-off="mouseout blur keyup"
aria-label="option"
role="button"
tabindex="0"
class="select-option"
></div>
</div>
<div class=select__option css-3dmylm-option" id="react-select-2-option-1" tabindex="-1">
<div
class="__react_component_tooltip place-right type-info select-tooltip"
id="<"
role="tooltip"
data-id="tooltip"
style="left: 270px; top: 174px;"
>
Less than
</div>
<div
data-for="<"
data-tip="Less than"
data-event="mouseover focus keydown"
data-event-off="mouseout blur keyup"
aria-label="option"
role="button"
tabindex="0"
class="select-option"
>
<
</div>
</div>
`
my question is, can we have control on that outer div HTML, while modifying option.
Or please suggest if I'm following wrong approach.

'ng-repeat' re rendering creates a flicker

I am using ng-repeat to list all the "zones". It works just fine on the first rendering and even when additional data from the server is added to the existing data it works without any issues or flickers. But when the "$rootScope.zones" is assigned a new value (the user can change the sort order from Alphabetical to Proximity, which sets a new value for the $rootScope.zones in that sorting order) the whole ng-repeat list goes blank for a few seconds and then works fine again.
This is not a very big issue except in the zones I have some text with CSS bubbles around. The text disappears but the bubbles remain.
How can I set the $rootScope.zones such that it doesn't create that flicker? Alternatively, how can I make sure that the "bubbles" only appear when the text is there.
This is my ng-repeat:
<ion-list class="card" ng-if="$root.currentMode.zoneBroadcast == true" can-swipe="true">
<div class="button-bar no-padding">
<button class="button bold" ng-class="{'button-calm': sortMethod === 'Alphabetically'}" ng-click="changeSortMethod('Alphabetically')">Alphabetically</button>
<button class="button bold" ng-class="{'button-calm': sortMethod === 'By Proximity'}" ng-click="changeSortMethod('By Proximity')">By Proximity</button>
</div>
<ion-item class="item no-border no-padding dark-bg" ng-repeat="zone in $root.zones track by zone.zoneName"
ng-if="checkVisibility(zone.zoneName)">
<div class="item-divider text-center">
<span>
Zone ID : <span>{{zone.zoneName}}</span>
</span>
</div>
<div class="item-body" ng-class="checkIfZoneMatches(zone.zoneName) ? 'zone-broadcast-green' : parseStringToInteger(zone.Trips.length) > 0 ? 'zone-broadcast-red' : checkIfZoneCanBookIn(zone.zoneName) ? 'zone-broadcast-yellow' : zone.Lineup.FreeList.length > 0 ? 'zone-broadcast-blue' : 'zone-broadcast-normal'">
<div class="row">
<div class="col">
<span ng-class="{'lineup free' : zone.Lineup.FreeList.length != 0}">{{zone.Lineup.FreeList.toString()}}</span>
<span ng-class="{'lineup loaded' : zone.Lineup.LoadedList.length != 0}">{{zone.Lineup.LoadedList.toString()}}</span>
<span ng-class="{'lineup accepted' : zone.Lineup.AcceptedList.length != 0}">{{zone.Lineup.AcceptedList.toString()}}</span>
<span ng-class="{'lineup offered' : zone.Lineup.OfferedList.length != 0}">{{zone.Lineup.OfferedList.toString()}}</span>
<span ng-class="{'lineup break' : zone.Lineup.BreakList.length != 0}">{{zone.Lineup.BreakList.toString()}}</span>
<span ng-class="{'lineup stc' : zone.Lineup.STCList.length != 0}">{{zone.Lineup.STCList.toString()}}</span>
</div>
</div> ...
I have tried ng-if, ng-hide, track by, etc. but nothing seems to work.
Here's the CSS I am using to create the bubbles.
.lineup{
background: white;
border-radius: 2em;
font-weight: bold;
font-size: 100%;
padding: 1%;
}
.free {
color: #00b140;
}
.loaded{
color: #6b46e5;
}
.accepted{
color: #0a9dc7;
}
.offered{
color: deeppink;
}
.break{
color: orangered;
}
.STC{
color: saddlebrown;
}
I expect the bubbles to appear only when the text is there. Moreover, when the sort order is changed by the user it should not go blank for over 2 seconds then render the template.
I would really appreciate your help.
Instead of using ng-if with ng-repeat, pipe to a filter:
SLOW
<ion-item class="item no-border no-padding dark-bg"
ng-repeat="zone in $root.zones track by zone.zoneName"
ng-if="checkVisibility(zone.zoneName)">
Faster
<ion-item class="item no-border no-padding dark-bg"
ng-repeat="zone in zones | filter : zoneFilter track by zone.zoneName">
$scope.zoneFilter = function(item) {
return $scope.checkVisibility(item);
};
For more information, see
AngularJS filter API Reference
Changing
zone.Lineup.FreeList.length != 0 to zone.Lineup.FreeList.length > 0 solved the bubble problem.

is there a way to place material icon as input background?

Is there a way to place material icon in an input filed as background at the right?
I know I can place an image as input filed background but material icons are not images and I think these are created by fonts.
this is what I am trying but no luck
<input type="search" class="global-search"
ng-model="vm.searchText"
ng-keyup="$event.keyCode == 13 ? vm.search() : null"
placeholder="I can help you to find anything you want!"/>
<a ng-click="vm.search()">
<i class="material-icons global-search-icon"></i> <!--search-->
</a>
the icon <i class="material-icons global-search-icon"></i> need to be the background image of <input type='text'/>
You can wrap your input and icon in a div:
<div id="divWrapper">
<input type="search" class="global-search"
ng-model="vm.searchText"
ng-keyup="$event.keyCode == 13 ? vm.search() : null"
placeholder="I can help you to find anything you want!"/>
<i class="material-icons global-search-icon"></i>
</div>
And add this styles:
#divWrapper{
display:inline;
position: relative;
}
#divWrapper i {
position: absolute;
left: 0;
}
.global-search:focus + i{
display: none;
}

ng-click first apply class, then execute function

I have a shopping cart (a rootScope array) which gets turned into a list of items in it, including a button to delete that item from the cart array (the red X).
I don't have enough reputation to add an image, so here's a link to what it looks like
What I want to have happen is when I click one of the red X buttons, the item first does an animation(some sort of fade out), and then the actual cart has the item spliced from it. Using ng-click I am able to either do one or the other, but not both. When both is applied the animation doesn't trigger because it doesn't have time to. Is there a way to wait for the animation to finish, then perform the function?
(the animation executed by applying a class to the div on ng-click, so possibly a watch for class change?)
Here's my code. The code won't work in the snippet but you can see my functions and html.
$scope.removeFromCart = function(removedGame) {
index = $rootScope.cartArray.indexOf(removedGame);
$rootScope.cartArray.splice(index, 1);
};
$(".disappear").hasClass('fadeOutRight')(function(){
$scope.removeFromCart(cartArray[0]) ;
});
.cartGameDiv {
height: 140px;
width: auto;
}
<div ng-repeat = "newGame in cartArray" ng-class="disappear">
<div>
<div class="col-sm-11 col-lg-11 col-md-11 cartGameDiv">
<div class="thumbnail">
<div class="pull-left">
<img style="height: 100px; width: 213px; padding: 5px; margin-top: 5px" src="{{newGame.thumbnail}}" alt="">
<div id="ratingDiv" style="margin-left: 8px; margin-right: 8px; margin-bottom: 5px;">
<div style="display: inline-block" ng-bind-html="getTrustedHtml(newGame)"></div>
<p class="pull-right" style="color: #d17581">{{newGame.numberReviews}} reviews</p>
</div>
</div>
<div class="caption">
<h4 style="margin-top: 0" class="pull-right">{{newGame.price}}</h4>
<h4 style="margin-top: 0"><a class="categoryGameName" href="#details/{{myGamesList.indexOf(newGame)}}">{{newGame.name | removeSubName}}</a>
</h4>
<p>{{newGame.description.substring(0,290) + '...'}}</p>
</div>
</div>
</div>
</div>
<div class="col-sm-1 col-lg-1 col-md-1 cartGameDiv">
<img style="margin-bottom: 10px; margin-top: 10px;" src="images/glyphIconCheckmark.png" alt=""/>
<img ng-click="disappear='animated fadeOutRight'; removeFromCart(newGame)" style="margin-bottom: 10px" src="images/glyphIconRemoveGame.png" alt=""/>
<img src="images/glyphIconLike.png" alt=""/>
</div>
</div>
If you have any idea how to delay the function call until after the animation I'd really appreciate it! Thanks!
This is very simple to do using ngAnimate. Add the ngAnimate script to your page (you can get this from numerous CDNs), include ngAnimate as a dependency to your module and then just add some simple CSS.
.ng-leave{
-webkit-animation: fadeOutRight 1s;
-moz-animation: fadeOutRight 1s;
-o-animation: fadeOutRight 1s;
animation: fadeOutRight 1s;
}
In your example, you need not do any work applying the class yourself, ngAnimate will do it for you.
Here is a Plunker demonstrating how you would do it.

overflow-y not working with ng-if in Internet Explorer with Angular

I am using Angular 1.2.16 and testing with IE 11.
In my app, in settings.html, I have the following section:
<section class='scrollable'>
<section class='hbox stretch'>
<aside class="aside-md bg-white b-r" data-ng-controller='RecipientsCtrl'>
<div data-ng-if='inputMode' data-ng-include="'partials/recipient-form.html'"/>
</section>
</section>
where 'scrollable' class is defined as:
.scrollable {
overflow-x: hidden;
overflow-y: auto;
}
and recipient.form:
<div class="panel-body">
<form name='rform' ng-submit='addRecipient(rform)' novalidate='novalidate' role="form">
<label>Recipient's Name</label>
<input type="text" class="form-control" ng-model='recipient.name' name="name" placeholder="Enter name" required='', data-mongoose-error=''/>
....
<button type="submit" class="btn btn-sm btn-success">Add</button>
</form>
</div>
A button click puts the controller in 'inputMode'. This works fine with Chrome, Safari and Firefox. In IE, when you click the button to get into the 'inputMode' it seems like nothing happens, but when you resize the window a bit you see the form.
The following makes it work in IE:
Remove the 'scrollable' class from the section (not an option as I need that)
Display the form directly without the 'inputMode' condition (not an option)
I tried ng-show as well at no avail.
Any ideas?
Thanks.
Changing the css seems to have fixed it:
.scrollable {
overflow-x: hidden;
overflow-y: auto;
min-height: 100%;
}

Resources