Unable to remove tr in a table using jquery - javascript

so I am having a problem in removing a particular tr in table using jquery.
So this is the scenario:
I have a table in which rows where clickable. And when I clicked one of them, I will be able to update the object data associated with that row. However, after updating the object, I want to reflect the changes in the td's of that particular tr.
My solution is, to remove the old tr and replace with the new tr. However, It did not remove the old tr instead just inserted the new tr. So this is my code:
function update_table_after_updating(selected_violator){
violators_table.find('tr').each(function (i, el) {
var tr = ($(this));
var td_text = $(this).find('td:first').text();
if(td_text == selected_violator.violator_id){
console.log(tr);
//I cant remove this row
tr.remove();
return false;
}
});
update_table(selected_violator);
}
The update_table() function
function update_table(violator){
var img_str1 = '<img class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.front_temp_file_path + '\">';
var img_str2 = '<img style=\"margin-left: 10px;\" class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.rear_temp_file_path + '\">';
var img_str3 = '<img style=\"margin-left: 10px;\" class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.right_temp_file_path + '\">';
var img_str4 = '<img style=\"margin-left: 10px;\" class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.left_temp_file_path + '\">';
violators_table.dataTable().fnAddData([
violator.violator_id,
violator.get_full_name(),
'Under Construction',
img_str1 + img_str2 + img_str3 + img_str4,
]);
$('#violators_tbl tbody tr').on('click', function(){
var td = $(this).find('td:first').text();
//returns violator object
selected_violator = get_violator(td);
show_modal('view_violator');
});
}
Thank you very much! Your responses will be greatly appreciated.
PS: I am using jquery DataTables.

Well this is kinda disappointing, I have searched through Jquery Docs then I have find this:
.empty() -> This method removes not only child (and other descendant)
elements, but also any text within the set of matched elements. This
is because, according to the DOM specification, any string of text
within an element is considered a child node of that element. Consider
the following HTML:
Unlike remove(). empty() also removes child nodes of the selected element.
And, voila! The tr has been removed.

Related

Setting up event handlers for buttons in Javascript / HTML

I would like to set up event handlers for all “Add” buttons.
are you fine with a Vanilla JS snippet?
Something along these lines would do:
function registerHandlers () {
var buttons = document.querySelectorAll('.button');
[].slice.call(buttons).forEach(function (button) {
button.addEventListener('click', onClick, false);
});
}
function onClick (event) {
event.preventDefault();
var button = event.target;
var id = button.id;
var desc = document.getElementById(id + '-img').getAttribute('title');
var qty = document.getElementById(id + '-qty').value;
addToTable(desc, qty);
}
function addToTable (desc, qty) {
var row = '<tr><td align="left">' + desc + '</td><td align="right">' + qty + '</td></tr>';
var tbody = document.querySelector('#orderlist tbody');
tbody.innerHTML = tbody.innerHTML + row;
}
registerHandlers();
The code is untested :-)
But here's how it works:
registerHandlers:
Find all elements on the page which have the class "button" (via CSS Selector)
Turn the results from a NodeList into an Array using [].slice.call.
Go over the list and register an event listener for "click"s on that element.
onClick:
Stop the default behaviour of the browser.
Determine the clicked button by inspecting the target property of an event.
Get the associated ID attribute's value.
Build the selector string for the image, search the whole document for it. Read the title attribute of the found image. (This can crash if no such element was found).
Same with the Quantity.
Update the table.
addToTable:
Build a string with the desc and qty in between. You might want to put more effort by using createElement or DOMParser and get some sanity checks that way.
Find the <tbody> of the orderlist.
Append it's innerHTML with your new row.
Finally call registerHandler to make the above work.

Write text over div without using .text()

