Ways to recycle code with similar functionality but varying variable names

I have 3 buttons that copy content from a text area. All three functions are the same, only the variable name changes. How can I combine these into a single function instead of having three separate ones?

<div class="divclip">
    <button
      type="button"
      class="btn btn-light btn-sm"
      (click)="copyInputMessage(userinputAscii, 'toogleCopyBtnAscii')"
      id="copyBtnOne">
      {{ toogleCopyBtnAscii ? "Copy" : "Copied" }}
    </button>
</div>
 <div class="divclip">
    <button
      type="button"
      class="btn btn-light btn-sm"
      (click)="copyInputMessage(userinputHex, 'toogleCopyBtnHex')"
      id="copyBtnTwo"
    >
      {{ toogleCopyBtnHex ? "Copy" : "Copied" }}
    </button>
  </div>
  <div class="divclip">
    <button
      type="button"
      class="btn btn-light btn-sm"
      (click)="copyInputMessage(userinputBinary, 'toogleCopyBtnBinary')"
      id="copyBtnThree"
    >
      {{ toogleCopyBtnBinary ? "Copy" : "Copied" }}
    </button>
  </div>

This is the component.ts code

  
  copyInputMessage(inputElement, toggleVariable) {
    this[toggleVariable] = !this[toggleVariable];
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }

Answer №1

Each function shares the same final three lines. To streamline the code, consider creating a new function:

  copyInputMessage(inputElement){
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }
  copyInputMessageAscii(inputElement) {
    this.toogleCopyBtnAscii = !this.toogleCopyBtnAscii;
    copyInputMessage(inputElement);
  }

  copyInputMessageHex(inputElement) {
    this.toogleCopyBtnHex = !this.toogleCopyBtnHex;
    copyInputMessage(inputElement);
  }

  copyInputMessageBinary(inputElement) {
    this.toogleCopyBtnBinary = !this.toogleCopyBtnBinary;
    copyInputMessage(inputElement);
  }

Alternatively, you can simplify it further by using:

  copyInputMessage(inputElement,charType) {
    switch(charType) {
      case "hex":
        this.toogleCopyBtnHex = !this.toogleCopyBtnHex;
        break;
      case "binary":
        this.toogleCopyBtnBinary = !this.toogleCopyBtnBinary;
        break;
      default: // assume "ascii"
        this.toogleCopyBtnAscii = !this.toogleCopyBtnAscii;
        break;
    }
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }

Answer №2

Here is a more efficient way to handle copying input messages in different formats:

//Reusable function

copyInputMessage(inputElement, inputType) {
        if(inputType === 'binary') {
            this.toogleCopyBtnBinary = !this.toogleCopyBtnBinary;
        }
        if(inputType === 'hex') {
            this.toogleCopyBtnHex = !this.toogleCopyBtnHex;
        }
        if(inputType === 'ascii') {
           this.toogleCopyBtnAscii = !this.toogleCopyBtnAscii;
        }
        this.toogleCopyBtnBinary = !this.toogleCopyBtnBinary;
        inputElement.select();
        document.execCommand('copy');
        inputElement.setSelectionRange(0, 0);
      }

// calling function

copyInputMessageAscii(userinputAscii, 'binary');
copyInputMessageAscii(userinputAscii, 'hex');
copyInputMessageAscii(userinputAscii, 'ascii');

Answer №3

To implement different behaviors based on the type parameter, you can utilize a switch case statement within the shared function.

  processInput(type) {
    switch (type) {
      case 'Text':
        this.toggleTextBehavior = !this.toggleTextBehavior;
        break;
      case 'Number':
        this.toggleNumberBehavior = !this.toggleNumberBehavior;
        break;
      case 'Boolean':
        this.toggleBooleanBehavior = !this.toggleBooleanBehavior;
        break;
    }
    inputElement.select();
    document.execCommand('copy');
    inputElement.setSelectionRange(0, 0);
  }

Answer №4

Consider utilizing arrays to keep track of user actions, inputs, and buttons. Below is a sample code demonstrating how you can approach the issue using arrays

In your TypeScript file

userInputs = ['Ascii', 'Hex', 'Binary'];
toogleCopyBtn = this.userInputs.reduce((prev, next) => ({prev, [next]: false}), {})
copyInputMessage(userInput) {
  this.toogleCopyBtn[userInput] = !this.toogleCopyBtn[userInput];
  const inputElement = document.querySelector('#inputElement' + userInput) as HTMLInputElement
  inputElement.select();
  document.execCommand('copy');
  inputElement.setSelectionRange(0, 0);
}

In your HTML

<div *ngFor='let userInput of userInputs; let index = index' class="divclip">
  <button
    type="button"
    class="btn btn-light btn-sm"
    (click)="copyInputMessage(userInput)"
    [attr.id]="'copyBtn' + userInput">
    {{ toogleCopyBtn[userInput] ? "Copy" : "Copied" }}
  </button>
</div>

<input *ngFor='let userInput of userInputs' type="text" [attr.id]='"inputElement" + userInput'>

