I have a onsen-ui project and I'm using Monaca Cloud IDE to build it. I'm still struggling with a few key concepts when it comes to onsen-ui, but I can't figure it out from readying the docs.
At the moment I'm trying to implement a "range" input on a onsen carousel-item. The range input is rendered just fine, but I can't slide it. When I try to slide it, I actually scroll the carousel. My current idea to solve this problem is to set the entire carousel to "disabled", since it's not that important for the user to scroll back to the previous page (although that would be nice). One of my biggest issues is the action listeners and how to call methods pertaining to ons-.. components.
<ons-page>
<ons-carousel fullscreen swipeable auto-scroll auto-scroll-ratio ="0.2">
<ons-carousel-item>
<img class="custom_logo_top_welcome" src="images/Leaf_PNG.png"/>
<br />
<br />
<br />
<p class="custom_p_welcome">Start saving today and see the likely value when you retire.</p>
<div class="custom_bottom_div_welcome"><p class="custom_bottom_p_welcome">Swipe left</p></div>
</ons-carousel-item>
<ons-carousel-item >
<p class="custom_dateOfBirth_p_setup">Please enter your date of birth:</p>
<div class="custom_datePicker_div_setup"><p>Test Div</p></div>
<p class="custom_dateOfRetirement_p_setup">What is your expected retirement age?</p>
<input type="range" class="range custom_range_setup" />
<div class="custom_bottom_div_setup"><ons-button class="custom_bottom_button_setup" onclick = "navToIndex()">Done</ons-button></div>
</ons-carousel-item>
</ons-carousel>
</ons-page>
So basically what I'm thinking about doing here is to set the carousel to "disabled" when the user swipes to the second carousel item.
How do I do this? If there's a better way to solve the issue, please feel free to share.
Thanks in advance!
Here is the code that solves the issue in the question. It is a combination of the other two answers given, so I can't take all the credit for this.
Code in index.html:
document.addEventListener('ons-carousel:postchange', function(event){
if (event.activeIndex === 1) {
rangeTouchEvents();
}
});
Function called in above code are as follows:(Note: In my project, this code is in an external .js file which is loaded in index.html)
function rangeTouchEvents()
{
ons.ready(function() {
var range = document.getElementById("range");
range.addEventListener('touchstart', function () {
document.querySelector("ons- carousel").removeAttribute("swipeable");
});
range.addEventListener('touchend', function () {
document.querySelector("ons-carousel").setAttribute("swipeable", "");
});
});
}
Code Explained:
The first snippet of code is where you add an action listener to the <ons-carousel>
This listens for any changes, and if a change occurs, it tests to see whether or not the active index of the carousel is 1. Index 1 is the index on which the range element is displayed (in my application). If the carousel is on index 1, it will call the function, otherwise nothing will happen.
The function is simply adding action listeners to the "range" element. The first action listener fires when a user touches the range element, and switches the scrollable attribute to "false". As soon as the user releases the range element, the second action listener fires. The second action listener sets the scrollable attribute back to "true".
The reason why you can't simply add the "touchStart" and "touchEnd" action listeners to the range element is because of the onsen framework. It doesn't allow you to run scripts from within <ons-page>
(at least that's what I've experienced.) You can run the code to add the action listeners in index.html, but it won't work, since the "range" element only gets created when the carousel reaches index 1, thus the action listeners have nothing to bind to yet. That is why you first have to put an action listener on the <ons-carousel>
to check when index 1 is active. When it is active, the range element will be created, and the action listeners can be bound to it.
Credit to @AndiPavlio and @FranDios
If you want to be able to use the range
element but still be able to swipe the carousel
, you can do something like this:
HTML
Add id="range"
to the range
element, like this:
<input id="range" style="position: absolute; top: 300px" type="range" class="range custom_range_setup" /></div>
JS
ons.ready(function() {
var range = document.getElementById("range");
range.addEventListener('touchstart', function () {
document.querySelector("ons-carousel").removeAttribute("swipeable");
});
range.addEventListener('touchend', function () {
document.querySelector("ons-carousel").setAttribute("swipeable", "");
});
});
When you'll touch the range
element, the carousel
swipeable
attribute will be removed, until the touch action ends. This will allow you to have both the functionalities working.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With