Best jQuery plugin implementation for binding JavaScript's oninput event - javascript

I know jQuery doesn't support the oninput event, so have myself started to write a plugin to do the job. Although don't understanding very well all the stuff related to events in jQuery or JavaScript I ended up with usable code that currently satisfies my requirements.
Unfortunately I think my current implementation can crash, specially when using it in conjunction with other libraries because am setting directly the oninput member of the DOM elements.
Do you know a better and portable way to solve this problem, maybe using methods such as jQuery's "on" or JavaScript "addEventListener"?
Here is a working example of the code i'm currently using:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript">
////////////////////////////////////////////////////////////////////////////
// jQuery plugin to bind an event handler to the "oninput" JavaScript event.
(function ($) {
// Add an "input" method to all jQuery objects
$.fn.input = function (handler) {
// iterate over all DOM elements in the jQuery object
this.each( function () {
// set a new method to run when "oninput" is fired
this.oninput = function (prevHandler) {
return function (ev) {
// call previous handler if exists
if( typeof prevHandler === 'function' ) {
prevHandler.call (this, ev);
}
// call new handler
handler.call (this, ev);
};
}(this.oninput); // immediate evaluation, pass current handler as argument
});
};
} (jQuery));
////////////////////////////////////////////////////////////////////////////
</script>
<script type="text/javascript">
// Test the plugin
$(document).ready (function () {
$('#one').input (function () {
alert ('Input on one: ' + $(this).val());
});
$('#three,#four').input (function () {
alert ('Input on three or four: ' + $(this).val());
});
$('#one,#two,#three').input (function () {
alert ('Input on one, two, or three: ' + $(this).val());
});
$('#one,#two,#three,#four').input (function () {
alert ('Input on any: ' + $(this).val());
});
});
</script>
</head>
<body>
<input id='one'/><br/>
<input id='two'/><br/>
<input id='three'/><br/>
<input id='four'/><br/>
</body>
</html>
Thanks in advance!!

jQuery's 'on' can handle any event so you could simply do something like this:
(function() {
var outputElement = document.getElementById('mirror-input');
$('#input-stuff').on('input', function (event) {
outputElement.innerText = event.target.value;
});
}())
http://jsfiddle.net/YCAtZ/

Related

jQuery mouseup() issue