Check out a live demo here

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

I'm having trouble getting jQuery to work properly with Bootstrap buttons

In simple terms, my objective is to have two buttons on a page where "1" is displayed when the first button is pressed and "2" is displayed when the second button is pressed. This functionality works fine with radio inputs, but when I incorporate button la ...

I'm completely unsure of how to properly test this using Qunit

Exploring a Function: /js/lib/front.js var Front = function(){ this.onSignUp = function(){ if (!Form.assertInput("email")) { $("input[name=email]").focus(); this.showHiddenMessage("Email not set."); return false; } } ...

How to temporarily modify/add CSS class in Angular 2

In my Angular 2 application, there is a label that displays the current amount of points for the user. Whenever the number of points changes, I want to briefly change the class of the label to create an animation effect that notifies the user of the chang ...

My custom function is not invoking the Firebase function createUserWithEmailAndPassword

The function createUserWithEmailAndPassword is not being triggered within the SignUpUser function when the onClick event occurs. However, it works when I use onClick={signUpUser(email,password)} import React from 'react'; import styled from &apo ...

Combining 2 dates into a single cell format

I'm struggling to change the date format of two dates displayed in one cell using ag-grid. I have tried creating a new function called dateFormatterr with two parameters, but it doesn't seem to work. Below is a snippet of my code and a screenshot ...

Edge browser saves your most recent PDF viewing preferences

Within my Angular application, we have integrated a feature where users can view a PDF report downloaded via an API within an iFrame. .TS code: In the TypeScript code snippet provided, we are subscribing to the execution of the reportservice and handling ...

Tips for arranging Intervals in sequence?

I've been developing a customized Pomodoro timer with user-defined work and rest times. In my Timer component, I have the following initial logic: useEffect(() => { start(3); start(timeData.workTime); start(timeData.restTime); }, []) c ...

Group by month and calculate the total sum using mongoose in MongoDB

I'm currently working with the orderdetails model in my project. Here is a snippet of the schema: const model = new Schema( { district: { type: String }, category: String, producer: String, variety: String, qty: String, price ...

Is now the ideal moment to implement Angular 4?

When considering using Angular 4 for an enterprise SAP system, is it better to stick with Angular 2 and wait for the final release of Angular 4? There have been rapid releases of Angular 4 that may affect our decision. (View changelog) Your suggestions ar ...

Tips for effectively wrapping Material UI v5 component to ensure the Grow component functions correctly

Being a newcomer to React, I want to apologize in advance for any silly mistakes or inaccuracies that may be present. I have successfully implemented the code for my Blog page: export default function Blog() { const [photos, setPhotos] = useState([]); ...

What is the best way to achieve the functionality of this ajax jquery using vanilla JavaScript?

I am attempting to replicate this jQuery ajax POST request in Vanilla JS, which currently looks like: $.ajax({ method: 'POST', url: window.location.href + 'email', data: { toEmail: to, fromName: from, ...

Exploring the Concept of Nested ViewModels in Knockout.js Version 3.2.0

I have a global view model that is applied to the main div and I also have other view models that I want to apply to nested elements within my main div However, I am encountering an issue: You cannot bind multiple times to the same element. Below is ...

Create and save data to a local file using Angular service

I am facing an issue with my Angular service: import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { person } from '../interfaces/iperson ...

Accessing a td element using an external JavaScript file

Struggling to reference a specific td id using an external Javascript file. I aim to implement a mouseOver event that will alter the content when a user hovers over an image within a table cell marked as follows: <td id="lifeCalculatorButton"& ...

Handling the onClear event in a Primeng Calendar

I am currently working on detecting when the p-calendar input is cleared either by pressing the backspace key or by pressing the delete key. Here is the code snippet I am using: <p-calendar appendTo="body" [(ngModel)]="endDateValue&qu ...

Navigate back to the previous page following the completion of an AJAX data submission

When using ajax to send data from page A to the server, the spring controller returns welcome page B. This process works correctly on Firefox and Internet Explorer, but on Chrome, there is an issue where after successfully sending the data via ajax, the de ...

Creating a series of tiny vertical markings along the horizontal line using the input range

I have a range input and I am looking to add small vertical lines at intervals of 10 on the horizontal line representing each default step. The range of my input is from 0 to 40 and I would like to have small vertical lines at 10, 20, and 30. I need to ac ...

Error: npm ran out of memory and could not complete the read operation

Every time I try to run an angular command, I keep getting the error message: "npm ERR! ENOMEM: not enough memory, read." Does anyone have a solution for this issue? ...

When utilizing a property on "this" within a function defined in a constructor, the compiled JavaScript code produces an undefined result

Currently, I am in the process of creating a prototype where my objective is to develop a webservice using the express framework in TypeScript, compile it to TS, and host it within a firebase functions environment. The code structure includes a Controller ...

Accept only the keys specifically assigned to an object

Trying to develop a TypeScript class where it is initialized with an object and contains a method that only accepts keys from that object. Here's the code: class MyClass { properties = {}; constructor(properties) { this.properties = propertie ...