Automatically activate click events based on modifications in certain div classes - must be repeated in a loop

When a user makes changes within the .ap-create-story-panel-wrap div and then clicks outside of that specific div, I want to trigger a button click in my function.

I am currently using the data-panel attribute as the selector for the container variable. It works fine for the first one, but I need it to work for all other .ap-create-story-panel-wrap divs as well.

I attempted to use a loop with the data attribute as a selector, but it did not yield any results.

$('.ap-create-story-panel-wrap[data-panel="basicinfopanel"]').change(function() {
  $(document).mouseup(function(e) {
    var container = $('.ap-create-story-panel-wrap[data-panel="basicinfopanel"]');

    // if the target of the click isn't the container nor a descendant of the container
    if (!container.is(e.target) && container.has(e.target).length === 0) {
      $(".btn-basicinfopanel").trigger("click");
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="ap-create-story-panel-wrap" data-panel="infopanel">
  <input type="text>
</div>
<a class="btn-basicinfopanel" data-target="certificatepanel">Save/Next</a>

<div class="ap-create-story-panel-wrap" data-panel="certifypanel">
  <input type="text">
</div>
<a class="btn-certifypanel" data-target="certifypanel">Save/Next</a>

<div class="ap-create-story-panel-wrap" data-panel="photopanel">
  <input type="text>
</div>
<a class="btn-photopanel" data-target="photopanel">Save/Next</a>

Answer №1

It's unclear if I have correctly understood the problem. Let me try to rephrase the issue as I interpreted it (my response will be based on that).

Issue: Multiple div elements with an input in each. Whenever the value of the input changes, it should automatically trigger a click event on the corresponding button within the parent div.

Solution: Target the input within each div.ap-create-story-panel-wrap

$('div.ap-create-story-panel-wrap input')

If you also want the click event to trigger when the user moves to the next input using the TAB key, listen for a change

.on('change', function() {});

In the callback function, retrieve the target button from the parent div

let tgt = $(this).closest('div.ap-create-story-panel-wrap').data('panel');
let bCls = '.btn-'+tgt;   // button class

Subsequently, trigger the click event

$(bCls).trigger('click');

The entire process looks like this:

$('div.ap-create-story-panel-wrap input').on('change', function() {
    let tgt = $(this).closest('div.ap-create-story-panel-wrap').data('panel');
    let bCls = '.btn-'+tgt;   // button class
    $(bCls).trigger('click');
});

Please let me know if you prefer not to trigger a click event when the focus is lost from an input, only when a mouse click occurs after a change (although I cannot think of a reason for this).

In any scenario, I would avoid attaching a persistent click event directly to the document. Instead, I suggest detaching the event at the end of the function as recommended in one of the previous answers, or updating and comparing the data-old values of the inputs right after the click event triggers.

UPDATE:

As per the feedback provided in a comment, please refer to the inline comments for clarification (especially note the modification in the first line of the HTML snippet).

$(document).ready(function() {
    // Record the original value of each input to compare with later
    $('div.ap-create-story-panel-wrap input').each(function() {
        $(this).data('old', $(this).val());
    });

    // Listen for mouse clicks anywhere except input fields
    $(document).mouseup(function(e) {
        // Identify which input values changed
        $('div.ap-create-story-panel-wrap input').each(function() {
            let ov = $(this).data('old');
            let nv = $(this).val();
            
            if(nv != ov) {
                console.log('Previous value: ',ov || "empty field");
                console.log('Current value: ',nv || "empty field");
                
                // Trigger a click event on the respective button
                let tgt = $(this).closest('div.ap-create-story-panel-wrap').data('panel');
                
                console.log('Change detected in ', tgt);
                
                let bCls = '.btn-'+tgt;   // Button class
                $(bCls).trigger('click');

                // Update data-old with the new value for further tracking
                $(this).data('old', $(this).val());
            }
        });
    });
    
    $('div.ap-create-story-panel-wrap').on('click', function(e) {
      e.stopPropagation();
      return false;
    });

    // Added only for demo purposes, unnecessary in actual codebase
    $('a').on('click', function() {
        console.log('Clicked button target: ', $(this).data('target'));
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<!-- P.S: Modified data-panel="infopanel" to data-panel="basicinfopanel" for consistency with other divs -->
<div class="ap-create-story-panel-wrap" data-panel="basicinfopanel">
  <input type="text">
</div>
<a class="btn-basicinfopanel" data-target="certificatepanel">Save/Next</a>

<div class="ap-create-story-panel-wrap" data-panel="certifypanel">
  <input type="text">
</div>
<a class="btn-certifypanel" data-target="certifypanel">Save/Next</a>

<div class="ap-create-story-panel-wrap" data-panel="photopanel">
  <input type="text">
</div>
<a class="btn-photopanel" data-target="photopanel">Save/Next</a>

I hope this explanation is beneficial.

Answer №2

To determine which button to trigger on a change event, you can access the parent element of the input that was altered and check its data-panel attribute.

$('.ap-create-story-panel-wrap').change(function(e) {
  var container = $(e.target).parent();
  $(document).mouseup(function(e) {
    var dataPanelName = container.attr("data-panel");
    $(".btn-" + dataPanelName).trigger("click");
  });
});

Keep in mind that creating an event handler on the document may cause it to persist beyond the initial click trigger. Consider removing the listener after it has been triggered once.

Instead of triggering a button click, consider directly calling the relevant javascript functions for better performance.

Answer №3

Have you considered using the || operator instead of &&?

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

Utilizing JQuery Ajax in Synchrony with UI Dialogs

I am struggling with creating an ajax pop up when a button is clicked in the order include of my main smarty template. Despite including jquery, jquery ui, and the necessary js file script, the page just reloads instead of displaying the pop-up as intended ...

"Modifying a variable within an object while iterating through a loop

I am attempting to update a variable within an object while looping through the elements. Specifically, I am targeting all parent elements with the class "parent" to use with the ScrollMagic plugin. Here is my code: var childElement = $('.child' ...

Encountered an issue in GoJS with Angular 4: ERROR TypeError: Unable to access property 'class' of null at Function.F.fromJson.F.fromJSON

I have just started exploring GoJS and decided to create a sample project by utilizing the Kanban sample available on the GoJs website. I attempted to use Angular and Typescript for this, but encountered an error. AppComponent.html:1 ERROR TypeError: Cann ...

JQuery is having trouble with playing multiple sound files or causing delays with events

I've been working on a project that involves playing sounds for each letter in a list of text. However, I'm encountering an issue where only the last sound file is played instead of looping through every element. I've attempted to delay the ...

Is there a way to check if a user has previously visited a URL and automatically redirect them back to that page if they have

I'm looking for a way to detect if a user has already opened a specific link or URL in their browser tab. Is it possible to redirect the link to an active tab if the URL is already open? For example, if a user clicks on a link and JS code opens a new ...

Suggestions for retaining buttons functionality during drag and drop operations using jQuery UI?

My goal is to create new preset buttons when a button is dropped into the "timeslot" div. However, I am struggling to achieve this and ended up creating a function called "init()" which removes all existing buttons and generates new preset buttons every ti ...

Javascript Callback function not working as expected

I'm attempting to include an anonymous callback function in my code. I know it might seem a bit messy. By typing into the intro section, it triggers the animation using the .typed method with specific parameters. What I'm struggling to do is imp ...

Obtain all the data in the table cells using Jquery

I've been tasked with a unique challenge. There's a table with a form inside it, and I'm using Jquery to handle the form. Is there a way to retrieve the data from the <td></td> element without any specific id or class? The situa ...

Troubleshooting: How the Mozilla scrollbar is affecting the positioning of my elements (with jsfiddle

I need assistance with my code on both Chrome and Mozilla browsers. The layout looks perfect in Chrome, but in Mozilla, the scrollbar is affecting the positioning of my list elements. Could someone please help me figure out how to make it consistent acros ...

Is there a way to switch out the navigation icons on the react-material-ui datepicker?

Can the navigation icons on the react-material-ui datepicker be customized? I've attempted various solutions without any success. <button class="MuiButtonBase-root MuiIconButton-root MuiPickersCalendarHeader-iconButton" tabindex="0&q ...

Is it possible to delete a section of the URL within an anchor tag prior to the #anchor

My webpage contains a link that looks like this: <li class="jump"><a href="http://example.com/#about">About Me</a></li> I am interested in using jQuery to eliminate the 'http://example.com/' section of any URL found with ...

Show the information received from ajax on the webpage

I am facing an issue with displaying the value I receive from AJAX data in this modal. I have set the id="view_name" on a span element but for some reason, it's not showing up. Below is the code snippet that triggers the fun_view function: <td> ...

Issue with STS 4.7: CSS Autocomplete feature not functioning properly in Spring Boot project

Currently working on a web application using Spring Boot and Thymeleaf as the template engine. I've stored all my CSS files in the "resource/static/css" directory. However, when attempting to edit an HTML file, STS does not provide suggestions for CSS ...

Generate time-dependent animations using circles

Hey there, I am trying to create an animation that involves drawing three circles and having one of them move from right to left. The circles should appear randomly in yellow, blue, or orange colors on the canvas at different intervals (3 seconds between ...

What are some ways to enhance mobile browsing with CSS?

I'm facing a challenge with optimizing my webpage for different mobile resolutions in my beginner HTML/CSS course. Whenever I use a website resolution simulator to test, the layout doesn't look right on certain settings. Is there a method to aut ...

Include a border around the list items within two separate columns

I am trying to create 2 columns using li and want to add borders to each of them. However, I'm facing an issue where there are double borders for 2 li. This is the code snippet I have tried: .ul1 { column-count: 2; column-gap: 0px; } .li1 ...

What is the best method for creating uniform cards with different amounts of text that won't cause overflow issues?

At the moment, I have a container that acts as a boundary for a group of cards: .cards-container { display: flex; align-items: stretch; justify-content: center; flex-wrap: wrap; margin-top: 20px; border: 5px solid violet; } .card { ...

Adjust the color of a specific cell within a table using JavaScript

I am looking to dynamically change the row color based on the content of a <td> tag using only HTML, CSS, or JS within my current application setup that does not support external src. Below is the code snippet: table { width: 750px; border-c ...

Designs for an HTML5 Cheeseburger navigation interface

I've been struggling to implement a functional and visually appealing hamburger menu on my website. The challenge lies in integrating the menu seamlessly into the page rather than having it just pop up abruptly. Despite trying various webkit tools, I ...

Challenges with CSS floating and centering in responsive design

My footer consists of 3 elements structured in the following way: <div class="footer"> <div class ="jumperMenu"> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> ...