Chat Tool

 

A chat tool is basically just display records in a portal, but restricted by an addressee.
So we need at least one table with employees (Team table) and another table for the messages (Messages table).
In addition, we create another table for the parameter data (Parameter Table) – such as HTML components and the JQuery library.
Finally we add a table for link calls that we already know from the Kanban article (Link Table).

Let’s first take a look at the portal display restrictions in Filemaker.
– The text length in the display is fixed by the size of the Portal Row
– It can display only very static images or files
– Links are not possible
– Limited options for graphical display and control from within the portal

We quickly realize the disadvantages of such a display in Filemaker portals for a chat history.

To achieve a haptic known from other programs we will once again use HTML and JQuery in a Filemaker Webview.

I had played for a long time with the idea to add a notification function that shows the new messages outside the chat tool like in other programs.
But I have never been able to produce a usable result from a modal window that is displayed as notification.

If you want to build such a notification, you should have a look at the ingenious approach of the brilliant guys from Clickworks.
There they describe how to implement a “perform script on client”, which is absolutely necessary for a client notification.
https://www.clickworks.eu/en/trigger-a-script-on-another-client/

If you combine that with this great idea for displaying a timed card from ISO FileMaker Magazine, it can end up being a really cool notification system.

But now let’s look at the chat tool step by step.

As with other tools, we start with a login window where you select your account from a drop-down list and log in with your password.

Chat1
The login list consists of a simple HTML and a little CSS that displays the avatar images as round graphics.

HTML:

<!DOCTYPE html>
<html lang=”en”>
<head>
<style>
__css
</style>
</head>
<body>
<div class=”container clearfix”>
<div class=”people-list” id=”people-list”>
<ul class=”list”>
__memberList
</li>
</ul>
</div>
</div>
<script>
function theFunction(p){
var msg = ‘__function||||’ + p
window.location = ‘__script&param=’+msg;
};
</script>
</body>
</html>

 

CSS:

@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
*, *:before, *:after {
box-sizing: border-box;
}
html,body {
background: #444753;
font: 11px “Verdana”, Arial, sans-serif;
padding: 0px;
color: white;
}
.container {
margin: 30 auto;
width: 260px;
background: #444753;
}
.imgProfil {
border-width: 2px;
border-color: grey;
border-style: solid;
width: 30px;
margin: 0px;
border-radius: 50%;
}
.people-list {
width: 260px;
float: left;
}
.people-list .search {
padding: 20px;
}
.people-list input {
border-radius: 3px;
border: none;
padding: 14px;
color: white;
background: #6A6C75;
width: 90%;
font-size: 14px;
}
.people-list .fa-search {
position: relative;
left: -25px;
}
.people-list ul {
list-style-type: none;
padding-left: 30px;
padding-right: 20px;
}
.people-list ul li {
list-style-type: none;
padding-bottom: 10px;
}
.people-list img {
float: left;
}
.people-list .about {
float: left;
margin-top: 8px;
padding-left: 8px;
}
.people-list .status {
color: #92959E;
}
.online, .offline, .me {
margin-right: 3px;
font-size: 14px;
}
.online {
color: #86BB71;
}
.offline {
color: #E38968;
}
.me {
color: #94C2ED;
}
.align-left {
text-align: left;
}
.align-right {
text-align: right;
}
.float-right {
float: right;
}
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: ” “;
clear: both;
height: 0;
}
.selectable:hover{
font-weight: bold;
}

 

In Table Team field „loginList“ as unstored calculation:

Wenn ( person|group = 1 ; 
" <li class=\"clearfix\" style='cursor: pointer;' onclick='theFunction(" & Zitat ( id ) & ")'>
<img class=\"imgProfil\" src=\"data:image/gif;base64," & Base64Encode ( avatar_ƒ ) & "\" alt=\"avatar\">
<div class=\"about\">
<div class=\"name\">" & firstname_lastname & „</div>
</div>
</li>"
;
""
)

In the webview the placeholders are then simply exchanged for the data:

