Adding a div to the preceding div based on matching IDs in AngularJS

Here is a representation of my layout in HTML:

<div ng-repeat="message in messages">
        <div ng-class="{'messages messages--sent': userId == message.id,         
            'messages messages--received': userId != message.id}">
                <div class="message">
                    {{message.content}}
                </div>
        </div>
    </div>
    

This is how the messages array is structured:

$scope.messages = [
        {
            "id":"Michael",
            "content":"Hey"
        },
        {
            "id":"Rich",
            "content":"Yow"
        },
        {
            "id":"Rich",
            "content":"How are you"
        },
        {
            "id":"Michael",
            "content":"Im okay"
        },
        {
            "id":"Michael",
            "content":"Im missed you!"
        },
    ];
    

This is the desired layout I'm aiming for

The previous layout is styled with the following CSS code:

.messages--received .message:first-child {
      border-top-left-radius: 50px;
    }

    // More CSS styling...

    .messages--sent .message:last-child {
        border-bottom-right-radius: 50px;
        margin-bottom: 10px;
    }
    

However, this is the issue that arises

The problem lies in the creation of a new div during each loop of ng-repeat, which I do not want. I aim to append the next {{message.content}} to the previously created div if their {{message.id}} matches.

If they do not match, a new div should be created as usual. Your assistance on this matter would be greatly appreciated. Thank you :)

Note: I prefer not to filter and group everything as I have tried before but faced misunderstandings. Hence, I have provided images this time to facilitate better comprehension. THANK YOU ^_^

Answer №1

The method provided may not be the most efficient way to handle this situation, but here is how it can be done:

<div ng-repeat="message in messages" ng-if="message.id != messages[$index - 1].id" style="border:1px solid red">
    <div >
            <div class="message">
                {{message.content}} - {{$index}}
            </div>
    </div>
  <hr>
    <div  
        ng-repeat="nextMessage in messages | startFrom : $parent.$index + 1"
         ng-if="nextMessage.id == messages[$parent.$index].id && ($index == 0 || nextMessage.id == messages[$index-1].id)" style="border:1px solid blue"
        >
            <div class="message">
                {{nextMessage.content}} - {{$index}}
            </div>
    </div>
</div>

You can also use an ng-repeat start index filter from:

app.filter('startFrom', function() {
    return function(input, start) {
        if(input) {
            start = +start; //parse to int
            return input.slice(start);
        }
        return [];
    }
});

I have added two ng-if conditions. One on the ng-repeat to skip iterations with matching ids from the previous one, and another inside to display subsequent items with matching ids. The nested ng-repeat adds each message with the same id until a different id is encountered.

You could integrate the first inner div within the ng-repeat as well, but for now, I have kept it separate.

Here is a fiddle without the CSS part, showcasing grouped messages highlighted in red: https://codepen.io/neptune01/pen/Qvzzed

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

Exploration Pointers for Foursquare Web Users

Why does my search suggestion keep returning '568 broadway' even after I have updated the authentication to my client id and client secret? Currently running on: https://api.foursquare.com/v2/venues/suggestCompletion?ll=40.7,-74&query=fours ...

Is there a significant distinction between value and defaultValue in React JS?

React's homepage features the final illustration (A Component Using External Plugins) with a textarea: <textarea id="markdown-content" onChange={this.handleChange} defaultValue={this.state.value} /> While typing, the ...

Error code 12030: AJAX request status

When making an ajax XMLHttpRequest using the POST method, I am encountering a readyState of 4 with a status of 12030. It is known that 12030 is a Microsoft-specific state code indicating that the connection was not sustained. However, I have been unable to ...

Aligning two images vertically using the display: table-cell property

I'm trying to align two images vertically using CSS' display: table-cell property, but it doesn't seem to be working even after specifying the height. <div style='display: table;height:500px'> <div style=' displa ...

Unlocking the power of accessing nested data in JSON files dynamically

