Bootstrap onClick button event - javascript

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.

Related

Identify HTML elements when event triggers

I have my app with tons of buttons/inputs/etc. with different events. I want to clearly identify each one of them which some event triggers on.
For example, when I have a piece of my app:
<div class="someClass">
<div>
<someOtherElement>
<div></div>
<div><button ng-click="someClickEvent($event)"></button></div>
</someOtherElement>
</div>
</div>
I want to identify somehow, which button I have just clicked:
function someClickEvent(e) {
// some identification code here
}
[edit]
Maybe I wrote this wrong... I want some identification like XPath or something that will point which button were triggered (for error logging purposes).
So when I click my button and some error occurs, I want to identify the button and log some information about it (e.g. div[0].someClass>div[0]>someOtherElement[0]>div[1]>button[0]).
You can get identify the button and log it by this:
$scope.clickFunc = function(event){
$scope.clickedElement = event.target.outerHTML;
};
DEMO: http://jsfiddle.net/rjdzuxaL/1/
Use ng-click instead on onclick
<button ng-click="myFunction($event)">test</button>
Working demo
Change HTML to:
<button ng-click="myFunction($event)">test</button> //onclick works on javascript. For Angularjs, use ng-click.
JS:
$scope.someClickEvent = function(e) {
// some identification code here
var element = e.target; // this will give you the reference to the element.
}
You should avoid handling DOM in the controller. Use directives for them.

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>

JS Event bubbling up the DOM

