Styling elements conditionally with AngularJS-controlled CSS

Looking for some guidance in Angular as a newcomer. I am attempting to adjust a style when clicked. On my page, I have multiple content spaces created using the same template. Upon clicking a "more" link, I desire to expand that specific section. I have achieved this functionality with the following code that triggers a CSS effect.

<a href="#" ng-click="isActive = !isActive"><strong>more</strong></a>

My challenge lies in collapsing the previously expanded section when a new section is clicked to expand. As it stands, the expansion only applies to the current section.

Answer №1

If you're looking to hide and show elements based on a variable other than a simple boolean true/false, you'll need to take a different approach. Here's one way to do it.

<a ng-click="active = 0" ng-class="{show: active==0}"></a>
<a ng-click="active = 1" ng-class="{show: active==1}"></a>

This method can also be used with ng-repeat for added flexibility

<a ng-repeat="section in sections" ng-click="active = $index" ng-class="{show: active==$index}"></a>

Answer №2

If you want to ensure only one item is selected at a time, utilize selectedItem in the $scope and apply ng-if in the template to verify if the chosen item matches the current item. See the example below:

angular.module('myApp', [])

.controller('MainController', function ($scope) {
    var items = [],
        vm = {};

    // properties
    $scope.vm = vm; 
    vm.items = items;
    vm.selectedItem = null;

    //methods
    vm.setItem = function (item) {
        // reset current item to more
        if (vm.selectedItem) {
          vm.selectedItem.detailsText = 'More';
        }

        // collapse if selecting same item
        if (item === vm.selectedItem) {
            vm.selectedItem = null;
            return;
        }

        item.detailsText = 'Less';
        vm.selectedItem = item;
    };

    activate();

    // initialization logic
    function activate() {   
        for(var i = 0; i < 15; ++i) {
            items.push({id: i, title: 'Item: ' + i, details: 'Item ' + i + ' Details', detailsText: 'More'});
        }
    }
});
html {
    box-sizing: border-box;
}

*, *:before, *:after {
    box-sizing: inherit;
}

a {
  color: #004b8d;
  text-decoration: underline;
  cursor: pointer;
}

a:hover {
  color: #2c88e6;
  text-decoration: none;
}

.container {
    width: 500px;
    border: 1px solid black;
}

.item {
    padding: 12px;
    border-bottom: 1px solid gray;
}

.item:last-child {
    border: 0;
}

