jQuery addClass() not working when also using attr("href", something) - javascript

I want to create a link (in form of a Bootstrap button) that works only on the second click; on the first click it is supposed to change its appearance a bit. For this I use .addClass(newClass), .removeClass(oldClass), and then attr("href", newUrl).
(Edit) To clarify: In the beginning, the link (anchor) has "#" as its href target, and an onlick handler. That handler, when executed on the first click, will remove itself from the anchor, and instead set the desired target URL in the hrefattribute. That is supposed to cause the link to only redirect to its target URL on the second click.)
This almost works, but only if I omit the attr() setting. When it is there, the class reverts to the old class of the link as soon as the script exits. When I step through it in the debugger, the link briefly changes its appearance as expected, but changes back when the event handler exits.
This is the HTML code:
<a id="twoclick-vjffkrzw" onclick="enabletwoclickbutton('twoclick-vjffkrzw',
'http://localhost/something.php?cmd=admin&func=userdetail&pk=53&action=removerole&rolepk=1')"
class="btn btn-xs btn-warning" href="#">Remove this</a>
The script:
function enabletwoclickbutton(btn_id, url) {
var whichbtn = '#' + btn_id;
var btn = $(whichbtn);
if (btn.hasClass("btn-warning")) {
btn.off("click");
btn.attr("href", url);
btn.removeClass('btn-warning');
btn.addClass('btn-danger');
} else {
console.log("Hey, this shouldnt happen.");
}
}
I'm not very experienced in JS and jQuery, so it's quite possible that this is a stupid mistake on my side, but I just can't see it.

