Utilize JQuery to create expand and collapse functionality for a div

Trying to decipher the intricacies of this JQuery code has been quite the challenge for me. I would normally opt for a different approach, but it seems I must adhere to this particular method. My main issue lies in getting the functionality right - when clicking on the plus symbol, content should expand and the symbol should change to a minus symbol with a color change. The expanding part works fine, but the collapsing doesn't quite function as intended. Additionally, the use of Sass in this project has me stumped, particularly the &.expanded syntax. What exactly does it signify? I've combed through the HTML but can't seem to locate a class named expanded, yet it's referenced in the JQuery code within the _Layout file.

Unclear JQuery function ($(".contact_item.expanded") ?? What does this signify?):

<script>
        /* expand */
        $(".contact_item .head").click(function () {
            $('.contact_item.expanded .head').next('div').slideUp();
            $('.contact_item.expanded').removeClass('expanded');
            $(this).parent('div').toggleClass('expanded');
            $(this).next('div').slideDown();
        });
    </script>

The perplexing Sass code snippet featuring the enigmatic & symbol:

 .contact_item {
        width: 100%;
        border: 1px solid #f1e7e0;
        background-color: #fcf6f5;
        margin: 3px 0px;
        float: left;

        &.expanded {
            .head .name {
                color: #f60;
            }

            .head .name span {
                border-color: #f60;
                color: #f60;

                &.plus {
                    display: none;
                }

                &.minus {
                    display: block;
                }
            }
        }

        .head {
            .name {
                font-family: "Tahoma";
                color: rgb(100, 100, 100);
                font-size: 11.1px;
                text-transform: uppercase;
                padding: 7px 15px;
                cursor: pointer;
                position: relative;

                span {
                    position: absolute;
                    display: block;
                    width: 20px;
                    height: 20px;
                    border-radius: 50%;
                    border: 1px solid #706f6f;
                    text-align: center;
                    right: 15px;
                    top: 7px;
                    font-size: 18px;
                    line-height: 17px;

                    &.minus {
                        display: none;
                    }
                }
            }
        }
    }

It's evident in this image that the CALIFORNIA OFFICE section is expanded, but the collapse and expand behavior of clicking the minus symbol is glitchy...

https://i.sstatic.net/yPC6N.png

UPDATE

Using the F12 tool to inspect the HTML, it's clear that <div class="contact_item"> transitions to

<div class="contact_item expanded">
, but this transformation isn't reflected in Razor:

       <div class="row">
                                    <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
                                        @{ var locations = LocationLookup.GetLocations(); }
                                        @{ int numloc = locations.Count / 2;}
                                        @{ var newlist = locations.Take(numloc);}
                                        @foreach (var loc in newlist)
                                        {
                                            <div class="contact_item ">
                                                <div class="head">
                                                    <div class="name">@loc.Name office<span class="plus">+</span> <span class="minus">-</span></div>
                                                </div>
                                                <div class="info">
                                                    <ul>
                                                        <li>
                                                            <div class="icon"><img src="//lig.azureedge.net/public/UK/Content/Images/marker.png" alt=""></div>
                                                            @loc.Address @loc.Continued, @loc.City, @loc.PostCode, @loc.State
                                                        </li>
                                                        <li>
                                                            <div class="icon"><img src="//lig.azureedge.net/public/UK/Content/Images/phone.png" alt=""></div>
                                                            @loc.Phone
                                                        </li>
                                                    </ul>
                                                    <div class="clearfix"></div>
                                                </div>
                                            </div>
                                        }
                                    </div>
                                    <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
                                        @for (int i = numloc; i < locations.Count; i++)
                                        {
                                            <div class="contact_item ">
                                                <div class="head">
                                                    <div class="name">@locations[i].Name office<span class="plus">+</span> <span class="minus">-</span></div>
                                                </div>
                                                <div class="info">
                                                    <ul>
                                                        <li>
                                                            <div class="icon"><img src="//lig.azureedge.net/public/UK/Content/Images/marker.png" alt=""></div>
                                                            @locations[i].Address @locations[i].Continued, @locations[i].City, @locations[i].PostCode, @locations[i].State
                                                        </li>
                                                        <li>
                                                            <div class="icon"><img src="//lig.azureedge.net/public/UK/Content/Images/phone.png" alt=""></div>
                                                            @locations[i].Phone
                                                        </li>
                                                    </ul>
                                                    <div class="clearfix"></div>
                                                </div>
                                            </div>
                                        }
                                    </div>
                                </div>
                            </div>

