Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Onsen-ui combining carousel with range input & action listeners/methods

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!

like image 561
sj.meyer Avatar asked Jan 07 '23 00:01

sj.meyer


2 Answers

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

like image 153
sj.meyer Avatar answered Feb 06 '23 10:02

sj.meyer


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!

like image 33
Andi Pavllo Avatar answered Feb 06 '23 10:02

Andi Pavllo