A Clever CSS Chat Display.

By Daniel Wood, 22 March 2022

css chat teaser

Introduction

In this article we're going to take a look at a very simple approach to displaying an internal chat conversation in FileMaker. The premise is simple - we have a series of messages that need displaying and we want it to look like your standard messaging app (think Messenger, Slack or WhatsApp).

The underlying chat framework is all FileMaker, this is purely an exercise in display, and trying to make it as simple as possible to implement for developers.

 

chat 01

 

What's the Issue?

If we just want to display messages - which are themselves records in a table - then you may think "why not just use a portal, or list view".  Well there are a couple of reasons why these are not that suitable.

The first is a question of size.  We have no way of knowing how large a chat message will be and thus how big to make a field that needs to display it. FileMaker portals have to be of a fixed height, and so while we can simulate a messaging display, the crucial thing we cannot do is dynamically determine a portal rows height.

Similarly with list-view, unless we are viewing a chat in preview mode (not very useful) then we cannot dynamically determine size of a row.

 

Why Not Javascript?

In searching for a suitable way to solve this issue, we obviously approached Javascript given its reputation as being a problem solver for things that cannot be solved with out of the box FileMaker tools.

Javascript does offer a number of chat implementations however these are primarily focussed on website chat, such as end user / customer interaction. They also focus heavily on the communication protocol and delve into the need to set up web servers, listeners etc - all well beyond the scope of our requirement.

 

chat 02

Wait, set up what now? 

  

Example File

This is a good time to mention that as always we include an example file for this article. It pays to check it out as it will help make sense of what we discuss below, as well as showing you what we're implementing.

Click here to download the Example File. 

 

HTML to the Rescue!

The question was asked - why not just build a display using some basic HTML and CSS? If we could generate some HTML code - styled with CSS - then perhaps that's all we need.  That is exactly what we did!

Consider a <div> tag.  W3 Schools defines a <div> tag as:

The <div> tag defines a division or a section in an HTML document.

The <div> tag is used as a container for HTML elements - which is styled with CSS or manipulated with JavaScript.

The <div> tag is easily styled by using the class or id attribute.

 All we need to do is generate a <div> tag for each message and have it render within.  We can then also use CSS to style the contents of that div however we choose.

 

A simple <div> tag

What a simple <div> tag looks like.

 

And CSS to the Rescue!

As mentioned, the real power here is in the CSS. With CSS we can apply virtually any kind of formatting to the contents inside our <div> tag. In this case we're going to format it to look like a chat bubble.

Consider a standard chat display. There is a left side (message sent by you, the person viewing the chat), and a right side (message sent by everyone else).

We also want to display in this way, and so what we need is 2 different styles - one to format a message on the left hand side, and one to format a message on the right hand side.

 

Example: A Basic Chat framework

In order to talk through how we build our HTML, let's first consider a very basic chat framework. This has been implemented in our example file just enough to show a chat conversation being displayed.

chat 11

The basic structure is:

Chat: 1 record per chat (in our example we restrict it to 1 record)
ChatMessages: 1 record per individual message sent for a given chat.
Users: This has 1 record per user of your solution. Note some solutions don't have a User table, in which case you can just use your FileMaker account names as a substitute.
ChatUsers: Defines who is participating in the chat. 1 record per user (or account) per chat. This is simply a join table between Users and Chat.

So pretty straightforward. With the above framework there is potential to have multiple different chats going on in your solution, involving different people for different purposes.

 

Formatting a Message Display

First we're going to focus on the ChatMessages table because this is where we need to take our message and turn it into some HTML code for viewing.

In this table you'll find a field called message_json. This is a JSON representation of the chat message for display. It contains 2 pieces of information:

The JSON message

The first is "owner". The owner of a message is a unique identifier of who created it. If you are using the framework above, then this is going to be the ChatUser ID of the person who created the message.

The second value "message" is a reference to a custom function called @CHAT_messageFormat. We have abstracted the code into a custom function because it is easier to digest, and reusable.

This function takes 3 parameters:

_owner: in this case it is a display name for the owner, such as user name or account name.
_message: The actual chat message.
_timestamp: A timestamp of when the message was created.

 

chat 05

Now, this function is purely for constructing some HTML in whatever format you desire. In our case we have utilised another custom function @DATE_format (which we love!) to make our timestamp into a nicer format.

The HTML part comprises of a single <div> and two <p> tags. In our <p> tags we place the message along with the owner & timestamp.

You will note that our second line with the owner & timestamp is assigned a class owner. This is so we can use CSS to style this line separately by defining a class of the same name.

Our main <div> actually has two classes defined for it:

  • chat-message
  • chat-message-[SIDE]

The first class is for general formatting of the message, things like font, sizes etc. The second is for positioning a message either left/right, and for colouring accordingly.  Note that [SIDE] is actually a placeholder that we are going to replace when the time comes with either the word "left" or "right".

So in actuality there are two classes for this called chat-message-left and chat-message-right.

 

Styling the Message

If we take a look at the CSS, it's pretty easy to follow and see how messages are formatted. We won't go into the technicalities of CSS, suffice to say you'll find it easy to locate the above classes and make formatting changes. The key classes defined are:

  • .chat-container .chat-message: Padding and font properties of a message box
  • .chat-container .chat-message p: Formatting of the main message content
  • .chat-container .chat-message p.owner: Formatting of the second line of owner name & timestamp
  • .chat-container .chat-message-left/right: Coloring of the left/right hand message box accordingly.

