When using ngx-slider in Angular, it unexpectedly fires off when scrolling on mobile devices

I am currently developing a survey application that utilizes ngx-sliders. However, I have encountered an issue on mobile devices where users unintentionally trigger the slider while scrolling through rows of slider questions, resulting in unintended changes to their answers.

I have attempted to disable the slider on the (touchmove) event, but it only works after the slider value has already been changed. Disabling it on (touchstart) does not yield the desired results either. Even after trying the touchEventsInterval slider option and using event.preventDefault(), I have had no success.

My latest attempt involves accessing the slider with ElementRef. One potential solution is to set the slider as readonly, detect a click at its position, mark that specific tick as active by changing its class, but I am facing difficulties in implementing this approach. I am uncertain if this method is effective or feasible.

At this point, I am running out of ideas and seeking advice on how to address this issue.

Here is a snippet of the HTML code:

<div class="slider-field hide-value-ticks mb-5">
  <div class="subtitle-black mb-4">{{answer.rowAnswerText ?? ''}} {{answer.columnAnswerText}}</div>
      <ngx-slider 
      *ngIf="options" 
      class="touch-slider" 
      [value]="selectedAnswer" 
      (valueChange)="sliderValueChange($event)" 
      [options]="options"
      (click)="onClick($event)
      #sliderNgx
      ></ngx-slider>
</div>

And here is the .ts file:


export class PathfinderStepSliderComponent implements OnInit {

  // Add the TypeScript code here

}

Answer №1

After much troubleshooting, I finally found a solution to my issue. By setting the readonly slider option to true and implementing a click listener, I was able to resolve the problem:

onSelectAnswer(e, slider) {
    // A bug was identified where clicking between ticks set the index to 2 (in the middle of the slider)
    const ignoreTargetClassName = 'ngx-slider-span ngx-slider-bar';
    
    const sliderElements = [...(slider.elementRef.nativeElement.getElementsByClassName(e.target.className) as any)];
    
    const index = sliderElements.findIndex(elem => elem === e.target);
    
    if (index !== -1 && (e.target.className !== ignoreTargetClassName)) {
      this.selectedAnswer = index;
    }
  }

Here is the updated HTML file:

<div class="slider-field hide-value-ticks mb-5">
  <div class="subtitle-black mb-4">{{answer.rowAnswerText ?? ''}} {{answer.columnAnswerText}}</div>
    <ngx-slider 
    id="slider"
    *ngIf="options" 
    class="touch-slider" 
    [value]="selectedAnswer" 
    (valueChange)="sliderValueChange($event)" 
    [options]="options"
    (click)="onSelectAnswer($event, ngxSlider)"
    #ngxSlider
    ></ngx-slider>
</div>

Answer №2

A different technique suggested in this Stack Overflow post involves utilizing the CSS property pointer-events.

You can set the .ngx-slider class to have pointer-events: none, while setting .ngx-slider-pointer to have pointer-events:all.

In my case, I had to nest these selectors within the ::ng-deep selector - you can refer to the custom-styling guide for ngx-slider for more information.