I've got again a rather simple question, that I couldn't find an answer to.
I was using sofar the Jquery function .text() to write text on mouseenter on a dynamically created div. I came to realise that this only worked on my Iceweasel, but not in Chrome for instance. Instead ot .text() everywhere people advised of using the .val(), but I can't seem to figure out exactly how to use it in my implementation, since the divs had no previous text value.
Please find below a simple code, with .text() to understnad the question.
(function(){
for (var i = 0; i < 3; i++) {
var span = document.createElement("span");
span.innerHTML = "<img width=\"" + data.size[i][0] + "\" height=\"" + data.size[i][1] + "\" id=\"" + i + "\">";
span.style.position = "absolute";
span.style.left = data.coords[i][0] + "px";
span.style.top = data.coords[i][1] + "px";
document.body.appendChild(span);
}
}());
for (var i=0; i<3; i++) {
$('#' + i).mouseenter(function() {
$(this).text("text");
});
$('#' + i).mouseleave(function() {
$(this).text("")
});
}
http://jsfiddle.net/ckpx6esj/1/
I hope someone can give me an idea, of how to apply .val() or use something else entirely to make this work for chrome also.
Best Regards and Thanks in advance!
The problem is that you put text in an image tag!
<img>Some text</img>
This is invalid HTML, see this answer.
If you want text over an image, I suggest using a div with background: url(...) instead.
Updated fiddle.
The cleverest I could think to don't screw up your for loop is appending a <p> tag containing your text and removing it on mouseleave:
for (var i=0; i<3; i++){
$('#' + i).on("mouseenter",function() {
$(this).parent().append("<p>text</p>");
});
$('#' + i).on("mouseleave",function() {
$(this).parent().find("p").remove();
});
}
Fiddle:
http://jsfiddle.net/ckpx6esj/2/
Besides, text was not working because you are listening to the image (<img>) instead of the span. Images has no .text() prototype, hence you should access its parent() (which is a <span> in that case) if you want to use the .text() prototype, but using .text() on the parent will remove the image, hence the idea of appending the text and removing it later.
According to specification, val() function is to set value attribute and it only matters for input fields on your page. text() function is to change content of your element.
The .val() method is primarily used to get the values of form elements
such as input, select and textarea.
So you should use text() function in your code.
Also according to your code you change text property of <img> element. This is not good. You should change text of your <span>. So just move your id to span element.
If you want the jQuery equivalent of Javascript's native innerHtml, go for $(this).html('text');.
Take a look at these functions:
http://api.jquery.com/html/
$(this).html('text');
http://api.jquery.com/append/
$(this).append('text'); // Note that this appends instead of replaces
http://api.jquery.com/val/
$(this).val('text');
Or if you're feeling adventurous:
http://api.jquery.com/appendto/
$('text').appendTo($(this)); // Performance penalty for creating an object out of 'text'
First I will use class instead id, it will save using the second loop,
also if you want to have also text and also image you can do it but it will be littel complicated I would recommand add some child element to the span that will contain the text, I didnt do it just for the challenge
http://jsfiddle.net/ckpx6esj/5/
simple plugin to change the text without changing the html elements
$.fn.selectorText = function(text) {
var str = '';
this.contents().each(function() {
if (this.nodeType === 3) {
if(typeof(text) === 'string'){
this.textContent = text;
return false;
}else{
str += this.textContent || this.innerText || '';
}
}
});
return str;
};
var thisData = [{
'coords' : [[100,100], [300, 300], [200, 200]],
'size' : [[30, 30], [30, 30], [30, 30]]
}];
var data = thisData[0];
(function(){
for (var i = 0; i < 3; i ++){
var span = document.createElement("span");
span.setAttribute('class','spanImage');
span.style.position = "absolute";
span.style.left = data.coords[i][0] + "px";
span.style.top = data.coords[i][1] + "px";
span.innerHTML = "\n<img width=\"" + data.size[i][0] + "\" height=\"" + data.size[i][1] + "\" id=\"" + i + "\">";
document.body.appendChild(span);
}
$('.spanImage')
.on( 'mouseenter', function() {
$(this).selectorText('text');
})
.on( 'mouseleave', function() {
$(this).selectorText('');
});
}());

TinyNav.js issue, need element ID

