How to pass parameters into onclick function parameters into dynamically created buttons? - javascript

My javascript reads text from a file and creates button dynamically base on the button creation below. The problem I am facing is it is not able to call the function on click. I've tried removing the parameters to call it and it works however I can't seem to get it to work with passing of parameters. Can someone help me with it?
JS:
function toggleVisibility(type){
alert(type);
}
Button creation:
var button='<button type="button" class="btn btn-block btn-inverse active" data-toggle="button tooltip" title="Click this to enable/disable viewing of '+this+'" onclick="toggleVisibility('+"'"+this+"'"+')">'+word+'</button>';

You shouldn't use inline handlers, first of all, and it's easier to create it with jQuery anyways:
var that = this;
var button = $("<button>");
button.addClass("btn btn-block btn-inverse active");
button.attr({
type: "button",
"data-toggle": "button tooltip",
title: "Click this to enable/disable viewing of " + that
});
button.text(word);
button.on("click", function () {
toggleVisibility(that);
});
(yes, I know you could chain all of the method calls, I just wanted to do it this way)
When you're ready to put this button somewhere, just use $container.append(button);.
Everything depends on what this is or what you want/expect it to be. If you need the parameter passed to toggleVisibility to be the specific button that was just clicked (I'm guessing to toggle its visibility), just pass this (ignore the that). As for setting the title attribute, I'm not sure what you want :)
If you have an HTML structure like:
<div id="container">
<!-- Buttons go somewhere in here -->
</div>
And you're appending the buttons to that container (or somewhere in that container), it would be more efficient to bind a single click handler to the container with event delegation:
$("#container").on("click", ".special-btn-identifier", function () {
toggleVisibility(this);
});
Of course, you'd need to add a "special-btn-identifier" class to the buttons, so that this event handler will work (and remove the individual click handlers for each button, as this will cover them). This single event handler only needs to run once, preferably as soon as the #container is ready...like in $(document).ready(function () {});.

Replace your following line:
.. onclick="toggleVisibility('+"'"+this+"'"+')">'+word+'</button>';
for this one:
.. onclick="toggleVisibility(this)">'+word+'</button>';
as you dont need to escape the this keyword, nor including a different this from the context where you were creating the button text.

Register the onClick event on the document instead of in the html when you create the button.
$(document).on('click', 'button.btn-inverse', function() { toggleVisibility(this); return false;});

Don't create inline HTML strings, don't use intrusive Javascript.
Though I don't even advise you to create them with vanilla jQuery, you may try with:
var $button = $('<button></button>', {
'text' : word
'type' : 'button',
'class' : 'btn btn-block btn-inverse active',
'data-toggle' : 'button tooltip',
...
// any other attributes
});
// append the $button anywere
$( someContainer ).append($button);
$( someContainer ).on('click', '.btn', function(event){
// you can refer to the button with $(this) here
});

Related

How to disable the click on an icon after one click?

