Utilizing jQuery to close a modal when clicking outside of its container

Trying to target elements in my practice layout but struggling to figure out the right approach:

BASIC HTML

<button id="opencontact" type="button" name="button">
  <i class="far fa-envelope fa-2x"></i>
</button>

<section id="contact-section">
  <div class="contact-container">
    <div class="contact-content">
      <h2>Contact Us</h2>
      <label for="">Email</label>
      <input type="text" name="" value="">
      <label for="">Name</label>
      <input type="text" name="" value="">
      <label for="">Message</label>
      <textarea name="name" rows="8" cols="80"></textarea>
      <button type="button" name="button">Submit</button>
    </div>
  </div>
</section>

CSS STYLES:

body {
  padding: 0;
  margin: 0;
  font-family: Helvetica;
  box-sizing: border-box;
}

#opencontact {
  bottom: 10px;
  right: 10px;
  position: fixed;
}

#contact-section {
  height: 60%;
  width: 40%;
  position: absolute;
  top: 20%;
  left: 30%;
  display: none;
  align-items: center;
  justify-content: center;
  background-color: red;
}

#contact-section.show {
  display: flex;
}

.contact-container {
  height: 90%;
  width: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

.contact-content {
  height: 90%;
  width: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

JQuery SCRIPT to open the contact-section when #opencontact is clicked:

<script type="text/javascript">

  $("#opencontact").click(function() {
    $("#contact-section").toggleClass("show");
  });

</script>

Need help with a script to close the modal when clicking outside the #contact section. Existing solutions tried didn't work, so looking for suggestions.

Answer №1

To start, you need to set up a click listener for the entire website. Each time a click occurs, you will check if the element you are interested in is clicked. Despite the fact that an if statement is executed for every click, this does not pose a performance issue and is the correct way to address this situation.

Your code should resemble the following (without using jQuery). For reference, you can view the snippet here.

const contactSection = document.querySelector('#contact-section');
let isContactSectionShowed = false;

window.addEventListener('click', function (e) {
  if (e.target === contactSection && !isContactSectionShowed) {
    contactSection.classList.add("show");
    isContactSectionShowed = true;
  } else if (e.target !== contactSection && isContactSectionShowed) {
    contactSection.classList.remove("show");
    isContactSectionShowed = false;
  }
});

Answer №2

$(document).ready(function() {

  const modal = $('#contact-section');

  $("#opencontact").click(function() {
    modal.toggleClass("show");
  });

  $(document).click(function(event) {
    // Check if NOT click on modal or button
    if (!$(event.target).closest("#contact-section, #opencontact").length) {
      modal.removeClass("show")
    }
  });

});
body {
  padding: 0;
  margin: 0;
  font-family: Helvetica;
  box-sizing: border-box;
}

#opencontact {
  bottom: 10px;
  right: 10px;
  position: fixed;
}

#contact-section {
  height: 60%;
  width: 40%;
  position: absolute;
  top: 20%;
  left: 30%;
  display: none;
  align-items: center;
  justify-content: center;
  background-color: red;
}

#contact-section.show {
  display: flex;
}

