Click outside to edit the input inline

I am currently attempting to enable inline editing for an input field by incorporating a clickOutside directive. The issue I am facing is that when I click on the element to edit, the editMode variable becomes true, displaying the input immediately. However, the clickOutside event triggers right away, causing the editMode to become false and preventing my edit action from working properly:

<span *ngIf="!editMode" (click)="edit(); editMode = true"></span>
<input *ngIf="editMode" (clickOutside)="save(); editMode = false">

How can I address this issue effectively? Your assistance is greatly appreciated.

Below is the code for my clickOutside directive:

import {Directive, ElementRef, Output, EventEmitter, HostListener} from '@angular/core';

@Directive({
    selector: '[clickOutside]'
})
export class ClickOutsideDirective {
    constructor(private elementRef: ElementRef) {
    }

    @Output()
    public clickOutside = new EventEmitter<MouseEvent>();

    @HostListener('document:click', ['$event', '$event.target'])
    public onClick(event: MouseEvent, targetElement: HTMLElement): void {
        if (!targetElement) {
            return;
        }

        const clickedInside = this.elementRef.nativeElement.contains(targetElement);
        if (!clickedInside) {
            this.clickOutside.emit(event);
        }
    }
}

Answer №1

Creating Interactive Elements with HTML and Typescript

<span *ngIf="!editMode" (click)="edit($event); editMode = true">Click to trigger editing mode</span>
<input *ngIf="editMode" (clickOutside)="save(); editMode = false">

Utilizing Components in Angular Framework

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  editMode = false;

  edit(event) {
    event.stopImmediatePropagation();
    console.log(this.editMode);
  }

  save() {
    console.log(this.editMode);
  }

}

Answer №2

Revise your code to look like this:


  <span *ngIf="!editMode" (click)="edit();editMode = true" >span</span>
  <input *ngIf="editMode" (clickOutside)="save();editMode = false;"  
           [delayClickOutsideInit]="true">

Incorporating [delayClickOutsideInit]="true" is essential.

Referencing the ng-click-outside documentation,

Postpones the initialization of the click outside handler. This could be beneficial for elements that are shown conditionally

Answer №3

To ensure that the click event is fully processed before displaying the input element, you may want to consider delaying the setting of editMode:

<span *ngIf="!editMode" (click)="setEditMode()"></span>

This can be achieved by using the following method:

public setEditMode(): void {
  setTimeout(() => {
    this.edit();
    this.editMode = true;
  }, 50);
}

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

Error: An attempt to make changes to a database that does not permit mutations has resulted in an InvalidStateError