After clicking on the icon with ids (#prevleft and #nextright) , an ajax function is called. During the time ajax function loads a new table, I want to disable the icon click.
HTML Code:
hrHTML='<tr><th colspan="5"><i class="icon icon-chevron-left icon-2x lr"
style="float:left;" title="Previous Five Weeks"
id="prevleft"></i>' +"Weekly Utilization"+'<i class="icon icon-chevron-right
icon-2x lr" style="float:right;" title="Next Five Weeks" id="nextright"
></i></th>
</tr>';
The table row is appended dynamically as shown above. Want to disable #prevleft and #nextright after one click.
The following line doesn't work:
$('#prevleft').prop("disabled", true);
I am new to coding, so all help is appreciated.
Just check with the version of the jquery your using, I hope that your using jquery 1.5 or below
For jQuery 1.6+
Use can use .prop() function:
$('#prevleft').prop("disabled", true);
$("#nextright").prop("disabled", true);
For jQuery 1.5 and below
You need to use .attr() and disable the icon
$("#prevleft").attr('disabled','disabled');
$("#nextright").attr('disabled','disabled');
and for re enable the icon (remove attribute entirely):
$("#nextright").removeAttr('disabled');
$("#prevleft").removeAttr('disabled');
Assuming you have an event handler on a icon, in any version of jQuery you can use the following property to check if your icon is enabled or not
if (this.disabled){
// your logic here
}
Bind simple a click event when clicked on prevleft and prevright id icon.
$("body").on("click","#prevleft ,#prevright",function(){
var _this = $(this);
$(this).prop("disabled","true");
// ajax call code right here
// on ajax success function right this line
success: function(resp){
_this.prop("disabled","false");
}});
})
You have attached an event listener to one or more elements that do not yet exist in document. You can use event delegation, or jQuery() function to attach event to element when created.
Pass html string to jQuery(), use .find() to get "#prevleft", #nextright selectors, attach click event using .one(), append jQuery() object to document
$(elementWherehrHTMLIsAppended)
.append(
$(hrHTML)
.find("#prevleft, #nextright")
.one("click", function() {
$(this).prop("disabled", true)
}).end()
);
You can add a class to the element and check for the class when the user clicks.
For example:
$('#prevleft').click(function(){
if($(this).hasClass('clicked')){
// do nothing or return false
}else{
// ajax call
// on a successful call you can add the class using:
$('#prevleft').addClass('clicked');
}
});
Let me know if this is what you were asking for. This also gives you the ability to add an alert or do something if the button was already clicked.
Hope this helped!
Try my code, this event only called when icon hasn't class 'clicked', in the first call we will add 'clicked' class to prevent this event from this time.
$('#prevleft:not(.clicked), #nextright:not(.clicked)').on('click', function(){
$(this).addClass('clicked');
});
Hope this can help you!

How to mark elements that can have click events?

