Onsen-UI combine tabbar and carousel - onsen-ui

I'd like to combine a tabbar with carrousel, so that I can navigate between tabs not only by tapping the tabbar but also by swiping like the way it works for a carousel.
I found that this codepen (http://codepen.io/frankdiox/pen/EVpNVg) (as listed in this answer (https://stackoverflow.com/a/33486827/6857215) almost does what I want, except that by just using the CSS style of a tabbar, I'm losing the automatic material-design on android which is not what I want.
I would love to have a solution that contains just something like this:
<ons-page>
<ons-carousel swipeable auto-scroll fullscreen id="carousel">
<ons-carousel-item> Page one </ons-carousel-item>
<ons-carousel-item> Page two </ons-carousel-item>
<ons-carousel-item> Page three </ons-carousel-item>
</ons-carousel>
<ons-tabbar position="top">
<ons-tab onclick="carousel.setActiveCarouselItemIndex(0)" active>One</ons-tab>
<ons-tab onclick="carousel.setActiveCarouselItemIndex(1)">Two</ons-tab>
<ons-tab onclick="carousel.setActiveCarouselItemIndex(2)">Three</ons-tab>
</ons-tabbar>
</ons-page>
Since onsen ui 2 is out, I'd thought maybe someone has a neater solution for this than the old example?

Related

trouble with splitter and navigator in onsenUI

I have a navigator and global splitter in my app. My navigator pushes my first page as tempHome and i need set page attribute for splitter also tempHome to use the splitter.
<ons-navigator id="myNavigator">
<ons-page>
<ons-splitter>
<ons-splitter-side id="menu" side="right" width="220px" swipe-target-width="150px" collapse swipeable>
<ons-page>
<ons-list>
<ons-list-item tappable>
test
</ons-list-item>
</ons-list>
</ons-page>
</ons-splitter-side>
<ons-splitter-content id="content" page="tempHome"></ons-splitter-content>
</ons-splitter>
</ons-page>
</ons-navigator>
so I have twice tempHome in the first page of my app.
Is there any help?
Thank you
The codepen which you mentioned shows a splitter inside a navigator.
However both the navigator and splitter can contain inner pages - so in your case what you want to do is just change the structure the other way around. Since you want to have the side menu always that just means that it should be outside the navigator.
You can put the navigator inside the ons-splitter-content and you will get the desired result.
<ons-splitter>
<ons-splitter-side collapse swipeable>
// menu content...
</ons-splitter-side>
<ons-splitter-content>
<ons-navigator id="myNavigator" page="home.html"></ons-navigator>
</ons-splitter-content>
</ons-splitter>
Here's a modified Demo.
Sidenote: I just modified the example from the codepen which you mentioned, so it's actually using angular, however do note that for Onsen 2 angular is not a required :)
<ons-navigator id="myNavigator">
<ons-page>
<ons-splitter>
<ons-splitter-side id="menu" side="right" width="220px" swipe-target-width="150px" collapse swipeable>
<ons-page>
<ons-list>
<ons-list-item tappable>
test
</ons-list-item>
</ons-list>
</ons-page>
</ons-splitter-side>
<ons-splitter-content id="content" page="tempHome"></ons-splitter-content>
</ons-splitter>
</ons-page>

<ons-navigator> within a tab not loading

I have tried buttons and lists, but for whatever reason, I cannot push a page to the navigator stack from within a tab. Having said that, I am new to Onsen and could easily be messing something up. I have followed the examples and they work fine when just doing a tab nav or just doing a navigator, but not both. This question was similar but did not solve my issue: Onsen UI Pagination: navigator and tabbar
The below code doesn't work. Any help is greatly appreciated! The login.html page is in the root www folder and I am using Monaca cloud IDE.
<body>
<ons-tabbar position="bottom">
<ons-tab page="home.html" active="true">
<ons-icon icon="fa-home"></ons-icon>
<span style="font-size: 14px">Home</span>
</ons-tab>
<ons-tab page="gameon.html">
<ons-icon icon="fa-bullseye"></ons-icon>
<span style="font-size: 14px">Game On!</span>
</ons-tab>
<ons-tab page="progress.html">
<ons-icon icon="fa-line-chart"></ons-icon>
<span style="font-size: 14px">Progress</span>
</ons-tab>
<ons-tab page="settings.html">
<ons-icon icon="fa-gear"></ons-icon>
<span style="font-size: 14px">Settings</span>
</ons-tab>
</ons-tabbar>
<ons-template id="home.html">
...
</ons-template>
<ons-template id="gameon.html">
...
</ons-template>
<ons-template id="progress.html">
...
</ons-template>
<ons-template id="settings.html">
<ons-navigator var="navigator">
<ons-page>
<ons-toolbar>
<div class="center">Settings</div>
</ons-toolbar>
<ons-button modifier="large" onclick="navigator.pushPage("login.html", { animation: "slide" });">Login</ons-button>
<ons-list>
<ons-list-item onclick="navigator.pushPage('login.html');" modifier="chevron">Login</ons-list-item>
<ons-list-item>
Another Option
<ons-switch modifier="list-item" checked></ons-switch>
</ons-list-item>
</ons-list>
</ons-page>
</ons-navigator>
</ons-template>
Update: So after reviewing the docs for Onsen 2.0, I discover that for ons-navigator, the var attribute is for angular which I am specifically trying to avoid using as I want to keep the overhead as minimal as possible and just stick with straight JS (no frameworks). So the docs here https://onsen.io/2/reference/ons-navigator.html leave me confused as there is no way to reference the object without var. Thus it would seem, that if you are going to use the navigator then you must be using AngularJS which contradicts the JS reference page of the same docs which indicates that it doesn't require Angular and just the Onsen loader.js. Is this correct or am I losing my marbles?
Update 2: So after implementing the change below and it still not working, ran it on my phone and finally got an error message. I even reverted back to the original code and get the same error, which is:
Uncaught (in promise) Error: "html" must be one wrapper element. www/lib/onsenui/js/onsenui.js: 4139
My guess is that this has to do with using and calling to an external page as well. I will try pulling everything out to standalone html pages and just call the templates themselves. Who knows???
I found the issue. On the login.html page, I had the <style> block outside the <ons-page> tags. From the JS referenced in the error message, I was able to determine that there were multiple HTML wrappers being incited. Luckily, a quick fix for a stupid question on my part!

Parent controller module is not loaded after pop page through <ons-back-button> from a pushed page

that's my first question so I´m afraid to be a silly one but I have done a lot of research before and spend many ours trying to fix this by changing the code. I´m relatively new to web app programming and maybe missing some conceptual knowledge that can be blocking me to go forward.
Environment and tools: Using cordova, onsen ui, Android studio, angularjs to develop a sort of Engineer Calculator on my area of expertise, I´m not a professional programmer.
The app is based in a series of pages connected as in the below user data/page flow and the app is working fine except for the problem I´m asking for help.
(I cant post images yet)
It's a dataflow like this:
menu.html >> page1.html >> load.html
For every html page view I have a controller module, all modules in the same controller file. The sliding menu defined in the index.html calls the page1.html for instance, that is the only page having a SVG graphic than linked to load.html page through a onclick Push page. See below the pages code:
menu.html
<body onload="onLoad()" ng-app="calcfcc" ng-controller="calcfccController">
<!-- to transfer to AS start here -->
<ons-sliding-menu
menu-page="menu.html" main-page="page1.html" side="left"
var="menu" type="reveal" max-slide-distance="200px" swipable="true">
</ons-sliding-menu>
<!-- sliding-menu - Menu list here!!! -->
<ons-template id="menu.html">
<ons-page modifier="menu-page">
<ons-toolbar modifier="transparent"></ons-toolbar>
<ons-list class="menu-list">
<ons-list-item class="menu-item" ng-click="menu.setMainPage('page1.html', {closeMenu: true})">
<ons-icon icon="fa-home"></ons-icon>
{{menu1}}
</ons-list-item>
page1.html called from slide menu:
<ons-navigator animation="slide" var="page1navi">
<ons-page ng-controller="initController" on-device-backbutton="backbuttonpage()" style="background: #001a00;">
<ons-toolbar fixed-style>
<div class="left">
<ons-toolbar-button id="popoverb1" ng-click="menu.toggle()">
<ons-icon icon="ion-navicon" size="28px" fixed-width="false"></ons-icon>
</ons-toolbar-button>
</div>
<div class="center">
{{pageheader1}}
</div>
<div class="right" style="padding: 7px;">
<img src="img/AASis78x31branco.png" alt="AASis" >
</div>
</ons-toolbar>
page1.html portion that calls load.html from a clickable SVG icon:
<g
id="g4533"
onclick="page1navi.pushPage('load.html', { animation : 'slide' } )"
transform="translate(0,-66.958368)">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4485);fill-opacity:1;fill-rule:evenodd;stroke:#6e6e6e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect10449"
width="60"
height="60"
x="275.33713"
y="786.85248"
rx="6.7857499"
ry="6.3835001" />
load.html page:
<ons-page ng-controller="loadController">
<ons-toolbar>
<div class="left"><ons-back-button>{{about1}}</ons-back-button></div>
</ons-toolbar>
<p class="textarea" style="font-size: 20px; border: 2px solid #0066FF; margin: 5px">
{{load1}}
</p>
So my problem is that page1.html controller is loading fine, load.html controller is also loading fine and making it's job but when a press the load.html page "back" button to return to page1.html the page1 controller is not loaded and I cant refresh the view with data I have manipulated on load.html.
It's not about global vars, is just that the right controller is not loaded.
When a called page1.html from index.html it works, but I can ask the user to get back to side menu just to refresh. Also reload all is not a option, very annoying to the user.
Any idea how to solve this?
TKS in advanced!!!!
Controllers are only run once when the page is created. When you use back-button you are destroying load.html and moving back to page1.html, but this one was already created in the page stack so its controller won't be called again. Also, AngularJS will only recognize changes if they are done inside Angular's scope. Otherwise you will need to use $scope.$apply() to let Angular know about the changes. You could use $scope.$apply() on Onsen UI's postpop event.
In any case, if you are using AngularJS I think you should have ng-click instead of onclick. Also, you can bind the text-area to a scope variable using ng-model, so every change you do in the view will be stored automatically. I think it should be enough with these two changes.
Hope it helps!