There are others but we won't get into these but you can't go wrong having a play and seeing what they do. 

 

Our CSS

 

Constructing the HTML

Okay so now we have a bunch of messages with a representation in HTML. We now need to generate the overall HTML to be rendered in the web viewer which will comprise multiple <div> tags - 1 per message.

This is simply an exercise of finding our set of messages and looping through them to build up the HTML.

To make this as simple as possible, we'll take our JSON payload from earlier, and collate a list of these which we feed to a special custom function @CHAT_buildMessages.

It is important to collate the jSON from your records in chronological order because the order in which we build is the order in which they will be displayed.

Constructing the HTML

 

Our custom function takes 2 parameters:

_owner: the unique identifier representing who is currently viewing the chat
_messageList: A return delimited list of JSON objects, one per message.

We use a simple While function to loop through each JSON message. From within each message we check the value of the "owner" key, and compare this to the "owner" passed through in the function parameter. This tells us whether the message belongs to the owner and thus should be formatted with the left class, or whether we instead format it with the right class.

 

The End Result

Put it all together and you get something this:

 

CSS chat!

 

Here you can see that Daniel is selected as the owner, and thus all of Daniels messages are displayed on the left side.  If we switch perspective instead to Cath, we now see all her messages on the left.

 

the chat from a different users perspective

 

The main content of the HTML looks like this:

<body  = 'footer'">
<div class="chat-container chat-push">
<div class="chat-message chat-message-right">
<p><span style="" >Hi all. Just wanted to let you all know that we will be heading out for lunch on Friday next week</span></p>
<p class="owner">Daniel Sun 27/2/22 10:20 am</p>
</div>
<div class="chat-message chat-message-left">
<p><span style="" >Cool, can't wait!</span></p>
<p class="owner">Cath Sun 27/2/22 10:25 am</p>
</div>
<div class="chat-message chat-message-right">
<p><span style="" >????</span></p>
<p class="owner">James Sun 27/2/22 10:39 am</p>
</div>
<div class="chat-message chat-message-right">
<p><span style="" >I can't make it sorry, thanks for the invite though.</span></p>
<p class="owner">Mary Sun 27/2/22 10:45 am</p>
</div>
<div class="chat-message chat-message-right">
<p><span style="" >All good Mary, thanks for letting me know.</span></p>
<p class="owner">Daniel Sun 27/2/22 2:49 pm</p>
</div>
<div class="chat-message chat-message-left">
<p><span style="" >Hey Daniel, will there be vegetarian options available?</span></p>
<p class="owner">Cath Mon 28/2/22 8:58 am</p>
</div>
<div class="chat-message chat-message-right">
<p><span style="" >Yes they cater to vegetarians and vegans. There is a menu online, I'll email you further details</span></p>
<p class="owner">Daniel Mon 28/2/22 9:05 am</p>
</div>
<div class="chat-message chat-message-left">
<p><span style="" >Thanks!</span></p>
<p class="owner">Cath Mon 28/2/22 10:41 am</p>
</div>
<div class="chat-message chat-message-right">
<p><span style="" >I'm off for a run</span></p>
<p class="owner">James Mon 28/2/22 12:30 pm</p>
</div>
</div>
</body>

Nothing more than a series of <div> tags, with the appropriate style applied - so simple!

 

Taking it Further

Now, this is meant to illustrate a very basic approach to a chat display and we think we achieved this satisfactorily. However there are some things to consider:

  • This is not live. You need to refresh the entire chat if a message is added
  • Given the entire message is refreshed, incredibly long chats might take longer to build

The intention of this is for relatively small chats within a solution, that aren't "live" chats. However we see potential to extend this in a number of ways, one of which is actually utilising Javascript to dynamically add <div> tags to the HTML when a message is received. We could utilise the Javascript functionality in FileMaker 19 to push new messages to a web viewer, or have the chat be entirely loaded by javascript functions.

We'd love to see what you'd come up with!

Other cool potential things that could be done with this include:

  • Adding an avatar image to the display for a user
  • Customising message colors per user
  • Clickable links in messages that run scripts, or open URLs
  • Hover states on messages

 

W3 Schools has an example of an Avatar chat

W3 Schools has an example of an Avatar chat display

 

Example File

Here again is a download link to our example file. We hope you find it useful:

Click here to download the example file

 

 

Something to say? Post a comment...

Comments

  • Erwin Bouwmeester 20/08/2022 12:36am (1 month ago)

    Hi there,

    Great article and sample file. However, I would like to add an avatar (photo) to the message of the sender and my knowledge it too limited to get it done myself, even with the w3schools examples.... Possible to give me some more directions how to get in the right direction???

    Thank you so much an keep up the good work!
    Erwin

  • James Glendinning 22/03/2022 9:47pm (6 months ago)

    Fantastic article as ever. I've had a couple of requests for chat functions, but never actually built one, so this is really cool. Makes a nice break from always resorting to JS too!
    BTW - the @DATE CF is awesome too - I'm having that!

RSS feed for comments on this page | RSS feed for all comments

Categories(show all)

Subscribe

No Tags