I'm sure this is something simple that I am missing but I'm at a loss.
I have this block of jQuery:
jQuery("span.frm_inline_total").digits();
jQuery(".frm_input_group").on("blur", "input", function () {
jQuery("span.frm_inline_total").digits();
});
jQuery(".frm_range_container input").mouseup(function () {
jQuery("span.frm_inline_total").digits();
console.log("mouse up");
});
jQuery(".frm_range_container input").mousedown(function () {
jQuery("span.frm_inline_total").digits();
console.log("mouse down");
});
That calls a function to place commas in some field numbers. I don't think it's relevant, but here is the function:
jQuery.fn.digits = function () {
return this.each(function () {
jQuery(this).text($(this).text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"));
})
}
My issue is this. Everything works except when I try to call digits() using mouseup(). It logs the mouseup() event with 'console.log', and the mousedown() event correctly works, but no mouseup(). ...alert("mouse up") works, just not 'digits'.
For what it's worth, I'm placing this event on a built-in slider in a drag-and-drop website I am editing. My "development" is limited to client side code. There is already an event on it to retrieve the new values that I thought might be interfering, but then I don't understand why it would fire logs or alerts.
Assuming your HTML structure is something like this:
<div class="frm_range_container">
<div class="frm_input_group">
<span class="frm_inline_total">Value to replace</span>
<input value="Click me"></input>
</div>
</div>
and the rest of your code works, changing the code like below should produce desired output.
// added logs to check in console, digits function is the same
$.fn.digits = function () {
console.log('digits'); // test to see if reaches digits() function
return this.each(function () {
// this should be the correct element.
$(this).text(
$(this).text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
);
})
}
$(".frm_range_container input").on('mouseup mousedown', function (e) {
console.log(e.type);
$("span.frm_inline_total").digits();
});
If you want to only target span.frm_inline_total contained in each frm_range_container, you can use $("span.frm_inline_total", this).digits(); for that

how to pass parameter in jquery using .on?

Good Day, this maybe a silly question :) how can I pass a parameter to an external javascript function using .on ?
view:
<script>
var attachedPo = 0;
$this.ready(function(){
$('.chckboxPo').on('ifChecked', addPoToBill(attachedPo));
$('.chckboxPo').on('ifUnchecked', removePoToBill(attachedPo ));
});
</script>
external script:
function addPoToBill(attachedPo){
attachedPo++;
}
function removePoToBill(attachedPo){
attachedPo--;
}
but Im getting an error! thanks for guiding :)
You need to wrap your handlers in anonymous functions:
$('.chckboxPo')
.on('ifChecked', function() {
addPoToBill(attachedPo);
})
.on('ifUnchecked', function() {
removePoToBill(attachedPo);
});
You can also chain the calls to on as they are being attached to the same element.
If your intention is to count how many boxes are checked, via passing variable indirectly to functions try using an object instead like this:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pBkhX/
var attachedPo = {
count: 0
};
$(function () {
$('.chckboxPo')
.on('change', function () {
if ($(this).is(':checked')) {
addPoToBill(attachedPo);
} else {
removePoToBill(attachedPo);
}
$("#output").prepend("" + attachedPo.count + "<br/>");
});
});
function addPoToBill(attachedPo) {
attachedPo.count++;
}
function removePoToBill(attachedPo) {
attachedPo.count--;
}
If it is not doing anything else you can simplify the whole thing to count checked checkboxes:
$(function () {
var attachedPo = 0;
$('.chckboxPo')
.on('change', function () {
attachedPo = $(".chckboxPo:checked").length;
});
});
"DOM Ready" events:
you also needed to wrap it in a ready handler like this instead of what you have now:
$(function(){
...
});
*Note: $(function(){YOUR CODE HERE}); is just a shortcut for $(document).ready(function(){YOUR CODE HERE});
You can also do the "safer version" (that ensures a locally scoped $) like this:
jQuery(function($){
...
});
This works because jQuery passes a reference to itself through as the first parameter when your "on load" anonymous function is called.
There are other variations to avoid conflicts with other libraries (not very common as most modern libs know to leave $ to jQuery nowadays). Just look up jQuery.noConflict to find out more.

Jquery click functions runs before clicking

