-
Notifications
You must be signed in to change notification settings - Fork 0
api_methods
Static methods:
Instance methods:
- addRecordToTable
- closeChildTable
- deleteRecord
- deleteRows
- deselectRow
- destroy
- editRecord
- editRecordByKey
- editRecordViaAjax
- getRowByKey
- getSelectedRows
- getSortingInfo
- hideColumn
- load
- openChildTable
- performDelete
- recalcColumnWidths
- recalcColumnWidthsOnce
- reload
- selectRow
- setColumnVisibility
- showAddRecordForm
- showColumn
- toggleRowSelection
- updateRecordInTable
Waits for a field in a form to be ready, mostly used for dependant fields when they get their data from the server See the events section for examples
FTable.waitForFieldReady('myfieldname', e.form);do a ftable-get
const result = await FTableHttpClient.get('incidents.php', {
ids: idsjoined,
action: 'ajax_bulk_assets',
do_action,
change_location
});do a ftable-post
const result = await FTableHttpClient.post('incidents.php', {
ids: idsjoined,
action: 'ajax_bulk_assets',
do_action,
change_location
});This method is used to add a new record to the table programmatically.
table.addRecordToTable(record)- record: The record object to add (required).
const table = new FTable('#StudentTableContainer', { /*...*/ });
table.addRecordToTable({
Name: 'My full Student name',
EmailAddress: 'test123@example.com',
Password: '123',
Gender: 'M',
CityId: 4,
BirthDate: '2002-11-18',
Education: '2',
About: 'Adding test record',
IsActive: true,
RecordDate: '2011-11-12'
});If you want to update the backend server too, use performCreate:
async function addRecordWithServer(data) {
try {
const result = await table.performCreate(data);
if (result.Result === 'OK') {
const record = result.Record || data;
table.addRecord(record); // Add to UI
table.emit('recordAdded', { record, serverResponse: result });
return record;
} else {
table.showError(result.Message || 'Create failed');
}
} catch (error) {
table.showError(table.options.messages.serverCommunicationError);
}
}
// Usage example:
addRecordWithServer({
name: 'John',
email: 'john@example.com'
});Closes an open child table for a table row.
table.closeChildTable(row)- row: The DOM row element.
Deletes an existing record from the table programmatically.
table.deleteRecord(options)- key: The key (ID) of the record to delete (required).
-
clientOnly (boolean, default:
false): Iftrue, the record is only deleted from the table, not from the server. -
animationsEnabled (boolean, default: table's behavior): If
false, no animation is shown. -
url (string, default:
deleteActionof the table): A custom URL for deleting the record. - success (function): Callback when the record is successfully deleted.
- error (function): Callback if an error occurs.
const table = new FTable('#StudentTableContainer', { /*...*/ });
table.deleteRecord({
key: 42
});Deletes the specified rows from the server and table. This method can be combined with getSelectedRows method. Thus, you can get selected rows and pass to deleteRows method to delete them.
table.deleteRows(rowskeys)- rowkeys: An array of row keys to delete.
Deselects the specified row.
table.deselectRow(row)- row: row element to deselect.
Completely removes the table from its container.
table.destroy()Forces the edit dialog of a row to open.
table.editRecord(row)Forces the edit dialog of a record to open.
table.editRecordByKey(keyFieldValue)Is simply a combo of getRowByKey and editRecord
const table = new FTable('#MyTableContainer', { /*...*/ });
// To force the editDialog to open
const hash = window.location.hash;
const match = hash.match(/edit=(\d+)/);
if (match) {
const idToEdit = match[1];
table.editRecordByKey(idToEdit);
}This example allows linking from other HTML pages to the page containing this JS with something like mypage.html#edit=123. This will then open the MyTableContainer FTable edit dialog for row with key value 123 (if the row is present, can be a problem if paging is on, but see editRecordViaAjax).
Forces the edit dialog of a record to open via AJAX.
table.editRecordViaAjax(keyFieldValue, myAjaxUrl)const table = new FTable('#MyTableContainer', { /*...*/ });
// To force the editDialog to open
const hash = window.location.hash;
const match = hash.match(/edit=(\d+)/);
if (match) {
const idToEdit = match[1];
table.editRecordViaAjax(idToEdit, myAjaxUrl);
}The myAjaxUrl call will get the name and value of the key-field passed along and should respond with something like:
//Return result to FTable
$fTableResult = [
'Result' => "OK",
'Record' => $row
];
echo json_encode($fTableResult);Resulting JSON is then something like:
{
"Result": "OK",
"Record": { "PersonId": 5, "Name": "Dan Brown", "Age": 55, "RecordDate": "/Date(1320262185197)/" }
}This example allows linking from other HTML pages to the page containing this JS with something like mypage.html#edit=123. This will then open the MyTableContainer FTable edit dialog for row with key value 123 (row content loaded via AJAX request).
Returns the DOM row element for a record via the key field's value of the record key.
table.getRowByKey(keyValue)Returns all selected rows as an array of DOM elements.
const selectedRows = table.getSelectedRows()const table = new FTable('#PersonTable', { /*...*/ });
const selectedRows = table.getSelectedRows();
selectedRows.forEach(function(row) {
const recordKey = row.recordKey; // contains the row key id
const record = row.recordData; // contains all columns
const personId = record.PersonId;
const name = record.Name;
});Returns an array of field names with their current sorting (ASC/DESC).
const sortingInfo = table.getSortingInfo()Makes a column hidden. A shortcut version of table.setColumnVisibility
table.hideColumn(columnName)Loads records from the server.
table.load(postData, completeCallback)- postData: Optional data to send to the server.
- completeCallback: Optional callback function called when loading is complete.
const table = new FTable('#PersonTable', { /*...*/ });
table.load({ CityId: 2, Name: 'Halil' });If parameters are given via the load call and the same parameters exist in the listQueryParams option, the ones in the load call add/override params defined in the listQueryParams option.
Opens a child table for a table row.
table.openChildTable(row, tableOptions, opened)- row: The DOM row element.
- tableOptions: Standard FTable options for the child table.
- opened: Callback function called when the child table is opened.
const table = new FTable('#PersonTable', {
// ... other options
fields: {
// ... other fields
Phones: {
title: '',
width: '5%',
sorting: false,
edit: false,
create: false,
listClass: 'child-opener-image-column',
display: function (personData) {
// Create an image that will be used to open the child table
const img = document.createElement('img');
img.className = 'child-opener-image';
img.src = '/Content/images/Misc/phone.png';
img.title = 'Edit phone numbers';
// Open child table when user clicks the image
img.addEventListener('click', function () {
table.openChildTable(
img.closest('tr'),
{
title: personData.record.Name + ' - Phone numbers',
actions: {
listAction: '/PagingPerson/PhoneList?PersonId=' + personData.record.PersonId,
deleteAction: '/PagingPerson/DeletePhone',
updateAction: '/PagingPerson/UpdatePhone',
cloneAction: '/PagingPerson/ClonePhone',
createAction: '/PagingPerson/CreatePhone?PersonId=' + personData.record.PersonId
},
fields: {
PhoneId: {
key: true,
create: false,
edit: false,
list: false
},
PhoneType: {
title: 'Phone type',
width: '30%',
options: { '1': 'Home phone', '2': 'Office phone', '3': 'Cell phone' }
},
Number: {
title: 'Phone Number',
width: '30%'
},
RecordDate: {
title: 'Record date',
width: '20%',
type: 'date',
displayFormat: 'dd.mm.yy',
create: false,
edit: false
}
}
},
function (data) { // opened handler
data.childTable.load();
}
);
});
// Return image to show on the person row
return img;
}
}
}
});When you want to override the default Delete action flow, you can call this method to perform the actual delete.
// Override the delete button click handler after the table is initialized
table.on('recordsLoaded', function() {
// Find all delete buttons within the table
const deleteButtons = table.elements.table.querySelectorAll('.ftable-delete-command-button');
deleteButtons.forEach(button => {
// Remove any existing click handlers (FTable's default)
const newButton = button.cloneNode(true);
button.parentNode.replaceChild(newButton, button);
// Add your custom click handler
newButton.addEventListener('click', async function(e) {
e.preventDefault();
e.stopPropagation();
// Get the row and record data
const row = this.closest('.ftable-data-row');
const record = row.recordData;
// Create your custom modal content
const modalContent = document.createElement('div');
modalContent.innerHTML = `
<p>Are you sure you want to remove ${record.XXX}?</p>
<label for="additional-info">Extra info asked:</label>
<textarea id="additional-info" name="additional_info" rows="4" style="width: 100%; margin-top: 10px;"></textarea>
`;
// Create and show the custom modal using FtableModal
const customDeleteModal = new FtableModal({
title: 'Bevestiging Verwijderen',
content: modalContent,
buttons: [
{
text: 'Cancel',
className: 'ftable-dialog-cancelbutton',
onClick: () => customDeleteModal.close()
},
{
text: 'Remove',
className: 'ftable-dialog-deletebutton',
onClick: async () => {
const additionalInfo = document.getElementById('additional-info').value;
// Prepare the data to send to the server
// The key field (e.g., 'id') is required for deletion
const deleteData = {
[table.keyField]: record[table.keyField], // Essential for deletion
additional_info: additionalInfo, // Your extra field
// You can add more fields here if needed
};
customDeleteModal.close();
try {
// Manually call the delete action with your custom data
const result = await table.performDelete(deleteData);
if (result.Result === 'OK') {
// Reload the table or remove the row manually
table.reload();
if (result.Message)
table.showInfo(result.Message);
} else {
if (result.Message)
table.showError(result.Message);
}
} catch (error) {
table.showError('Server communication error.');
console.error('Delete failed:', error);
}
}
}
]
});
customDeleteModal.create().show();
});
});
});Recalculate the column widths when a table becomes visible. Can be useful in hidden tabs.
table.recalcColumnWidths()Recalculate the column widths once when a table becomes visible. Can be useful in hidden tabs but is only done the first time the table becomes visible.
table.recalcColumnWidthsOnce()Example usage (as used in Events Made Easy WordPress plugin):
if (target == "tab-mailings") {
// Do this only when the tab is active, to avoid doing mail lookups if not needed
// Delay the trigger to ensure the tab content is fully rendered
setTimeout(function() {
const table = new FTable('#MailingsTableContainer', { /*...*/ });
table.recalcColumnWidthsOnce();
document.getElementById('MailingsLoadRecordsButton').click(); // custom button that triggers load with extra filters set
}, 100); // Adjust the delay as necessary
}FTable holds a cache for 10 seconds. If you do external actions and need to reload data, this function first clears the cache and then performs a load.
table.reload()The reload function takes an optional parameter to indicate that you want to keep the state of the selected rows. By default this is false, passing "true" will keep the state.
Selects the specified row.
table.selectRow(row)- row: row element to select.
Changes the visibility of a column.
table.setColumnVisibility(columnName, visibility)- columnName: The name of the column.
-
visibility: Can be
'true'or'false'.
Programmatically opens a "create new record" form dialog.
table.showAddRecordForm()Makes a column visible. A shortcut version of table.setColumnVisibility
table.showColumn(columnName)Inverts the selection state of the specified row in the table.
table.toggleRowSelection(row)- row: A DOM row element to invert.
Updates an existing record on the table programmatically.
table.updateRecordInTable(record)- record: The record object to update (required).
const table = new FTable('#StudentTableContainer', { /*...*/ });
table.updateRecordInTable({
StudentId: 42,
Name: 'My full Student name',
EmailAddress: 'test123@example.com',
Password: '123456',
Gender: 'M',
CityId: 4,
BirthDate: '2001-11-18',
Education: '3',
About: 'Updated this record',
IsActive: true,
RecordDate: '2012-01-05'
});If you want to update the backend server too, use performUpdate:
async function updateRecordWithServer(key, newData) {
try {
const result = await table.performUpdate(newData);
if (result.Result === 'OK') {
const row = table.getRowByKey(key);
if (row) {
table.updateRowData(row, result.Record || newData);
table.emit('recordUpdated', { record: result.Record || newData, row, serverResponse: result });
}
} else {
table.showError(result.Message || 'Update failed');
}
} catch (error) {
table.showError(table.options.messages.serverCommunicationError);
}
}
// Usage example:
updateRecordWithServer(5, {
id: 5,
name: 'Jane',
email: 'jane@example.com'
});