Transform js into a more dynamic format to avoid redundancy when displaying items upon click

I came across a simple lightbox code snippet, but it's based on IDs and I plan to use it for more than 20 items. I don't want to manually write out 20 JavaScript lines when there could be a more efficient way to handle it dynamically. My JS skills are not advanced enough to streamline this process.

codepen link

HTML:

<template id="one">
    <h1>Using HTML &lt;template one&gt; Tag</h1>
    <p>The template element contains HTML code without displaying it.<br>Not supported in older browsers.</p>
</template>


<button class="template" data-ref="one">template</button>


<template id="two">
    <h1>Utilizing HTML &lt;template two&gt; Tag</h1>
    <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
</template>


<button class="template" data-ref="two">second template</button>

JS:

const templateInstance = basicLightbox.create(document.querySelector('#one'))
const templateInstanceTwo = basicLightbox.create(document.querySelector('#two'))


document.querySelector('button.template' + '[data-ref=one]').onclick = templateInstance.show
document.querySelector('button.template' + '[data-ref=two]').onclick = templateInstanceTwo.show

While this setup does function, it lacks scalability when dealing with a large number of templates.

Answer №1

To streamline the code, you can implement a loop that goes through each button.template element to add individual event handlers. Within these handlers, extract the value from the data-ref attribute and utilize it to create the lightbox. Below is a functional example:

document.querySelectorAll('button.template').forEach(button => {
  button.addEventListener('click', e => {    
    basicLightbox.create(document.querySelector(e.target.dataset.ref)).show();
  });
});
html {
  width: 100%;
  height: 100%;
  font-family: sans-serif;
}

body {
  display: flex;
  align-items: center;
  align-content: center;
  justify-content: center;
  flex-wrap: wrap;
  min-height: 100%;
  margin: 0;
  color: white;
  text-align: center;
}

button {
  display: inline-block;
  appearance: none;
  background: #2875ed;
  margin: .5em;
  padding: .5em 1em;
  border: none;
  color: white;
  font: inherit;
  border-radius: 3px;
  cursor: pointer;
  outline: none;
}
<link rel="stylesheet" href="//s.electerious.com/basicLightbox/dist/basicLightbox.min.css" />
<script src="//s.electerious.com/basicLightbox/dist/basicLightbox.min.js"></script>
<template id="one">
  <h1>HTML &lt;template one&gt; Tag</h1>
  <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
</template>
<button class="template" data-ref="#one">template</button>

<template id="two">
  <h1>HTML &lt;template two&gt; Tag</h1>
  <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
</template>
<button class="template" data-ref="#two">template two</button>

Answer №2

Here is an alternative method using pure javascript, without the need for an external library:

function initialize() {
    let buttons = document.querySelectorAll("button.template");
    for (let button of buttons) {
        button.onclick = displayTemplate;
    }
}

function displayTemplate(event) {
    let main = document.querySelector("main");
    let template = document.querySelector("template").content;

    let element = template.querySelector(`div#${event.currentTarget.dataset.templateId}`);
    if (!element) return;

    template.append(...main.childNodes);
    main.appendChild(element);
}

window.onload = initialize;
* {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
}

body {
    padding: 1rem;
}

button {
    font-size: 1rem;
    color: white;
    background-color: blue;
    border: none;
    border-radius: .25rem;
    padding: .50rem;
}
<nav>
    <button class="template" data-template-id="t1">Template 1</button>
    <button class="template" data-template-id="t2">Template 2</button>
    <button class="template" data-template-id="t3">Template 3</button>
    <button class="template" data-template-id="t4">Template 4</button>
</nav>
<br>
<main>
    <h2>Choose a template</h2>
</main>

<template>
    <div id="t1">
        <h1>Template 1</h1>
        <p>The day had started brightly. The sun finally peeked through the rain after a week, and birds were chirping in its warmth. Little did anyone know what was about to unfold. It was a worst-case scenario with no escape.</p>
    </div>
    <div id="t2">
        <h1>Template 2</h1>
        <p>It had been Dana's dream for years, yet she failed to take any steps towards realizing it. There was always a valid excuse to delay or prioritize another project. As she woke up, she realized she stood at a crossroads once again. Would it be another excuse or would she finally gather the courage to chase her dream? Dana got up and took that crucial first step.</p>
    </div>
    <div id="t3">
        <h1>Template 3</h1>
        <p>Breastfeeding benefits both babies and mothers. Breastfed infants receive antibodies from their mothers against common illnesses. They are less likely to become obese as adults. Breastfeeding fosters a unique bond between mother and child. Mothers who breastfeed reduce their risk of developing breast cancer. Additionally, breastfeeding aids in quicker post-pregnancy weight loss. The advantages of breastfeeding are plentiful.</p>
    </div>
    <div id="t4">
        <h1>Template 4</h1>
        <p>A teardrop of amber clung to the branch, reaching fullness and waiting to fall. It lingered, unlike other droplets content to grow and release. This particular droplet had aspirations for legacy. It longed to be remembered long after its counterparts had faded into obscurity. And so, it awaited the perfect specimen to ensnare, hoping to be uncovered centuries later as a cherished relic.</p>
    </div>
</template>

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

Using AngularJS to send a post request with cherrypy

