Using RxJs in an Angular 2 application to enable row selection in a table by detecting mouse movements

Check out this example of an Angular 2 application with row selection in a table: https://plnkr.co/edit/HdQnWqbg9HloWb4eYGHz.

The row selection functionality is implemented using mouse event handlers (mousedown, mousemove, mouseup).

Below is the template code from table.comp.html:

<table class="table table-hover">
  <tbody>
    <tr *ngFor="let td of data; let i = index" 
        (mousedown)="onSelectionStart(i)" 
        (mousemove)="onSelection(i)" 
        (mouseup)="onSelectionEnd()" 
        [class.selected]="td">
      <td>row {{ i }}</td>
      <td>selected: {{ td }}</td>
    </tr>
  </tbody>
</table>

Here is the code for the Component (table.comp.ts) containing the event handlers:

export class TableComponent {
    private data: Array<any> = [];
    constructor() {
        [1, 2, 3, 4].forEach(x => this.data.push(false))
    }
    mouseDown: boolean = false;
    select: boolean = false;

    onSelectionStart(index) {
      this.mouseDown = true;
      this.select = !this.data[index];
    }
    onSelection(index) {
      if (!this.mouseDown)
          return;

      this.data[index] = this.select;
      console.log("You see me many times!");
    }
    onSelectionEnd() {
        this.mouseDown = false;
    }
}

Objectives:

  1. Prevent multiple re-selections of the same item. The message "You see me many times!" should only display once per row.

  2. Utilize RxJs to achieve the first objective.

Note: This code is based on Angular 2 RC3 and RxJs 5

Answer №1

For a more efficient way, use the mouseenter event instead of mousemove. This will only be triggered once when the mouse enters the element.

<table class="table table-hover">
  <tbody>
    <tr *ngFor="let td of data; let i = index" 
        (mousedown)="onSelectionStart(i)" 
        (mouseenter)="onSelection(i)" 
        (mouseup)="onSelectionEnd()" 
        [class.selected]="td">
      <td>row {{ i }}</td>
      <td>selected: {{ td }}</td>
    </tr>
  </tbody>
</table>

To see this in action, check out the updated Plunker for a live example

Answer №2

Currently, it seems challenging to implement declarative functionality in Angular2 / Rxjs due to the lack of asynchronous data flow.

An ongoing discussion is centered around introducing observables for elements and events:

One possible approach is to utilize the Observable.fromEvent method directly...

Check out a sample implementation below:

@Component({
  template: `
    <tr #tr ngFor="...">
    </tr>
  `
})
export class TableComponent {
  @ViewChildren('tr')
  trs:QueryList<ElementRef>;

  ngAfterViewInit() {
    this.trs.toArray().forEach((tr)=> {
      Observable.fromEvent(tr, 'mousedown').subscribe(event => {
      });
    });
  }
}

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

Fetching Data Using Asynchronous API Calls

My goal is to retrieve all results consistently from the API, but I am encountering varying outcomes. The for loop seems to be skipping some requests and returning a random number of records. Can anyone provide assistance? I have experimented with using t ...

Is it possible to access a class with protected/private fields written in TypeScript from outside the class in JavaScript?

Currently, I am delving into TypeScript classes (though my experience with OOP is limited). The following code snippet is extracted from the chapter on classes in https://www.typescriptlang.org/docs/handbook/classes.html Here's the issue at hand: I ...

Error in Angular async pipe: Input argument of type 'any[] | null' cannot be assigned to a parameter of type 'any[]'

Having an issue with using the async pipe in Angular within an *ngFor loop. Here is my code snippet: <ul> <li *ngFor="let user of users | async | search:(filterValue | async)!">{{ user.name }}</li> </ul> The error I am encou ...

Launching a website by running ng serve on an EC2 instance running Ubuntu 16.04

I have been trying to work on this Git project, but I'm facing issues in getting the website to function properly on my server. Oddly, everything seems to be working fine on my Mac. Despite not encountering any error messages, I am unable to access t ...

Trapped in a Continuous Observing Loop with MdSnackBar in Angular Material within Angular 2