I want my jquery to load a function when a button is clicked.
This works fine:
$(document).ready(function() {
$("#register").click(function() {
alert("button");
});
This one will show the test() function before the document loads:
$(document).ready(function() {
function test(param1, param2){
alert("param1: "+param1+" param2: "+param2);
}
$("#register").click(test("a","b"));
});
How can i fix this ?
$(document).ready(function() {
$("#register").click(function() {
alert("button
});
should be:
$(document).ready(function () {
$("#register").click(function () {
alert("button");
});
});
And
$(document).ready(function() {
function test(param1, param2){
alert("param1: "+param1+" param2: "+param2);
}
$("#register").click(test("a","b"));
});
should be
$(document).ready(function () {
function test(param1, param2) {
alert("param1: " + param1 + " param2: " + param2);
}
$("#register").click(function () {
test("a", "b");
});
});
$(document).ready() fires once the DOM is ready.
I think your problem is in this code:
$("#register").click(test("a","b")); // I suppose it is executing test().
you just pass the parameters through event handler like this.t allows you to pass a data map to the event object that automatically gets fed back to the event handler function by jQuery as the first parameter. The data map would be handed to the .click() function as the first parameter, followed by the event handler function.
$(document).ready(function() {
function test(e){
alert(e.data.param1); // returns "a"
alert(e.data.param2); // returns "b"
}
$("#register").click({param1 : "a" , param2 : "b"} , test);
});
More you want about event Handler Stack Overflow
The problem is in your click event handler. This is what you have:
$("#register").click(test("a","b"));
Here you are immediately executing the test("a","b") function. Instead you want to pass in a function that calls this. Therefore the corrected code is
$("#register").click(function (){
test("a","b");
});

Function becomes undefined after first trigger

I have a block of code like so:
function doSomething() {
someVar.on("event_name", function() {
$('#elementId').click(function(e) {
doSomething();
});
});
}
// and on document ready
$(function () {
$('#anotherElemId').click(function () {
doSomething();
});
});
The problem that I'm encountering is that when I call doSomething() from anotherElemId click event(that is binded on document ready) it works as expected, but calling it recursively from elementId click doesn't work.
Any ideas? Thinking is something trivial that I'm missing.
Is someVar an actual jQuery reference to a dom element? (e.g. $('#someitem'))
The second problem is you cant put a .click event inside a function that you would like to instantiate later on. If you are trying to only allow #elementId to have a click event AFTER some previous event, try testing if a tester variable is true:
var activated = false;
$(function () {
$('#anotherElemId').click(function () {
activated = true;
});
$('#secondElemId').on("event_name", function() {
if (activated) {
// code that happens only after #anotherElemId was clicked.
}
});
});

Add more behavior to existing onclick attribute in javascript

how can i add more behaviour to existing onclick events e.g.
if the existing object looks like
link
<script>
function sayHello(){
alert('hello');
}
function sayGoodMorning(){
alert('Good Morning');
}
</script>
how can i add more behavior to the onclick that would do also the following
alert("say hello again");
sayGoodMorning()
Best Regards,
Keshav
Here's the dirtiest way :)
<a href=".." onclick='sayHello();alert("say hello again");sayGoodMorning()'>.</a>
Here's a somewhat saner version. Wrap everything into a function:
..
JavaScript:
function sayItAll() {
sayHello();
alert("say hello again");
sayGoodMorning();
}
And here's the proper way to do it. Use the event registration model instead of relying on the onclick attribute or property.
<a id="linkId" href="...">some link</a>
JavaScript:
var link = document.getElementById("linkId");
addEvent(link, "click", sayHello);
addEvent(link, "click", function() {
alert("say hello again");
});
addEvent(link, "click", sayGoodMorning);
A cross-browser implementation of the addEvent function is given below (from scottandrew.com):
function addEvent(obj, evType, fn) {
if (obj.addEventListener) {
obj.addEventListener(evType, fn, false);
return true;
} else if (obj.attachEvent) {
var r = obj.attachEvent("on" + evType, fn);
return r;
} else {
alert("Handler could not be attached");
}
}
Note that if all 3 actions must be run sequentially, then you should still go ahead and wrap them in a single function. But this approach still tops the second approach, although it seems a little verbose.
var link = document.getElementById("linkId");
addEvent(link, "click", function() {
sayHello();
alert("say hello again");
sayGoodMorning();
});
Another way not mentioned is to capture the function currently assigned to the element.onclick attribute, then assign a new function that wraps the old one. A simple implementation to demonstrate would be something like
function addEvent(element, type, fn) {
var old = element['on' + type] || function() {};
element['on' + type] = function () { old(); fn(); };
}
var a = document.getElementById('a');
function sayHello(){
alert('hello');
}
function sayGoodMorning(){
alert('Good Morning');
}
addEvent(a, 'click', sayHello);
addEvent(a, 'click', sayGoodMorning);
Working Demo here
One way would be to write a third function:
link
<script>
function sayHello(){
alert('hello');
}
function sayGoodMorning(){
alert('Good Morning');
}
function foo() {
alert("say hello again");
sayGoodMorning();
}
</script>
link
would also work
Assuming a slight change to your code:
link
In plain ol' JavaScript, you'd do something like this.
var a = document.getElementById('a1');
a.onclick = function () { alert('say hello again'); a.onclick(); }
It's worth noting that jQuery makes this a bit easier. See the documentation on the click, bind, and one, for example, and in general the section on event handler attachment.

Categories

Resources