My Kanban tool is in no way related to the add-on of filemaker.
This article covers the whole development from the beginning.
If you like to have an open version of the Kanban 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.
Because the Kanban tool is complex, I will divide this article into topics:
- Feature list
- History and Development
- Manual
- Technical details
1. Feature list:
- Compatible under Filemaker version 16 without modal windows
- Team administration with individual login
- Individual preferences
- Admin function
- Any number of kanbans
- Any number of lists
- Archive function (automatic sorting into archive after one day)
- Filter Kanban cards by team members
- Minimization of cards for clarity
- Fast switching between kanbans
- Assign team members to Kanban and cards
- Attachments to cards
- Create tasks in cards for a task list
- Display due date, open/completed tasks, team members, comments and attachments in overview
- Email info system for changes in cards
- Presets like colors, shorten long card text, Kanban and filter preset, minimize cards
- Comment list structured by weeks for quick overview
- Search function over all cards
- Searchable archive list
- Creation of cards in any kanban/list by custom scripts
- Inbox to connect email account or create via external scripts (cards without kanban or list are collected here for distribution)
- Master Kanban (Integrates lists from other Kanbans, so that cards from the Master Kanban can be distributed to other lists)
- Executable Links (EMail/Telephone/HTTP/External Custom Links in own database)
- Create custom links
2. History and Development:
When I first started thinking about a Kanban system in Filemaker in 2016, I first looked around at existing solutions. But very quickly I realized that the existing tools either didn’t appeal to me for visual reasons or simply didn’t have the features I wanted.
So I started looking around for Kanban jquery plugins.
Many plugins were very close to what I had in mind, such as lobipanel.
It looks fantastic and has a great feature set.
However, with each plugin I had problems – either with the calls from the webview in Filemaker or the display, the inclusion of icons, etc. – but I was not able to find a solution.
After these frustrating experiences, I thought of Aaron Giard and his article series for Scarpetta Group.
I remembered the jquery plugin “Draggable” and found the “Sortable/Portlets” a very easily adaptable and customizable plugin.
For me as a non-native HTML programmer jquery is much easier to program than pure javascript.
However, based on this plugin I had to program the complete functionality and GUI myself.
But sometimes, and this is just a difficult but important decision, you just have to take a step back as a programmer and see that designing something completely from scratch is more promising than desperately bending something.
For this project I used the visualization method already described.
I looked at several very well done interface GUIs on the internet and then started to design my own interface with the basic functions – I must confess that I am really not a good graphic designer !
So I started to build up the functions from the visualization and to adjust the graphics again and again.
Until the middle of 2020, so many functions have been added that I think I have programmed a good Kanban that could be useful to many other people, whether by adopting the tool in their own databases or simply by “Look & Learn”.
I cannot mention it often enough: Even after many years of programming experience I still learn with every article I read or with every software I test !
To this day, I extend my Kanban (not to mention bug fixes) through user feedback or because I myself miss a feature when using it.
I firmly believe that only good software is created when there is a constant and continuous development.
The difficult part of such a development is to completely rewrite a part of a software or to remove a nice feature because it doesn’t fit into the concept (anymore).
3. Manual:
Startup
After starting the tool, the login screen shows up in which the team members created in Kanban are displayed.
After you have clicked on your avatar, you will be prompted to enter your password if a password is stored, or you will be logged in directly to kanban.
Main Screen
The main screen is divided into 3 sections:
Info Area: On the left is an Info Area (up to Filemaker 16, card details are displayed here).
Function area: Above the card window are the functions that affect the Kanban as a whole. This area holds more functions if they are marked as Admin in the Team Data.
Card area: Here are the lists and cards of the Kanban that is currently displayed.
Admin screen
Team Screen
Function area
The functions marked with * are only visible for admin team members.
Filter Team
By selecting a team member, only his cards are displayed in the card area.
Comment List
Calls the current card list in the info area so that you can quickly get an overview of new comments on cards.
Search
Searches all cards in all kanbans that are visible to the logged in user and not yet archived.
Archiv
Searches all archived cards. You can archive cards by creating a list „Archiv“ in any Kanban and drop cards onto this list.
Preferences
Here users can change their preferences themselves. See info Area screenshot Preferences.
Cards Min/Max
This button lets you switch between the minimized (only headers are displayed) and maximized (the entire card is displayed) modes.
Create Board*
This creates a new Kanban board. The settings for this board can then be entered in the info Area screenshot Board.
Create List*
This creates a new list in the current Kanban board. The settings for this list can be entered in the Info Area screenshot List.
Team edit*
The Team settings can be entered in the Info Area screenshot Team List/Team member.
Inbox*
The inbox contains cards that are not assigned to a list or kanban. In this inbox you can create cards from other databases or cards created by an email account.
The admin can then distribute these cards to other boards by e.g. a master kanban (kanban in which the todo lists of other boards are displayed).
Link edit*
The Link edit button opens a modal window containing a list of fixed links (hyperlink, send email and phone call) and custom defined links.
When you create a new custom link, a new empty line appears.
A custom defined link consists of a title (which appears in the card window), a function name (this must be a unique value), the filename of the custom filemaker file to be accessed and the script name of the script to be executed in the custom filemaker file.
Select Board
If you select a Kanban board from the pop up, the lists and cards of this board are displayed and in the info Area (screenshot Board) the preference data of the board appears.
Team list boards
This is only a display of the assigned team members of the current board.
Team member (Filter Team)
The name of the team member selected via the “Filter Team” filter function is displayed here.
Info Area
The Info area displays different data depending on the selected function.
In the default view the list of comments of the current week on maps is displayed.
Card area
In the card area the lists and cards of the kanban board are displayed.
Lists can be created by the admin and provided with a button “+ Create Card”.
A special list is the “Archive” list, which does not show its cards in the card area after one day.
Cards can be moved between lists by drag & drop.
The functions in a nutshell:
Card details
Clicking on a card opens a modal window with details of the card (for filemaker versions lower than 16 this information is displayed in the info area).
Within the detail view you can select the individual areas or create new data there.
Card data
Team assignment
Comments
Attachments
Tasks
4. Technical details:
At this point I would like to point out pitfalls that have made my life difficult in programming and show a solution so that you do not fall into the same traps in your own solutions.
Parameter:
A parameter table contains the general data that is needed at certain places in the database.
And this is exactly how I store the parameter table in the relationships graph.
Each table that needs parameters is linked with its main occurrence directly to the parameter table.
Filemaker webview:
I like to calculate a webview by an unstored formula field (certainly not the most performance optimized variant) because then you can change the content of the webview dynamically.
This allows you to store the required jQuery libraries centrally in a text field in the table parameter and include them in the formula field by a simple “Substitute”.
“data:text/html,” & Substitute ( Parameter::HTML_Kanban ;
[“__display” ; If ( DefaultMinimize = 1 ; “display: none;”; “” )] ;
[“__ui-icon ui-icon” ; If ( DefaultMinimize = 1 ; “ui-icon ui-icon-plus” ; “ui-icon ui-icon-minus” )] ;
[“__jquery-ui.css” ; Parameter::jquery_ui_css] ;
[“__jquery-ui.js” ; Parameter::jquery_ui.js ] ;
[“__jquery-1.10.2.js”;Parameter::jquery_1.10.2.js] ;
[“__css” ; Parameter::CSS_kanban] ;
[“__script” ; Parameter::Script] ; // “fmp” & sc_appVersion & “://” & “$/” & Get ( FileName ) & “?script=Return”
[“__glyphiconspath” ; “file://” & Middle ( Get ( TemporaryPath ) ; Position ( Get ( TemporaryPath ) ; “/” ; 1 ; 2 ) ; Length ( Get ( TemporaryPath ) ) )] ;
[“__data” ; List ( Lists::div )] ;
[“__functionDotify” ; If ( DefaultMaxChars ≠ “” and DefaultMaxChars > 0 ; limitText ; “” )] ;
[“__overlay” ; If ( Var_overlay = 1 ; “document.getElementById(‘overlay’).style.display = ‘block’;” ; “” )]
)
Likewise, you can also simply replace HTML parts of the webview with “Substitute”, for example.
This “Subsitute”, for example, simply inserts a line in the HTML when the team member has clicked on the “Cards minimize” parameter in his Kanban.
[“__display” ; If ( DefaultMinimize = 1 ; “display: none;”; “” )] ;
Script calls:
As I mentioned in a previous article, I do not prefer the new functions available under filemaker 19 for calling a Filemaker script from Java Script native, but rather the calls via URL from the webview.
This simply has to do with the fact that (to my knowledge at least) it is not possible to nest script calls.
But this is very important in my Kanban, because on the one hand I want to open the details by a click on the card itself and on the other hand I want to execute custom links (like email or phone numbers) in the card HTML DIV.
$( “.portlet-content” ).on( “click”, function( e )
{var id = $(this).closest(‘.portlet’).attr(‘id’);
$( self.location = ‘__script¶m=selectItem||||’ + id );
});
<div id='" & id & "' class='portlet'>
In this call, the id (which I used in the jQuery portlet DIV – it’s simply the Filemaker record id) is passed as a variable with a URL call to the Filemaker script.
As already said, the difficult part is to find the place in the Java script where you have to insert the URL call for the Filemaker script.
For example, the trigger for the end of the drop event in the Java script must be placed in the parameters of the jQuery plugin of the card portlets.
update: function( event, ui ) {
var changedList = this.id;
var order = $(this).sortable(‘toArray’);
var positions = order.join(‘;’);
output = changedList + ‘[‘ + positions + ‘]’
},stop: function( event, ui ) {
var id = ui.item.attr(“id”);
$( self.location = ‘__script¶m=reorder||||’ + output + id );
}
The “output“ variable must be created in the portlet’s “Update” parameter and then passed with the “Stop” parameter of the portlet’s drop event.
Create Links in cards:
A separate detailed article on this topic can be found here
For the creation of links in the cards I have written a set of custom functions that identify a link to be generated based on keywords and create a Filemaker URL script call.
The main function identifies the type of call and calls the corresponding sub custom function:
masterCall ( text ; theList ; counter )
Let ( [ max = ValueCount ( theList ) ; counter = If (counter = 0 or counter = "" ; 1 ; counter ) ; valueList = Substitute ( GetValue ( theList; counter ) ; "••••" ; ¶ ) ; beginString = GetValue ( valueList ; 1 ) ; endString = GetValue ( valueList ; 2 ) ; replaceString = GetValue ( valueList ; 3 ) ; newText = Case ( beginString = "[http" ; httpCall ( Text ; beginString ; endString ; replaceString ) ; beginString = "[Email:" ; mailCall ( Text ; beginString ; endString ; replaceString ) ; fmpCall ( Text ; beginString ; endString ; replaceString ) ) ] ; Case ( counter < max ; masterCall (newText; theList; counter + 1 ) ; counter = max ; newText ) )
Sub function http:
httpCall ( text ; beginString ; endString ; replaceString )
Let ([
lenBegin = Length(beginString);
lenEnd = Length(endString);
ptBegin = Position(text; beginString; 1; 1);
ptEnd = Position(text; endString; ptBegin + lenBegin; 1) + lenEnd;
modText = Left(text; ptBegin - 1);
remainText = Middle(text; ptEnd; 9999999);
replace = Middle ( text ; ptBegin + Length (beginString ) ; ptEnd - 1 - ptBegin - Length (beginString ) );
replaceClean = Austauschen ( replace ; [ "%" ; "%25" ] ; [ "¶" ; "%0D" ] ; [ " " ; "%20" ] ; [ "!" ; "%21" ] ; [ "\"" ; "%22" ] ; [ "#" ; "%23" ] ; [ "$" ; "%24" ] ;
[ "&" ; "%26" ] ; [ "'" ; "%27" ] ; [ "(" ; "%28" ] ; [ ")" ; "%29" ] ; [ "*" ; "%2A" ] ; [ "+" ; "%2B" ] ; [ "," ; "%2C" ] ;
[ "-" ; "%2D" ] ; [ "." ; "%2E" ] ; [ "/" ; "%2F" ] ; [ ":" ; "%3A" ] ; [ ";" ; "%3B" ] ; [ "<" ; "%3C" ] ; [ "=" ; "%3D" ] ;
[ ">" ; "%3E" ] ; [ "?" ; "%3F" ] ; [ "@" ; "%40" ] ; [ "[" ; "%5B" ] ; [ "\\" ; "%5C" ] ; [ "]" ; "%5D" ] ; [ "^" ; "%5E" ] ;
[ "`" ; "%60" ] ; [ "{" ; "%7B" ] ; [ "|" ; "%7C" ] ; [ "}" ; "%7D" ] )
];
Case(
lenBegin > 0 and lenEnd > 0 and
ptBegin > 0 and ptEnd > lenEnd;
modText & replaceString & "http" & replaceClean ) & "'>http" & replace & "" &
httpCall(remainText; beginString; endString; replaceString) ; text) )
Sub function Email:
mailCall ( text ; beginString ; endString ; replaceString )
Let ([
lenBegin = Length(beginString);
lenEnd = Length(endString);
ptBegin = Position(text; beginString; 1; 1);
ptEnd = Position(text; endString; ptBegin + lenBegin; 1) + lenEnd;
modText = Left(text; ptBegin - 1);
remainText = Middle(text; ptEnd; 9999999);
replace = Middle ( text ; ptBegin + Length (beginString ) ; ptEnd - 1 - ptBegin - Length (beginString ) );
textDisplay = "Email"
];
Case(
lenBegin > 0 and lenEnd > 0 and
ptBegin > 0 and ptEnd > lenEnd;
modText & replaceString & replace & "'>" & replace & "" &
mailCall(remainText; beginString; endString; replaceString) ; text) )
Sub function custom Links (e.g. external databases/scripts):
fmpCall ( text ; beginString ; endString ; replaceString )
Let ([
lenBegin = Length(beginString);
lenEnd = Length(endString);
ptBegin = Position(text; beginString; 1; 1);
ptEnd = Position(text; endString; ptBegin + lenBegin; 1) + lenEnd;
modText = Left(text; ptBegin - 1);
remainText = Middle(text; ptEnd; 9999999);
replace = Middle ( text ; ptBegin + Length (beginString ) ; ptEnd - 1 - ptBegin - Length (beginString ) );
textDisplay = LeftWords ( beginString ; 1 )
];
Case(
lenBegin > 0 and lenEnd > 0 and
ptBegin > 0 and ptEnd > lenEnd;
modText & replaceString & replace & "'>" & textDisplay & " " & replace & "" &
fmpCall(remainText; beginString; endString; replaceString) ; text) )
escaping illegal characters to avoid HTML errors:
When you let users enter text, they often use characters that can cause problems in the HTML code.
To avoid this I wrote a custom function “FilterChar” that simply allows only those characters that can be displayed without problems.
FilterChar ( text )
Filter ( text ; "1234567890ßqwertzuiopüasdfghjklöäyxcvbnm
QWERTZUIOPÜASDFGHJKLÖÄYXCVBNM !$%()[]{}=?*+-,._¶:/@•<>" )
Include jQuery icons in Filemaker webview:
Find the “.ui-widget-….ui-icon” entries in the “jQuery UI” CSS file and replace them with a placeholder e.g. “__glyphiconspath”:
.ui-icon,
.ui-widget-content .ui-icon {background-image: url(“__glyphiconspath/ui-icons_444444_256x240.png”);}
.ui-widget-header .ui-icon {background-image: url(“__glyphiconspath/ui-icons_444444_256x240.png”);}
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon,
-button:hover .ui-icon,
.ui-button:focus .ui-icon {background-image: url(“__glyphiconspath/ui-icons_555555_256x240.png”);}
.ui-state-active .ui-icon,
.ui-button:active .ui-icon {background-image: url(“__glyphiconspath/ui-icons_ffffff_256x240.png”);}
.ui-state-highlight .ui-icon,
.ui-button .ui-state-highlight.ui-icon {background-image: url(“__glyphiconspath/ui-icons_777620_256x240.png”);}
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {background-image: url(“__glyphiconspath/ui-icons_cc0000_256x240.png”);}
.ui-button .ui-icon {background-image: url(“__glyphiconspath/ui-icons_777777_256x240.png”);}
Place the icon files “ui-icons_… .png” in the parameter table in container fields and export them in a Start Script to the temporary Filemaker directory.
Then replace the placeholder “__glyphiconspath” in the Webviewer formula field.
“data:text/html,” & Substitute ( Parameter::HTML_Kanban ;
…
[“__glyphiconspath” ; “file://” & Middle ( Get ( TemporaryPath ) ; Position ( Get ( TemporaryPath ) ; “/” ; 1 ; 2 ) ; Length ( Get ( TemporaryPath ) ) )] ;
…
)
Just working out and implementing this little feature took me hours of work and headaches 🙂
Acknowledgements:
In this Kanban some plugins and custom functions used under MIT license.
Without these clever programmers this tool would not have been possible and I am deeply grateful that they
have made their tools available – Nanos gigantum humeris insidentes.
Custom functions:
WordBeginsWith
Andrew Persons
http://www.excelisys.com
FieldBeginsWith
Andrew Persons
http://www.excelisys.com
UniqueList
Agnès Barouh
http://www.tictac.fr/CoinFileMaker/Page.html
WordWrap
Jonathan Stark
http://jonathanstark.com
MergeValues
Peter Wagemans
https://www.lesterius.com
ListXor
Daniel Wood
http://www.teamdf.com
ListAminusListB
unkown author
ExtractXMLAttributeList__cf
Steve Hearn
http://coresolutions.ca
ExtractData
Andy Knasinski
http://www.nrgsoft.com
ErrorDescription
Andrew Duncan
http://www.databuzz.com.au
CustomList
Agnès Barouh
http://www.tictac.fr/CoinFileMaker/Page.html
ParameterToVariables
Mislav Kos
#Assign
Jeremy Bante
http://scr.im/jbante
Color Picker
Desktop Services, Inc.
http://desktopservices.net/blog/files/filemaker-color-picker-example.php
jquery Plugins:
Letterpic
George Yakovlev
https://yakovlevga.github.io/letterpic
jQuery UI – v1.12.1
http://jqueryui.com
ExecuteSQL Search
Mike Duncan
https://www.soliantconsulting.com/blog/filemaker-search-executesql
Icons:
iconsdb
https://www.iconsdb.com