on click fires outside of hyperlink - javascript

I am creating a dynamic delete link that as such:
<a id=\"removeAtt__" + i + "\" class=\"remove_button\" style=\"color:#aaa;\"><i class=\"fa fa-times-circle\"></i> remove</a>
I am using the following code once the link is clicked:
$(document).on("click", $('[id*=removeAtt__]'), function () {
var id = event.target.id;
var n = id.lastIndexOf('__');
var result = id.substring(n + 2);
$('#othAtt__' + result).remove();
});
What I am finding is that even when I click outside of the hyperlink at times, it fires the delete. Is there a better way to do this so it fires on click of the hyperlink all the time.

You need to pass a selector, like
$(document).on("click", '.remove-button', function () {
var id = this.id;
var n = id.lastIndexOf('__');
var result = id.substring(n + 2);
$('#othAtt__' + result).remove();
});
And oldschool solution is to define a function to be executed when the button is clicked and call it in the onclick attribute of the tag.

You're selector is not correct so it's actually executing on $(document). This is my preference on writing jQuery selectors:
$('[id*=removeAtt__]').on("click", function () {
var id = $(this).attr('id);
var n = id.lastIndexOf('__');
var result = id.substring(n + 2);
$('#othAtt__' + result).remove();
});
The reason is if my selector is off I don't get a false sense that code is actually working.

Related

How to pass a HTML control to another javascript function

I want to pass HTML control to another function inside JavaScript. I am calling a modal popup which has a input control and a save button.
The function in which i am calling the modal popup has entire GridView row as a parameter. I want to pass this to another javascript function which will be called on the button click inside of modal dialog.
I tried as below but it passes a string variable.
function ShowDialogPeoplePicker(id, requestType, cntrl) {
var row = cntrl.parentNode.parentNode;
var rowIndex = row.rowIndex - 1;
var Approvers = row.cells[1].getElementsByTagName("span")[0];
if (requestType == "AddApprovers") {
$('#btnAddApprover').removeAttr('onclick');
$('#btnAddApprover').attr('onClick', 'if (!setApprovers(\'' +cntrl + '\')) return false;');
}
}
The below function will be called on a button click and will set the values inside GridView row.
function setApprovers(cntrl)
{
var usernames= $("#hdnApproversName_CTO").val();
var row = cntrl.parentNode.parentNode;
var rowIndex = row.rowIndex - 1;
row.cells[1].getElementsByTagName("span")[0].innerHTML = usernames;
$("#overlayTasks").hide();
$("#dialogTasks").hide();
return false;
}
Instead of attaching your click handler like this:
$('#btnAddApprover').attr('onClick', 'if (!setApprovers(\'' +cntrl + '\')) return false;');
Try this instead:
$('#btnAddApprover').on('click', function() {
setApprovers(cntrl);
});
If you need to remove previously added event listeners, you can do that with:
$('#btnAddApprover').off('click');
Or if you want to attach the listener to listen just one time in the first place, you can use:
$('#btnAddApprover').one('click', function() {
setApprovers(cntrl);
});
(with one instead of on). Hope this helps!
Instead of
$('#btnAddApprover').attr('onClick', 'if (!setApprovers(\'' +cntrl + '\')) return false;');
use
$('#btnAddApprover').click(function() {
return setApprovers(cntrl);
}

Is it a scope issue?

I add a close button to the card. I try this code but the close button seems not working.
$('#add-pet').on('click', e => {
// Grab info from the form
let $name = $('#pet-name').val();
let $species = $('#pet-species').val();
let $notes = $('#pet-notes').val();
let $newPet = $(
'<section class="six columns"><div class="card"><p><strong>Name:</strong> ' + $name +
'</p><p><strong>Species:</strong> ' + $species +
'</p><p><strong>Notes:</strong> ' + $notes +
'</p><span class="close">×</span></div></section>'
);
// Attach the new element to the page
$('#posted-pets').append($newPet);
});
$('.close').on('click', function() {
$(this).parent().remove();
});
However, when I move this code:
$('.close').on('click', function() {
$(this).parent().remove();
});
right after the $('#posted-pets').append($newPet);
Then it works OK.
Why it is like that?
Whenever you want to make an event for an element which may be appended via jquery, you can try:
$(document).on('click', '.close', function() {
$(this).parent().remove();
});
It works after you appending span.close tag. Even if outside the scope
$('#add-pet').on('click', /*...*/);
Update:
You can also try:
$('#add-pet').on('click', e => {
let close_tag = $('<span>').addClass('close');
// do stuff...
// set event
close_tag.on('click', function () {
$(this).parent().remove();
});
$('#posted-pets').append(close_tag);
});
When the close function is outside of the div, it's trying to attach to existing .close elements and the element you are trying to attach to doesn't exist at that point in time. You need to do it inside because you need to have the $newPet element actually created before you can attach to it.
$('.close') will search in the dom.
If you haven't appended your html, then it can't be found by jQuery

jQuery bind click not adding elements

I have a button that when I click it more than once it is adding elements from the previous click. It works fine the first time through. We are using jQuery 1.11.1.
$(function() {
$('a[name="generateReport"]').bind('click', function() {
$(this).attr('href', $(this).attr('href') + '?est=' + est.value + '&prodcd=' + prodcd.value + '&startDate=' + startDate.value + '&endDate=' + endDate.value + '&tracking=' + tracking.value);
})
})
What I am seeing is that the URL past to the server is adding the fields from the prior click. This of course causes issues when it gets to the server. Does this need to be cleared out after each click?
This is the code that calls it from our Grails app(2.4.3)
<g:link class="btn btn-primary" name="generateReport" controller="generateTTLReport" action="renderOutput">
<i class="icon-print icon-white"></i>
Generate Report
</g:link>
Thanks,
Tom
Split the current href at the "?" to remove the query string parameters. Also, let jQuery build your new query string parameter string.
$(function() {
$('a[name="generateReport"]').on('click', function() {
var $this = $(this),
path = $this.attr('href').split('?')[0],
params = {
est: est.value,
prodcd: prodcd.value,
startDate: startDate.value,
endDate: endDate.value,
tracking: tracking.value
},
href = [path, $.param(params)].join('?');
$this.attr('href', href);
});
});
The problem with your code is, every time you click on that button, bind callback is invoked. So the first time you clicked, it got the href attribute added some parameters and replaced it. Again when you clicked on that for the second time, it does the same thing. It gets the href attribute which now contains parameters from previous update and then replace the existing. If you keep the href as it is, and only update the query parameters, you can define that as a global variable and use that in your event handler
You can hard code that link as a variable within in your script like this
$(function() {
// define your variable within document.ready but outside your event handler
var reportURL = '/LSRTIS/generateTTLReport/renderOutput';
$('a[name="generateReport"]').bind('click', function() {
var urlWithParams = reportURL + '?est=' + est.value + '&prodcd=' + prodcd.value + '&startDate=' + startDate.value + '&endDate=' + endDate.value + '&tracking=' + tracking.value;
$(this).attr('href', urlWithParams );
});
});
Hope this helps :)

Repeatable Blocks

I currently have a bit of JS which will generate buttons based on the data attribute stored in the HTML, which will generate 2 buttons:
Plus Button to add a repeatable block(Will/should only display a plus button if there is only one block)
A minus button to remove the repeatable field(will/should show when there is more than one blocks)
Thing is, I have the buttons working fine, but when I added the event handlers for them to do as I ask, and click on them nothing happens, am not sure why and hopefully you can point me in the right direction.
Regards!
P.S jQuery Code
$('.glyphicon-plus-sign').on("click", function () {
prevInput = $(this).prev('input');
count = $(prevInput).attr('data-count');
countIncremented = count++;
br = '<br/><br/>';
inputElement = '<input type="' + $(prevInput).attr("type") + '" name="' + $(prevInput).attr("name") + countIncremented + '" data-count="' + countIncremented + '"/>';
$(br + inputElement + plusMinusButtons).insertAfter('.' + $(prevInput).attr("name") + ':last');
});
$('.glyphicon-minus-sign').on("click", function () {
prevInput = $(this).prev('input');
$(this).remove(prevInput).remove(this);
});
$("button").click(function () {
console.log("here");
x = $('#form').serializeArray();
$.each(x, function (i, field) {
console.log(field.name + ":" + field.value + " ");
});
I currently have a bit of JS which will generate buttons
Dynamically adding buttons means you have to approach events a little differently. You need to do the following:
$('body').on("click", '.glyphicon-minus-sign', function () {
...
}
$('body').on("click", '.glyphicon-plus-sign', function () {
...
}
Essentially, you are now listening to clicks on the body element, instead of the actual buttons (which might not actually exist yet). Any other statically created buttons aren't affected.

get clicked link-button ID where all buttons already bind to one function

the app receive a n html dive and create a page and append it to the app
I bind all link-buttons in set of pages to one function
which will do different tasks depends on the id of the page
now I have a problem when a page has more than one link-button
I need the ID of the clicked button
Html:
<a id="x">x </a>
<a id="y">y </a>
Js:
var btns = [];
$('#page-' + newpages[j].pageID + ' a').each(function () {
btns.push({
id: this.id,
value: this.value,
name: this.name
});
});
for (i in btns) {
$('#' + btns[i].id).bind('click', function () {
test(btns[i].id)
});
// bin all buttons in current page to test()
}
};
};
function test(x) {
var page = $('.ui-page-active').attr('id');
/////////
//here I'm trying to ge the ID of clicked button of that page (each ID means something)
var pos = '';
$('#' + page + ' a').click(function () {
//Get the id of this clicked item
var BID = $(this).attr("id");
alert(BID);
send(BID);
});
Why don't you just bind to the click event on each button independently? If you switch by ID anyway why go through a generic function, any shared functionality can be abstracted into a function and utilized by each click handler so you loose nothing.

Categories

Resources