How to add jquery tabledit buttons to new rows of a table - javascript

How to tell to jQuery tabledit that the rows are changed? The buttons only generated for existing rows, when I add a new row (for example using jQuery), the table buttons doesn’t appear in the new row. I saw in tabledit code, that there is possibility to switch between view and edit mode (maybe this would help me), but don’t know how to access these methods after the tabledit is created and when rows has been changed.
A little snippet from my code:
$(document).ready(function(){
$(‘#btn’).click(function(){ ... adding row, I need to update tabledit here });
$(‘#table’).Tabledit(...parameters...); }
});
tabledit

Here is the best solution I could come up with for your situation.
I created an "Add" button. NOTE the for-table attribute so I can figure out what table to add to later.
<button id='add' for-table='#example1'>Add Row</button>
Then I created a click handler for the "Add" button.
$("#add").click(function(e){
var table = $(this).attr('for-table'); //get the target table selector
var $tr = $(table + ">tbody>tr:last-child").clone(true, true); //clone the last row
var nextID = parseInt($tr.find("input.tabledit-identifier").val()) + 1; //get the ID and add one.
$tr.find("input.tabledit-identifier").val(nextID); //set the row identifier
$tr.find("span.tabledit-identifier").text(nextID); //set the row identifier
$(table + ">tbody").append($tr); //add the row to the table
$tr.find(".tabledit-edit-button").click(); //pretend to click the edit button
$tr.find("input:not([type=hidden]), select").val(""); //wipe out the inputs.
});
Essentially;
Deep Clone the last row of the table. (copies the data and attached events)
Determine and set the row identifier.
Append the new row.
Automatically click the Edit button.
Clear all inputs and selects.
In my limited testing this technique appears to work.

jQuery Tabledit should be executed every time a table is reloaded. See answer given here:
refreshing Tabledit after pagination
This means that every time you reload the table (e.g. navigating to new page, refreshing etc), you must initialize Tabledit on the page of the table where it wasn't initialized. The problem is that there is no way to know whether Tabledit has been initialized on the table already, hence if you re-initialize it, duplicate buttons (edit, delete..) will be added to the rows of the table. You also cannot destroy a non-existent Tabledit, hence calling 'destroy' always beforehand will not help.
I hence created my own function to tell me if Tabledit is initialized on a certain page of a table or not:
function hasTabledit($table) {
return $('tbody tr:first td:last > div', $table).hasClass("tabledit-toolbar");
}
and using it as follows:
if( !hasTabledit($('#table')) ) {
$('#table').Tabledit({
url: 'example.php',
columns: {
identifier: [0, 'id'],
editable: [[1, 'points'], [2, 'notes']]
},
editButton: true,
deleteButton: false
});
}
The hasTabledit(..) function checks whether the last cell of the first row of the table has a div which has the tabledit-toolbar class, since this is the div that holds the Tabledit buttons. You may improve it as you like. This is not the perfect solution but it is the best I could do.

Related

Assigning Row_Ids to dynamically added rows in Datatables

I am working on making an editable Datatable using Jeditable. I need to be able to dynamically add rows, which I have successfully done. By default, it appears that Datatables will add everything with a row_id of 0, which makes it impossible to differentiate added rows from each other.
So I am working on a function that assigns the row_id. There are no errors, but it also does not seem to work as it still returns a row_id of 0 for all added rows.
$('#addRow').on( 'click', function () {
var rowIndex = $('#example').dataTable().fnAddData([ "column1Data", "column2Data"]);
var row = $('#example').dataTable().fnGetNodes(rowIndex);
$(row).attr('id', row_id_counter);
row_id_counter ++;
Entire code:
http://jsfiddle.net/j2frzerj/
I tested your code in the fiddle provided, and it is adding new table rows with sequential id's, starting with index 0. I am not seeing any duplicate id's of 0?
http://prntscr.com/ew3tg9
http://prntscr.com/ew3tlr

jQuery DataTable : Delete row and reload

Now, I am working with jQuery DataTable. Everything is going well in intializing data tables with javascript data array.
In my table, it included remove row button. When I clicked the Remove button of each row, I delete record using following function.
function removeRow(itemList, recordIndex){
itemList.splice(recordIndex, 1);
dataTable.clear();
dataTable.rows.add(itemList);
dataTable.columns.adjust().draw(false);
}
This function performed well with no error. At that, I set false to draw() function to prevent going to first page when delete records in any other page.This one also working for me.
The problem is, when my itemList has 11 records, and I go to second page of data table and delete the 11th record.
So, my itemList will left only 10 record and My data table should show the first page of paging.
But, jQuery data table is not doing that. It still have in second page with no records.
I don't know how to fix that one. I want to show previous page after delete every records from current page.
I know `draw()`` function without false parameter will go to first page. But it go to first page in every deletion.
I only want to go to previous page, when I deleted all records from current page.
Please, help me. Thanks.
I found an hacky way to get the previous pagination when the current has been emptied.
It is specific to jQuery DataTable, since using it's class naming.
Try it in CodePen.
function removeRow(recordIndex){
// Get previous pagination number
var previousPagination= parseInt( $(document).find(".paginate_button.current").data("dt-idx") ) -1;
// Splice the data.
data.splice(recordIndex,1);
myTable.clear();
myTable.rows.add(data);
myTable.columns.adjust().draw(false); // May ajust the pagination as empty... `.draw(false)` is needed.
// Decide to redraw or not based on the presence of `.deleteBtn` elements.
var doIdraw=false;
if($(document).find(".deleteBtn").length==0){
doIdraw=true;
}
myTable.columns.adjust().draw(doIdraw); // Re-draw the whole dataTable to pagination 1
// If the page redraws and a previous pagination existed (except the first)
if(previousPagination>1 && doIdraw){
var previousPage = $(document).find("[data-dt-idx='" + previousPagination + "']").click();
}
// Just to debug... Console.log the fact that only one pagination is left. You can remove that.
if(previousPagination==0 && doIdraw){
}
}
Notice that I used:
#myTable as the table id
.deleteBtn as the delete buttons class
data as the dataTable data
I removed all console.log() and example related code in the code above (but not in CodePen).
"Delete this →" button handler is:
$("#myTable").on("click",".deleteBtn",function(){
var rowElement = $(this).closest("tr");
var rowIndex = myTable.row(rowElement).index();
removeRow(rowIndex);
});

Insert Row(child) in table using JavaScript

I have table containing 4 main rows and one (expand or collapse) button.On click of (expand or collapse) button i want to insert one more row in middle of all rows(which result in total 8 rows) by iterating the table rows.How to do this using Javascript?See the image below.Any suggestion.
This is the code i have return on click of Expand or Collapse button,
jQuery('#btnId').click(function() {
var that = this;
$("#example tbody tr").each(function(i) {
//what code need to add here
});
});
Due to the fact, that you haven't provided a code example, I only can suggest one way to achieve this.
You can determine the row above the row you'll want to insert by an id on the tr or by a css selector like :nth-of-type(4) for example.
After that, you can use this row as jquery element (example: $("tr#yourrow")) and append a row after it using append().
Example: $("tr#yourrow").append("<tr>... your row definition ...</tr>")
Based on the updated question:
jQuery('#btnId').click(function() {
var that = this;
$("#example tbody tr").each(function(i, object) {
$(object).after("<tr>... your row definition ...</tr>")
});
});
The row definition should be done by yourself. I don't know the logic behind the iteration in your case. But I think you'll get it. :)

jQuery UI checkboxes misbehaving when cloned

I'm trying to create a table of inputs that automatically adds a new row when you enter text in one of the inputs on the bottom line. For the most part, it works fine. However, I'm having some trouble with jQuery UI checkbox buttons.
The checkbox buttons are supposed to change their icon when clicked. This works fine for the original buttons, but the cloned button that appears when you add a new row doesn't work properly.
You can see it in jsfiddle here. To replicate the issue, put some text in the third input down. You'll see that a fourth row appears. If you press the fourth checkbox, you'll see the third checkbox is the one whose icon changes. The wrong button also gets ui-state-focus but doesn't actually get focus, which really baffles me, though the correct button does get ui-state-active and seems, as far as I can tell, to evaluate as having been checked properly.
To be clear, the two checkboxes do not have the same ID, and their labels are for the right checkbox - the createNewRow() function takes care of that. If you comment out the line that turns the checkboxes into jQuery UI checkboxes, you'll see everything works fine. If you console.log the value of $(this).attr('id') in the buttonSwitchCheck function, you'll see that it has the right ID there too - if you click the fourth button, it'll tell you that the id of $(this) is "test4", but it's "test3" (the third button) that gets the icon change.
I'm going mad staring at this and I'd appreciate any help people can give. Here's the code:
// Turns on and off an icon as the checkbox changes from checked to unchecked.
function buttonSwitchCheck() {
if ($(this).prop('checked') === true) {
$(this).button("option", "icons", {
primary: "ui-icon-circle-check"
});
} else {
$(this).button("option", "icons", {
primary: "ui-icon-circle-close"
});
}
}
// Add a new row at the bottom once the user starts filling out the bottom blank row.
function createNewRow() {
// Identify the row and clone it, including the bound events.
var row = $(this).closest("tr");
var table = row.closest("table");
var newRow = row.clone(true);
// Set all values (except for buttons) to blank for the new row.
newRow.find('.ssheet').not('.button').val('');
// Find elements that require an ID (mostly elements with labels like checkboxes) and increment the ID.
newRow.find('.ssheetRowId').each(function () {
var idArr = $(this).attr('id').match(/^(.*?)([0-9]*)$/);
var idNum = idArr[2] - 0 + 1;
var newId = idArr[1] + idNum;
$(this).attr('id', newId);
$(this).siblings('label.ssheetGetRowId').attr('for', newId);
});
// Add the row to the table.
newRow.appendTo(table);
// Remove the old row's ability to create a new row.
row.removeClass('ssheetNewRow');
row.find(".ssheet").unbind('change', createNewRow);
}
$(document).ready(function () {
// Activate jQuery UI checkboxes.
$(".checkButton").button().bind('change', buttonSwitchCheck).each(buttonSwitchCheck);
// When text is entered on the bottom row, add a new row.
$(".ssheetNewRow").find(".ssheet").not('.checkButton').bind('change', createNewRow);
});
EDIT: I was able to find a solution, which I'll share with the ages. Thanks to "Funky Dude" below, who inspired me to start thinking along the right track.
The trick is to destroy the jQuery UI button in the original row before the clone, then reinitializing it immediately afterwards for both the original row and the copy. You don't need to unbind and rebind the change event - it's just the jQuery UI buttons which have trouble. In the createNewRow function:
row.find('.checkButton').button('destroy');
var newRow = row.clone(true);
row.find('.checkButton').add(newRow.find('.checkButton')).button().each(buttonSwitchCheck);
Try using the newer method .on, that allows for delegation, which should help with the dynamic changes to your DOM:
$(".checkButton").button().each(buttonSwitchCheck);
$("table").on("change", ".checkButton", buttonSwitchCheck);
I'm not sure, but it might help with not having to worry about binding events to specific elements.
Also, you could use it for the textbox change event:
$("table").on("change", ".ssheetNewRow .ssheet:not(.checkButton)", createNewRow);
Here's your fiddle with my changes: http://jsfiddle.net/Cugb6/3/
It doesn't function any different, but to me, it's a little cleaner. I thought it would've fixed your problem, but obviously hasn't, due to problems with the button widget.
And funny enough, it doesn't seem they "support" cloning: http://bugs.jqueryui.com/ticket/7959
i think you are using deep clone, which also clones the event handler. in your create new row function, try unbinding the change event then rebind on the clone.

Knockoutjs complex binding combo select table

I have a table for adding a new budget details like the image below:
When I select an Income Account then another row is added to the viewmodel collection:
I want to set all field values to "0.00" when the new row is added and also I have a problem because if I delete a row then the "change" event of the combo doesnt exist so there is no way to add a new row when changing the last combo.
Any clue? Here is the fiddle working sample: http://jsfiddle.net/rLUyS/9/
Here is the code that I use to bind the change action to the last added combo:
$('select[name=cboincomeaccount_' + newRowIndex + ']').bind("change", {
combo: $(this)
}, handler);
function handler(event) {
newRowIndex++;
var combo = jQuery(this);
var row = combo.parent().parent();
appViewModel.addRow();
// Unbind
combo.unbind('change');
// Bind new combo
jQuery('select[name=cboincomeaccount_' + newRowIndex + ']').bind("change", {
combo: jQuery(this)
}, handler)
jQuery(row).find('input[name^="txtincmonth"]').removeAttr('disabled');
};
Thanks in advance!!
This might not be so much of a Knockout issue as it is a user interface issue.
I want to set all field values to "0.00" when the new row is added
Well that's easy enough. Simply initialize the the observable row to all zeros.
When I select an Income Account then another row is added to the viewmodel collection...
and also I have a problem because if I delete a row then the "change" event of the combo doesnt exist so there is no way to add a new row when changing the last combo.
This is probably a negotiable requirement.
Why not create an 'Add' button instead of insisting on this "nifty" behavior that adds a row when the user makes a section in the dropdown list?
Besides, even if we could accomplish what you're asking for (and I can envision a way that we could do this), what will you do when it's time to save the user's input to the server? Were you planning on ignore that last empty row?

Categories

Resources