Austauschen ( Team~Parameter#X::HTML_memberList ; 
["__memberList";Liste ( Team~Team#person#search::loginList )] ;
["__script";Team~Parameter#X::Script_memberList] ;
["__function";"clickLoginList"] ;
["__css";Team~Parameter#X::HTML_memberList_css]
)

After logging in, you will get to the actual chat view.

Chat2

Here, a modified team list with your respective online status is displayed in the left area.
If you now select a chat partner, you can chat with this partner in the right area.

Chat3

To display the new chat entries as fast as possible an unsaved calculation is created in the team table which
generates the HTML content.

For performance reasons, you should limit the number of messages to a date range.

HTML Chat:

<!DOCTYPE html>

<html lang=”en”>

<head>

<script type=”text/javascript”>__jquery-1.10.2.js</script>

<style>

body{

  overflow-y: hidden;

  margin: 0px; 

  padding: 0px; 

}

.navbar {

  position: fixed;

  top: -10px;

  left: -50px;

  width: 120%;

  display: block;

  transition: top 0.1s;

  height:100px;

  background-image: linear-gradient(to top, rgba(240, 240, 240,0), rgba(240, 240, 240, 1)); /* Standard syntax (must be last) */

}

.containerRight {

  display: inline-block;

  min-width: 51%;

  float: right;

  border-radius: 14px 14px 14px 14px;

  margin: 10px auto;

  background: #94C2ED;

  color: __fontcolor;

  padding: 12px 12px 0px;

  text-align: right;

  font-family: verdana;

  line-height: 1.5;

  position: relative;

  flex-direction: column-reverse;

}

.containerLeft {

  display: inline-block;

  min-width: 51%;

  float: left;

  border-radius: 14px 14px 14px 14px;

  margin: 10px auto;

  background: #86BB71;

  color: __fontcolor;

  padding: 12px 12px 0px;

  text-align: left;

  font-family: verdana;

  line-height: 1.5;

  position: relative;

  flex-direction: column-reverse;

}

.containerRight::after {

  content: ”;

  clear: both;

  display: table;

  position: absolute;

  border-style: solid;

  border-width: 10px 0 10px 10px;

  border-color: transparent #94C2ED;

  display: block;

  width: 0;

  z-index: 1;

  right: -10px;

  top: 12px;

}

.containerLeft::after {

  content: ”;

  clear: both;

  display: table;

  position: absolute; 

  border-style: solid; 

  border-width: 10px 10px 10px 0;

  border-color: transparent #86BB71;

  display: block;

  width: 0;

  z-index: 1;

  left: -10px;

  top: 12px;

}

.imgProfilLeft {

  width: 40px;

  float: left;

  margin: 10px;

  margin-left: 0px;

  margin-top: 0px;

  border-radius: 50%;

}

.containerRight p {

  display: inline-block;

  float: right;

}

.containerLeft p {

  display: inline-block;

  float: left;

}

.imgProfilRight {

  width: 40px;

  float: right;

  margin: 10px;

  margin-right: 0px;

  margin-top: 0px;

  border-radius: 50%;

}

.time-right {

  float: right;

  color: __fontcolor;

}

.time-left {

  float: left;

  color: __fontcolor;

}

body{

  font-size: 11px;

  padding: 10px;

  background-color: #F0F0F0;

}

</style>

</head>

<body>

<div id=”navbar” class=”navbar” style=”z-index: 10000″></div>

__entries

<script>

$(document).ready(function() {  

 

  $(‘.clickToOpen’).on(‘click’, function (e) {

     var msg = ‘exportFile||||’ + $(this).data(“value”);       

     window.location = ‘__script&param=’+msg;

  }); 

// When the user scrolls down 20px from the top of the document, slide down the navbar

window.onscroll = function() {scrollFunction();};

 

function scrollFunction() {

  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {

    document.getElementById(“navbar”).style.top = “0”;

  } else {

    document.getElementById(“navbar”).style.top = “-50px”;

  }

}

 

$(window).load(function() {

window.scrollTo(0,document.body.scrollHeight);

});

});

</script>

</body>

</html>

 

The formula field that represents the actual message as a buble looks like this

Wenn ( id_team = "" ;
SetzeVar (
[
box = Wenn ( Var_actualId = id_sender ; "containerRight" ; "containerLeft" ) ;
img = Wenn ( Var_actualId = id_sender ; "imgProfilRight" ; "imgProfilLeft" ) ;
time = Wenn ( Var_actualId = id_sender ; "time-right" ; "time-left" ) ;
name = Wenn ( Var_actualId = id_sender ; "◀ " & Message~Team#receiverId::firstname ; "▶ " &
Message~Team#senderId::firstname ) ;
time = ZeichenRechts ( "0" & KalendertagZahl ( A_Angelegt_am ) ; 2 ) & "." &
ZeichenRechts ( "0" & MonatZahl ( A_Angelegt_am ) ; 2 ) &
" " & ZeichenRechts ( "0" & Stunden ( A_Angelegt_um ) ; 2 ) & ":" &
ZeichenRechts ( "0" & Minuten ( A_Angelegt_um ) ; 2 ) ;
Thumb = Wenn ( Thumbnail = "?" ; Parameter::img_file ; Thumbnail ) ;
ThumbTitle = Wenn ( Thumbnail = "?" ; "<figcaption>" & file & "</figcaption>" ; "" ) ] ;
"<div class='" & box & "'><img class='" & img & "' src='data:image/gif;base64," &
Base64Encode ( Message~Team#senderId::avatar_ƒ ) &
"' alt='Avatar'><span class='" & time & "'>" & " <b>" & name & " - " & time & "</b>" & "</span><br>" & text_html &
Wenn ( thumbnail ≠ "" ; "<br><div class='clickToOpen' style='cursor: pointer;' data-value='" & UUID &
"'><figure><img " &
Wenn ( thumbnail = "?" ; "width='40px' "; "" ) & "src='data:image/gif;base64," & Base64Encode ( Thumb ) & "'/>" &
ThumbTitle & "</figure></div>" ; "" ) & "</div>"
)
)

Again in the webview formula field of the Team table the placeholders are replaced by the data:

Wenn ( online = 1 UND refresh = 1 ; 
Austauschen ( Team~Parameter#X::HTML_chat ; 
["__jquery-1.10.2.js";Parameter::jquery_1.10.2.js] ; 
["__entries";Liste ( Team~Message#sender_receiver::html_message )] ; 
["__script";Team~Parameter#X::Script_chat] ; 
["__fontcolor";Wenn ( fontcolor = "" ; "#FEFEFE" ; fontcolor )]
)
;
chat_Webview
)

 

 

If you like to have an open version of the file, just send me an email.
You have any questions? Feel free to send me an email, I’ll try to answer as soon as possible.