Use JavaScript to add a div element to the page ten times every time the button is clicked

Here is the code I have written:

$(document).ready(function () {
          $('<button class="btn more">View More</button>')
         .appendTo(".listing-item-container")
         .click(function() {
            $(this).closest(".listing-item-container").removeClass("collapsed");
          });
          $('<button class="btn less">View Less</button>')
         .appendTo(".listing-item-container")
         .click(function() {
           $(this).closest(".listing-item-container").addClass("collapsed");
         });
      });   
.listing-item-container.collapsed > :nth-of-type(n+3) {
      display:none;
    }
    
    .listing-item-container > .more {
      display:none;
    }
    .listing-item-container > .less {
      display:block;
    }
    
    .listing-item-container.collapsed > .more {
      display:block;
    }
    .listing-item-container.collapsed > .less {
      display:none;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="listing-item-container collapsed">
        <div class="listing-item">
            <p>FEATURES</p>
            <ul class="no-list-style">
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
            </ul>
        </div>
        <div class="listing-item">
            <p>FEATURES</p>
            <ul class="no-list-style">
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
            </ul>
        </div>
        <div class="listing-item">
            <p>FEATURES</p>
            <ul class="no-list-style">
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
            </ul>
        </div><div class="listing-item">
            <p>FEATURES</p>
            <ul class="no-list-style">
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
                <li>list content</li>
            </ul>
        </div>
        <!--  Remaining listing-item divs here   -->
    </div>

In the code above, clicking on view more will expand all remaining 'listing item' divs, while clicking on view less collapses all the divs to display only 2.

I want the functionality to show only the next 2 'listing item' divs when I click view more, along with the corresponding button. This pattern should repeat for all the remaining 'listing item' divs, and end with a view less button displayed. Clicking view less should collapse the last 2 'listing item' divs each time.

What changes can I make to my code to achieve this desired output?

Answer №1

The secret lies in utilizing the jquery slice() function (which is similar to javascript slice() but operates on a jquery collection).

var howManyItemsToShow = 2;
$(".listing-item").hide().slice(howManyItemsToShow).show();

This code snippet will hide all the items and then display the first 2 items. This triggers a single UI update action. If you incorporate animations like .slideDown / .fadeIn, the approach will be different.

You can increment your "pagesize" value (2 in this example) each time you click and make updates accordingly.

To control the display of more/less buttons efficiently, implement a check for start/end conditions and refer to the helpful css trick:

var lines = 2;
var pagesize = 2;

// Load them up-front assuming no changes for small efficiency gain (and DRY)
var items = $(".listing-item-container .listing-item");

$(document).ready(function() {
 $('#lt;button class="btn more">View More</button>')
    .appendTo(".listing-item-container")
    .click(function() {
    
      lines += pagesize;
      items
        .show()
        .slice(lines).hide();
        
      if (lines >= items.length)
        $(this).closest(".listing-item-container").removeClass("collapsed");
    });

  $('<button class="btn less">View Less</button>')
    .appendTo(".listing-item-container")
    .click(function() {
      // Similar logic for "less" with -= and different condition checks
      // Combine with "more" button for DRYness or keep separate for clarity
      lines -= pagesize;
      items.show();
      items.slice(lines).hide();
      if (lines <= pagesize)
        $(this).closest(".listing-item-container").addClass("collapsed");
    });
});
.listing-item-container.collapsed>:nth-of-type(n+3) {
  display: none;
}

.listing-item-container>.more {
  display: none;
}

.listing-item-container>.less {
  display: block;
}

.listing-item-container.collapsed>.more {
  display: block;
}

.listing-item-container.collapsed>.less {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="listing-item-container collapsed">
  <div class="listing-item">
    <p>FEATURES</p>
    <ul class="no-list-style">
      <li>list content</li>
      <li>list content</li>
      <li>list content</li>
      <li>list content</li>
    </ul>
  </div>
  <!-- Repeat listing-item div structure multiple times -->
  <!-- Additional listing-item divs go here   -->
</div>

Answer №2

I decree that it shall be done in this manner...

((parentRef='.listing-item-container', ItemsRef='.listing-item', startView=2, addView=2 )=>
 {
  const
    listItems  = document.querySelectorAll(ItemsRef)
  , btMoreLess = document.querySelector(parentRef).appendChild( document.createElement('button'))
    ;
  btMoreLess.className = 'showMore'

  var listItemsViewCount = startView -addView;

  btMoreLess.onclick =_=>
    {
    listItemsViewCount += btMoreLess.classList.contains('Less') ? -addView : +addView
    listItems.forEach( (item,i)=> item.classList.toggle('noDisplay',i>=listItemsViewCount) )

    if (listItemsViewCount >= listItems.length)  btMoreLess.classList.add('Less')
    else if (listItemsViewCount === startView)   btMoreLess.classList.remove('Less')
    }

  btMoreLess.click()  // commence
  }
)() // IIFE termination
.noDisplay{ display:none; } 
button.showMore:before { content : 'View More'; }
button.showMore.Less:before { content : 'View Less'; }

.listing-item-container   { counter-reset: itemCounter;         }
.listing-item             { counter-increment: itemCounter;     }
.listing-item > p::before { content: counter(itemCounter) '.';  }
<div class="listing-item-container">
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <div class="listing-item">
    <p>FEATURES</p>
    <ul> <li>list content</li> <li>list content</li> <li>list content</li> <li>list content</li> </ul>
  </div>
  <!--  100 more listing-item divs present here   -->
</div>

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

Chrome's spinner fails to appear when performing a synchronous ajax request in IE9

While implementing an ajax request, I want my users to see a spinner for visual feedback. Surprisingly, the spinner works flawlessly on Firefox 13, but fails to function on Chrome and IE9 even though the ajax request takes approximately 1.2 seconds to comp ...

Methods for encoding and decoding special characters using either JavaScript or jQuery

I am looking for a solution to encode and decode various special characters using JavaScript or jQuery... ~!@#$%^&*()_+|}{:"?><,./';[]\=-` I attempted to encode them using the following code snippet... var cT = encodeURI(oM); // ...

What is the best way to get rid of a connect-flash notification?

I'm having trouble removing the message (with the username displayed) after logging out by pressing the logout button. Every time I try to press the logout button, it just refreshes the page without any action. I want to stay on the same page and not ...

Express Module Paths Failing to Function Properly

When I first started building my routes, I had everything in one api.js file. However, I realized there might be a better approach, so I did some research online to see how others handle it. After following a few tutorials, I decided on a new layout with s ...

Steps for making a toggle button with Bootstrap

Initially, I developed a web application using HTML, CSS, and JavaScript. Later on, I was requested to recreate it using Bootstrap as well. While I managed to complete the task successfully, I encountered an issue where toggle buttons in the web app revert ...

Fixing the reinitialization of a data table

I've been grappling with this issue for quite some time now (exactly 5 days) and I keep encountering the following error. DataTables is throwing a warning: table id=activities-table - Cannot reinitialize DataTable. For more details regarding this ...

Is there a way to adjust the transparency of a span element's background without affecting the text itself?

I have some code that needs to be customized. This is my HTML: <div class="text-rotator add-top-half add-bottom-half align-left white-txt medium-txt uppercase highlight-bg"> <div class="rotator-wrap" style="display: block;"> <sp ...

Ways to stop React from refreshing the page upon clicking the submit button

Is it possible to prevent a React component from reloading the page when a submit button is pressed? Here is an example of component code: class MyComponent extends React.Component<IEditCampaignStateProps & IEditCampaignDispatchProps, EditCampaignStat ...

What is the best way to retrieve router parameters within a JSX component?

How can I pass the post ID as a prop to the EditPost component in order to edit it? render() { return ( <Router> <Switch > <Route path="/edit/:id"> <EditPost index={/*what do I do here?*/} /> ...

Struggling to verify credentials on CouchDB

I'm currently facing an issue with authentication while trying to access a couch server from a web application served on port 80. The credentials seem to be removed when passing them in the URL and the session cookie isn't sent to the server. He ...

Discover the method of connecting to a unique JavaScript trigger while utilizing IJavaScriptExecutor

In our web application, we have an event called timelineEventClicked that is created by a custom trigger. canvas.addEventListener('click', function (evt) { evt.stopImmediatePropagation(); var mousePos = ge ...

Customizing the title style of the Material-UI app bar

Is there a way to customize the AppBar title in Material-UI without using inline styling? I have a separate CSS file and I want to be able to adjust the size of the title, for example. Something along these lines: .app-bar title { font-size: 120px !i ...

Switching input types in Android WebView: From Numeric to Password

I am facing an issue with my webview. In the webview, I have three input types: Number Text Password The problem is that when I switch from the number input field to the password input field, the numeric keyboard opens up instead of the qwerty keyboard. ...

The middleware is causing disruptions in the configuration of redis and express

I've recently started using Redis and I'm facing an issue with my middleware 'cache' function that seems to be causing problems in my code. Everything works fine without it, the data displays correctly in the browser, and when I check f ...

Guide to implementing personalized validation for an angular component

In my Angular component, I am looking to implement a custom input validator. However, I am facing an issue while trying to access the ngModelController in the $onInit function. It seems that the form is not populated at this stage. Strangely, in the sendEm ...

What are some strategies for breaking down large components in React?

Picture yourself working on a complex component, with multiple methods to handle a specific task. As you continue developing this component, you may consider refactoring it by breaking it down into smaller parts, resembling molecules composed of atoms (it ...

Why is the Google Map missing from the Bootstrap modal dialog?

I have multiple links on my website, each describing a different location with unique map data. I would like to display a modal bootstrap dialog with an embedded Google map when a user clicks on any of the links - ensuring that the location shown correspon ...

Utilizing jQuery to send an Ajax GET request for a JSON file

Recently I have begun delving into the world of jQuery and Ajax, attempting to utilize both technologies to retrieve a JSON FILE. Below is the structure of the file: [ { "userId": 1, "id": 1, "title": "delectus aut autem", "completed": f ...

Adding over 20,000 rows to a table can be time-consuming, causing the page to become unresponsive once the process is complete

Looking at my table structure, it appears as follows: <tr ng-repeat="friend in friends | orderBy:predicate:reverse"> <td>{{friend.name}}</td> <td>{{friend.phone}}</td> <td>{{f ...

Convert text into a clickable link

Creating a form with numerous text fields, some of which require numerical input. The main goal is to have users enter a tracking number, order number, or any other type of number that, when submitted, will open a new URL in a separate window with the spec ...