On my meteor app I have comments and within those comments I have a button "reply" when I click on reply the form to leave an additional comment will open.
The problem is that when I click on a reply button it opens the form on all the other comments as well as the one clicked instead of only where I clicked.
this is my code
template.replyComments.events({
'click #replyToCommentButton2': function(e) {
$(".commentToShow").show();
},
//...
)};
and html
<button class="btn waves-effect waves-light" data-show="#form2" id="replyToCommentButton2">Reply
<i class="mdi-content-send right"></i>
</button>
Try using stopPropagation and narrowing down the .commentToShow class, maybe adding a data attr to the button you are clicking that will tell you the element to show:
HTML:
<a id="replyToCommentButton2" data-show="#form2">Reply</a>
JS:
template.replyComments.events({
'click #replyToCommentButton2': function(e) {
e.stopPropagation();
$(this).parent().find('.commentToShow').show();
},
)};
There are two things you'll need to do, one of them is to stop the propagation event from bubbling up the event chain and the second one is only reference the current object (referenced with this), because you're targeting all the classes instead of the current object.
template.replyComments.events({
'click #replyToCommentButton2': function(e) {
e.stopPropagation();
var targetedForm = $(this).data("show");
$(".commentToShow", targetedForm).show();
},
This should help to understand event propagation: What's the difference between event.stopPropagation and event.preventDefault?
So this is not really answer to your question, but unless you are using some third party lib that requires you to manipulate the DOM with jQuery there is a more Meteoric approach to this.
// comment.coffee
Template.comment.created = ->
# Keep the state of the comment in a ReactiveVar on the template instance
this.showReplyField = new ReactiveVar
Template.comment.events
"click [data-reply]": (e, tmpl) ->
e.stopPropagation()
# If the reply field is open then close it and vice verse
currentState = tmpl.showReplyField.get()
tmpl.showReplyField.set !currentState
Template.comment.helpers
reply: ->
# Get the state and expose it to the template. It will update reactively when the value changes and only for this template/comment.
Template.instance().showReplyField.get()
// comment.html
<template name="comment">
<p>{{text}} </p>
{{#if reply}}
{{> newComment}}
{{else}}
<button class="button" data-reply>reply</button>
{{/if}}
</template>
<template name="newComment">
<!-- Your new comment html here -->
</template>
Note that you will need to meteor add reactive-var to add the reactive var package.
This is what I'm using in my comments package for a blog. You can check out the source code here if you wish.
And if you dont like coffeescript you can translate it.
If you still prefer to use jQuery you should probably use the template optimised version that ships with Meteor. Within an event handler it's available as tmpl.$ and will only select elements within the template (so children will be included too).
This was the answer to the problem I was having (answered by someone on Meteor forums)
template.replyComments.events({
'click #replyToCommentButton2': function(e, template) {
template.$(".commentToShow").show();
},
//...
)};

Set a JQuery function on the button HTML declaration

I'm trying to use AJAX loading a set of sucessive pages in a main page, as I show you in the next picture:
I learned (thanks to this community!) to call other pages' content, by assigning the load() function to the onclick event of a button, like this:
$(document).ready(function() {
$('#btn').click(function() {
$('#result').load('./poi-data-no-heading.html');
});
});
But what if I have one button with id="btn" on every page? The functionality of any button with that id will be the same always, because (I think) the document.ready is not triggered when I use the load() method, so it's never replaced with new functionality.
E.g. initial functionality should be navigate from page 1 to page 2, and when page 2 is loaded, the functionality should be to navigate from page 2 to page 3.
As Js developer, I would do the following:
<!-- In the HTML file -->
<button id="btn" onclick="loadContent()">Load</button>
<div id="result"></div>
/* In the JS file */
function loadContent(){
/*the code to retrieve content*/
$('#result').load('http://fiddle.jshell.net/webdevem/JfcJp/show/');
}
This way I could assign the functionality to every button, no matter what's the ID or if the document.ready is triggered. But mixing Js with JQuery is not an option... So, how do you think I should manage to do something similar with JQuery?
Thanks in advance.
P/d: Here is a useful fiddle I used to try ideas: http://jsfiddle.net/gal007/vkcug7t7/1/
You could use the on() event from jQuery, which can listen for events on elements dynamically rendered (you can't do that with the click() method). So in this case you have to listen to the event on a parent element, one that doesn't change with the load method. On that button, use an HTML5 data-* attribute to define the id that you wish to load.
HTML:
<btn id="result" data-load-id="1">Load</btn>
Javascript:
$('#container').on('click', '#result', function() {
var id_to_load = $(this).data('load-id');
load('/url?' + id_to_load);
});
I've updated your fiddle : jsfiddle

Preventing event bubbling (for javascript onclick events)

I am using javascript to interact with a CMS which provides a button for users to add things to their basket.
However, I am using the javascript to try and prevent the customer from doing so unless they have made a selection from a drop-down menu elsewhere on the page.
As there are many different buttons that could potentially get them to the basket (including the example below) and all of which have different methods for doing so, rather than write many lines of code to prevent each method and then re-enable that method when a selection is made I am trying to do a kind of 'catch-all' fix where I just cover any such buttons / links with another div so as to effectively 'mask' the button below it until they make a decision.
I first tried to use absolute positioned divs to do this which works beautifully until the user does something like re-size a textbox on the page and then suddenly my absolutely positioned div is in the wrong place!!
So I'm now using JQuery's .wrap() which solves this problem nicely.. BUT.. Now I can't use z-index to position the div above the required buttons as those buttons are within the mask not below it!
I have done a lot of reading about event bubbling but I am not sure whether I've not found the right information yet, or maybe I understand it correctly or possibly that event bubbling is leading me down the wrong path all together as I can't seem to take those concepts and apply them to this scenario.
so.....
given the following HTML structure:
<div class="btnMask">
<div class="button">
<a onclick="pageSubmit();return false;" href="#" id="addToBasket">
<span>Add to Basket</span>
</a>
</div>
</div>
where the div with class="btnMask" is added by my javascript.
Plus the following JQuery:
$('.btnMask').click(function() {
// prevent default actions and alert the customer to select something;
});
How do I go about stopping the tag firing when clicking the .btnMask div?
and (in case the answer to that does not make the answer to my other question obvious...)
How would I switch that on and off ? (I have a function that checks the drop-down onchange and sets the z-index to 99 / -99 so I would want to change this to incorporate this new method.)
Thank you in advance for your help.
<< EDIT >>
Using the initial answers to this I managed to solve the problems for links that take you away from the page using a regular href.
So I have now fixed the links where the HTML is like the following:
<div class="btnMask">
<div class="button">
<a id="nextPage" href="/link/toanotherpage.asp?id=667868465726122926234">
<span>Click to go to Page 2</span>
</a>
</div>
</div>
However, like I said there are many methods being used to take people away from the page and and e.preventDefault(); and e.stopPropagation(); don't work for my original example (presumably because they use an onclick rather than a href ?).
Is there a way to do the same thing as e.preventDefault(); and e.stopPropagation(); are doing on my .btnMask div but will also deal with contained links that are being trigged by an onclick?
thanks
<< EDIT >>
Updated the question title to reflect the exact issue rather than just event bubbling on regular links.
If you want to prevent event bubbling and cancel default action then you can return false from the event handler.
$('.btnMask').click(function() {
return false;
});
Or use preventDefault and stopPropagation
$('.btnMask').click(function(e) {
e.preventDefault();
e.stopPropagation();
});
$('.btnMask').click(function(e) {
e.stopPropagation();
});
Your onclick handler is fired before your jquery click handler. You can do something like this
function pageSubmit() {
alert('pageSubmit');
}
var link = document.getElementById('addToBasket');
var linkClickHandler = link.onclick;
link.onclick = null;
$('.button').data('linkClickHandler', linkClickHandler);
$('.button').on('click', function(e){
var clickHandler = $(this).data('linkClickHandler');
var link = $(this).find('a').get(0);
clickHandler.apply(link, [e]);
});
$('.btnMask').on('click', function(e){
if (!$(this).hasClass('test')) {
e.preventDefault();
e.stopPropagation();
}
});
and the html as
<div class="button">
<a onclick="pageSubmit();return false;" href="#" id="addToBasket">
<div class="btnMask test">
<span>Add to Basket</span>
</div>
</a>
</div>
If you remove the class test from btnMask div the pageSubmit handler will not be called,
and when it is present the handler is called.

Categories