1

I was wondering if there is a way to adjust my chat box so that messages appear coming form the bottom, as any chat app work. I am using Django and bootstrap 4, here is my code:

                            <div class="list-group flex-column-reverse " id="Chatting" style="transform: rotate(-180deg);">

{% for message in object.messages.all %}

    <a class="list-group-item list-group-item-action border-white "  {% if message.user == user  %} style="background-color: rgba(190,229,235,0.1);"{% endif %}>
        <div class="row text-lowercase" style="height: 15px;">
        <div class="col text-left">
            <p style="font-size: 10px;">{{ message.user.first_name }} {{ message.user.last_name|slice:":1" }}</p>
        </div>
        <div class="col">
            <p class="text-right" style="font-size: 10px;">{{ message.date|date:"SHORT_DATETIME_FORMAT" }}</p>
        </div>
        </div><span>

        {{ message.text|linebreaks }}
        {% if message.attachment %}
            <img src="{{ message.attachment.url }}" width="50%"  ></img>
        {% endif %}
    </span>
    </a>


{% endfor %}

The id list of name has overflow: auto on it. If I use the code without The rotation part and without flex-column-reverse, the list of messages begin from the top of the box, which is counter-intuitive. If I use only flex-column-reverse I get the ordering correct but when the page loads it loads with the oldest message and the user has to scroll down, it also means everytime he writes a message he has to scroll down again. The hack that I am using works by showing the order correct and the page loads at the last message, however the scroll bar is at the left of the chat box and works in reverse with the mouse scroll. I added the ending screenshot. Is there any solution without using javascript? I am really horrible in comprehending javascript :÷ enter image description here

RC-
  • 163
  • 10

1 Answers1

0

I would do that in the view instead of the template. What I suggest is (assuming you are using class based views, I'd overload the get_context_data method to add the messages sorted as I want them:

def get_context_data(self, **kwargs):
    context = super(). get_context_data(**kwargs)
    # Now we add messages sorted in ascending order by date
    # I'm assuming you are using some kind of DetailView or similar
    # which has an 'object' field
    context['messages'] = self.object.messages.order_by('date')

    return context

Then in your template you have to iterate over messages variable directly instead of object.messages.all.

Even more, if you normally want the messages in that order I would add that to the Meta class ordering attribute of your Message model like so:

class Message(Model):
    # whatever is your model

    class Meta:
        ordering = ['date']

As per your last comment I would then suggest you just simply iterate the list in reverse order (take a look to this part of the documentation). Summarizing you should:

{% for message in obj.messages.all reversed %}
    <!-- Do whatever you want to render your messages --!>
{% endfor %}

For keeping the scroll down you will need some JS or CSS trick. I think you may find this question useful.

ivissani
  • 2,614
  • 1
  • 18
  • 12
  • to be honest I used the django-conversation package, and tried to update it for my use, but I found it complicated to understand their code, this is why I am trying to deo the sorting in the template. I don – RC- Dec 19 '18 at 04:40
  • Are you overriding a template of the package or are you working with your own view? – ivissani Dec 19 '18 at 12:38
  • I am overriding the template of the package. The view is untouched. – RC- Dec 19 '18 at 17:57
  • your last edit is good, using reversed is almost the same as column-reverse in css, I will try to have a look at your question link. I saw it before but though it is too complicated. But apparently there is no solution using only css. – RC- Dec 20 '18 at 15:26