Up until now, I've been using id to trigger click events in jquery, like:
<button class="btn" id="doAction">Action</button>
$(document).on('click', '#doAction', function ()
{
// handle the click event
}
However, what if I have multiple elements on the page that should trigger the same click event?
For example:
<button class="btn" id="doAction">Action</button>
...
<span class="action-trigger" id="doAction">Action</div>
$(document).on('click', '#doAction', function ()
{
// handle the click event
}
The problem with this is that there should only exist one unique id on any given page.
My question is, what are modern conventions to deal with this?
One solution I thought of was to add a data-action="doAction" property to each element that should trigger the click event.
Is this a good way to solve this or are there better ways?
You can use a class as well. I personally prefer to use a prefix js- and do not add CSS styles to those, e.g.: js-doaction:
$(document).on('click', '.js-doaction', function() {
// handle the click event
}
html:
<button class="btn js-doaction">Action</button>
...
<span class="action-trigger js-doaction">Action</div>

JQuery function not working on element after ID has been changed

I've got a button and I want it to perform one function every odd time that it is clicked (1st, 3rd, 5th, etc) and a second function every even time that it is clicked (2nd, 4th, 6th, etc). I thought the best way to do this would be to change the id of the button and assign two JQuery functions. However, that doesn't seem to work. As you can see in this jsfiddle, when I change the id of the button, the function from the first id still gets called.
$("#search").click(function() {
alert("search clicked!");
$("#search").html("Close Search");
$("#search").attr("id", "csearch");
});
$("#csearch").click(function() {
alert("csearch clicked!");
$("#csearch").html("Search");
$("#csearch").attr("id", "csearch");
});
Why is that the case? Is it because JQuery essentially binds the function to the button when the document loads, so even though I change the id, the function is still bound?
p.s. I already found another solution to my problem, so I'm not interested in answers in that regard. Just looking to learn a little more about JQuery and Javascript.
Yes, jQuery will run through your initialization code once, when the document loads, and attach the click handlers to elements currently in the DOM. When your code runs, only the #search element exists - the $("#csearch") selector will match no elements and the click handler won't be assigned to any elements.
A jQuery object references a DOM element by reference, not by id - when you change the id of an element, a jQuery object created previously that pointed to that element will still hold a reference to the element.
If you change dynamically data in HTML you have appeal to body, because separator ('#csearch') doesnt exist after load page. Try it:
$(document).ready(function() {
$('body').on('click','#search', function() {
alert("search clicked!");
$("#search").html("Close Search");
$("#search").attr("id", "csearch");
});
$('body').on('click','#csearch', function() {
alert("csearch clicked!");
$("#csearch").html("Search");
$("#csearch").attr("id", "search");
});
})
Although you have found another way to go, a nice way to do this is to use the modulus operator (%) which can be used to return a 0 or 1.You could assign a value to the button and on the onclick - pass that value to a function where you check the returned value (ie:var number=value%2) which will give either a 0 if the number is even or a 1 if it is odd. You can then use that to direct the action of the button click - if number ==0 then do this, if it is ==1 then do that.
You then increment the count and reset the value of the button for the next click. That way you do not have to change the id of the button- you just change its behaviour. Just a thought for a method of toggling the effect of a button click :)
Look up event delegation - there's plenty of answers on SO that explain it in detail.
As for your solution - just add a data value to the button and toggle it / read it on each click. Then there's no need to change the id, so no need to change the event handler:
$("#search").click(function() {
var oddeven = $(this).data("oddeven") || 1;
if (oddeven == 1) {
alert("search clicked!");
$(this).html("Close Search");
$(this).data("oddeven", 2)
}
else {
alert("csearch clicked!");
$(this).html("Search");
$(this).data("oddeven", 1)
}
});
Updated fiddle: https://jsfiddle.net/vxn3ozzb/1/
Alternatively, you could have two buttons and toggle between them:
<button id="search" class="btn btn-default action-button shiny-bound-input" type="button">
Search
</button>
<button id="csearch" class="btn btn-default action-button shiny-bound-input" type="button" style='display:none'>
Close Search
</button>
code
$("#search").click(function() {
alert("search clicked!");
$(this).hide();
$("#csearch").show();
});
$("#csearch").click(function() {
alert("close search clicked!");
$(this).hide();
$("#search").show();
});
Fiddle: https://jsfiddle.net/vxn3ozzb/2/
You need to use event delegation, instead of binding when dealing with elements with changing selectors.
$(document).ready(function() {
$(document).on("click","#search",function() {
alert("search clicked!");
$("#search").html("Close Search");
$("#search").attr("id", "csearch");
});
$(document).on("click","#csearch",function() {
alert("csearch clicked!");
$("#csearch").html("Search");
$("#csearch").attr("id", "csearch");
});
})
Working example : https://jsfiddle.net/DinoMyte/vxn3ozzb/4/
I believe, changing the ID of an element would not be an appropriate idea for this particular scenario. Instead, it's better to use data attributes to accomplish this. For example, Instead of changing the ID, you could change the data attribute value to track it and then you can apply your logic accordingly. This way in future, if you want to add additional behaviour to the button (odd, even and somethingElse), you don't need to write an additional event handler, just need to add one more condition to the same event handler. Going forward, if the behaviours of the button are increasing, you can separate the logic out and put it into one function by passing the behaviour value to it, that way your event handler will be much cleaner and manageable.
Please suggest if anyone has a better solution.
$(document).ready(function() {
$("#search").on("click", function() {
var action = $(this).data("action");
if(action === "odd") {
$(this).data("action", "even");
alert("odd");
}
else if (action === "even") {
$(this).data("action", "odd");
alert("even");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<button id="search" data-action="odd" class="btn btn-default action-button shiny- bound-input" type="button">
Search
</button>
</div>

Passing specific value to modal from dynamic buttons

I have a few different modals on my page that need data passed into them. I solved that problem with this other question, which has me using jQuery now and was really helpful. This is what I have now:
$(document).on("click", ".edit", function () {
$(".modal-body #value").val($('.edit').data('id'));
});
My problem is that since my page has dynamically created buttons (from a foreach based on the model), no matter which button I click, this gets the value from the first button. How do I instead get the value from the button that was clicked.
I thought about giving them all separate ids, but I don't want to make a function for each id. I read that there is a data property to this .on method, but I can't find a good example of how to use it and if it would work in my case.
If anyone has any suggestions I would be very grateful. Thank you!
$(document).on("click", ".edit", function () {
// Use $(this) to reference the clicked button
$(".modal-body #value").val($(this).data('id'));
});
You can reference the button being clicked by using the this keyword. Try the following:
$(document).on("click", ".edit", function () {
$(".modal-body #value").val($(this).data('id'));
});
Use Bootstrap's events:
$('#your-modal').on('show.bs.modal', function (e) {
var btn = $(e.relatedTarget);
var id = btn.data('id');
$("#value").val(id);
});
See the "Events" section of http://getbootstrap.com/javascript/#modals :
[The show.bs.modal event] fires immediately when the show instance method is called. If caused by a click, the clicked element is available as the relatedTarget property of the event.

jQuery won't bind click to underscore template using .on() for items added via function

I'm using underscore to create some elements and appending them to a div with jQuery.
At the bottom of the page I'm using jQuery's .on() to respond to clicks on the elements.
$('.pickup').on('click',
function(e) {
alert("hello");
}
);
Via some user interaction (in Google maps), I've got to add more elements to the div and want them to respond to clicks as well. For some reason they do not. I've pared it all down on jsfiddle:
http://jsfiddle.net/thunderrabbit/3GvPX/
When the page loads, note that clicking on the lines in output will alert('hello') via jQuery.
But click the [add] button and the new lines do not respond to clicks.
My HTML
<div id="unit_2225" class="pickup">
<span>Click me; I was here first</span>
</div>
<script type="text/template" id="unit-template">
<div class="unit-item">
<span class="pickup">
<span>click us (<%= unit_id %>) via underscore</span>
</span>
</div>
</script>
<div id="divID">
</div>
<button>add</button>
My Javascript
var addUnitToDiv = function(key,val) {
console.log(val);
var template = _.template($('#unit-template').html(),val);
$('#divID').append(template);
}
var unit_ids = [{unit_id:'hello'},
{unit_id:'click'},
{unit_id:'us'},
{unit_id:'too'},
{unit_id:112}];
$.each(unit_ids, addUnitToDiv);
var unit_pids = [{unit_id:'we'},
{unit_id:'wont'},
{unit_id:'respond'},
{unit_id:'to'},
{unit_id:'clicks'},
{unit_id:358}];
createMore = function() {
$.each(unit_pids, addUnitToDiv);
}
$('.pickup').on('click','span',function() {
alert("hello");
});
$('button').click(createMore);
I found a similarly worded question but couldn't figure out how to apply its answer here.
Instead of binding events directly to the elements, bind one event to their container element, and delegate it:
$("#divID").on("click", ".pickup", function () {
// Your event handler code
});
DEMO: http://jsfiddle.net/3GvPX/3/
In this case, the event handler is only executed for elements inside of the container #divID that have the class "pickup".
And in your scenario, the elements are being added to the element with an id of "divID". Thus, where the two selectors came from.
This is handy because, as you've found out, dynamically adding elements doesn't magically bind event handlers; event handlers bound normally with .on() are only executed (bound) on those present at the time of binding.
It could even help if you change the delegated selector to "span.pickup" (if you know the elements will always be a <span> like in your template), so that the DOM is filtered by the tag name first.
Reference:
http://api.jquery.com/on/#direct-and-delegated-events
Working demo http://jsfiddle.net/u2KjJ/
http://api.jquery.com/on/
The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. You can attach the handler on the document level.
Hope it fits the need, :)
code try the code changed below
$(document).on('click','.pickup',function() {
alert("hello");
});

Categories