Changing attribute not working as expected - javascript

I made the following example to describe my problem:
$("tr > td > #arm").on("click", function() {
$(this).parent().children("#arm").prop("disabled", true);
$(this).parent().children("#disarm").prop("disabled", false);
});
$("tr > td > #disarm").on("click", function() {
$(this).parent().children("#arm").prop("disabled", false);
$(this).parent().children("#disarm").prop("disabled", true);;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table>
<tr>
<td>
<button id="arm" disabled>Arm</button>
</td>
<td>
<button id="disarm">Disarm</button>
</td>
</tr>
</table>
<script>
</script>
I have the above table with one row that contains 2 cells and a button in each cell. One of them is disabled so I made a script where when I press the second button it should enable the first one and disable the one which was clicked.
Disabling the button that was clicked work as I expected but I don't know why it doesn't enable the other button.

You're not selecting the right element. Your code is
$(this).parent().children("#disarm")
where $(this) is the #arm element, then parent() is the td cell.
So basically you're searching for a children element (#disarm) of that cell, that's why he can't find it
Try with this instead
$("tr > td > #arm").on("click", function() {
$(this).prop("disabled", true);
$(this).closest("tr").find("#disarm").prop("disabled", false);
});
$("tr > td > #disarm").on("click", function() {
$(this).closest("tr").find("#arm").prop("disabled", false);
$(this).prop("disabled", true);
});
Here it is a WORKING DEMO of your code :)

you need to use prev and next
$("tr > td > #arm").on("click", function() {
$(this).parent().children("#arm").prop("disabled", true);
$(this).parent().next().children("#disarm").prop("disabled", false);
});
$("tr > td > #disarm").on("click", function() {
$(this).parent().prev().children("#arm").prop("disabled", false);
$(this).parent().children("#disarm").prop("disabled", true);;
});
https://jsfiddle.net/hfr33exa/1/

Try to totatlly remove disable attribute from element. As far as I know not all browsers correctly works with disable="false"

you can add a class and then use prop function as below
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<table>
<tr>
<td>
<button id="arm" disabled class="test">Arm</button>
</td>
<td>
<button id="disarm" class="test">Disarm</button>
</td>
</tr>
</table>
<script>
$('.test').click(function(){
$(".test").prop('disabled', function () {
return ! $(this).prop('disabled');
});
});
</script>
</body>
</html>
DEMO
description: I have added a class test to all the buttons and then I used the prop function. So the button on which click event occurs is disabled and rest all are enabled

Here is the solution of your problem. Use removeAttr to remove disabled to the element.
<table>
<tr>
<td>
<button id="arm" disabled>Arm</button>
</td>
<td>
<button id="disarm">Disarm</button>
</td>
</tr>
</table>
<script>
$("tr > td > #arm").on("click", function() {
$("#arm").prop("disabled", true);
$("#disarm").removeAttr("disabled");
});
$("tr > td > #disarm").on("click", function() {
$("#arm").removeAttr("disabled");
$("#disarm").prop("disabled", true);;
});
</script>
here is a jsfiddle of a working example

There is no reason to select the parent when you click on the button.
$(this).parent().children("#arm").prop("disabled", true);
should just be
$(this).prop("disabled", false);
Now when you are trying to pick the other element you do this.
You pick the parent of the button
You look for the other button inside of that element.
The problem is the button is in a sibling of the parent. But there is no need to select the parents when you have the id. Just select it by its id to start, it will be faster.
$("table tbody").on("click", "button", function() {
var btn = $(this).prop("disabled", true);
var opposite = btn.attr("id") === "disarm" ? "#arm" : "#disarm";
$(opposite).prop("disabled", false);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<td>
<button id="arm" disabled>Arm</button>
</td>
<td>
<button id="disarm">Disarm</button>
</td>
</tr>
</table>

Related

Disable click anywhere except one cell (in the selected row) when a cell enters the edit mode

How do I disable click on all grid cells except one cell in a row? I am trying to disable clicks on any cell in the grid, when a cell enters the edit mode. So I tried:
$('#QCStatus tr td').bind('click',function() {
return false;
});
//QCStatus is the id of the grid
To enable click on a cell, in the same row that is being edited, I tried:
$('#QCStatus tr.selected-row td[aria-describedby="QCStatus_ActionIcons"]').bind('click',function() {
return true;
});
But this doesn't have any effect as click is disabled by the first snippet. What is the correct way to achieve this?
You can exclude the selected row it with :not() here:
$('#QCStatus tr:not(.selected) td').on('click', function(e) {
$('pre').prepend('event :::: '+e.type+'\n');
return false;
});
.selected{background:yellow;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='QCStatus'>
<tr><td>click</td></tr>
<tr class='selected'><td>click</td></tr>
<tr><td>click</td></tr>
<tr><td>click</td></tr>
</table>
<pre></pre>
This will bind the click on all the tds which are not the children of tr.selected.
As per your comment you can add more:
How could I just exclude the td in the selected row td[aria-describedby="QCStatus_ActionIcons"]?
$('#QCStatus tr:not(.selected) td:not([aria-describedby="QCStatus_ActionIcons"])').on('click', function(e) {
$('pre').prepend('event :::: '+e.type+'\n');
return false;
});
Use event.stoppropagation() for element to be eliminated for click event. It prevents further propagation of the current event.
$('tr').on('click', function() {
console.log('clicked!');
});
$('.disabled').on('click', function(e) {
e.stopPropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table border="1">
<tr>
<td>Hello</td>
<td class="disabled">Disabled</td>
</tr>
<tr>
<td>Hello</td>
<td class="disabled">Disabled</td>
</tr>
<tr>
<td>Hello</td>
<td class="disabled">Disabled</td>
</tr>
</table>
Fiddle here
add a "disabled" attribute to those buttons where you want to disable the click.
for a div disabled attribute doesn't work.
in those cases use "pointer-events:none;" in your css of that particular divs.

How to get value when td clicked in table

I have a table with html controls such as a select, etc.. Now when I click on a tag I want to get span value in first td
And I tried this:
$('tr > td a').on('click', function(e) {
alert($(this).parent().find('td').eq(0).find('span').html());
});
table, tr, td, th {
width: 750px;
border: 1px solid black;
border-collapse: collapse;
align: centre
}
select, a {
display: block;
}
<table>
<tr>
<th>Name</th>
<th>Clicks</th>
<th>Clicks2</th>
</tr>
<tr>
<td>
<span id="span1">Hi!</span>
Save
</td>
<td style="block">
Click Me
<select>
<option>1</option>
</select>
</td>
<td>
Click Me
<select>
<option>2</option>
</select>
</td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
Fiddle link
I tried to show popup only when a is clicked but it is poping up every time td is clicked.
So I gave a tag a class Click and tried to achieve the same but couldn't.
How to show popup only when a clicked
Your a is display:block so it maintains the whole space of the td. Give your a display:inline-block. This will let the a take only the space it needs. And then your clickhandler will work.
You can also use the javascript function onclick="functionname()" inside your 'a' tag and write your popup code in that function.
This code
$('tr > td a').on("click"...
adds a click handler to the a, then the this inside is the a, so
$(this).parent()
gives the td
followed by
.find('td')
will try to find a td inside the td, which won't happen
To get the first td use closest which goes up the parents until if find the target, ie:
$(this).closest('tr').find('td:first').find('span').html()
or
$("td:first > span", $(this).closest('tr')).html()
(or .eq(0) if you don't like :first)
You could asign a class to the span in your first column, say myClass, like this:
<table>
<tr>
<th>Name </th>
<th>Clicks</th>
<th>Clicks2</th>
</tr>
<tr>
<td>
<span class="myClass" id = "span1">Hi!</span>
Save
</td>
<td style="block">
Click Me
<select>
<option>1</option>
</select>
</td>
<td>
Click Me
<select>
<option>2</option>
</select>
</td>
</tr>
</table>
,and use jQuery like this:
$('td > a').on('click', function (e) {
alert($(this).parents('tr').find(".myClass").html());
});
See here
Just change you script from this
$(function(){
$('tr > td a').on('click', function(e) {
alert($(this).parent().find('td').eq(0).find('span').html());
});
});
To this
$(function () {
$('tr > td a').on('click', function (e) {
alert($(this).parent().find('span').html());
});
});
Here is a jsFiddle : https://jsfiddle.net/CanvasCode/hdzswrn7/

How to capture if a button in a table is clicked

I have a table of buttons
<table>
<tr><input type="button" id="aaa1"></tr>
<tr><input type="button" id="aaa2"></tr>
etc
</table>
I would like capture when button is clicked, so I've written this code:
$('table').on('click', "[id^='aaa']", function(event){
$(this)....
});
I think the problem is that this code is repeated for all the buttons, but I just wanna capture the button that I click. Can anyone help me?
Try:
$("table input[type='button']").on('click', function(event) {
...
});
You code isn't working because you have no table cells inside your table rows.
I think the problem is that this code is repeated for all the buttons
This is not the case, the below example should show this.
I would continue using the deferred method you are currently using because it only adds one listener to the page instead of several for each of the buttons, however I would change it slightly to catch type=button, as shown below:
$('table').on('click', 'input[type="button"]', function(event) {
alert($(this).attr('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="button" id="aaa1" value="B1" />
</td>
</tr>
<tr>
<td>
<input type="button" id="aaa2" value="B2" />
</td>
</tr>
</table>
Try this.
$(document).ready(function(){
$(".buttons").on("click",function(){
var value = $(this).attr("value");
alert(value + " is clicked");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><input type="button" id="aaa1" value="button1" class="buttons"></tr>
<tr><input type="button" id="aaa2" value="button2" class="buttons"></tr>
etc
</table>
You can't directly add element inside tr.Use the td inside tr and add the element inside the tr
$(document).ready(function(){
$("table input[type='button']").click(function() {
alert('Button with id = "'+ this.id +'" is clicked');
console.log(this);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td><input type="button" id="aaa1"></td></tr>
<tr><td><input type="button" id="aaa2"></td></tr>
</table>

jQuery Table Row Click Event also firing when i click a link

Here is what i have so far, getting the row number is working great but i need to make it so that when i click on the link in the table, it doesnt fire the code inside the function.
<table>
<tr class="row">
<td>A</td>
<td><a class="link" href="foo.html">Foo</a></td>
</tr>
<tr class="row">
<td>B</td>
<td><a class="link" href="Bar.html">Bar</a></td>
</tr>
</table>
<script>
$(function(){
$('.row:not(.link)').click(function(){
var $row = $(this).index();
});
});
</script>
The selector .row:not(.link) will select all elements that have a class "row" and don't have the class "link", which is not what you are looking for.
You need to use event.stopPropagation within the click event of the a.link elements so that the click event is not propagated to the parents, which includes row.
Try this:
<table>
<tr class="row">
<td>A</td>
<td><a class="link" href="foo.html">Foo</a></td>
</tr>
<tr class="row">
<td>B</td>
<td><a class="link" href="Bar.html">Bar</a></td>
</tr>
</table>
<script>
$(function(){
$('.row').click(function(){
var $row = $(this).index();
});
$('.row .link').click(function(e){
e.stopPropagation();
});
});
</script>
Just a bit late, but this is first link in Google I opened in search for solution to relative topic. So, it may become useful for someone:
$(".clickableRow").click(function(e) {
if (e.target.nodeName != "A") {
window.document.location = $(this).attr("href");
}
});
Links in a row, I mean standart , will work as usual, and this example markup will have three independent link activations:
<tr class="clickablerow" href="profile.html">
<td>John Doe, the VP</td>
<td>PrintChat</td>
</tr>
Heres a quick fix in jquery, just use instanceof
$("#news-table tr").click(function(e){
if((e.srcElement instanceof HTMLAnchorElement)!=true )console.log("IIIIIIHA HA!");
});
You need to prevent event propagation in the click event of the links - here's a sample: http://jsfiddle.net/6t8u7/1/
As you can see, clicking on the link just fires one event. Clicking on the row fires the other event.
The reason you're getting the current behaviour is that the click event from the link "bubbles up" to the parent element.
With a data attribute, there's no need for a class:
$(document).on('click', '[data-href]', function(e) {
if($(e.target).hasClass('ignore'))
return;
var ignore = ['input', 'a', 'button', 'textarea', 'label'];
var clicked = e.target.nodeName.toLowerCase();
if($.inArray(clicked, ignore) > -1)
return;
window.location = $(this).data('href');
});
Usage example (tr is just an example - you can use div, etc):
<tr data-href="your_url">
<td class="ignore">Go nowhere</td>
<td>Go to your_url</td>
<td>Go to another_url</td>
<td><input type="text" value="Go nowhere"></td>
</tr>
You can also use this without explicitly selecting the row in the second function.
$(function(){
$('.row').click(function(){
var $row = $(this).index();
});
$('.link').click(function(event){
event.preventDefault();
event.stopPropagation();
});
});
Just add: if (e.target.tagName == 'A') return; to row click and Link element will use its own logic.
Here is more detailed example:
$("#table tr").click(function(e) {
// Skip if clicked on <a> element
if (e.target.tagName == 'A') return;
// Logic for tr click ...
});
Also can be usable (especially if you use href with span or other nested items in href):
$(".row").click(function(e) {
var hasHref = $(e.target).closest('td').find('a').length;
if (! hasHref) {
window.document.location = $(this).data("href");
}
});

jQuery Children selector question

I have the following code:
$("#Table1 tbody").children().each(function(e){
$(this).bind('click',
function(){
// Do something here
},
false)
});
The Table1 html table has 2 columns; one for Names and one for a <button> element.
When I click on a table row, it works fine. When I click on the button, the button code fires; however, so does the row code.
How can I filter the selector so the button doesn't trigger the parent element's click event?
This is what you want.
It's stopPropogation that will stop the parents.
<table>
<tr>
<td>The TD: <input type="button" id="anotherThing" value="dothis"></td>
</tr>
</table>
<div id="results">
Results:
</div>
<script>
$(function() {
$('#anotherThing').click(function(event) {
$('#results').append('button clicked<br>');
event.stopPropagation();
});
$('td').click(function() {
$('#results').append('td clicked<br>');
});
});
</script>
Here's a link to an example of it working as well:
http://jsbin.com/uyuwi
You can tinker with it at: http://jsbin.com/uyuwi/edit
You could also do something like this:
$('#Table1 tr').bind('click', function(ev) {
return rowClick($(this), ev);
}); //Bind the tr click
$('#Table1 input').bind('click', function(ev) {
return buttonClick($(this), ev);
}) //Bind the button clicks
function rowClick(item, ev) {
alert(item.attr('id'));
return true;
}
function buttonClick(item, ev) {
alert(item.attr('id'));
ev.stopPropagation();
return true;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="Table1">
<tbody>
<tr id="tr1">
<td>
The TD: <input type="button" id="button1" value="dothis" />
</td>
</tr>
<tr id="tr2">
<td>
The TD: <input type="button" id="Button2" value="dothis" />
</td>
</tr>
</tbody>
</table>
Is it possible to remove the button code and just run the row code, therefore kind of using event bubbling.
Another couple options:
can you add a class to the TD that has the button in it and in the selector, do '[class!="className"]'
maybe try event.preventDefault(). You can see it being used here. this way you can prevent the default action that is triggered when the button is clicked, although I'm not sure if it will completely prevent the bubbling.

Categories