So I downloaded TinyNav.js which helps me with my websites menu and can't figure out how to get the element ID from the "a" tag. I have modified TinyNav.js in one spot here.
The code is right here:
https://github.com/viljamis/TinyNav.js/blob/master/tinynav.js
I need help with line 61.
window.location.href = $(this).val();
I changed this line to
window.location.onClick = (A javascript function call which expects a string)
The string in this case is what I need help on. I need to get the SELECTED items ID, and I can't seem to find a way to do that. The
$(this).val();
returns to me the href of the selected item I clicked on in my menu but again, I want just the selected element's ID. How do I get this value?
The <option> elements are created dynamically in the tinyNav script on line 40:
options += '<option value="' + $(this).attr('href') + '">';
They only have a value attribute, no IDs.
I'm assuming that your ID values are inside you <a> tags, such as:
About
You can grab the IDs and put them into your options like this:
options += '<option value="' + $(this).attr('href') + '" id="' + $(this).attr('id') + '">';
Then you can get the ID inside the change function.
Change this (lines 60-62):
$select.change(function () {
window.location.href = $(this).val();
});
To this:
$select.change(function () {
console.log($(this).find(":selected").attr('id'));
window.location.href = $(this).val();
});
The value of $(this) is the select element that is being changed. Then you can use .find(":selected") to get the selected option element, and finally .attr('id') to get the ID attribute.
Here is a jsfiddle: https://jsfiddle.net/t72wdcwc/41/
window.location.onClick is incorrect. Javscript is case-sensitive and uses onclick, with no camelCase. You can do the following:
window.location.onclick = function() {
yourFunction($(this).attr("id"));
}
function yourFunction(id) {
alert("You clicked " + id);
}

jQuery Multiple Append

I'm going to append multiple values from an input, curious on how I can dry the append code. Possibly into a function, thanks!
var $inputFirst = $('input:first').val();
var $inputSecond = $('input:second').val();
$('ul').append('<li>' + $inputFirst + '</li>');
$('ul').append('<li>' + $inputSecond+ '</li>');
This should work for you
$(':input').each(function(i){
$('ul').append('<li>'+$(':input').eq(i).val()+'</li>')
})
Assuming you have same number of input and li. You can iterate through the li and append the corresponding input value it.
inputs = $('input');
$('ul li').each(function(){
$this).append(inputs.eq($this).index()));
});
Note As a additional note you are using tag that will effect the whole page. It might include the element you do not want to be part of this. So use class or some other attributes to access both li and input elements.
inputs = $('.class-of-input');
$('.class-of-ul li').each(function(){
$this).append(inputs.eq($this).index()));
});
hey i have created example for you on jsfiddle:-
$(document).ready(function() {
$("#createLI").click(function() {
var lis = "";
$(".forLI").each(function() {
var vl = $(this).val();
lis += "<li>" + vl + "</li>"
});
$("ul").append($(lis));
});
});
working example link:http://jsfiddle.net/BtkCf/166/
we are using class to filter the input so it will select all the inputs while creating LI tags.
in above example you can have any number of input boxes.
just provide a class 'forLI' to input boxes it will append there text values to ul as li.
we can not select value like this $('input:second').val(); you can use $('input:eq(1)').val();
thanks

Is it possible to add table cells dynamically and give them a different id?

In this fiddle you see a table with a select-field where you should select a name.
Below there are 5 input-fields where one could type in some text and 3 input-fields which are set to readonly.
I wanted to ask whether there is a way to add table cells dynamically when clicking on the button. The result should like this fiddle. The id should be incremented by i+.
I tried cloning the code, but could't figure out how to do increment the id of the cloned input-field. The only input-fields I do not want to clone are the readonly input-fields.
Do you have an example code or a link you would recommend? A hint to start would be helpful as well.
I've been searching the net already, but wasn't able to find something.
Here is the code you ask (i added an id to the button to target it easy)
$('#add').click(function(){
$(this)
.closest('table')
.find('tr td:first-child:not(:has([readonly]))')
.each(function(){
var $this = $(this);
$this
.clone()
.each(function(){
var $inp = $(':input',this);
var id = $inp.attr('id');
var idwithoutnum = id.replace(/([0-9]+)$/,'');
var maxId = $(':input[id^='+idwithoutnum+']:last').attr('id');
var idnum = parseInt(/([0-9]+)$/.exec(maxId)) + 1;
var newid = id.replace(/([0-9]+)$/,idnum);
$inp.attr('id', newid);
alert(newid); // remove this line
})
.insertAfter($this
.closest('tr')
.find('td:last')
);
});
});
example at http://jsfiddle.net/fMZDd/7/
I would choose not to use tables for dom manipulation. Either way, here is how you could do it.
to add a table cell
var td = document.createElement("td")
var idVals = prevId.match(/^([a-z_]*)([0-9]+)$/)
td.innerHTML = "<input type='text' id='"+ idVals[1] + (parseInt(idVals[2]) + 1) +">";
tr.appendChild(td)
Hope this helps.

Categories