.contact-container {
  height: 90%;
  width: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

.contact-content {
  height: 90%;
  width: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js" integrity="sha256-KzZiKy0DWYsnwMF+X1DvQngQ2/FxF7MF3Ff72XcpuPs=" crossorigin="anonymous"></script>

<button id="opencontact" type="button" name="button">
  <i class="far fa-envelope fa-2x"></i>
</button>

<section id="contact-section">
  <div class="contact-container">
    <div class="contact-content">
      <h2>Contact Us</h2>
      <label for="">Email</label>
      <input type="text" name="" value="">
      <label for="">Name</label>
      <input type="text" name="" value="">
      <label for="">Message</label>
      <textarea name="name" rows="8" cols="80"></textarea>
      <button type="button" name="button">Submit</button>
    </div>
  </div>
</section>

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

What's the ideal file structure for Codeigniter paired with Angularjs?

Recently, I embarked on a project using Codeigniter and AngularJS for an app. However, I encountered some issues when attempting to use font-awesome offline. After investigating the problem, I concluded that it may be related to the file folder structure ...

Is there a way for me to set a default filename when saving an HTML page?

On my webpage, such as www.example.com/NYSE/rates, I want to give the user the option to save the HTML they see on their local disk. When they click "Save as", I would like to automatically set the default filename to be NYSE_rates_09_12_2011.html. This fi ...

What is the best strategy for positioning an anchor element within a list item using JSX or Bootstrap in a way that maximizes efficiency?

I have the following code snippet <li className = "list-group-item list-group-item-success" key ={todo.id}>{todo.text}<a style="float:right;" onClick={() => props.onEdit(todo)} className="edit-todo glyphicon glyphicon-edit" href="#"& ...

The img:first-of-type selector targets specifically the first image within a group

When a user visits my website using a touch device or without Javascript support, I want the first of two images to display. To achieve this, I am targeting them using Modernizr. The menu button at the top of the page: <img src="menubutton.png" alt="M ...

extract information from the HTML id attribute and assign it to a PHP variable using the GET method

After reviewing numerous examples, I am still unable to retrieve the value from the ID attribute in my input element. This identifier is crucial for deleting records from the database, but my attempts with Get method have been unsuccessful. <?php ...

Line breaks showing up on the page that are not present in the HTML source code

Why are unwanted line breaks appearing in my rendered DOM that are not in the source code, causing the content to be displaced? And how can I resolve this issue? Below is the code snippet: <div class="float-left" style="position:relative;left:15px"> ...

Creating a menu bar in jQuery that functions similarly to tabs, but without the need to change divs

Currently, I am exploring ways to create tab functionality similar to jQuery's tabs plugin but without the need to switch between DIVs. Essentially, I am looking for a jQuery plugin that solely handles rendering the tab bar and allows me to designate ...

Issues with Stylesheet Rendering in Firefox

Take a look at this Kendo UI Dojo example: When rendered in Firefox, the "right" should also be placed in the header, but it's not. It works correctly in IE11 and Chrome. What am I doing wrong? ...

Can the <container> block be positioned beneath the <header> block?

header { background: blue; color: white; width: 100%; } .container { background: green; text-align: center; width: 100%; height: 100px; transform: skew(0, -10deg); color: white; position: relative; top: 55px; } .container .home{ p ...

The size of the cursor varies depending on the line it's placed on

I have a content editable div where three lines are separated by BR tags. When I click on the second line, the cursor becomes bigger than that in the first line. .content { line-height: 35px; } <div class="content" contenteditable="true"> ...

Integrating HTML into a C# Windows form application

Just diving into the world of online shopping and came across an e-commerce cart that I'd like to integrate into my own website. The platform provided me with a HTML code snippet for embedding, which is great. However, I'm wondering if it's ...

Trying to configure and use two joysticks at the same time using touch events

I have been grappling with this problem for the past two days. My current project involves using an HTML5/JS game engine called ImpactJS, and I came across a helpful plugin designed to create joystick touch zones for mobile devices. The basic concept is th ...

Navigating Tabs and jQuery for JSON Data Refresh: A Step-by-Step Guide

Struggling to implement a basic UI and seeking advice from the community. Here's my current setup: 1) Using getJSON to fetch a JSON string (multidimensional array) from a PHP page. 2) Utilizing 2 jQuery.each loops to iterate through the JSON data and ...

reveal the concealed divs within the list elements

html: In my HTML document, I have a unordered list (ul) with each list item (li) constructed like this: <li class="A">list-item <div>1</div> <div class="B">2 <div class="C">3</div> </div> ...

Is there a subsequent event that follows the data-rel attribute with the value of 'back'?

How can I determine the value of window.location.hash when a user navigates back using a button with data-rel='back'? Is there a specific event that triggers at this moment? ...

What is the best way to incorporate white-space:normal within the text of a jQuery Mobile grid button?

Below is the code for my jQuery Mobile Grid buttons: <div class="ui-grid-b my-breakpoint"> <div class="ui-block-a"><button type="button" data-theme="c"> <img src="res/icon/android/business.png" height="45"><br>Business</ ...

Automated tools and frameworks for the testing of website performance

Hello, I have a website that heavily relies on AJAX for server communication. I am looking to conduct performance and stress testing using automated scripts. Can you provide any suggestions or recommendations? I am specifically interested in the functiona ...

The export from chart.js does not include a member named 'ChartDataSets'. Perhaps you were referring to 'ChartDataset'? ts(2724)

Encountered an error message when trying to import ChartDataSets in line-chart.component.ts 'chart.js' does not have a member named 'ChartDataSets'. Perhaps you meant 'ChartDataset'? Uncertain about the source of the issue. C ...

A step-by-step guide on showcasing freshly submitted input data through Ajax

I'm having trouble with this issue! Once I submit the new input, it doesn't show up in the div. Below is my JavaScript code: $('#addVariable').validate({ rules: { variable: {required:true}} , submitHandler: functio ...

Utilizing AJAX to invoke a function

I'm having trouble explaining this, but I'll try my best. I created a function that calculates the remaining amount needed to qualify for free delivery based on different basket value thresholds. Whenever a product is added to the basket, the b ...