Update multiple records with a checkbox

This first requires you to add the checkbox snippet from this example:  Add checkboxes to a table

This following snippet will add an "Update" button below your view header and update all checked records with the data you specify in the data variable.

Once all records are updated, an alert will display confirming the update.

Note: This still needs some work! There's no function to catch errors, etc.  

var addCheckboxes = function(view) {

// add the checkbox to to the header to select/unselect all
$(’#’ + view.key + ‘.kn-table thead tr’).prepend(’<th><input type=“checkbox”></th>’);

$(’#’ + view.key + ‘.kn-table thead input’).change(function() {
$(’.’ + view.key + ‘.kn-table tbody tr input’).each(function() {
$(this).attr(‘checked’, $(’#’ + view.key + ‘.kn-table thead input’).attr(‘checked’) != undefined);
});
});

// add a checkbox to each row in the table body
$(’#’ + view.key + ‘.kn-table tbody tr’).each(function() {
$(this).prepend(’<td><input type=“checkbox”></td>’);
});
}

var updateRecords = function(id, records, data) {
$.ajax({
url: ‘https://api.knackhq.com/v1/objects/object_1/records/’ + id,
type: ‘PUT’,
/***** CHANGE TO YOUR OWN APPID AND API KEY HERE *****/
headers: {‘X-Knack-Application-ID’: ‘YOUR-APP-ID’, ‘X-Knack-REST-API-Key’: ‘YOUR-API-KEY’},
data: data,
success: function(response) {
if ( records.length ) {
// Every time a call is made, the array is shifted by 1.
// If the array still has a length, re-run updateRecords()

    updateRecords(records.shift(), records);
  } else {            
    // We know all records are processed when length = 0
    alert('Update complete!');
    Knack.hideSpinner();
  }
}

})
}

/**** CHANGE VIEW_ID TO YOUR OWN VIEW ID ****/
$(document).on(‘knack-view-render.VIEW_ID’, function (event, view) {

// Add an update button
$(’<button id=“update”">Update</button>’).insertAfter(’.view-header’);

// Add checkboxes to our table
addCheckboxes(view);

// Click event for the update button
$(’#update’).click(function () {

// We need an array of record IDs
var record_ids = [];

// Populate the record IDs using all checked rows
$('#' + view.key + ' tbody input[type=checkbox]:checked').each(function() {
  record_ids.push($(this).closest('tr').attr('id')); // record id
});
 
Knack.showSpinner();
 
// Define the fields you want to update
var data = {
  field_1: 'Closed'
};

// Use the first ID in the array, then pass in the rest of the array
updateRecords(record_ids.shift(), record_ids, data);

})
});

    

Does anyone have a demo of this working please?

Hi,
I changed the code, now when you press the button it updates all the selected records not just the first.

// Function that adds checkboxes
var addCheckboxes = function(view) {
// Add the checkbox to to the header to select/unselect all
$('#' + view.key + '.kn-table thead tr').prepend('<th><input type="checkbox"></th>');
$('#' + view.key + '.kn-table thead input').change(function() {
$('.' + view.key + '.kn-table tbody tr input').each(function() {
$(this).attr('checked', $('#' + view.key + '.kn-table thead input').attr('checked') != undefined);
});
});
// Add a checkbox to each row in the table body
$('#' + view.key + '.kn-table tbody tr').each(function() {
$(this).prepend('<td><input type="checkbox"></td>');
});
}

$(document).on('knack-view-render.view_#', function (event, view) {

// Add update button
$('<button id="update"">Update</button>').insertAfter('.view-header');

//Add checkboxes to table
addCheckboxes(view);

// Click event for the update button
$('#update').click(function () {

// Array of record IDs
var record_ids = [];

// Populate the record IDs using all checked rows
$('#' + view.key + ' tbody input[type=checkbox]:checked').each(function() {
record_ids.push($(this).closest('tr').attr('id')); // record id
});

// turn on the Knack wait spinner
Knack.showSpinner();

// Field(s) to update
var data = {
field_1: ' ',
field_2: ' '
};

// set the delay to prevent hitting Knack API rate limit (milliseconds)
var myDelay = 100;

//call updateRecords function
$(function() {
updateRecords(record_ids.shift(), record_ids, data);
});

// use an ajax call to set the new value in knack for each checked record in the record ID array
var selectedRecords = record_ids.length + 1
function updateRecords(id, records, data) {
$.ajax({
url: 'https://api.knackhq.com/v1/objects/object_#/records/' + id,
type: 'PUT',
headers: {'X-Knack-Application-ID': ' ',
'X-Knack-REST-API-Key': ' '},
data: data,
success: function(response) {
if (record_ids.length > 0) {
// every time a loop is made, the array is shifted by 1.
// if the array still has a length greater than 0, re-run another updateRecords loop
setTimeout(updateRecords(record_ids.shift(), record_ids, data), myDelay);
}
else {
alert('Updating ' + selectedRecords + ' records.');
Knack.hideSpinner();
window.location.reload(true);
// Knack records are updated now
}
}
})
}
})
});

Kevin, below is what you need to update:

var # = $('#view_#-field_# option:selected').val();

Hi,
 
This is a really great solution and works perfectly. I do however have a requirement that I cannot seem to get to work. I need the var data to be updated to a field value from a 'details view' above the table. I have tried to store the value in a variable that I reference (see below) but the table cells are updated with a blank value. 
 
Any suggestions will be greatly appreciated
 
Many Thanks
Kevin
 
 
 
var INV  = $('#view_218-field_184').text();

 
// Define the fields you want to update
var data = {
field_279: INV
};

Hi all, i'm wondering how you can trigger a pop-up window to display the values of the field (when the field is a multiple choice) instead of setting it up at a specified value.

In the above example, the update button will update the value of the field 13 to "Test" which is one of the value possible. That's fine I've managed to adapt this to my own use.

But let's say I need to give the app user the ability to select one or more value among all the values of the multiple choice field ?

And how would it be possible to restrict the displayed values depending upon the logged-in user (assuming this is of course a connected records)

I'm pretty sure it's doable ... but can't figure out how (and way above my skills somehow)

@Kimberley Sare is it possible for you to make a multiple-choice field there instead?

Zac and Brent - I stand on your shoulders! Thank you so much! It's working for me as expected. !

 

(one caveat - a phantom button shows up at the bottom of my screen. no harm tho)

Hi Jason

I have got around this by changing this:
$(document).on('knack-view-render.view_X', function(event, view) {

to:
$(document).one('knack-view-render.view_X', function(event, view) {

May I ask a question please?

I am using this script to update a field that is a connected field (Tax Allowances), using the "display field" in the parent record (Tax Year) (which is a one to many relationship so appears as a single selection dropdown in the builder. I want to update the Tax Year to 2019/20 so have added this:

field_1086: '2019/20'

The code runs fine and the record is updated but rather than '2019/20' it's blank. 

What am I doing wrong please?

Ok, I have this working on one of my tables, but if I search the table or move from page to page in the table, another copy of the button is being created since the table renders again when searching/moving page to page.

 

How do I prevent the multiple buttons being created?

Here is the updated link for that snippet:

https://www.knack.com/developer-documentation/#add-checkboxes-to-a-table

I have also edited Nic's original post with the updated link. 

Does anyone have the 'Add checkboxes to a table" snippet? This is a dead link when I click it now. Appreciate it.

Tried this code with updated fields and views and I get the spinner then a blank screen. :(

Ted & Zak,

I had the same issue where only the first record checked would update. I made a few changes and the code below should work. There is still a lot of room for improvement. 

var addCheckboxes = function(view) {

// add the checkbox to to the header to select/unselect all
$('#' + view.key + '.kn-table thead tr').prepend('<th><input type="checkbox"></th>');

$('#' + view.key + '.kn-table thead input').change(function() {
$('.' + view.key + '.kn-table tbody tr input').each(function() {
$(this).attr('checked', $('#' + view.key + '.kn-table thead input').attr('checked') != undefined);
});
});

// add a checkbox to each row in the table body
$('#' + view.key + '.kn-table tbody tr').each(function() {
$(this).prepend('<td><input type="checkbox"></td>');
});
}


/**** CHANGE VIEW_ID TO YOUR OWN VIEW ID ****/
$(document).on('knack-view-render.view_39', function(event, view) {

// Add an update button
$('<button id="update"">Update</button>').insertAfter('.view-header');

// Add checkboxes to our table
addCheckboxes(view);

// Click event for the update button
$('#update').click(function() {

// We need an array of record IDs
var record_ids = [];

// Populate the record IDs using all checked rows
$('#' + view.key + ' tbody input[type=checkbox]:checked').each(function() {
record_ids.push($(this).closest('tr').attr('id')); // record id
});

Knack.showSpinner();

// Define the fields you want to update
var data = {
field_13: 'Test',
field_12: 'Hold',
field_18: 10
};

// seet the delay to prevent hitting API rate limit (milliseconds)
var myDelay = 100;

//call updateRecords function
$(function() {
updateRecords(record_ids.shift(), record_ids, data);
});

var selectedRecords = record_ids.length + 1
function updateRecords(id, records, data) {

$.ajax({
//CHANGE OBJECT_ID TO YOUR OWN OBJECT ID
url: 'https://api.knackhq.com/v1/objects/object_25/records/' + id,
type: 'PUT',
/***** CHANGE TO YOUR OWN APPID AND API KEY HERE *****/
headers: {
'X-Knack-Application-ID': 'YOUR APP ID',
'X-Knack-REST-API-Key': 'YOUR API KEY'
},
data: data,
success: function(response) {
if (record_ids.length > 0) {
// Every time a call is made, the array is shifted by 1.
// If the array still has a length, re-run updateRecords()
setTimeout(updateRecords(record_ids.shift(), record_ids, data), myDelay);
} else {
alert(selectedRecords + " Updated");
Knack.hideSpinner();
location.reload();
}
}
})
}
})
});

 

 

I'm in the same shoes as Zak. The checkboxes and submit button are showing up, but it will only change the value for the first record selected.

I've got this 90% working, however my update button only updates a single record in the table, and does not update all checked rows. I have followed this code presented above exactly. Did anyone else run into this issue?

Hello,

just a newbie question:

in updateRecord function definition you have 3 parameters, but inside it you call it again with just first 2. 

Shouldn't you pass data parameter in this call?

Is the scope in JavaScript works across callback functions? I mean that, if you just passed the parameter in first call it will be still available for subsequent calls?

Thanks for clarifying this for me. I have just started with Javascript few days ago ;-)

Hi Nicolas, thanks very much for this. I was wondering if one could change this code to, instead of updating records, insert records into another object for each of the checked records in the table? I am not really any good at programming, so I would really appreciate any help you I can get here...

Thanks again

Thank you really much Nicolas. Really appreciate the help! :) 

Awesome.  Was playing around with this myself and this is much better code.

:)

Thanks

Hi Pal,

Sorry there's 1 more thing you need to change:

url: 'https://api.knackhq.com/v1/objects/object_1/records/' + id,

Change object_1 to the object ID for your records