Use e.preventDefault() to avoid the default behavior of anchor.
Your way (however I recommend you to go with one below for readability and easy to modify later.)
html
<a id="twoclick-vjffkrzw" onclick="enabletwoclickbutton(event,'twoclick-vjffkrzw', 'http://localhost/something.php?cmd=admin&func=userdetail&pk=53&action=removerole&rolepk=1')" class="btn btn-xs btn-warning" href="#">Remove this</a>
js
function enabletwoclickbutton(e,btn_id, url) {
var whichbtn = '#' + btn_id;
var btn = $(whichbtn);
if (btn.hasClass("btn-warning")) {
e.preventDefault();
//btn.off("click");
btn.attr("href", url);
btn.removeClass('btn-warning')
.addClass('btn-danger');
} else {
console.log("Hey, this shouldnt happen.");
}
}
Recommended
Do not mix your javascript and html which is very hard to read as you can see in your code. You can write the entire code in javascript only
eg.
$('#twoclick-vjffkrzw').click(function(e){
var btn = $(this);
if (btn.hasClass("btn-warning")) {
e.preventDefault();
//btn.off("click");
btn.attr("href", 'http://localhost/something.php?cmd=admin&func=userdetail&pk=53&action=removerole&rolepk=1');
btn.removeClass('btn-warning');
btn.addClass('btn-danger');
} else {
console.log("Hey, this shouldnt happen.");
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="twoclick-vjffkrzw" class="btn btn-xs btn-warning" href="#">Remove this</a>

First add return false; after the onclick function call to stop the default redirect. Then in your function you can set the onclick to null so that it isn't called a second time.
function enabletwoclickbutton(btn_id, url) {
var whichbtn = '#' + btn_id;
var btn = $(whichbtn);
if (btn.hasClass("btn-warning")) {
btn.off("click");
btn.attr("href", url);
btn.removeClass('btn-warning');
btn.addClass('btn-danger');
btn.attr('onclick', null);
} else {
console.log("Hey, this shouldnt happen.");
}
}
.btn-warning {
color: orange;
}
.btn-danger {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="twoclick-vjffkrzw" onclick="enabletwoclickbutton('twoclick-vjffkrzw',
'http://localhost/something.php?cmd=admin&func=userdetail&pk=53&action=removerole&rolepk=1');return false;" class="btn btn-xs btn-warning" href="#">Remove this</a>

you have to check if it is the first time you click the button. to do this you can use a variable . check the code below
var clk=0;
function enabletwoclickbutton(btn_id, url) {
if(clk==0){
clk++;
}else{
clk=0;
var whichbtn = '#' + btn_id;
var btn = $(whichbtn);
if (btn.hasClass("btn-warning")) {
btn.off("click");
btn.attr("href", url);
btn.removeClass('btn-warning');
btn.addClass('btn-danger');
} else {
console.log("Hey, this shouldnt happen.");
}
}
check jsfiddle

I'd use data attribute to store url value (added my-btn class for clarity)
<a data-action="http://localhost/something.php?cmd=admin&func=userdetail&pk=53&action=removerole&rolepk=1" class="btn btn-xs btn-warning my-btn" href="#">Remove this</a>
Then set click function with jQuery instead of using onClick attribute (as it's not good practice):
$('.my-btn').click(function(event){
// prevent default click action:
event.preventDefault();
if ($(this).hasClass("btn-warning")) {
$(this).removeClass('btn-warning').addClass('btn-danger');
}else{
// go to url on a second click:
location.href = $(this).data("action");
}
});
EDIT (#A.Wolff comment)
BTW.: Checking the existence of btn-warning class is actually pointless. The click event won't be handled at the second click anyway...
$('.my-btn').click(function(event){
event.preventDefault();
$(this).removeClass('btn-warning').addClass('btn-danger')
.off('click').attr('href', $(this).data("action"));
});

With input from the various answers, I was able to find out what was happening.
Apparently the changed href will be executed only after the the event handler exits. Since in my configuration by chnce it redirected to the same page, the page was actually reloaded, that's why the button/link got its original appearance back and that tricked me into believing that the attr() setting didn't work right.
The key was to simply call event.preventDefault() before setting the new URL.
Some of you recommended (directly or indirectly) to generate the button click handler in JS directly. I don't think this would make the code better readable (the only thing that made the HTML unreadable is the long URL.) As the HTML is generated dynamically, this wouldn't be a practical solution anyway.
So, the finalized code looks like this:
function enabletwoclickbutton(e, btn_id, url) {
var whichbtn = '#' + btn_id;
var btn = $(whichbtn);
if (btn.hasClass("btn-warning")) {
e.preventDefault();
btn.off("click");
btn.attr("href", url);
btn.removeClass('btn-warning');
btn.addClass('btn-danger');
} else {
console.log("Hey, this shouldnt happen.");
}
}
Now it works as exected.

Related

how can I add a confirmation page before deleting the data using javascript?

I have an element, which redirects to another page on click like this:
<a href="javascript:void(0);" onclick="location.href='?page=del$id=12345'">
Actually, how to add some confirmation (like yes/no) before deleting that data (reloading the page)?
I have tried to write code like this:
<a href="javascript:void(0);" onclick="return confirm('Are you sure?')" location.href="?page=del$id=12345">
but this code has not worked for me.
Any ideas?
You can put your confirmation inline. Like this:
var c = confirm('Are you sure ?'); c== true ? (location.href='https://stackoverflow.com/') : ''
Try this one:
click
Add page url in href attribute code simple like this
Click
My suggestion:
var confirmed = false;
del.onclick = () => {
if (confirmed) {
location.href = del.dataset.goto;
} else {
del.innerText = 'Please, click again to confirm';
confirmed = true;
}
}
#del {
color: blue;
cursor: pointer;
}
<div id="del" data-goto="https://stackoverflow.com">Delete</div>
If you prefer, you can use <button type="button"> instead of <div>.
Anyway, I recommend you to separate JavaScript from HTML code.

How can I set click function on my current element?

I am trying to dynamically set a click function on a role=button element I add from jQuery. Here is my code:
box_resources.forEach(function(box){
var title_button = '<a class="btn btn-primary btn-xs" style="margin:5px">' + title + '</a>';
var $list_item = $(title_button);
$list_item.click(function() {
console.log("hello");
});
$("#resources-master-list").append(title_button);
});
It seems this way does not work. Does anyone have any idea? Thanks!
Instead of adding a new click handler each time you add an item to the DOM, try using event delegation. To understand how this works, check out the link for more information.:
$(document).on("click", "[role='button']", function () {
alert("i'm clicked");
});

when location path is empty use onClick function

I'm trying to use a href and onClick depending on the url.
if $location.path() is empty such like www.mysite.com/ then use onClick function
if url is like www.mysite.com/about then use href="javascript:history.back()"
<a href="javascript:history.back()" data-ng-click="vm.backToResult();">
<i class="fa fa-angle-left"></i>
Back to Search Results
</a>
vm.backToResult = function() {
if (!$location.path()) {
$window.history.back();
} else {
$window.location.href = '#!/list-of/options/';
}
}
I think this is working but I have to double click to actually trigger it but not entirely sure to be honest.

jQuery .click() doesn't fire but console.log shows output

I'm having a problem in my code where I click a DOM-element using JavaScript. The click does not work and I am almost sure it is no dumb programming mistake (always dangerous to say).
After deleting some DOM-elements I want my code to click an element and trigger its onclick event. However this doesn't work. According to my code the event triggers but the event doesn't happen and the click event returns the jQuery object.
HTML:
<div class="castor-tabs">
<div class="castor-tab" data-path="../SiteBuilding/alertbox.js" data-saved="saved" data-editor="5475c897f1900editor">
<span class="castor-filename">alertbox.js</span>
<span class="castor-close"><i class="fa fa-fw fa-times"></i></span>
</div>
<div class="castor-tab" data-path="../SiteBuilding/index.php" data-saved="saved" data-editor="5475c89903e70editor">
<span class="castor-filename">index.php</span>
<span class="castor-close"><i class="fa fa-fw fa-times"></i></span>
</div>
<div class="castor-tab active" data-path="../SiteBuilding/makesite.php" data-saved="saved" data-editor="5475c8997ac77editor">
<span class="castor-filename">makesite.php</span>
<span class="castor-close"><i class="fa fa-fw fa-times"></i></span>
</div>
</div>
JavaScript:
$(".castor-tabs").on("click", ".castor-close", function() {
var tab = $(this).parent();
if(tab.attr("data-saved") == "saved") {
// File is saved
if($(".castor-tab").length > 1) {
// 1 element is 'tab' the other is a second tab
if(tab.next().length > 0) {
// If element is to the right
window.newTab = tab.next();
} else if(tab.prev().length > 0) {
// If element is to the left
window.newTab = tab.prev();
}
} else {
window.newTab = false;
}
var editor = tab.attr("data-editor");
$("#" + editor).remove(); // textarea linked to CodeMirror
$("#" + editor + "editor").remove(); // Huge CodeMirror-element
tab.remove();
if(window.newTab) {
console.log("window.newTab.click()");
console.log(window.newTab.click()); // Simulate click()
}
} else {
// File isn't saved
}
});
The onclick event:
$(".castor-tabs").on("click", ".castor-tab", function() {
$(".castor-tab.active").removeClass("active");
$(this).addClass("active");
var editor = $(this).attr("data-editor");
$(".CodeMirror").hide();
$("#" + editor).show();
});
I saved the element in the window object for a reason. After the code runs and it skips the click-part I still have the DOM-element i want to click saved in the window object. This means I can run
console.log(window.newTab.click());
again. Surprisingly this does click the element and this does activate the click-event. It also returns the DOM-element instead of the jQuery-object.
The image shows in the first two lines the failed click. The third line is my manual input and the fourth line is the successful return value of the click().
I hope you can help me to solve this.
UPDATE
.trigger("click") unfortunately gives the same output..
UPDATE 2
To help you i made the website available on a subdomain. I know many of you hate it if you have to go to a different page but I hope you'll forgive me because in my opinion this cant be solved through JSFiddle.
The link is http://castor.marknijboer.nl.
After clicking some pages to open try closing them and you'll see what i mean.
try adding return false; at the end, when binding .castor-close click event
$(".castor-tabs").on("click", ".castor-close", function() {
var tab = $(this).parent();
if(tab.attr("data-saved") == "saved") {
// File is saved
if($(".castor-tab").length > 1) {
// 1 element is 'tab' the other is a second tab
if(tab.next().length > 0) {
// If element is to the right
window.newTab = tab.next();
} else if(tab.prev().length > 0) {
// If element is to the left
window.newTab = tab.prev();
}
} else {
window.newTab = false;
}
var editor = tab.attr("data-editor");
$("#" + editor).remove(); // textarea linked to CodeMirror
$("#" + editor + "editor").remove(); // Huge CodeMirror-element
tab.remove();
if(window.newTab) {
console.log("window.newTab.click()");
console.log(window.newTab.click()); // Simulate click()
}
} else {
// File isn't saved
}
return false;
});
Instead of simulating a click, why not just pull the click logic out of your click function and just call the javascript function using the arguments that you'll need to perform your business logic?
Your code is working but not able to trigger click event binded to castor-close because i tag is empty. Put some text in it and check
<span class="castor-close"><i class="fa fa-fw fa-times">Click me</i></span>
DEMO
Your click handler has the requirement that the click target should have the class castor-close but when you are calling click via JavaScript you are clicking the parent element instead (.castor-tab), and the click handler doesn't react.

jquery - link appended to table doesn't work

Hey guys I have some jquery code that adds a row to a table with a link to remove it and return it back to the select. Here's the code:
$('#addUser').on('click', function (e) {
var selectedUser = $('#Utilizadores option:selected').text();
$('#tabela > tbody:last').append('<tr id="'+selectedUser+'"><td>' + selectedUser + '</td><td><a id="removeUser" href="#" class="btn btn-default btn-xs"><i class="glyphicon glyphicon-remove"></i></a></td></tr>');
$("#Utilizadores option[value='" + selectedUser + "']").remove();
e.preventDefault();
});
It works! But now I want to do the reverse action of this. So I was just tying it out and not even the alert goes off. Here's the remove code:
$('#removeUser').on('click', function (e) {
alert('teste');
e.preventDefault();
});
The same id I gave to the <a> tag but still nothing gets called. I inspect the element and the id is corret and everything.
Does anyone know what the problem is?
To anyone who stumbles here and doesn't see the warning above!
You can check a Question for the same problem here
Try using the live() method
$('#removeUser').live('click', function (e) {
alert('teste');
e.preventDefault();
});

Categories

Resources