I am facing an issue while attempting to initiate a transaction within the then() function. An exception is thrown when I try to do so. Below is the code snippet in question: open.onsuccess = function (e1) { var dbase = e1.target.result; $.get("https://w ...

What is the best way to utilize a while loop in order to calculate the Fibonacci sequence?

Just recently delved into the world of Js and encountered an issue that has me stumped. Despite exhaustive searching, I haven't been able to find a similar solution. Any assistance would be greatly appreciated. var i = 0; var j = 1; var k = 0; fun ...

What is preventing me from using jQuery to dynamically insert HTML onto the page?

Below is the HTML code for a Bootstrap Modal dialog box: <div class="modal fade" id="rebateModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> ...

Displaying a continuous loop of full-screen images using the chocolat.js library

I need some help creating a fullscreen slideshow that loops images using Chocolat JS. According to the documentation, I should start with: <div class="chocolat-parent" data-chocolat-title="set title"> <a class="chocolat-image" href="series/1 ...

Fetching picture from the database using AJAX and adding it in Laravel version 5.4

I've been using an AJAX request to fetch data from my database and then appending it to a div. However, I've run into an issue with the image source. My image files are stored in a public folder named "image_files". The problem arises when trying ...

Converting dynamic text enclosed in asterisks (*) into a hyperlink on a webpage with the use of JavaScript

I'm facing a unique situation where I need to transform specific text on an HTML page into anchor tags using JavaScript/jQuery. The text format is as follows: *www.google.co.uk/Google* *www.stackoverflow.com/StackOverflow* The desired outcome should ...

Angular Materials auto-complete - Presenting choices depending on certain criteria

I have implemented 4 components, each containing a material autocomplete feature with the same set of options. Whenever I select an option in one component, it sets isAvailable to false and disables that option in the other components. The array below show ...

Problem encountered in Typescript when using async/await with Promise.all to iterate through multiple results

Encountering an issue with this result set because its type is unknown. Despite trying various approaches, the same error persists and I'm uncertain about the next steps to take. Any assistance would be greatly appreciated! Here's the specific e ...

Leveraging Next.JS for static site generation with Apollo client-side data fetching

Utilizing Next.JS SSG has greatly enhanced the loading speed of my website. However, I am facing a challenge where I need to fetch some data client-side that is specific to the logged-in user. For example, imagine a YouTube-like website with a Video page ...

A step-by-step guide on integrating PDF.js with Vue 3 and accessing the distribution folder locally

I must clarify that I am restricted from using any vue libraries to preview PDFs; only pure pdf.js and vue 3 are permitted. Utilizing pdf.js for presenting PDF files within my vue 3 project. Inquiring about the ideal folder structure for the project to en ...

ReactJS - run a JavaScript snippet once the Ajax call has successfully fetched and displayed the data

Where is the optimal placement for JavaScript code in order to execute a plugin after rendering is complete? <html> <head> <script src='https://cdnjs.cloudflare.com/ajax/libs/es6-promise/3.2.2/es6-promise.min.js'></script ...

Trouble encountered in converting the ajax data that was received

Ajax is commonly used to fetch data from the server. The data is successfully displayed in an alert as data: {"status": "Active","broadcastmsg": "msg"} However, when displayed in HTML i.e. <p id="demo"></p>, it shows up as undefined. This s ...

Generate a PDF document from a selection of table rows using the pdfmake library in Vue-tables-2

Searching for a way to generate a pdf of multiple selected rows in vue-tables-2, I came across the pdf library called pdfmake which seems promising. As someone new to this concept, I'm having difficulty figuring out how to: Integrate it into a vue-t ...

An Alternative Approach to Implementing the Ternary Operator in JavaScript

Do you find this logical operation to be rational? const user = users && users[0] || null; Is it identical to this conditional or ternary operation: const user = users ? users[0] : null; ? Let's assume users represents an array. ...

Guide to maintaining the route view in Angular

Is it possible to maintain the state of a page in Angular so that users can return to the same view when revisiting the same route? For example, let's say RouteA has a search bar where users can input a query. When a user enters a search term and vie ...

Converting an object into a list of lists using Typescript

When making an API call from Angular 5, the response is returned in the following format. { "metadata":{ "lastSyncTime":"2000-11-21T16:07:53", "dataFromDB":true }, "allocationReports":[ ...

How can I display a Bootstrap modal in Ember.js after rendering it in an outlet?

I'm facing a challenge in my Ember.js application where I need to trigger the opening of a Bootstrap modal from my ApplicationRoute upon calling the openModal action. This is what my ApplicationRoute looks like: module.exports = Em.Route.extend({ ...

What is the best approach for sending a binary image post request to an API using nodejs?

I am receiving the image binary in this manner: axios.get("image-url.jpg") Now, I want to utilize the response to create a new POST request to another server const form = new FormData(); const url = "post-url-here.com"; form.appe ...

Menu Slide – Inability to close by clicking div in specific section

I am attempting to create a slide menu that (a) opens, displaying a white faded overlay over the rest of the page and (b) closes when I click a link in the menu or anywhere on the white overlay. (a) Opening the menu works correctly. (b) However, I am enc ...

Modifying the color of a specific div using jQuery

I am attempting to develop a function that changes the background color of a div when a user clicks on it and then clicks on a button. The value needs to be saved as a variable, but I'm having trouble getting it to work because it keeps saying that th ...