I have this JavaScript function :
function putVote(trackid, vote) {
}
and I call this function trought :
Link
I would like to use e.preventDefault(); on putVote(), but I think I'm wrong in some ways. How can I do it?
Cheers
The simplest thing to do would be to return false from the function in the handler (return false would only work in putVote if the handler had return putVote('data1', 'data2)).
But as Pointy said, a much better technique is to attach the event handler from JavaScript, most easily achieved by using a library/framework such as jQuery or Prototype.
The easiest way:
Link
If you're using jQuery.
JS:
$("#link").click(function(evt) {
evt.preventDefault();
putVote('data1', 'data2');
});
HTML:
Link
If you're using the latest version of jQuery and the HTML5 doctype.
JS:
$("#link").click(function(evt) {
evt.preventDefault();
var $self = $(this);
putVote($self.data("one"), $self.data("two"));
});
HTML:
Link
In your case, the trick with using jQuery-style binding is that you want to be able to pass through element-specific parameters to the handler ("data1", "data2"). The "modern" way to do that would be this:
<a href="#" class='data-clickable' data-click-params='["data1", "data2"]'>Link</a>
Then, in a "ready" handler (or some other appropriate place), you'd bind your handler:
$('a.data-clickable').click(function(e) {
var elementData = $(this).data('click-params');
//
// ... handle the click ...
//
e.preventDefault();
});
The "elementData" variable will end up (in this case, anyway) being an array with two values in it, "data1" and "data2". You can give JSON-notation values to "data-foo" attributes, and when you fetch the attributes with the jQuery ".data()" method it will automatically decode the JSON for you.
Related
So lets say I have a button #button. I want it to toggle visibility of some element #element. So with plain jQuery I would do
$("#button").on("click", function() {$("#element").toggle();})
Or with an explicit side-effect:
var visible = true;
$("#button").on("click", function() {visible = !visible; $("#element").show(visible);})
What would be the equivalent of this in Bacon.js. I would assume it's possible to do without any side-effects, but I can't figure it out how.
EDIT: Let me clarify: without any side-effect which aren't a part of Bacon.js-objects.
The docs give an almost literal example on how to do that with .assign and $.fn.asEventStream:
$("#button").asEventStream("click").assign($("#element"), "toggle");
Caveats: with an event stream you can't use the Property::assign method, yet onValue works the same way. Also we want to ensure that toggle isn't invoked with the event as an argument, so you'd rather use
$("#button").asEventStream("click").onValue($("#element"), "toggle", null, null);
For explicit state, we use the scan method:
$("#button").asEventStream("click") // a stream of click events
.scan(true, // iterate it, starting with true
function(visible, e) {
// ignore the event parameter
return !visible; // just toggle the boolean
}) // now we've got a property of a changing boolean value
.assign($("#element"), "show");
I'm not entirely positive about this, but it appears that Bacon.js relies on either jQuery or Zepto to function properly. From the API Documentation on GitHub:
API Creating streams
$.asEventStream(eventName) creates an EventStream from events on a
jQuery or Zepto.js object. You can pass optional arguments to add a
jQuery live selector and/or a function that processes the jQuery event
and its parameters, if given, like this:
$("#my-div").asEventStream("click", ".more-specific-selector")
$("#my-div").asEventStream("click", ".more-specific-selector", function(event, args) { return args[0] })
$("#my-div").asEventStream("click", function(event, args) { return args[0] })
For what its worth, here's a fiddle that shows how you would do this in vanilla JavaScript:
http://jsfiddle.net/cs01rm3v/
I can't seem to access the variable defaultValue down in my .blur() function. I've tried various stuff but with no luck. So far I only get an empty object. What's wrong?
jQuery(document).ready(function(){
jQuery('#nameInput, #emailInput, #webInput').focus(function(){
var defaultValue = jQuery(this).val();
jQuery(this).val("");
})
.blur(function(defaultValue){
if(jQuery(this).val() == ""){
jQuery(this).val(defaultValue);
}
});
});
Looks like the question is about the passing data into the .blur or .focus event.
per jQuery API - http://api.jquery.com/blur/
blur( [eventData ], handler(eventObject) )
So if you want to pass data - you can send a parameter to event - which will appear as data in event object.
see this fiddle for more info
http://jsfiddle.net/dekajp/CgP2X/1/
var p = {
mydata:'my data'
};
/* p could be element or whatever */
$("#tb2").blur(p,function (e){
alert('data :'+e.data.mydata);
});
Because your code is wrong :-) you define var inside function (var defaultValue) which is then immediately wiped out.
There are two solutions: define your var as a global var before you bind blur event, or store it in the data of object liket his (which I recommend):
$(document).ready(function(){
$('#nameInput, #emailInput, #webInput').focus(function(){
$(this).val("").data('defaultValue',jQuery(this).val());
}).blur(function(defaultValue){
if($(this).val() == ""){
$(this).val($(this).data('defaultValue'));
}
});
});
It seems to me that you don't understand the basics of JavaScript.
First of all variables in JS are localized to function's scope, so you can't declare variable with var in one function and access it in other function
Second, you can't pass anything to DOM-event handler, except event-object, this is defined by the DOM specification, sometimes you can use event data parameter to the blur jQuery method.
Try this:
jQuery(document).ready(function(){
var defaultValue;
jQuery("#nameInput, #emailInput, #webInput").focus(function(){
defaultValue = jQuery(this).val();
jQuery(this).val("");
})
.blur(function(){
if(jQuery(this).val() == ""){
jQuery(this).val(defaultValue);
}
});
});
First of all, you need to distinguish blur method (function) and handler (function) which is the argument to the blur. You was trying to pass the defaultValue exactly to handler, but that can't be done. Inside handler the defaultValue would be equal eventObject, so you can do smth like console.log(defaultValue.timeStamp) and you'll see smth like 123482359734536
In your approach you can't even use event.data argument to the blur cause it will be set at the time of blur's call (attaching handler). You need to declare a var outside of the both handlers, so it will be visible to both of them
You may consider to read some comprehensive book on JS.
I read "Professional JaveScript For Webdevelopers" by Nicolas Zakas. There is a new edition
I have the following code:
function showAddrBox() {
var prompt = document.getElementById('addr_prompt');
prompt.style.display = 'block';
document.generic_form.address.style.display = 'block';
document.generic_form.onsubmit = validateAddrForm;
}
function hideAddrBox() {
var prompt = document.getElementById('addr_prompt');
prompt.style.display = 'none';
document.generic_form.address.style.display = 'none';
document.generic_form.onsubmit = null;
}
The problem is that sometimes I have additional functions attached to onSubmit that I want to preserve. I want to be able to add and remove individual functions from the onSubmit event, not just set them with onsubmit =. In other words, I need a way to accomplish something like this:
document.form.onsubmit += function;
document.form.onsubmit -= function;
Any ideas?
Quirksmode has a wonderful article about advanced event registration.
Short form is: You can bind multiple events using addEventListener (attachEvent in older versions of IE).
if (someform.addEventListener) {
someform.addEventListener('submit', somefunc, false);
} else {
someform.attachEvent('onsubmit', somefunc);
}
To remove them you can use removeEventListener and detachEvent respectively.
Pretty quickly you'll get annoyed by repetitively typing addEventListener and attachEvent, and you might consider making some generic code to bind events for you. Fortunately, other programmers have had the same idea, and many libraries are available that handle event management elegantly. jQuery tends to be the library of choice, because binding an event is as simple as:
$('#formid').submit(somefunc);
the generic event binding method is:
$('#formid').on('submit', somefunc);
to unbind you can use:
$('#formid').off('submit', somefunc);
Although all of this is well documented in the jQuery API.
Use element.addEventListener("eventName", callbackFunction, false) and element.removeEventListener("eventName", callbackFunction).
Where eventName is the name of the handler without the 'on'. So onsubmit becomes submit.
For documentation of the two functions, see:
https://developer.mozilla.org/en/DOM/element.addEventListener
https://developer.mozilla.org/en/DOM/element.removeEventListener
What I would do is have one onSubmit function right on the form that orchestrates the rest of the functions, performs logic on what to do when. At the end of that function execution you can return true if you want to proceed with the submission or return false if you don't.
u can mention two or more functions for a form like below.
<form name="formaname" onsubmit="function1(),function2()">
more on onsubmit
I have a jQuery plugin that needs to register a click event handler:
$.fn.myPlugin = function (options) {
var settings = {
// snipped
};
$.extend(settings, options || {});
$("body").click(function () {
// Do Something
});
// Rest of the plugin
});
The problem is that multiple invocations register the function more than once. Since the function needs to stay attached, I can't use .one().
Is there a way if a function is already attached? Can I give it a name or so? Or do I have to set some boolean flag using closure magic?
Namespace your events.
$('body').unbind('click.myPlugin').bind('click.myPlugin', function() {
..code...
});
More on Namespaced Events.
A very easy method with good performance would be to set a data element on the body element:
if (!$.data(document.body, 'myPluginRegistered') {
$.data(document.body, 'myPluginRegistered', true);
// do your plugin code here
}
Easiest might be the boolean plus closure magic you suggested. Alternatively, you could get the list of all functions bound to "click" object, and see if the function you're attaching is there already.
This question shows how to get the list.
List all javascript events wired up on a page using jquery
Though, the namespace suggestion that came in after I first responded is probably simpler.
Note: This question uses jQuery but the question has nothing to do with jQuery!
Okay so I have this object:
var box = new BigBox();
This object has a method named Serialize():
box.AddToPage();
Here is the method AddToPage():
function AddToPage()
{
$('#some_item').html("<div id='box' onclick='this.OnClick()'></div>");
}
The problem above is the this.OnClick() (which obviously does not work). I need the onclick handler to invoke a member of the BigBox class. How can I do this?
How can an object refer to itself in an event handler?
You should attach the handler using jQuery:
function AddToPage()
{
var self = this;
$('#some_item').empty().append(
$("<div id='box'></div>")
.click(function() { self.OnClick(someParameter); })
);
}
In order to force the event handler to be called on the context of your object (and to pass parameters), you need to add an anonymous function that calls the handler correctly. Otherwise, the this keyword in the handler will refer to the DOM element.
Don't add event handlers with inline code.
function AddToPage()
{
$('#some_item').html("<div id='box'></div>");
$('#box').click(this.OnClick);
}
EDIT:
Another way (avoids the extra select):
function AddToPage()
{
var div = $('<div id="box"></div>'); // probably don't need ID anymore..
div.click(this.OnClick);
$('#some_item').append(div);
}
EDIT (in response to "how to pass parameters");
I'm not sure what params you want to pass, but..
function AddToPage()
{
var self = this, div = $('<div></div>');
div.click(function (eventObj) {
self.OnClick(eventObj, your, params, here);
});
$('#some_item').append(div);
}
In jQuery 1.4 you could use a proxy.
BigBox.prototype.AddToPage= function () {
var div= $('<div>', {id: box});
div.click(jQuery.proxy(this, 'OnClick');
div.appendTo('#some_item');
}
You can also use a manual closure:
var that= this;
div.click(function(event) { that.OnClick(event); });
Or, most simply of all, but requiring some help to implement in browsers that don't yet support it (it's an ECMAScript Fifth Edition feature):
div.click(this.OnClick.bind(this));
If you are using jQuery, then you can separate your code from your markup (the old seperation of concerns thing) like this
$(document).ready(function() {
var box = new BigBox();
$('#box').click(function() {
box.serialize();
});
});
You only need to add the click handler once for all divs with id of box. And because the click is an anonymous function, it gets the scope of the function it is placed in and therefore access to the box instance.