This is the HTML code as displayed using the F12 tool in the browser, showcasing the structure within <section class="hidden-print" id="contact"> and the dynamic changes occurring with the <div class="contact_item"> sections.

Answer №1

Let's dive into the world of jQuery selectors and SASS to enhance our coding knowledge.

When using jQuery, remember that a selector line starts with the dollar sign ($) which represents jQuery functionality.

The selector you provide functions just like a CSS selector and targets specific elements in the HTML.

For example,

var elementsWithAppleClass = $(".apple");
will locate all elements with the CSS class "apple".

Now, onto understanding SASS - a CSS extension with added syntax for easier and more efficient styling.

In SASS, CSS selectors can be nested to streamline your coding process. For instance:

.banana
{
   .pear
   {
      /* Styles for elements with the pear class inside a banana class element */
   }
}

The & operator in SASS refers back to the above class and the condition following it.

.banana
{
   &.pear
   {
       /* Styles for elements with both banana and pear classes */
   }
}

You can also utilize this technique to write styles for nested CSS states.

.banana
{
    &:hover
    {
       background-color: yellow;
       cursor: pointer;
    }
}

Addressing your current issue:

To solve your problem effectively, ensure that the clicked item's current state is considered when implementing your logic.

    /* Expand */
    $(".contact_item .head").click(function () {

        if($(this).parent('div').hasClass('expanded'))
        {
           // The item is already expanded, collapse it.
           $(this).parent('div').toggleClass('expanded');
           $(this).next('div').slideUp();
        }
        else
        {
           // Another item is expanded, collapse it first.
           $('.contact_item.expanded .head').next('div').slideUp();
           $('.contact_item.expanded').removeClass('expanded');

           // Now expand the clicked item.
           $(this).parent('div').toggleClass('expanded');
           $(this).next('div').slideDown();
        }

    });

Check out the demo on jsfiddle

Answer №2

To start off, let's delve into the meaning of &.expanded in SaSS and $(".contact_item.expanded") in JQuery with some straightforward examples. (If you're not interested, skip to the answer below)

In SaSS, & signifies a parent selector. It is commonly used when nesting styles. Here's a simple illustration:

div {
  &.red { //equivalent to "div.red" in CSS (a div with the class 'red')
     background: red;
  }
}

In the above example, & references the parent, which is div. When SaSS is compiled to CSS, it will result in div.red... with & representing div (the parent)

Next, the .red (class 'red') following & indicates that the div possesses the class 'red'. This implies the HTML structure to be:

<div class="red">
  ... this will have a red background ...
</div>
<div>
  ... this will not have a red background ...
</div>

Note: div.red is DISTINCT FROM div .red, observe the space between div and .red. To learn about the distinction, check out the link provided below

Regarding $(".contact_item.expanded") in JQuery, it denotes that you're searching for an element with both the classes contact_item AND expanded SIMULTANEOUSLY. It will locate elements such as:

<div class="contact_item expanded">
  ... this div will be selected ...
</div>
<div class="contact_item">
  ... this div will not be selected ...
</div>
<div class="expanded">
  ... this div will not be selected ...
</div>

You can explore various selectors here

AS FOR YOUR QUESTION, YOUR JAVASCRIPT SHOULD BE -

    $(".contact_item .head").click(function () {
       if($(this).parent('div').hasClass('expanded')) {
         $(this).next('div').slideUp();
         $(this).parent('div').removeClass('expanded');
        } else {
          $(this).parent('div').addClass('expanded');
          $(this).next('div').slideDown();
        }
    });

View the Codepen demonstration here

In simpler terms, you also need to verify if the expanded class exists initially before adding or removing it as needed. The provided code accomplishes this.

Trust this explanation was helpful.

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

Incorporate Videos into HTML Dynamically

Is there a way to dynamically embed videos from a source into an HTML page? My goal is to make it easy to add new videos to the page by simply placing them in a folder and having them automatically embedded. I am wondering if this can be achieved using J ...

How can JQuery detect input in the fields?

I have the following HTML code and I am looking to trigger a function based on the input in any of the input fields, regardless of the field number. <input type="text" pattern="[0-9]*" name="code" maxlength="1" au ...

Why won't the sound play on the button with the picture?

I am currently working on a website project that requires buttons with pictures and sound. Despite my efforts, the sound feature is not functioning properly in Chrome and Firefox. I am still learning and would like to know how to toggle the sound on and of ...

