function handle jQuery event and parameter? - javascript

Take the following code,
// Update button clicked
function updateEntity(e) {
e.preventDefault();
var name = $(this).attr("name");
...
// some stuff
...
}
$(document).on("click", ".updateEntity", updateEntity);
Currently I have this for (go figure) updating an entity I've editted on button click. Now, its parameter is particularly expecting a jQuery event. However, I want to also be able to call this function (end goal: to minimize code) outside of a jQuery event. Like so,
// Do an update but then redirect to prevent adding the same estimate twice.
function createEstimate(e) {
updateEntity(e);
var link = $(this).attr("href");
window.location.href = link;
}
$(document).on("click", ".createEntity", createEstimate);
Question: How would I go about calling updateEntity or setting the function up, so that I can supply it to the click-event handler and call it like a function and still have it used correctly? Is this goal realistic or should I be structuring this differently if I want to achieve such a goal?
(Encase it is not obvious, my current problem is that on the function call updateEntity(e); $(this) becomes window instead of the clicked link.)

Use .call to set this correctly:
updateEntity.call(this, e);
Learn more about this.

Related

onclick needs to be double clicked

When using onclick in JavaScript to call the function nowClicked(), I need to click the object twice in order for the alert to show. Below is the code for my function.
function nowClicked() {
$('.object').click(function() {
$('.object').removeClass("clicked");
var myClass = $(this).attr("id");
alert(myClass);
$(this).addClass("clicked");
e.stopImmediatePropagation();
});
};
What is the problem?
Here's what happens the first time you click your button:
nowClicked is called because you've set it up on the button's onclick
nowClicked sets up a jQuery click handler for .object
The code inside the jQuery click handler only runs the next time you click on the button.
It looks like you are mixing up two ways of handling clicks -- one is using the onclick event, and the second is using jQuery. You need to pick one and stick to it instead of using both.
There is no need to put it inside another function,because click is itself handling a callback function.Remove the outer function nowClicked else remove the $('.object').click(function() {.In the second case you may to pass the context as a function argument.
$('.object').click(function() {
$('.object').removeClass("clicked");
var myClass = $(this).attr("id");
alert(myClass);
$(this).addClass("clicked");
e.stopImmediatePropagation();
});

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.

How to make an <a> tag element to trigger multiple functions with javascript/jquery

There is a link in my webpage, the link itself triggers a function that I could not modify, but I want to make the link, when clicked, also calls another JavaScript function at the same time or preferably after the first function is done. So one click to call two functions...could it be implemented? Thanks
<a title="Next Page" href="javascript:__doPostBack('Booklet1','V4504')">Next</a>
is the sample tag I want to modify, how could make it also call "myFunc" at the same time or preferably after _doPostBack is done.
P.S. the function parameter for _doPostBack such as V4504 is dynamically generated by the ASP user control. So I cannot simply treat it as a static function and bind it with another. I think I could only append some function to it? Unless I parse the whole page first and extract the function name with its current parameters...Since every time I click the link, the parameter such as V4504 changes its value....
Thanks!
You should be able to attach multiple event handlers to a single anchor tag, either with .onclick or .addEventListener('click', function)
https://developer.mozilla.org/en/DOM/element.addEventListener
You can attach a handler to an element click event using plain Javascript in such a way:
function hello()
{
alert("Hello!")
}
var element = document.getElementById("YourAElementID");
if (element.addEventListener)
{
element.addEventListener("click", hello, false);
}
else
{
element.attachEvent("onclick", hello);
}
It supprots all common browsers.
Yes, you can do this MANY ways (I use both $(this) and $('identifier') as you don't say how the functions are bound) :
$(this).click(function(){
my_function_1();
my_function2()
});
Or
$('my element').click(function(){
my_function_1();
});
$('my element').click(function(){
my_function_2();
});
Or, if the functions reside on another object:
$(this).click(function(){
my_function_1();
$('#other_element_id').trigger('click'); //there are a bunch of syntaxes for this
});
Sans JQuery, you can use:
var myObj = document.getElementById('element name');
myObj.addEventListener('click', function(){
alert('first!');
});
myObj.addEventListener('click', function(){
alert('second!');
});
Clicking will result in two sequential alert prompts

jQuery: Can't cache onclick handler?

I've got a step-by-step wizard kind of flow where after each step the information that the user entered for that step collapses down into a brief summary view, and a "Go back" link appears next to it, allowing the user to jump back to that step in the flow if they decide they want to change something.
The problem is, I don't want the "Go Back" links to be clickable while the wizard is animating. To accomplish this I am using a trick that I have used many times before; caching the onclick handler to a different property when I want it to be disabled, and then restoring it when I want it to become clickable again. This is the first time I have tried doing this with jQuery, and for some reason it is not working. My disabling code is:
jQuery.each($("a.goBackLink"), function() {
this._oldOnclick = this.onclick;
this.onclick = function() {alert("disabled!!!");};
$(this).css("color", "lightGray ! important");
});
...and my enabling code is:
jQuery.each($("a.goBackLink"), function() {
this.onclick = this._oldOnclick;
$(this).css("color", "#0000CC ! important");
});
I'm not sure why it's not working (these are good, old-fashioned onclick handlers defined using the onclick attribute on the corresponding link tags). After disabling the links I always get the "disabled!!!" message when clicking them, even after I run the code that should re-enable them. Any ideas?
One other minor issue with this code is that the css() call to change the link color also doesn't appear to be working.
I wouldn't bother swapping around your click handlers. Instead, try adding a conditional check inside of the click handler to see if some target element is currently animating.
if ($('#someElement:animated').length == 0)
{
// nothing is animating, go ahead and do stuff
}
You could probably make this a bit more concise but it should give you an idea... Havent tested it so watch your console for typeos :-)
function initBack(sel){
var s = sel||'a.goBackLink';
jQuery(s).each(function(){
var click = function(e){
// implementation for click
}
$(this).data('handler.click', click);
});
}
function enableBack(sel){
var s = sel||'a.goBackLink';
jQuery(this).each(function(){
var $this = jQuery(this);
if(typeof $this.data('handler.click') == 'function'){
$this.bind('goBack.click', $this.data('handler.click'));
$this.css("color", "lightGray ! important");
}
});
}
function disableBack(sel){
var s = sel||'a.goBackLink';
jQuery(s).each(function(){
var $this = jQuery(this);
$this.unbind('goBack.click');
$this.css("color", "#0000CC ! important");
});
}
jQuery(document).ready(function(){
initBack();
jQuery('#triggerElement').click(function(){
disableBack();
jQuery('#animatedElement').animate({/* ... */ }, function(){
enableBack();
});
});
});

preventing effects to be applied to the same object twice when adding objects with ajax

I'm having a little issue with an application I'm making. I have a page where the user edits a document via dragging modules into the page or "canvas" area.
http://thinktankdesign.ca/temp_img.jpg
When the page is loaded, javascript haves the modules collapsible (like above). However after the user drags in a new module the effect is applied again some new modules can collapse as well. here is the problem. each time a module loads the same effect gets applied to the modules that already can collapse. It ends up breaking their animations.
heres the code that gets executed on page load.
//make colapsible
$("h1.handle").click(function() {
var object = $(this);
v$(this).next().toggle("fast", colapsible_class(object));
vreturn false;
}).addClass("open");
and heres the code that gets executed in the creation of a module via ajax
function get_module(id){
var template = $('input[name=template]').val();
$.post(window.location.href, { template: template, module: id, mode: 'create' },
function(data){
$(data).insertBefore(".target_wrapper");
//enable deletion of module
$(".js_no_modules").slideUp("slow");
$(enable_module_deletion());
//show delete button
$("button[name=delete]").show();
//make colapsible
$("h1.handle").click(function() {
var object = $(this);
$(this).next().toggle("fast", colapsible_class(object));
return false;
}).addClass("open");
}
);
}
I need a solid way of preventing the toggle effect to be applied to the same module twice
Use jQuery 1.3 live events instead.
//make colapsible
$("h1.handle").live("click", function() {
var object = $(this);
v$(this).next().toggle("fast", colapsible_class(object));
vreturn false;
}).addClass("open");
and then eliminate the click declaration in the second block of code, changing it to $("h1.handle").addClass("open");
Live events bind all current and future matching elements with an event.
In your Ajax success handler try the following:
//make collapsible
$("h1.handle:not(.open)").click(function() {
var object = $(this);
$(this).next().toggle("fast", colapsible_class(object));
return false;
}).addClass("open");
The best way to solve your problem is, instead of using $("h1.handle") on the AJAX callback, go for $(data).find("h1.handle"). Something like,
var x = $(data);
x.insertBefore(...);
/* your other code */
x.find('h1.handle').click(...).addClass(...);
Like that, only the newly added items will have the event bounded. The already present ones will not be touched.
If we want to answer your question instead of just solving your problem, then we have several alternatives, such as:
store, in your objects, that the onclick event handler has been set so that you don't set it twice
always bind the onclick event, but always unbind it first
use jQuery's live events and the addClass open only on the newly created items.
IMO, the first one is the easiest. You can accomplish it by using jQuery's data(). Then you could do something like:
$("h1.handle").each(function() {
var me = $(this);
// if already has click handler, don't do anything
if (me.data('click_set') != null) { return true; }
// otherwise, store the data and bind the click event
me.data('click_set', true).click(function() {
/* the code you already have on the click handler */
}).addClass('open');
}
The second alternative involves storing the function that you pass inline to the click event binder in a variable, and then using jQuery's unbind to disable it.

Categories