What is the best practice for combining ons-sliding-menu and ons-split-view

I am developing a mobile app with phonegap and onsen ui.
There are ons-sliding-menu and ons-split-view which works fine separately.
My desire behaviour is showing menu-bar-button when the device is portrait and showing the menu when is on mobile landscape or tablet any orientation.
I have combine them like this
<ons-sliding-menu var="app.slidingMenu"
main-page="main.html"
menu-page="menu.html"
side="left"
type="push"
max-slide-distance="250px"
>
</ons-sliding-menu>
<ons-split-view var="app.splitView"
secondary-page="menu.html"
main-page="main.html"
main-page-width="70%"
collapse="portrait">
</ons-split-view>
....
and this for showing menu-bar-button and toggling menu
<ons-template id="main.html">
<ons-navigator>
<ons-page>
<ons-toolbar fixed-style>
<div class="left">
<ons-toolbar-button ng-click="ons.slidingMenu.toggleMenu()"><ons-icon icon="bars"></ons-icon></ons-toolbar-button>
</div>
<div class="center">xxx</div>
</ons-toolbar>
but when I add splitview the sliding-menu-button is not working at all.
Is there any best practice for combining them together?
You can use the ons-if-orientation directive to switch between the split view and the sliding menu.
<div ons-if-orientation="landscape">
<ons-split-view
secondary-page="menu.html"
main-page="main.html"
main-page-width="70%"
collapse="portrait">
</ons-split-view>
</div>
<div ons-if-orientation="portrait">
<ons-sliding-menu
max-slide-distance="200px"
menu-page="menu.html"
main-page="main.html">
</ons-sliding-menu>
</div>
There is a big problem with this approach though. There is actually two DOM trees for the menu and two DOM trees for the main page. So if you make some change to the DOM you will have to do it in two places in order for the pages to be in sync.
Try it out here:
http://codepen.io/argelius/pen/XJdabG

How to open menu in the split view from code?

The sliding menu template has a button on the toolbar that opens the side menu (shows it). The same menu (I mean appearance) is used in the split view example app. In this case there is no menu button on the toolbar, but the menu, even in the portait view, can be open by swiping right. Why not allow a user to open the menu from a button? Unfortunately there's no toggleMenu() method for the object. There is however openMenu() method but it doesn't work if used from code. My example code is:
<ons-split-view
secondary-page="secondary.html"
main-page="page1.html"
main-page-width="70%"
collapse="portrait"
var="menu">
</ons-split-view>
<script type="text/ons-template" id="page1.html">
<ons-page class="center">
<ons-toolbar>
<div class="left">
<ons-toolbar-button ng-click="menu.openMenu()">
<ons-icon icon="bars"></ons-icon>
</ons-toolbar-button>
</div>
</ons-toolbar>
</ons-page>
</script>
Could you please me to achieve the effect of opening the menu by clicking on a button?
Raf
Ok, I've found it... ons.splitView.toggle() - it opens/closes the menu.

Resources