/* component.scss */
::ng-deep {
    .ngx-slider {
        /* In my scenario, I only want mobile and tablet users to be unable to interact with the slider. For desktop, I want them to be able to click to a specific value */
        @media (max-width: 768px) {
            pointer-events: none;
            .ngx-slider-pointer {
                pointer-events: all;
            }
        }
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Bringing in a module that enhances a class

While scouring for a method to rotate markers using leaflet.js, I stumbled upon the module leaflet-rotatedmarker. After installing it via npm, I find myself at a loss on how to actually implement it. According to the readme, it simply extends the existing ...

Can someone explain the distinction between 'return item' and 'return true' when it comes to JavaScript array methods?

Forgive me for any errors in my query, as I am not very experienced in asking questions. I have encountered the following two scenarios :- const comment = comments.find(function (comment) { if (comment.id === 823423) { return t ...

Mouse event listener includes timeout function that updates a global variable

I'm currently working on a function that gets activated by a mouse click, but there's a 10-second cooldown period using setTimeout() before it can be triggered again. However, after the timeout, my variable doesn't get set to the correct boo ...

Typescript i18next does not meet the requirement of 'string | TemplateStringsArray NextJS'

While attempting to type an array of objects for translation with i18next, I encountered the following error message in the variable navItems when declaring i18next to iterate through the array Type 'NavItemProps[]' does not satisfy the constrain ...

Steps for gracefully throwing an error to an Angular RxJS Observable consumer

How can I handle errors from the 'BROKEN' line in this function so that they are passed to its subscriber, similar to how the 'WORKS' line does? I have observed that the 'Works' line successfully sends the error to this funct ...

Creating React Components with TypeScript: Ensuring Typechecking in Class and Function Components

Want to ensure typechecking works when defining React Class/Function components in TypeScript? Struggling to find a comprehensive guide on how to do it correctly. I've managed to define the Props and State interfaces, but I'm unsure about how to ...

Jest assertions encountering type errors due to Cypress

After using react-testing-library and @testing-library/jest-dom/extend-expect, I decided to install Cypress. However, I now face Typescript errors on all my jest matchers: Property 'toEqual' doesn't exist on type 'Assertion'. Did ...

The negation operator in Typescript is failing to negate as expected

When a user changes a multiselect element, there is a function that runs to control the visibility of an error message: getVisibility(multiselect) { if ((multiselect.selectedCategories.length < 1 && !multiselect.allSelected) && th ...

Unable to invoke an external function from bolt Response Handler Callback

I am facing an issue where I am unable to call my Update method from the bolt responseHandler. Can someone please help me with this problem? Using Angular 9: Error: core.js:1673 ERROR TypeError: this.updatePaymentInfo is not a function at Object.resp ...

Having trouble with assigning an error message in Formik validation using TypeScript

Currently, I am in the process of constructing a user input form in React & TypeScript using Formik. The form requires the user to input a name, email, and password. The input handling is functioning properly, but now I aim to implement validation functio ...

Activate the button in Angular2 when any character other than a space is inputted

I'm working on a comment section in the form of a text area and I need to enable another button when a user starts typing characters (excluding spaces) into the textarea. How can I achieve this in Angular 2? I have managed to make it work, but my iss ...

Identifying the scenario where Partial<T> inherits from T

I am facing a scenario where I am working towards achieving a specific "state": type State = { foo: number, bar: number, baz?: string }; Initially, I may not have reached the complete State yet but rather align with the structure of Partial<State>. ...

Can Bun automatically bundle my TypeScript files when I save them in VS Code?

Is it feasible for Bun to bundle my TypeScript upon saving a file in VS Code? The instruction manual suggests running bun run index.ts in the command line and including it in the package.json in this manner. However, I am unsure how to automate this proce ...

Steps for incorporating a toggle feature for displaying all or hiding all products on the list

Looking for some guidance: I have a task where I need to display a limited number of products from an array on the page initially. The remaining items should only be visible when the user clicks the "Show All" button. Upon clicking, all items should be rev ...

Unable to locate the image file path in React.js

I'm having trouble importing images into my project. Even though I have saved them locally, they cannot be found when I try to import them. import {portfolio} from './portfolio.png' This leads to the error message: "Cannot find module &apos ...

Tips for enhancing the FastifyRequest interface with a new property without erasing existing information in a declaration file

What is the method to integrate a property into an interface via declarations, while avoiding full object overwriting? declare module 'fastify' { interface FastifyRequest { user: User; } } //auth.ts ... const user = jwt.verify( ...

Creating a Worldwide Authorization Header with HttpClient Interceptors

I have implemented a global authorization header in my app using an interceptor to avoid declaring the authorization header in each get() function. However, I am facing an issue where the token is still being requested when I call the get() functions. Th ...

Expand or collapse Angular Material Accordion depending on selected Radio button choice

Is it possible to use a mat-accordion with radio buttons where each panel expands only when its corresponding radio button is selected? I have the radio buttons functioning correctly, but the panels are expanding and collapsing with every click rather than ...

Identifying collisions or contact between HTML elements with Angular 4

I've encountered an issue that I could use some help with. I am implementing CSS animations to move p elements horizontally inside a div at varying speeds. My goal is for them to change direction once they come into contact with each other. Any sugges ...

Ways to integrate user input into the header of an Angular HTTP post method

I need help figuring out how to incorporate user input into the header of a post method I am working with. I understand that some kind of binding is necessary, but I'm struggling to implement it in this case. Currently, I have a variable called postDa ...