.details {
    margin-left: 10px;
    color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainController" class="container">
    <div class="item" ng-repeat="item in vm.items">
        {{item.title}} <a ng-click="vm.setItem(item)">{{item.detailsText}}</a>
        <div class="details" ng-if="vm.selectedItem === item">
            {{item.details}}
        </div>
    </div>
</div>

This approach simplifies updates through the controller and template, eliminating the need to duplicate sections of the template for deactivation. All logic resides directly within the controller, facilitating unit tests. For instance:

it('should update selected item', function () {
    // ... initialize controller and $scope properties
    var item = {};
    $scope.vm.setItem(item);
    expect($scope.vm.selectedItem).toBe(item);
    expect(item.detailsText).toBe('Less');
});

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

Adjusting iframe height based on its source URL using JQuery

Currently, I have implemented a script to adjust the height of YouTube iframes in order to maintain a 16:9 aspect ratio while keeping the width at 100% of the container. The challenge I am facing is ensuring that the script only affects YouTube videos and ...

Is it possible to send a variable to the controller through UI-Router and ui-sref?

Is it possible to pass multiple variables through the UI-Router for use in a state's controller? In the HTML, I have <li class="blist-item grid-loader" ng-repeat="item in items"> <a ui-sref="item({ id: {{item.$id}} })"><h3>{{it ...

React - updates to server values do not display in DOM right away

When I work from the client side, I have a modal in my HomeComponent that allows me to select an element. My goal is to then display that selected element within the same HomeComponent (in the productosEnVenta function). The element chosen in the modal is ...

Why is it that when implementing React JS, the function setState is not updating the values on the chart when a Button is

Currently, my webpage is built using React JS and includes a JavaScript chart. I am trying to make the data in the chart dynamically change based on a value entered into a text box. When a button is clicked, the graph should update with the new results. Ho ...

Are instance prototypes exhibiting static behavior?

I'm in the process of creating a game for Windows 8 using HTML/Javascript and WinJS, but I'm running into issues with "prototypes" acting statically when they shouldn't. This is my first time working extensively with Javascript and dealing w ...

Curved edges achieved without the need for relative positioning

Can anyone help me with a specific code snippet to achieve rounded corners for this page ? Currently, I am using the PIE.htc file which only works when I declare position:relative; throughout the layout, causing disruptions. Is there a code workaround that ...

What is the best way to incorporate a PHP file into an HTML file?

Below is the code snippet from my index.php: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Voting Page</title> <script type="text/javascript" src="js/jquer ...

Show a Kendo Pie Chart that reflects information from the grid dataset

I am using KendoUI - Grid component Is there a way to transform this into a Kendo Grid? For example: I have set up a Kendo grid (table) with local data. When I click on the "Generate chart" button, I want the filtered data from the table to be used to cr ...

Photo Collection: Incorporating Images

I am currently working on a project to create a photo gallery and I am facing an issue with adding photos. The user should be able to browse for a picture and enter a title for it on a page. Both the image path and title need to be saved in an XML file fro ...

What is the process for disabling other group options in md-select when selecting an option from one group?

I'm currently working on creating a dropdown menu using the <md-select> tag alongside <md-optgroup>. I've been referencing the "Option Groups" example found here: https://material.angularjs.org/latest/demo/select However, I want ...

Having difficulty navigating the website due to the inability to scroll

I am experiencing a problem on this website where I am unable to scroll. Visit www.Batan.io After loading the website for the first time, the trackpad (mac) works fine initially but then the scroll function stops working. Although the sidebar works, chan ...

Searching for documents in MongoDB using minimum as a condition in the query

My user base is expansive, each facing a unique set of problems at different times. I am currently searching for users or documents that share a specific problem type (referred to as "top":1) but only among those, I am interested in isolating the entry wit ...

Utilize jQuery to enclose nested elements within a parent element

There is a Markup presented below, where this HTML content is being generated from Joomla CMS. I am seeking a jQuery method to reorganize this HTML structure without modifying its PHP code. <div class="item column-1"> <div class="page-header"& ...

adjust the webpage to be optimized for the size of the screen

Looking to adjust the webpage layout so that it fits perfectly on the screen without the need for vertical or horizontal scrolling. Additionally, we want the image to be centered. See below for the current code snippet: #copyright { top: 0px; right: ...

Utilizing the Bootstrap grid system for responsiveness is optimized for a first word that is precisely 15 characters

Trying to achieve responsiveness using basic Bootstrap. The layout becomes responsive only when the initial word in a sentence contains more than 15 characters, as illustrated below. https://i.stack.imgur.com/wyErA.png <!-- Headers --> <div clas ...

Setting a callback function as a prop for react-paginate in TypeScript: A step-by-step guide

When using react-paginate, there is a prop called onPageChange with the following type: onPageChange?(selectedItem: { selected: number }): void; After implementing it like this: const onPageChange = (selected): void => { console.log(selected); } ...

Tips for positioning slideshow below header in web design

I am currently working on enhancing the slideshow feature on my website. If you take a look at the image link provided below, you'll notice that the alignment of the slideshow is slightly off on both sides. Despite my attempts to adjust the CSS width ...

How to automatically insert a page break after a certain string in an array using JavaScript

I've created a code that is intended to implement page breaks after a specific number of new lines or words. I have defined an array that indicates where these breaks should occur within my element. In the example provided in my jsFiddle, you can see ...

Limit the selection of 'pickable' attributes following selections in the picking function (TypeScript)

In the codebase I'm working on, I recently added a useful util function: const pick = <T extends object, P extends keyof T, R = Pick<T,P>>( obj: T, keys: P[] ): R => { if (!obj) return {} as R return keys.reduce((acc, key) => { re ...

Incorporating a splash of color while changing the background color on scroll

Is it possible to include more colors between the "beginning-color" and the "ending-color" in this code that changes the background color on scroll? example $(document).ready(function(){ var scroll_pos = 0; var animation_begin_pos = 0; ...