Main Components
Tables - Done
download html file updated jan 9 2025 12 05pm pst view live version https //userfirst factory webflow\ io/tables security note security note when developing disabling a checkbox (or any ui element) in the interface is purely for user experience and error prevention—it’s not a security measure if someone re enables a disabled checkbox by modifying the markup (for example, using browser dev tools) and attempts to use it, your backend should respond in a way that prevents any unintended action in other words, at best nothing should happen, or at worst the user should see an error message under no circumstances should modifying source (such as using browser tools) change/effect how they create, access, modify or delete data server side data dependencies some dependencies are taken care of by global dependencies and are provided here for reference module global depenedency description jquery 3 5 1 yes required for animations, date range picker and other functions date range picker yes provides single date, and date range selection ui depends on jquery and moment js moment js yes required by date range picker provides date manipulation and formatting built in functions download as csv description exports table contents (header row and data rows as a csv file and initates download in the browser) audit records an entry to the audit log of the user downloading the data inline edit description when enabled, by clicking the inline edit icon in the cell the cell's data can be edited once editing is complete there is a save button there is also a cancel button to cancel the edit and revert the change inline edit types there are different editor types type description text is a plain text edit input, there is a max length option to restrict text input length dropdown a dropdown list generated based on a object populated via the json date uses the datepicker can be a single date or range if needed settings for the picker such as the start date/initial date are set in the json phone is a text box input, that on blur, or when clicking save uses the validatephone function to validate and reformat entries before save saves email is a text box input, that on blur, or when clicking save uses the validateemail function to validate and reformat entries before save url is a text box input, that on blur, or when clicking save uses the validateurl function to validate and reformat entries before save validation error handling if an error is returned by one of the function it returns an error message in the respose, that error message should be displayed in the \<div class="validation error inline edit"> error message \</div> you can use this same div to return server side valiation errors as well div is display\ none by default when using you must enable to make it visible as a best practice when clearing an error you should clear the contents of the div as well as hide it date picker description the date picker we are using is daterangepicker js it is suitable for both individual date, date/time, and date ranges this will be used in tables in two different areas, as a date range filter for filtering date columns and as a date picker for in line editing note a final js and documentation for this is being revised and will be published very soon html structure below is the general html structure of a table inside name \ more data columns delete selected export to csv select one canada united states \ more filter columns data tippy content="{checkboxdisabledtooltip}" data placement="right" > lorem ipsum is simply dummy text of the printing and typesetting industry {icon like trendingup} 555 555 5555 wprice\@email com {validation error} john doe\@email com \ more cells > 1234 \ more footer / total columns items per page 10 25 50 100 1000 1–10 of 103 items 1 2 of 11 pages html special notes last data row in table the last \<tr> in the \<tbody> should have the combo class last row added to it e g \<tr class="table row last row"> we could accomplish this programatically by doing this document addeventlistener('domcontentloaded', () => { const tbodies = document queryselectorall('tbody'); tbodies foreach(tbody => { const lasttr = tbody queryselector('tr\ last child'); if (lasttr) { lasttr classlist add('last row'); } }); }); json schema this document defines a json based schema for configuring dynamic tables, including features like add button and actions menu multi row selection (checkboxes) column filtering sorting (default sort and per column) inline editing totals row with sums/counts/averages pagination progress bars , toggles , and more how to use this schema schema table level configuration table field type description how it works headerrow object contains settings for the top row (add button, three dot menu, multi row selection) filterrowenabled boolean if true , a filter row appears below the header row defaults to false if not specified defaultsortcolumn string the id of the column to sort by on first render (e g , "item name" ) totalrowenabled boolean if true , displays a totals row at the bottom of the table (calculates sums, counts, averages where configured) recordsperpage number number of rows to display per page if total rows > recordsperpage , pagination controls appear rowselection boolean if true , the checkbox column is rendered on the table allowing single or multi row selections if false don't render the checkbox column at all don't just hide the div headerrow object field type description addbutton object settings for the add (+) button (label, enable/disable, on click function) tablemenu object settings for the table menu (3 dots) headerrow\ addbutton object field type description tooltip string text to be displayed if hovering the add button enabled boolean if false , hides the add button onclickfunction string the function name or event handler triggered on button click (e g , "addnewrecord" ) headerrow\ tablemenu object field type description enabled boolean if false , hides the table menu tooltip string text to be displayed if hovering the table menu button options array an array of menu options each option is an object with name , enabled , onclickfunction downloadascsv boolean if true , a “download as csv” option is shown and triggers the table’s csv export function headerrow\ tablemenu options array of objects field type description name string display text for the menu item (e g , "delete selected" ) onclickfunction string name of the function to call when the user selects this item, e g , "deleteselectedrows" onlywhenrowsselected boolean if true , this menu item is only visible when one or more rows are selected via checkboxes (assuming rowselection = true ) column level configuration columns each columacceptablen is an object in the columns array field type description how it works id string a unique id for each column used for filtering and sorting name string the header label for the column, e g "item name" type string one of text , date , email , number , money , toggle , starrating or progress textalign string|null aligns text to the left , right , or center if null it defaults to left if right or center add style="text align " to the div with the table data and table heading classes for each cell in this column (e g \<div style="text align textalign " class="table heading"> and \<div style="text align textalign " class="table data"> imagewidth number sets the image width/size in px for this column for every image in this column, update the width \<img width=" imagewidth px"> if imagewidth is empty it defaults to 32px imageaspectratio string|null sets the aspect ratio for the image options are "1/1" , "16/9" , or "3/2" for every image in this column, add the appropriate class to the image note table image defaults to 1 1 if 1/1 do nothing elseif 16/9 add class 169 elseif 3/2 add class 32 the modifier class must come after the main class (e g class="table image 169" ) dateformat string|null applicable when type="date" example "yyyy mm dd" acceptable inputs should be patterns we can pass directly to js these should be formatdate global function default to yyyy mm dd filterenabled boolean|null displays a filter control in the filter row if true default to true filtertype string|null one of text , dropdown , or datepicker default to text if null inlineeditenabled boolean|null if true , cells in this column can be edited in line unless overridden by the row default to false inlineedittype string|null editor type for in line edits text , dropdown , date , phone , email , or url default to text inlineeditdatepicker object if inlineedittype is "date", the inlineeditdatepicker object is required inlineeditdropdown object if inlineedittype is "dropdown", the inlineeditdropdown object is required inlineeditplaceholder string|null text to be used as the placeholder for the input box for text, phone, email, url, date etc (shows when the input field is empty) inlineedittextmaxlength number|null sets the maximum number of characters allowed showtotal boolean if true and totalrowenabled is true , a total displays in the total row for this column totaltype string|null the type of total/calculation "sum" , "count" , or "average" totaltooltip string|null hover text explaining how the total is calculated, e g , "sum of all item prices" overflow boolean if true , the column text is truncated with ellipses if it doesn’t fit minwidth number|null minimum width in pixels (e g , 80 ) maxwidth number|null maximum width in pixels (e g , 150 ) if null , there is no explicit maximum (beyond the container’s constraints) tooltipposition string|null changes the position where the tooltip opens options are top , top start , top end , right , right start , right end , bottom , bottom start , bottom end , left , left start , or left end if not provided it defaults to bottom set the data placement attribute on each element in the column with the data tippy content attribute set (e g \<div data tippy content=" tooltip " data placement=" tooltipposition ">) progressvariablecolor string|null if progressvariablecolor (string) is set to "true" , a dynamic gradient is applied based on progress percentage; if set to "reverse" , the gradient is reversed these are the only valid string options if provided, set the attribute data progress variable color=" progressvariablecolor " on each \<div> in the column with the class progress bar progress (e g \<div class="progress bar progress" data progress variable color="true">) datepicker object field type description singledatepicker boolean key switch for single date vs date range true → single date, false → date range startdate date|null the initial date (if singledatepicker = true ) or start of the initial range (if false ) must match dateformat if it’s a string picks todays date if null enddate date|null the end date of the initially selected range ignored if singledatepicker = true mindate date|null earliest date the user can select maxdate date|null latest date the user can select maxspan object (optional) the largest allowed range between startdate and enddate , e g { "days" 7 } showdropdowns boolean|null shows year/month dropdowns for quick jumps if true timepicker boolean|null displays time selection if true timepickerincrement number|null interval for minutes in time selection (e g , 15 ) only matters if timepicker = true opens null | "left" | "right" | "center" positions the picker relative to the input left, right, or center autoapply boolean if true , user’s selection is auto applied if false , they must press an “apply” button default to true datepicker maxspan object key type description days number limits the date range to the specified number of days (e g , 7 means start and end can’t exceed 7 days apart) weeks number limits the date range to the specified number of weeks (e g , 2 means the user can select at most a 2 week span) months number limits the date range to the specified number of months years number limits the date range to the specified number of years note you only need to supply one of these keys in the maxspan object for instance, { "days" 7 } or { "weeks" 2 } the date range picker https //www daterangepicker com/ uses moment js under the hood, so any key/value supported by moment’s add() method should work if multiple keys are provided, each will be applied additively however, that’s an advanced scenario—most commonly, you’ll specify just one inlineeditdropdown object (column level see cell level and more info below) field type description dropdownfilter boolean if true shows filter input at top of dropdown default false (no filter) sortbyvalue boolean if true sorts the options by value instead of by name honors sortdescending sort string|null if sort = null then no sort is applied if sort = asc sorts descending if sort = dsc sorts descending options object|null optionally sets the list of options at the column level (for example things like statuses active, pending etc ) inlineeditdropdown options object (column level see cell level and more info below) field type description name string name of the option value string value to return when saving isdefault boolean if true this item is selected by default if cell data is empty inlineeditdatepicker object same structure as datepicker object special notes type="progress" requires each cell to have progresspercent type="toggle" generally displays a switch for “active”/“inactive” or true/false states this is an inline edit option and should update the database when toggled type="money" typically formatted as currency the ui may prefix with $ or localize as needed row level configuration rows each row is an object in the rows array field type description how it works checkboxdisabled boolean if true , the row’s selection checkbox is disabled (when multi row selection is enabled in the header) checkboxdisabledtooltip string|null an explanation for why the checkbox is disabled, displayed on hover disableinlineedit boolean overrides any column inlineeditenabled if true , this row cannot be edited in line editbutton boolean if true , an “edit” button icon is displayed for this row deletebutton boolean if true , a “delete” button icon is displayed for this row bold boolean if true , apply the class if true apply the modifier class bold to the \<tr> cells array the set of cells for this row, each corresponding to a column definition in columns cell level configuration within each row’s cells array field type description how it works imagepath string|null url/path to an image to show in the cell (e g , user avatar, product image) add image as first element in side of div with class "table cell left" in this cell (e g \<div class="table cell left">\<img src=" imagepath " alt=" imagealt " class="table image">) imagealt string|null alt text for the image see imagepath example above data string the main text data of the cell for most column types, data is displayed directly the main text data of the cell for most column types, data is displayed directly supports basic html formatting, such as for bold text (e g \<div class="table data"> data \</div>) tooltip string|null text to be shown on hover of div of the appropriate div in this cell if type = progress then set the data tippy content attribute in the \<div> with the class progress bar container in this cell elseif type = toggle then set the data tippy content in the \<div> with the class toggle container in this cell elseif type = starrating then set the data tippy content in the \<div> with the class star rating container in this cell else set the data tippy content attribute in the \<div> with the class table cell left in this cell (e g \<div class="table cell left" data tippy content=" tooltip ">) hyperlink string|null if entered data becomes a hyperlink contents of the hyperlink string are the url for the link a \<a> tag is wrapped around the 'data' string (e g \<a href=" hyperlink " title=" data " target=" blank"> data \</a>) rightcontenttype string|null when set to "uparrow" , "downarrow" , "trendup" , "trenddown" , "checkmark" , "x" , "staroutline" , "starsolid" or "text" , displays an icon or text on the right side of the cell add other than text, add the appropriate svg to the div with class "table cell right content" in this cell see below for svgs (e g \<div class="table cell right content"> \<svg>\</svg> \</div>) rightcontenttext string|null used if rightcontenttype = "text" to show custom text at the cell’s right side add text to the div with class "table cell right content" in this cell (e g \<div class="table cell right content"> rightcontenttext \</div>) rightcontentcolor string|null color (e g , "#28a745" ) to apply to the right side icon or text add a style="color rightcontentcolor " to the div with class "table cell right content" in this cell (e g \<div class="table cell right content" style="color rightcontentcolor ;">) rightcontenttooltip string|null text to display in tooltip when hovering over rightcontent icon or text set the data tippy content in the \<div> with the class "table cell right content" in this cell (e g \<div class="table cell right content" data tippy content=" rightcontenttooltip "> starrating number a number of stars out of 5 stars for example 4 5 set the value the attribute data rating of the \<div> with the class star rating container in this cell (e g \<div class="star rating container" data rating=" starrating "> progresspercent number required if column type="progress" , this is the % to show in the progress bar must be 0 100 set the width in percentage of the \<div> with the class progress bar progress in this cell (e g \<div class="progress bar progress" style="width progresspercent %;"> inlineeditdropdownoption object used if inlineedittype = dropdown if options are set at the column level this is not needed (for example statuses) if this dropdown is to have content specific to this row it can be set in this object inlineeditdropdownoptions object (column level see cell level and more info below) field type description name string name of the option value string value to return when saving isdefault boolean if true this item is selected by default if cell data is empty example json { "table" { "headerrow" { "addbutton" { "tooltip" "add new row", "enabled" true, "onclickfunction" "handleaddrow" }, "tablemenu" { "enabled" true, "tooltip" "table options", "options" \[ { "name" "delete selected", "onclickfunction" "handledeleteselected", "onlywhenrowsselected" true } ], "downloadascsv" true } }, "filterrowenabled" true, "defaultsortcolumn" "description", "totalrowenabled" true, "recordsperpage" 5, "rowselection" true, "progressvariablecolor" true }, "columns" \[ { "id" "description", "name" "description", "type" "text", "filterenabled" true, "filtertype" "text", "inlineeditenabled" true, "inlineedittype" "text", "inlineeditplaceholder" "enter item description", "showtotal" false, "overflow" true, "tooltipposition" "right" }, { "id" "releasedate", "name" "release date", "type" "date", "dateformat" "yyyy mm dd", "filterenabled" true, "filtertype" "datepicker", "inlineeditenabled" true, "inlineedittype" "date", "inlineeditdatepicker" { "singledatepicker" true, "startdate" "2025 01 01", "mindate" "2024 01 01", "maxdate" "2026 12 31", "showdropdowns" true, "timepicker" false, "opens" "center", "autoapply" true }, "showtotal" false }, { "id" "price", "name" "price", "type" "money", "filterenabled" true, "filtertype" "text", "inlineeditenabled" true, "inlineedittype" "text", "inlineeditplaceholder" "$0 00", "showtotal" true, "totaltype" "sum", "totaltooltip" "total of prices" }, { "id" "quantity", "name" "qty", "type" "number", "filterenabled" true, "filtertype" "text", "inlineeditenabled" true, "showtotal" true, "totaltype" "count", "totaltooltip" "count of items" }, { "id" "activestatus", "name" "active status", "type" "toggle", "filterenabled" true, "filtertype" "dropdown", "inlineeditenabled" true, "inlineedittype" "dropdown", "inlineeditdropdownoptions" \[ { "name" "active", "value" "true" }, { "name" "inactive", "value" "false" } ], "showtotal" false }, { "id" "completion", "name" "completion", "type" "progress", "filterenabled" false, "inlineeditenabled" false, "showtotal" false }, { "id" "useremail", "name" "user email", "type" "email", "filterenabled" true, "filtertype" "text", "inlineeditenabled" true, "inlineedittype" "email", "inlineeditplaceholder" "email\@domain com", "showtotal" false } ], "rows" \[ { "editbutton" true, "deletebutton" true, "cells" \[ { "data" "widget a", "tooltip" "click to see widget a details", "hyperlink" "https //example com/widget a", "rightcontenttype" "starsolid", "rightcontentcolor" "#ffd700", "rightcontenttooltip" "it's a favorite" }, { "data" "2025 02 15", "tooltip" "release date" }, { "data" "19 99", "tooltip" "unit price" }, { "data" "12", "tooltip" "available quantity" }, { "data" "true", "tooltip" "active" }, { "progresspercent" 75, "progresstooltip" "75% done" }, { "data" "john doe\@example com", "tooltip" "contact email" } ] }, { "editbutton" true, "deletebutton" true, "cells" \[ { "data" "widget b", "imagepath" "https //example com/widget b png", "imagealt" "widget b image", "tooltip" "a fancy widget", "rightcontenttype" "trenddown", "rightcontentcolor" "#dc3545", "rightcontenttooltip" "trending down" }, { "data" "2025 03 10", "tooltip" "tentative release date" }, { "data" "29 99", "tooltip" "price" }, { "data" "5", "tooltip" "quantity in stock" }, { "data" "false", "tooltip" "inactive" }, { "progresspercent" 20, "progresstooltip" "20% done" }, { "data" "jane\@example com", "tooltip" "contact email" } ] } ] } svgs uparrow downarrow trendup trenddown checkmark x staroutline starsolid