Transforming with Babel to create pure vanilla JavaScript

Our current development process involves working with a custom PHP MVC Framework that combines HTML (Views), PHP files, and included JS with script tags (including JQuery, Bootstrap, and some old-fashioned JS libs). During the development stages, we want ...

Error: Attempting to access property 'question' of an undefined value

Trying to render information from a local .json file using Javascript functions, I encountered an error in the console for const answer despite being defined. I temporarily commented it out to test the function, only to receive the same TypeError for quest ...

Words with emphasized border and drop shadow effect

I am trying to achieve a specific font style. If it's not possible, I would like to get as close as possible to the desired style. However, due to IE support requirements, I am unable to use text-stroke. https://i.sstatic.net/JwQyb.png The closest a ...

The top margin in CSS relative positioning is not being displayed

My client has a specific requirement for the webpage to be positioned in the center of the screen. To achieve this, I have enclosed the entire webpage within a div element called "mainpage". Here is the CSS code: #mainpage { position:relative; wi ...

Creating functional dropdown menus with popperjs in the latest Bootstrap version 5

Currently, I am attempting to implement dropdown menus in Bootstrap 5. According to my research, this feature requires Popper.js integration, but I am uncertain of the correct way to include it in my Laravel project that utilizes Laravel Mix. I have made ...

Path dependency for sass in Laravel Elixir

Currently, I am working with Laravel 5.2 using elixir. I have encountered an issue when trying to integrate bootstrap-material-design with bootstrap-sass. The gulp task is giving me the following error message: gulp-notify: [Laravel Elixir] Sass Compilati ...

Tracking ajax calls with piwik: A step-by-step guide

I'm curious about how to enable piwik to track ajax requests. I know there is an API available, but I'm unsure about the exact steps I need to take in order to view ajax loaded pages in the dashboard. Could it be something like this: _paq.push( ...

Navigational elements, drawers, and flexible designs in Material-UI

I'm working on implementing a rechart in a component, but I've encountered an issue related to a flex tag. This is causing some problems as I don't have enough knowledge about CSS to find a workaround. In my nav style, I have display: flex, ...

Conflict between Angular's ng-repeat directive and Sass styling

Currently, I am working on a project and encountering an issue that is causing some difficulty: In order to create a navigation bar with equally distributed list elements based on the number of items, I am utilizing ng-repeat for data binding and Sass for ...

Modify the appearance of a specific <td> element using JavaScript to change its color

I am working on creating a quiz using HTML, displayed in a table format. Upon verification, I want to highlight the correct choice (which is represented by a <td> tag) in green, and the incorrect choice in red using the background property. Is there ...

Incorporating Bootstrap content directories into ASP.NET website projects

I've been experimenting with Bootstrap for website design, but I'm facing an issue with adding files to my project. When creating a project in Visual Studio 2015 using File/New/Web Site..., I'm able to simply Copy/Paste the css, fonts, js fo ...

Despite receiving fail reports, the AJAX post request actually successfully completes

Strange scenario. I have implemented AJAX to send data to a service, and the data is successfully stored in the database. However, instead of entering the done() section of the code, it always ends up in the fail() section for some unknown reason. Here is ...

Django redirects to an alternative template instead of the default one

After renaming my login.html file to login1.html instead of deleting it, I have been using Django-registration and Django-registration-views from Github. However, despite this change, Django continues to call registration/login1.html. Is there a way for me ...

what is the easiest way to retrieve JSON data by referring to HTML values using jQuery?

Although I am new to jquery, I am determined to complete my project. Seeking assistance from experienced individuals. My goal is to code the following HTML structure: <li value="bca"></li> <li value="bni"></li> <li value="bri"& ...

Mobile Chrome allows users to utilize the IFrame player API for enhanced video

Currently, I am working on creating a mobile website where I plan to include some YouTube videos using the IFrame player API (https://developers.google.com/youtube/iframe_api_reference). My main goal is to have the video start playing only after the user ...

Preserve the Browser Scroll Position when navigating to another page

Currently tackling a challenge with JS, JQuery, and PHP where I'm attempting to resolve an infinite scroll issue. The specific problem arises when scrolling down the page extensively while loading more pages via ajax, then navigating to a different pa ...

What is the best way to "re-upload" drop-down selection using javascript?

I am attempting to automate a drop-down selection process on a website using a headless browser called Firefox Marionette. The website is not under my control, and the process involves: A primary drop-down menu where I can choose an option. A secondary dr ...