Whenever my login attempt fails, I want to display a snackbar with the message 'error connecting'. After dismissing the snackbar, I would like the login to be retried after 10 seconds. However, I'm facing an issue where my observable is runn ...

What are the distinctions between manually and programmatically changing URLs in Angular 6?

My query pertains to differentiating navigation methods, specifically between clicking a button with [routerLink] and manually entering a URL in the browser's search bar. Update: I have a fixed menu on a certain page that appears as follows: <ul& ...

Ensuring strictNullChecks in Typescript is crucial when passing values between functions

When using the --strictNullChecks flag in TypeScript, there seems to be an issue with inferring that an optional property is not undefined when the check occurs in a separate function. (Please refer to the example provided, as articulating this clearly is ...

Using Typescript to retrieve the Return Type of a function when called with specific Parameter types

My goal is to create 2 interfaces for accessing the database: dao can be used by both admins and regular users, so each function needs an isAdmin:boolean parameter (e.g. updateUser(isAdmin: boolean, returnUser)) daoAsAdmin, on the other hand, allows metho ...

Tips on resolving handlebars 'module not found' error in typescript while compiling to umd

In my client-side JavaScript library written in TypeScript, I am attempting to incorporate Handlebars. However, when I try to import using import * as Handlebars from 'handlebars', I encounter an error message stating that TypeScript "cannot find ...

Removing properties of an object or a mapped type in Typescript by their values

Can we exclude specific properties from an object using a mapped type based on their value? Similar to the Omit function, but focusing on the values rather than the keys. Let's consider the following example: type Q = {a: number, b: never} Is there ...

What is the best way to deliver a file in Go if the URL does not correspond to any defined pattern?

I am in the process of developing a Single Page Application using Angular 2 and Go. When it comes to routing in Angular, I have encountered an issue. For example, if I visit http://example.com/, Go serves me the index.html file as intended with this code: ...

Is it possible for me to add a string to a URL as long as the string is not null?

When retrieving data from a database, I have the option to include specific parts for a more targeted search. Let's say I have an object structured like this: { title: "wonderland", aliases: "", ... } My goal now is to generate a URL for the ...

What is the proper way to import the Database class from BetterSqlite3 in a TypeScript project?

I am currently working on code that utilizes better-sqlite3 and my goal is to convert it to typescript. The original javascript code includes the following relevant sections: import Database from "better-sqlite3"; /** * @param {string} filenam ...

Is there a way to detect changes in a Service variable within an Angular component?

One of my components contains a button that activates the showSummary() function when clicked, which then calls a service named Appraisal-summary.service.ts that includes a method called calc(). showSummary(appraisal) { this.summaryService.calc(appraisal ...

Leveraging MatSort from Angular Material

In my customer.component.ts file, I have the following code: import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core'; import { NorthwindService } from 'swagger'; import {LiveAnnouncer} from '@angular/cdk/a11y&ap ...

Having trouble retrieving features from a QR code generated with Angularx-qrcode?

I utilized angularx-qrcode in order to create a QR code that displays data from qrInfo. However, I'm encountering the following error: ERROR TypeError: Cannot read properties of undefined (reading 'qrcElement') The code within qr-code-gener ...

Retrieving the input[text] value in TypeScript before trimming any special characters

One of the tasks I am working on involves a form where users can input text that may contain special characters such as \n, \t, and so on. My objective is to replace these special characters and then update the value of the input field accordingl ...

Generate sample data within a fixture

Currently, I am in the process of working on a project that involves creating users and conducting tests on those users. To generate user data such as first name and last name, I am utilizing the faker tool. My goal is to create a user with these generated ...

Using template literals with Optional chaining in Javascript does not yield the expected results

Trying to implement template literal with optional chaining. type Item = { itemId:number, price: number}; type ItemType = { A:Item, B:Item }; const data : ItemType = { A:{itemId:1, price:2}, B:{itemId:2, price:3} }; let key = `data?.${variable}?.ite ...

Errors TS2585 and TS2304 encountered during compilation of TypeScript file using Axios

What steps should I take to fix the errors that arise when attempting to compile my TypeScript code using tsc index.ts? node_modules/axios/index.d.ts:75:3 - error TS1165: In an ambient context, a computed property name must reference an expression of lite ...