I have two jqgrids setup and can drag from 'master' to 'target' grids. The row I drop into the 'target' grid is not saved to the database and has a generated, unique ID (prefixed with "new_"). I have a custom pager button that deletes the selected row. For saved rows, the event deletes the item from the database and reloads the grid. This works fine. However when I want to remove a dragged row that is NOT saved to the DB the row is not removed.
Here is my button function:
onClickButton: function () {
var deleteId = tgtGrid.getRowData(tgtGrid.getGridParam('selrow'))['ID'];
if (!deleteId) {
return false;
}
// remove an added row, not saved in DB
if (deleteId.indexOf('new_') != -1) {
tgtGrid.jqGrid('delRowData', deleteId);
} else {
// remove account saved in DB
$.post( url, { id: deleteId }, function (responseData) {
if (!responseData.success) {
// error here
} else {
// success here
tgtGrid.trigger('reloadGrid');
}
});
}
}
If I set up the button to use 'delRowData' on the saved row tgtGrid.jqGrid('delRowData', deleteId); it returns true and the row is removed from the grid (not the DB, as expected).
How do I remove a dropped row?
I found the problem lies within jqgrid and how it looks for the element to remove. The tgtGrid.getRowData(pager.getGridParam('selrow'))['ID'] will return the ID or column you set as the key in the column model. However, jqgrid looks at the <tr> element's ID for removing rows and this does not match in dropped rows. For data you load from a DB, the <td> element containing the ID/key will have a matching id attribute as the enclosing <tr> element. For dropped rows the <td> element is what you would expect but the enclosing <tr> element has a generated id attribute with the value "dnd_#" where # is some generated random number. Therefore you need to get this id to remove dragged and dropped rows that have not been saved to the data source. Below is the solution I came up with
var trId = $('td[title="' + deleteId + '"]').closest('tr').attr('id');
tgtGrid.jqGrid('delRowData', trId);
Related
When selecting a row in my SAPUI5 tree table I have to make sure that
all existing selections are removed
check if selected row has children and if so, select the item and all its children
To do that I use a function that gets called on the rowSelectionChange-Event of my table:
onRowSelectionChange: function(oEvent) {
if (oEvent.getParameters().userInteraction)
var oTable = oEvent.getSource();
var oObject = oEvent.getParameters().rowContext.getObject();
var iIndex = oEvent.getParameters().rowIndex;
// Check if row was selected or deselected
if (oTable.isIndexSelected(iIndex)) {
// Deselect other items
oTable.clearSelection();
// Select row again
oTable.addSelectionInterval(iIndex, iIndex);
// Check if object has children
if (oObject.content) {
//Select child rows here
} else {
// Do stuff
}
} else {
// Do stuff
}
}
}
As you can see the first thing I do is to check if the selection change's origin was an explicit user interaction, because, of course, clearing the selection and then adding the selection for the child rows will call the function again.
My problem is now, that when clearSelection() calls my function, the userInteraction-parameter is again set to true, despite not being an explicit user interaction. Am I missing something here?
Thank you!
The table involves a dropdown box and a normal <td> with a value. When onChange of the dropdown, the specific <td> must change to another dropdown. I've used jQuery to implement the function, but while I change the dropdown for the first row, the change is happening for the entire table. I just need the change to happen for the single row where the onChange function has been called.
$('td:nth-child(11),th:nth-child(11)').hide();
$('td:nth-child(10),th:nth-child(10)').show();
is used to hide and show the 10th and 11th columns.
doc.ready function() :
$(document).ready(function() {
$('td:nth-child(11),th:nth-child(11)').show();
$('td:nth-child(10),th:nth-child(10)').hide();
// ...
onChange function used :
$(document).on('change','.mySelect', function(event) {
event.preventDefault();
$('td:nth-child(11),th:nth-child(11)').hide();
$('td:nth-child(10),th:nth-child(10)').show();
//$(this).closest("td").show();
var _this = $(this);
var id =_this.val();
var statusValue = id;
$.get('AssignedTo', { statusVal : statusValue }, function(response) {
var select = _this.closest("tr").find("select[name='assigned']");
/* var select = $('#assigned'); */
select.find('option').remove();
$.each(response, function(index, value) {
$('<option>').val(value).text(value).appendTo(select);
});
});
});
Rather than using nth-child, consider using eq() - it's cleaner and doesn't come with some of the specificity issues of nth-child.
To get all <td> elements in the "changed" row, you can get the parent<td> by doing .closest("td") and select all of its siblings using .siblings("td")
To include the original one (and not only siblings), you'd use .addBack().
Finally, now that we have all the cells in the row, select the one you want using eq().
Put all together, it looks like this:
//Select the 11th cell in the row
var $cell = $(this).closest('td').siblings('td').addBack().eq(10);
Or, you could get the parent and choose all its children (instead of siblings) using .closest("tr") and children():
//Select the 11th cell in the row
var $cell = $(this).closest("tr").children("td").eq(10);
I am trying to iterate over all cells in a column (column index 1) in a DataTable and change the background color based on cell value using the following code:
var table = $('#my_table').DataTable( {...});
console.log("next, iterate over rows in table: "+table);
table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
console.log("looping over rows");
var cell = table.cell({ row: rowIdx, column: 1 }).node();
if (cell.data() == 'mouse'){
$(cell).css('background-color', 'orange');
}
});
console.log("finished iterating over rows ");
The table is displaying the data fine.
However the console log prints:
>>next, iterate over rows, table: [object Object]
>>finished iterating over rows
ie the
table.rows().every( function (...){...}
is not entered. I copied and pasted from DataTables examples and I have no idea why it is not being executed.
The only thing I can think of is that the DataTables docs here: https://datatables.net/reference/api/rows().every() mention- Iterate over each selected row. None of the rows in the table are selected, I just want to loop through every row (and change cell color) regardles if it is selected or not.
Note I also tried:
table.rows().eq(0).each( function ( index ) {
var row = table.row( index );
var data = row.data();
console.log(data)
});
And this is not executed either (console.log doesn't print anything from inside the function).
You can iterate over the table's td elements and capture the text content of each cell.
Apply some logic to these and you can easily assign each cell's background colour.
I have used arr.map() as it's ES6 JavaScript, but .each() works too.
$('table td').map(function(i, cell) {
var cellContent = $(cell).text();
console.log(i,cellContent); // for demonstration
if (cellContent === 'pending') $(cell).css('background-color', '#ccc');
});
This can be easily changed to get the cell element's data, class, or id too.
I have a table with 3 columns.
is hidden and is containing "id" of selected row
is containing "product" name
is containing an yes/no denoting product is present or not
On Row click push the details to an array as
$("#Product_grid_wrapper table tr").click(function () {
//empty the array
selectedProduct = [];
$('#Product_grid_wrapper table tr').removeClass("row_selected");
$(this).find('td').each(function () {
selectedProduct.push($(this).text());
});
$(this).addClass("row_selected");
});
But I was asked to change the "yes/no" with an image.I did it perfectly. Now the third column is containing Image tag , with image setting at runtime using aspx
but the code
selectedProduct.push($(this).text());
will fail for 3rd column as it is containing the image.How to handle this case?
I am able to give a class="yes/no" to Image tag from Server.But how can I read this value as per above code.can I find the type of content of table col and use appropriate function
$(this).find('td').each(function () {
//if(type of content of td is image tag)
{
selectedProduct.push($(this).html());
//will extract "class " of image tag to get "yes/no" value
}
else{
selectedProduct.push($(this).text());
}
});
If you've added a class yes/no to the image, you could try this:
if($(this).find('img').length == 1) {
selectedProduct.push($(this).find('img').attr('class'));
}
Try html()instead of text()
selectedProduct.push($(this).html());
Try using attributes in your elements instead of hiding columns and missusing css-classes if possible. Maybe like this:
<tr id="123">
<td>_productName</td>
<td>
<img data-present="yes" src="..." />
</td>
</tr>
You can then use:
selectedProduct.push({id : $(this).id, present : $(this).find('img').data('present')});
I'm building a system which outputs a list of cars on a screen(in a table element). The page loads the updates automatically with an HTTP call to the server.
Every car has an ID, a status and some irrelevant things.
Now when the user loads the page, the cars without the statuses 'maintenance' and 'wrecked' are shown and every five seconds new JSON data will be loaded from the server. If there comes a car out of the maintenance this one should be added to the table. The table is sorted by the car id and here comes the problem.
I have written a bit of pseudo code to clarify my problem:
if (row_with_greater_id_exits && row_with_lower_id_exists) {
place_row_between_firstRowWithGreaterId_and_FirstRowWithLowerId();
} else if (is_row_with_greater_id) {
jQuery('table#cars tbody').append(generatedHtml);
} else if (is_row_with_lower_id) {
jQuery('table#cars tbody').prepend(generatedHtml);
}
The problem is I don't know how to find the first row with a greater id or the first row with a smaller ID. The ID's are not always succeeding because some cars are wrecked and have the status wrecked.
I hope someone here has had a similar problem and can help me on my way to the solution.
Many thanks in advance!
You need to loop over the rows, and compare the ids. When your new row has and ID less than the current row in the loop, insert the new row before the current row, and break the loop.
rows.each(function(i, el) {
if (+newrow.id < +el.id) {
$(el).before(newrow);
return false;
}
})
if (!newrow.parentNode)
rows.parent().append(newrow);
This code assumes rows is a jQuery object that has a collection of all the rows, and newrow is a DOM element representing the new row.
Also assumes that the IDs are simple numbers. Note that numeric IDs are only valid in HTML5.
Personally, I'd just use the native API for this:
var tbody = document.querySelector("tbody");
tbody.insertBefore(newrow, [].reduce.call(tbody.rows, function(bef, el) {
return bef || +newrow.id > +el.id ? bef : el;
}, null));
No need to test for the isFirstLoad. When the tbody is empty, it'll still work. But you'll need a .reduce() shim for older browsers.
I have this: id="car-1" data-id="1"
I'll assume that data attribute is on the tr elements. Obviously you can adapt the following if it is on a cell within a row.
Loop through the table checking each row's id, and insert the new row immediately before the first row that has an id greater than the new one:
// assume newId is the new ID, somehow set from your JSON
var rowInserted = false;
jQuery('#invoices-outstanding tbody tr').each(function() {
var $row = $(this);
if (+$row.attr("data-id") > newId) {
$row.before(generatedHtml);
rowInserted = true;
// break out of each loop
return false;
}
});
if (!rowInserted)
jQuery('#invoices-outstanding tbody').append(generatedHtml);