How to mark elements that can have click events? - javascript

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>

Related

Run click event on multiple buttons according to their IDs in one function using JS only and not Jquery [duplicate]

Here I am having two buttons with id frm_submit1 and frm_submit2
<button type="button" id="frm_submit1">Click Me 1!</button>
<button type="button" id="frm_submit2">Click Me 2!</button>
In jquery, I need to do same onclick event for both the buttons. For one button (frm_submit1) click, I used like below. How can I use for multiple buttons?
$(document).on('click', '#frm_submit1', function(event) {
});
I used this, but didn't worked! Any idea?
$("#frm_submit1, #frm_submit2").click(function (e) {
// do something
});
Just separate the IDs by a comma:
$(document).on('click', '#frm_submit1, #frm_submit2', function(event) {
});
jsFiddle example
It's better for this case to use class :
$(".classForButtons").click(function () {
// do something
});
Try to use the button element as the selector instead. That will run on click on all buttons. Best would be do declare a class on the buttons that you want to use it on and then use the class as the selector instead.
$("button").click(function (e) {
// do something
});

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");
});

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

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
});

Bootstrap onClick button event

This seems a silly question but just got bootstrap and it doesn't gives any examples on the website about adding a Javascript callback to a button...
Tried setting my button an id flag and then
<div class="btn-group">
<button id="rectButton" class="btn">Rectangle</button>
<button class="btn">Circle</button>
<button class="btn">Triangle</button>
<button class="btn">Line</button>
<button class="btn">Curve</button>
<button class="btn">Pic</button>
<button class="btn">Text</button>
<button class="btn">Gradient</button>
</div>
I want to add a callback to Rectangle button...
$('#rectButton').on('show', function (e) {
//ACTION
})
cant get the point of bootstrap callbacks.
All I could found on the web is oriented to Rails + Bootstrap... no bootstrap and JS only.
There is no show event in js - you need to bind your button either to the click event:
$('#id').on('click', function (e) {
//your awesome code here
})
Mind that if your button is inside a form, you may prefer to bind the whole form to the submit event.
If, like me, you had dynamically created buttons on your page, the
$("#your-bs-button's-id").on("click", function(event) {
or
$(".your-bs-button's-class").on("click", function(event) {
methods won't work because they only work on current elements (not future elements). Instead you need to reference a parent item that existed at the initial loading of the web page.
$(document).on("click", "#your-bs-button's-id", function(event) {
or more generally
$("#pre-existing-element-id").on("click", ".your-bs-button's-class", function(event) {
There are many other references to this issue on stack overflow here and here.

Need to add another onClick event

I have a checkbox, that is styled using onclick handler.
The issue I have is , I also want to fire a div simultaneously.. to display hidden message.
Kind of like: checkbox ( tick to go featured )
If ticked show featured div, else hide.
Code I have is:
<span id="checkboxWrap" class="styledCheckboxWrap"><input name="include" type="checkbox" id="checkbox" onclick="setCheckboxDisplay(this)" class="styledCheckbox" /></span>
Wanted to also fire the div like...:
onClick="toggle('feature');"
Can I chain onClick events to one click handler?
ie..
onclick="setCheckboxDisplay(this);toggle('feature');"
Or am I going round in circles.
Use event listeners. They're better anyway. :)
var check = document.getElementById('checkbox');
check.addEventListener('click', function () {
setCheckboxDisplay(this);
});
check.addEventListener('click', function () {
toggle('feature');
});
Ideally, you should try to start using unobstrusive javascript which basically means you separate the structure from function by moving your javascript inside a <script> tag or into a separate file. So your code would look like this and make it easier to read.
HTML
<span id="checkboxWrap" class="styledCheckboxWrap">
<input name="include" type="checkbox" id="checkbox" class="styledCheckbox" />
</span>
Script
<script>
$(function(){
$('.styledCheckbox').click(function(){
setCheckboxDisplay(this);
toggle('feature');
});
});
</script>
Yes, you can call multiple statements in the onclick attribute as long as they are semicolon-delimited. That gets unweildy though, so I'll usually define a new function to wrap the two into one call.
Just delegate this to a function that does all your work...
// Somewhere in the head of the file...
function doOnClickStuff(target) {
toggle('feature');
setCheckboxDisplay(target);
}
And then just have the onClick handler invoke that...
onClick="doOnClickStuff(target);"

Categories