Building a new feature that allows users to input a word, choose the language, and receive the definition along with an example using the API service. To retrieve the desired data at position 0 of "exclamation" in the "meaning" section. This ensures that ...

Tips for extracting a specific attribute from an array of objects using both react and JavaScript while considering various conditions

I have a set of objects structured like this: const obj_arr = [ { id: '1', jobs: [ { completed: false, id: '11', run: { id: '6&apos ...

Changing the disabled textfield colour in Material-UI

I am looking to enhance the visibility of disabled text in a textfield by making it darker than the current light color: I have attempted to achieve this using the following code snippet: import { withStyles } from '@material-ui/styles'; import ...

Ways to make a div fill the whole screen and allow for scrolling as well

Issue I'm facing an issue with the login.php screen and the addphoto.php screen. I want these screens to cover the entire page, but despite using the following code: .login-screen, .form-screen { position: fixed; top: 0; left: 0; disp ...

What is the most efficient way to query through a Firestore database containing 5,000 users?

We are currently facing a challenge with our staffing application, which is built using vuejs and a firestore database containing over 5,000 users. Our primary issue lies in the need for a more efficient layout that allows admins to search for users within ...

The HTML header is not displaying at the proper width as intended

Let me lay out the blueprint I had in mind for my webpage: The body will have a width and height of 600 x 800 pixels with no padding, allowing elements to snugly align without any margin. Inside the body, there will be 3 key elements - a header, main c ...

Generate an array that can be accessed across all components

As someone new to reactjs, I'm trying to figure out how to handle an array of objects so that it can be global and accessed from multiple components. Should I create another class and import it for this purpose? In Angular, I would typically create a ...

After the decimal point, there are two digits

My input field is disabled, where the result should be displayed as a product of "Quantity" and "Price" columns ("Quantity" * "Price" = "Total"). However, I am facing an issue where the result often displays more than 2 digits (for example: 3 * 2.93), desp ...

The issue lies with Express Mongoose failing to store the data

Encountering some issues when trying to save an object created in Express nodejs using mongoose. Despite receiving a confirmation that the object is saved, it cannot be located even after attempting to access it through the server. Express route for savi ...

Update the innerHTML content dynamically every 5 seconds with Vue.js

I'm working on a new website and I'd like to spice things up by changing the header text with a random word every 5 seconds. Here's the starting point: const header = document.querySelector('.header') const needs = ['jacket& ...

Text alignment issues cause animation to vanish

Utilizing particles.js, I set up a full-screen particle effect by specifying the animation to be full-screen with height: 100vh;. This worked perfectly as intended. However, when attempting to add text on top of the particle animation and center it vertica ...

Error: "$$" not defined in this context

I am currently working on generating a dynamic pie chart programmatically with the intention of transforming it into a reusable React Component. The main idea is to have an interactive pie chart where each slice expands into a full pie when clicked. I came ...

generate a flexible div that adjusts its height based on the size of the browser window

Is it possible to create a div layout structured like this: <div_wrapper> <div_header> </div_header> <div_content> </div_content> </div_wrapper> Upon page load, the div_header o ...

Unable to detect controller while utilizing ngRoute functionality

I'm a beginner in the world of angularJS, and I've encountered an issue while using ngRoute in the same JavaScript file as one of my controllers. Here's the code: index.html <html ng-app="testModule"> <head></head> ...

Utilizing JSON for live population of search filter results

I'm currently developing a search function for my website that will sift through a JSON Object using regular expressions. My goal is to have the results displayed in real time as the user types, similar to how Google shows search suggestions. However ...

Currently seeking assistance in replacing an existing Wordpress object with a new one

I'm looking to swap out the current slider image with a new slider. Whenever I try to replace it with the TOP 5 Games, they disappear or don't show up at all. <?php if( function_exists('cyclone_slider') ) cyclone_slider('24&ap ...