Table [Row] cannot be deleted using jquery - javascript

I am having trouble deleting the row off the table using the button.
Live: http://jsfiddle.net/Z7fG7/21/
HTML:
<select class="combobox form-control">
<option value="" selected="selected">Choose a Person</option>
<option>Bob</option>
<option>Kyle</option>
</select>
<br>
<!-- Table -->
<table class="table">
<thead>
<div class="container">
<tr>
<th>First Last Name</th>
</tr>
</div>
</thead>
</table>
JS/Jquery:
$('.combobox').change(function(e) {
var selectedVal = $(this).val();
$('.table').append('<tr><td>' + selectedVal + '</td><td><img class="delete" src="images/delete.png" width="25" height="25"/></td></tr>');
});
$('table td img.delete').click(function(){
$(this).parent().parent().remove();
});
I am using Bootstrap. Any help would be great!

Have a look into delegated events http://learn.jquery.com/events/event-delegation/
Demo: http://jsfiddle.net/robschmuecker/Z7fG7/20/
var i = 1;
$("#addbutton").click(function () {
$("table tr:first").clone().find("input").each(function () {
$(this).val('').attr({
'id': function (_, id) {
return id + i
},
'name': function (_, name) {
return name + i
},
'value': ''
});
}).end().appendTo("table");
i++;
});
$(document).on('click', 'button.removebutton', function () {
alert("aa");
$(this).closest('tr').remove();
return false;
});

The click handler for the delete image has to be added to every new row in the table.
$('.combobox').change(function(e) {
var selectedVal = $(this).val();
$('.table').append('<tr><td>' + selectedVal + '</td><td><img class="delete" src="images/delete.png" width="25" height="25"/></td></tr>');
$('table td img.delete').click(function(){
$(this).parent().parent().remove();
});
});

Or, in addition to above, when you use .clone by default it remove all events. A cleaner answer using your existing code:
EDIT: Forgot to explain! Using .clone(true) keeps the events. Your .on function is working correctly without needing to reapply it on each new row too.
var i = 1;
$("#addbutton").click(function() {
$("table tr:first").clone(true).find("input").each(function() {
$(this).val('').attr({
'id': function(_, id) {return id + i },
'name': function(_, name) { return name + i },
'value': ''
});
}).end().appendTo("table");
i++;
});
$('button.removebutton').on('click', function() {
alert("aa");
$(this).closest( 'tr').remove();
return false;
});

Related

Jquery Datatable drag and drop a column from one table to another