I am facing an issue with posting events into a CherryPy small application that responds to GET/POST requests. When attempting to do so using AngularJS, nothing gets posted. I'm unsure if the problem lies with AngularJS or CherryPy (CP). Cross-domain ...

What is the best way to manually decrease the speed of an object's rotation using javascript?

Can anyone assist me with slowing down the mouse-controlled rotation of a 3D object in javascript? The current rotation is too sensitive and difficult to control manually. Below is the code I am using: <html> <head> <script src="js/thr ...

How can the first character position be reached by moving the cursor using the jquery mask plugin?

I have done a lot of research but couldn't find the exact same question with a satisfactory answer. Therefore, I decided to ask a more specific question. I am using the Jquery mask plugin and I want my cursor to always be at the beginning of the textb ...

The correct conclusion is reached by the function when the console.log statement is placed above the function call

By moving the console.log above the function call, the correct conclusion is reached. I double-checked multiple times by toggling the console.log on and off. Running on node.js v16.4.2. The input data is accurate. I attempted to replicate the issue in a di ...

What is the reason why Prettier does not automatically format code in Visual Studio Code?

After installing and enabling ESLint and Prettier in my Nuxt application, I made the switch to Visual Studio Code. However, when I open a .vue file and use CMD+ Shift + P to select Format Document, my file remains unformatted. I even have the Prettier ex ...

Formatting decimals with dots in Angular using the decimal pipe

When using the Angular(4) decimal pipe, I noticed that dots are shown with numbers that have more than 4 digits. However, when the number has exactly 4 digits, the dot is not displayed. For example: <td>USD {{amount| number: '1.2-2'}} < ...

Instructions on allowing the user to enter text for searching through an array of objects, and displaying a message if a match is found. Use only pure JavaScript

As a newcomer to JavaScript, I greatly appreciate the support from everyone on this platform. Thank you in advance for your help! I am currently working on building a basic music app as a learning project in JavaScript. The main goal is to understand how J ...

Adding content into a designated position in a document

My challenge is to find the index of user-provided data in order to insert new data at that specific point. I am familiar with array insertion methods, but extracting the index provided by the user is where I'm stuck. My current approach involves filt ...

Tips for sending a form without reloading the page in node.js and ejs

<form action="" method="post"> <div class="bottom_wrapper clearfix"> <div class="message_input_wrapper" id="eventForm"> <input class="message_input" name="msg" placeholder="Type your message here..." /> </div ...

Implementing character limits in VueJS fields

new Vue({ el: '#app', data() { return { terms: false, fullname:'', maxfullname: 10, mobile: '', maxmobile: 10, area: '', maxarea: 12, city: '', ...

What is causing fs.readFileSync to not recognize my json document?

So, I've been working on creating a Discord bot that can extract specific data from my JSON file. Here is the structure of my project: Project | +-- data/ | | | +-- compSciCourses.json | +-- src/ | | | +-- search.js | +-- bot.js | +-- t ...

The sequence of error middleware in Express4

Encountered a series of code execution that seemed unusual. Here's the code snippet: server.js const Actions_Single_PVC = require('./routes/Actions_single_PVC.js'); app.use('/Actions_single_PVC', Actions_Single_PVC); app.use((e ...

Tips for preventing recursion when utilizing scrollIntoView() in a scroll event handler

My goal is to break down my website into screen-sized sections that automatically scroll to the next section when a user begins scrolling. I attempted to accomplish this by using the following code: $(window).scroll(function() { getElementToScroll().s ...

Error encountered while executing jest tests due to an unexpected import token

Despite trying numerous solutions and suggestions on Stack Overflow, I am still unable to resolve the issue at hand. I recently discovered jest and attempted to use it by following a tutorial on testing React components with jest from DZone. However, when ...

Google Bar Graphs Cannot Display Decimal Values

Having an issue with my bar chart from Google Chart not displaying float numbers. Other types of bar charts provided by Google Chart work fine, but this specific type doesn't show the float numbers. Here is the code I have written: http://jsfiddle.ne ...

Unable to initiate the server generated by the express.js generator

Currently, I am trying to set up an Express.js server using their generator. Following the documentation, I was able to successfully create the basic structure. However, when attempting to run the prescribed command (SET DEBUG=transcriptverificationserver: ...

Typescript inheritance results in an undefined value being returned

I am trying to understand the code below, as I am confused about its functionality. In languages like C# or Java, using the base or super keyword usually returns values, whereas in TypeScript, I am receiving "undefined". However, when I switch from using " ...

Watching a Computed Value in EmberJS

What causes the discrepancy between the two sets of code? Utilizing computed: computed: Ember.computed('selected', function() { console.log('computed'); return this.get('selected'); }), observer1: Ember.observer(&ap ...

Sending a $.ajax post request transforming into a get

Struggling to understand the behavior of my jquery ajax request, I've hit a roadblock. function newContact() { $.ajax({ type: 'POST', contentType: 'application/json', // url: ...

Using React with Axios to trigger several requests with a single action

Let's say a user selects a team from a dropdown menu, triggering a request to an API endpoint. const selectHomeTeamStat = evt => { const { value } = evt.target; getStats(leagueId, value, 'home'); }; In this hypothetical scen ...