I am using: jquery.dataTables.js from: https://datatables.net
I am trying to drag and drop a column from one table to another.
EDIT:
so basically what I want to do is:
be able to drag and drop the names from table 2 into column called name in the table above
after drag and drop the name the same should disappear from the table 2.
case 2: if I add a new row using the button Add new Row
I need be able to drag a drop the names from table 2 into that column name too.
so basically I want to do a drag and drop just in the column not in the row.
I don't want create a new row just move the names from 1 table to another.
EDIT 2:
1- Can you drag/drop multiples values from Table #2 to Table #1?
no, the drag and drop will be possible just 1 by 1.
The drag and drop will be just possible after the user clicks in edit or add a new row.
so I will be able to replace names drom table 2 into the column names table 1
2- If no, the value dragged shall then replace the value where it is dropped?
yes
3- If yes,how should it work? Adding new rows with the other values blank?
no row need be added, we just need replace the column name.
how will works:
so after click in edit or add new row i will be able to drag a name from table 2 into column in
table 1.
few more resquests:
if select the row in table 2, this row should be change the color, showing was selected. and in the table 1 column name where this need be dropped need to change the color to show the user can be dropped, after the user drop the color should back to normal.
sample working here:
http://plnkr.co/edit/6sbmBzbXDzm4p6CjaVK0?p=preview
$(document).ready(function() {
var dataUrl = 'http://www.json-generator.com/api/json/get/ccTtqmPbkO?indent=2';
var options = [
{ key : 'option 1', value : 1 },
{ key : 'option 2', value : 2 },
{ key : 'option 3', value : 3 }
];
$(document).ready(function() {
var $table = $('#example');
var dataTable = null;
$table.on('mousedown', 'td .fa.fa-minus-square', function(e) {
dataTable.row($(this).closest("tr")).remove().draw();
});
$table.on('mousedown.edit', 'i.fa.fa-pencil-square', function(e) {
enableRowEdit($(this));
});
$table.on('mousedown', 'input', function(e) {
e.stopPropagation();
});
$table.on('mousedown.save', 'i.fa.fa-envelope-o', function(e) {
updateRow($(this), true); // Pass save button to function.
});
$table.on('mousedown', '.select-basic', function(e) {
e.stopPropagation();
});
dataTable = $table.DataTable({
ajax: dataUrl,
rowReorder: {
dataSrc: 'order',
selector: 'tr'
},
columns: [{
data: 'order'
}, {
data: 'name'
}, {
data: 'place'
}, {
data: 'delete'
}]
});
$table.css('border-bottom', 'none')
.after($('<div>').addClass('addRow')
.append($('<button>').attr('id', 'addRow').text('Add New Row')));
// Add row
$('#addRow').click(function() {
var $row = $("#new-row-template").find('tr').clone();
dataTable.row.add($row).draw();
// Toggle edit mode upon creation.
enableRowEdit($table.find('tbody tr:last-child td i.fa.fa-pencil-square'));
});
$('#btn-save').on('click', function() {
updateRows(true); // Update all edited rows
});
$('#btn-cancel').on('click', function() {
updateRows(false); // Revert all edited rows
});
function enableRowEdit($editButton) {
$editButton.removeClass().addClass("fa fa-envelope-o");
var $row = $editButton.closest("tr").off("mousedown");
$row.find("td").not(':first').not(':last').each(function(i, el) {
enableEditText($(this))
});
$row.find('td:first').each(function(i, el) {
enableEditSelect($(this))
});
}
function enableEditText($cell) {
var txt = $cell.text();
$cell.empty().append($('<input>', {
type : 'text',
value : txt
}).data('original-text', txt));
}
function enableEditSelect($cell) {
var txt = $cell.text();
$cell.empty().append($('<select>', {
class : 'select-basic'
}).append(options.map(function(option) {
return $('<option>', {
text : option.key,
value : option.value
})
})).data('original-value', txt));
}
function updateRows(commit) {
$table.find('tbody tr td i.fa.fa-envelope-o').each(function(index, button) {
updateRow($(button), commit);
});
}
function updateRow($saveButton, commit) {
$saveButton.removeClass().addClass('fa fa-pencil-square');
var $row = $saveButton.closest("tr");
$row.find('td').not(':first').not(':last').each(function(i, el) {
var $input = $(this).find('input');
$(this).text(commit ? $input.val() : $input.data('original-text'));
});
$row.find('td:first').each(function(i, el) {
var $input = $(this).find('select');
$(this).text(commit ? $input.val() : $input.data('original-value'));
});
}
});
$(document).ready(function() {
var url = 'http://www.json-generator.com/api/json/get/bXcKDeAbyq?indent=2';
table = $('#example2').DataTable({
ajax: url,
order: [[ 0, "desc" ]],
rowReorder: {
dataSrc: 'place',
selector: 'tr'
},
columns: [ {
data: 'name'
}]
});
});
});
div.addRow {
line-height: 45px;
background-color: #fff;
padding-left: 10px;
border-bottom: 1px solid;
border-top: 1px solid #e5e5e5;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<script src="//cdn.rawgit.com/DataTables/RowReorder/ce6d240e/js/dataTables.rowReorder.js"></script>
<link href="//cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="//cdn.datatables.net/rowreorder/1.2.0/css/rowReorder.dataTables.min.css" rel="stylesheet"/>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<table id="example" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>order</th>
<th>name</th>
<th>country</th>
<th>action</th>
</tr>
</thead>
</table>
<table id="new-row-template" style="display:none">
<tbody>
<tr>
<td>999</td> <!-- Use a large number or row might be inserted in the middle -->
<td>__NAME__</td>
<td>__COUNTRY__</td>
<td>
<i class="fa fa-pencil-square" aria-hidden="true"></i>
<i class="fa fa-minus-square" aria-hidden="true"></i>
</td>
</tr>
</tbody>
</table>
<br>
<div class="pull-right">
<button type="button" id="btn-cancel" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="btn-save" class="btn btn-primary" data-dismiss="modal">Save</button>
</div>
<br>
<br>
<h1>
table 2
</h1><br>
<br>
<table id="example2" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th> name</th>
</tr>
</thead>
</table>
<br>
<br>
<h1>
table 2
</h1><br>
<br>
<table id="example2" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th> name</th>
</tr>
</thead>
</table>
I've already responded to this question here: How to drag and drop a column into another
Some changes to your code (a global MouseUp event and a MouseDown event for the second table):
var rowChache = [];
function mouseUp(event) {
var ctrl = $(document.elementsFromPoint(event.clientX, event.clientY)).filter('input.border-highlight');
if (ctrl.length > 0 && rowCache.length > 0) {
var el = rowCache[0];
var data = el.row.data();
if (data.length > 0) {
ctrl.val(data[0].name);
el.row.remove().draw();
}
}
rowCache = [];
$('#example tr td:nth-child(2) input').removeClass('border-highlight');
}
table.on('mousedown', 'tbody tr', function() {
var $row = $(this);
var r = table.rows(function(i, data) {
return data.name == $row.children().first().text();
});
if (r[0].length > 0) {
$row.parents('table').find('tr').removeClass('highlight');
$row.addClass('highlight');
$('#example tr td:nth-child(2) input').addClass('border-highlight');
}
rowCache.push({
row: r
});
});
Check also the link: http://jsfiddle.net/f7debwj2/47/
Did you even try searching?
https://datatables.net/forums/discussion/30197/add-remove-table-rows-on-drag-and-drop-between-two-datatables
move rows between two datatables
https://gist.github.com/davemo/706167
drag n drop between two tables
Drag/drop between two datatables
The most important tidbit comes from the creator of datatables:
This is not a feature of DataTables, however, it should be quite possible using the API. Specifically I would suggest using row().remove() and row.add() to remove and add rows as required. The drag and drop code however would be external to DataTables.
You will either use https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API or do something in JS, and/or write the missing functionality into the API, but given the above links, you'll see how people have tackled the same problem you've described. Instead of rows, you'll do columns and I'm sure it can all be modified to do exactly what you want.
This one looks like similar to:
How to drag and drop a column into another
I have commented on the above post. See If you wanna take that approach.

jQuery - reusing code without duplicating it

I have a page that is essentially a table which has its rows duplicated when the button is pushed. Each additional row has a unique id/name.
I now have this problem. I essentially have a similar table on a different page. Main difference is that it may have additional inputs. At the moment, it looks something like this:
JavaScript
var cloned;
$(function() {
initDatepickersAndSelect();
$('#add_row').on('click', function(evt) {
addRow();
});
$('#delete_row').on('click', function(evt) {
deleteRow();
});
$('#add_row2').on('click', function(evt) {
addRow(x);
});
$('#delete_row2').on('click', function(evt) {
deleteRow(x);
});
});
function initDatepickersAndSelect() {
cloned = $("table tr#actionRow0").eq(0).clone();
$(".dateControl").datepicker({
dateFormat: "dd-mm-yy"
});
$(".responsibility").select2({
tags: true
});
$(".campaignType").select2({
tags: true
});
}
function addRow() {
var $tr = cloned.clone();
var newRowIdx = $("table#actionTable tr").length - 1;
$tr.attr('id', 'actionRow' + newRowIdx);
$tr.find("input, select").each(function(i_idx, i_elem) {
var $input = $(i_elem);
if ($input.is("input")) {
$input.val("");
}
$input.attr({
'id': function(_, id) {
return id + newRowIdx;
},
'name': function(_, name) {
return name.replace('[0]', '[' + newRowIdx + ']');
},
'value': ''
});
});
$tr.appendTo("table#actionTable");
$(".dateControl", $tr).datepicker({
dateFormat: "dd-mm-yy"
});
$(".responsibility", $tr).select2({
tags: true
});
$(".campaignType", $tr).select2({
tags: true
});
}
function deleteRow() {
var curRowIdx = $("table#actionTable tr").length;
if (curRowIdx > 2) {
$("#actionRow" + (curRowIdx - 2)).remove();
curRowIdx--;
}
}
HTML
<div class="col-md-12 noPadding">
<table class="table table-bordered table-hover additionalMargin" id="reportTable">
<thead>
<tr>
<th class="text-center">Something</th>
<th class="text-center">Something else</th>
</tr>
</thead>
<tbody>
<tr id='actionRow0'>
<td>
<select class="campType" name='reportInput[0][campType]' id="reportInput">
<option value=""></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</td>
<td>
<input type="text" name='reportInput[0][campDelivery]' id="dateInput" class="form-control" />
</td>
</tr>
</tbody>
</table>
<a id="add_row" class="btn btn-default pull-right">Add Row</a>
<a id='delete_row' class="pull-right btn btn-default">Delete Row</a>
</div>
The last thing I want to do is duplicate all of my JavaScript and rename things to match the above.
What I am wondering, is there anyway I could reuse the JavaScript?
Any advice appreciated.
Thanks
(code also available as JSFiddle)
Based on my understanding of the question, I think you could do something like this. Assuming a function called addRow as seen in your fiddle, the first step is to include that JS on all pages where you want that functionality. You then mentioned that other pages might have additional controls. For this, I'd override the function...
On the page with normal controls
function addRow() {
// Row adding code...
}
On the page with extra controls
var oldAddRow = addRow;
var addRow = function(){
$('.some_other_control').click(ctrlHandler);
$('.some .input').val('');
oldAddRow();
}
I suggest to have an invisible "template row" in your table, which you can copy to add new rows.
Something like this:
<style>
tr.template { display: none; }
</style>
<table id="table1">
<tr class="template"><td><input id="blah">/td><td><input id="foo"></td></tr>
</table>
<button id="add">Add Row</button>
<script>
function add_row($table) {
var count = $table.find('tr').length - 1;
var tr_id = ""+(count+1);
var $template = $table.find('tr.template');
var $tr = $template.clone().removeClass('template').prop('id', tr_id);
$tr.find(':input').each(function() {
var input_id = $(this).prop('id');
input_id = tr_id + '_' + input_id;
$(this).prop('id', input_id);
});
$table.find('tbody').append($tr);
}
$('#add').on('click', function() { add_row($('#table1')); });
</script>
I think it will be easier to make the code generic in this way. If you don't want the inputs in the template to be submitted, you can disable them or remove them somehow.
Demo: http://sam.nipl.net/table-demo.html
You may just clone a row and reset attibutes within with something like:
function addRow(id) {
var c = $("table#"+id+" tr").last();
$("table#"+id+" tbody").append(c.clone().attr({id: "addedrow" + Math.random()*10+1}));
}
function deleteRow(id,index) {
var curRowIdx = $("table#"+id+" tr").length;
if (curRowIdx > 2) {
if(index != void 0) {
$("table#"+id+" tr")[index].remove();
}else{
$("table#"+id+" tr").last().remove();
}
}
}
Call it with
$('#add_row').on('click', function(evt){addRow("reportTable");});
$('#delete_row').on('click', function(evt){deleteRow("reportTable",1);});
Maybe you'll prepare new rows for your table with something like
var emptyRow[id] = $("table#"+id+" tr").last();
and change
$("table#"+id+" tbody").append(c.clone().attr({id: "addedrow" + Math.random()*10+1}));
to
$("table#"+id+" tbody").append(emptyRow[id].clone().attr({id: "addedrow" + Math.random()*10+1}));

Jquery - check if checkbox was clicked

I have a jquery function, that activates only when a table row is clicked and if so, it invokes controller method. However, this row also contains checkbox, and if i click it i don't want this method to be called. I tried checking the clicked element type or other parameters like class, but it seems to only apply to the entire row. Any ideas how to make it work?
JQuery:
function AllowTableRowsToBeClicked() {
$('#pref-table tbody tr').click(function () {
var resourceName = $(this).attr('title');
var categoryName = $('#pref-table').attr('name');
var url = "/Home/GetSpecific";
$.post(url, { categoryName: categoryName, resourceName: myClass }, function (data) {
});
});
}
cshtml:
<table class="table table-striped table-hover margin-top-20 pref-table" id="pref-table" name=#Model.CurrentItemMode>
#for (int i = 0; i < Model.BiData.Count; i++)
{
<tr id=#Model.BiData[i].Name name=#i title="#Model.BiData[i].Name" class="tableRow">
#Html.Hidden("resourceList[" + i + "]", Model.BiData[i].Name)
<th>
#Html.CheckBox("checkBoxList[" + i + "]", Model.BiData[i].Selected, new { #class = "resourceCheckbox" })
</th>
<th>
#Model.BiData[i].Name
</th>
</tr>
}
</table>
If your checkbox has some id like box then you can check if the event originated from that checkbox and stop processing.
$('#pref-table').on('click',function (event) {
if(event.target.id === 'box'){
return;
}
var resourceName = $(this).attr('title');
var categoryName = $('#pref-table').attr('name');
var url = "/Home/GetSpecific";
$.post(url, { categoryName: categoryName, resourceName: myClass }, function (data) {
});
Here's a Pen to demonstrate the idea.
Try event.stopPropagation():
$('#pref-table input[type="checkbox"]').click(function(e) {
e.stopPropagation();
});
Using eventPropagation in the example below:
Html
<table width="100%">
<tr style="background:yellow">
<td>
<input type="checkbox" />
</td>
</tr>
</table>
javascript/jquery
$(document).ready(function() {
$('table tr').click(function(e) {
alert("row clicked");
});
$('input[type=checkbox]').click(function(e) {
e.stopPropagation();
alert("checkbox clicked")
});
});
Jsfiddle demo
I think your problem is you don't want to activate your event code when user clicks on checkbox, irrespective of checkbox state.
$('#pref-table tbody tr').click(function (event) {
if($(event.target).is(":checkbox")) return;
// your event code
});

On click function does not respond to a wrapped span tag

I am trying to toggle between an input field and a text field.
If I do it on just a span tag, then it works fine. However, if a span tag is wrapped as a table data, then it does not respond.
Any help will be appreciated.
UI
<div>
<table class="students">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span id ="nameSpan">elvis</span>
</td>
</tr>
</tbody>
</table>
</div>
JS
$(document).ready(function(){
var focusInName = '';
var focusOutName = '';
$(function () {
$(document).on("click", ".span", function () {
focusInName = $(this).html();
var input = $('<input />', {
'type': 'text',
'name': 'aname',
'value': $(this).html(),
'class': 'input'
});
$(this).parent().append(input);
$(this).remove();
input.focus();
alert(focusInName);
});
$(document).on('blur', ".input", function () {
focusOutName = $(this).val();
var span = $(
'<span />', {
'class': 'span',
'html': $(this).val()
});
$(this).parent().append(span);
$(this).remove();
alert(focusOutName);
});
});
});
Fiddle :HERE
Since you are using Class Selector (".class"), You need to add class span with span element
<span class='span' id ="nameSpan">elvis</span>
DEMO
Just remove the dot from the span
$(document).on("click", ".span", function () {
to
$(document).on("click", "span", function () {
Just remove . from first of span :
(document).on("click", "span", function () {

Jquery. Find all <tr> containing text from selected <option>

I try to show all lines contaning selected text from option after click on button, this is my code:
<select>
<option>text1</option>
<option>text2</option>
<option>text3</option>
<option>text4</option>
</select>
<button class="show"></button>
<button class="hide"></button>
<table>
<tr>
<td>text1</td><td>....</td>
</tr>
<tr>
<td>text2</td><td>....</td>
</tr>
<tr>
<td>text3</td><td>....</td>
</tr>
<tr>
<td>text1</td><td>....</td>
</tr>
</table>
I try to do something like this but it doesnt work:
$(function(){
b = $("tr");
$(".show").on("click", function(){
var a = $("select option:selected").text();
$(b).hide();
if ($("tr:contains('"+a+"')").length)
$(this).closest(tr).show();
});
$(".hide").on("click", function(){
$(b).show();
});
});
Can someone help me, pls :)
You need something like this. Don't pollute global space and use proper selectors. And there is no need to wrap a jQuery object again.
$(function() {
var b = $("table");
$(".show").on("click", function() {
var a = $("select option:selected").text();
b.find("tr").hide().end().find("td:contains('" + a + "')").parent().show();
});
$(".hide").on("click", function() {
b.find("tr").show();
});
});
Try this : You can use each to check each tr for selected option text and make it visible. No need to use closest('tr') as $(this) itself is a TR.
$(function(){
b = $("tr");
$(".show").on("click", function(){
var a = $("select option:selected").text();
b.hide();
//if ($("tr:contains('"+a+"')").length)
// $(this).closest(tr).show();
b.each(function(){
if($(this).text().indexOf(a)!=-1)
{
$(this).show();
}
});
});
$(".hide").on("click", function(){
b.show();
});
});
You can't use contains cause match any element that simple contains test(Select all elements that contain the specified text). Bu you can use each and match any td with same text and show parent(tr) like:
b = $("tr");
$(".show").on("click", function() {
var a = $("select option:selected").text();
$(b).hide();
$("td").each(function() {
if ($(this).text() == a) {
$(this).parents("tr").show();
}
});
});
$(".hide").on("click", function() {
$(b).show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option>text1</option>
<option>text2</option>
<option>text3</option>
<option>text4</option>
</select>
<button class="show">show</button>
<button class="hide">hide</button>
<table>
<tr>
<td>text1</td>
<td>....</td>
</tr>
<tr>
<td>text2</td>
<td>....</td>
</tr>
<tr>
<td>text3</td>
<td>....</td>
</tr>
<tr>
<td>text1</td>
<td>....</td>
</tr>
</table>
Make your buttons run functions directly here.
function show() {
var needle = $("select option:selected").text();
$('#myTable td').each(function() {
if ($(this).text() === needle) $(this).show();
});
}
function hide() {
var needle = $("select option:selected").text();
$('#myTable td').each(function() {
if ($(this).text() === needle) $(this).hide();
});
}
Take a look at this (jsFiddle).

Categories