I've written the following jQuery script, and I'm trying to make a 'cool transition', lol. When you start typing in #post-area-input input type=text-box, the page should switch to the 'compose.php' page (a form), while you type, and if you type over 19 characters, the textbox should expand to 80% width on keyup, if it's less than 30 characters, the box reverts to 300px.
Though, the problem is, if you blur out of the #post-area-input textbox, and then focus again, the load function reloads, and the other (possibly inputted) data in the compose.php file will be gone.
The question is: How do I make it so I prevent the last function from occurring again once it's already occurred? I've looked at .unbind(), but seeing as though there's another function being simultaneously on the same ID, that would disable the expanding function as well.
Thanks a lot! Very grateful for any answers :) (The script is below)
$('#post-area-input').keyup(function(){
if($('#post-area-input').val().length > 19){
$('#post-area-input').animate({width: '80%',}, 80, function(){});
}
else {
$('#post-area-input').animate({width: '300',}, 80, function(){});
}
});
$('#post-area-input').blur(function(){
if($('#post-area-input').val().length < 19){
$('#post-area-input').animate({width: '300',}, 80, function(){});
}
});
$('#post-area-input').keyup(function(){
$('#pcontent').load('compose.php').hide().fadeIn('slow');
});
I'd recommend against binding multiple anonymous functions to an event handler. Unbinding them can get ambiguous. Instead, declare the functions and bind/unbind them as such:
function keyUpFuncA(e) {
//code
}
function keyUpFuncB(e) {
//code
}
$(document).keyup(keyUpFuncA);
$(document).keyup(keyUpFuncB);
//then later when unbinding:
$(document).unbind("keyup", keyUpFuncA);
What may be tempting, but what you do not want to do, is resort to a global variable to track when load.php has been loaded.
You should name your keyup functions:
$('#post-area-input').bind("keyup.firstnameoffunction", function() { /* .. */ });
$('#post-area-input').bind("keyup.secondnameoffunction", function() { /* .. */ });
$('#post-area-input').unbind("keyup.firstnameoffunction");
you can also check what's currently binded to an object with this:
$('#post-area-input').data("events");
I'm a bit hazy on what is actually occurring, so please forgive me if I'm being obtuse, but one way to achieve event 'negation' could be to use a bool flag. For example:
var run_load_function = true;
...
$('#post-area-input').blur(function(){
run_load_function = false;
...
});
...
$('#post-area-input').keyup(function(){
if (run_load_function)
$('#pcontent').load('compose.php').hide().fadeIn('slow');
});
Then you also have the opportunity to reset the bool whenever you need it, providing some fine-grain control. Good question, and I'm looking forward to other answers! Hope this helps! :)
Related
im trying to get a lil project going but im stuck on a very annoying thing.
$(document).ready(function() {
$("#search-button").click(console.log('hello'))
});
as you can see im targeting a search button with the id search-button and as soon as i click it something should happen. in this case i put a console.log in to test if it works but it doesn't. it always logs it as soon as i load the page , not when i click the button i target. ... what am i doing wrong
if you need more info on this pls tell me i tried to keep it as simple as i could
ty for your help
O.k
The click handler needs a function argument, not just the console.log by itself. Try this:
$(document).ready(function() {
$("#search-button").click(function() {
console.log('hello');
});
});
Inside of .click should be a handler .click(handler) and the handler should be a function. The browser is reading the code and when it hits console.log('hello'), it does it! It's seeing .click etc, but it doesn't matter; it next sees console.log and does it.
Try
$(document).ready(function() {
$("#search-button").click(function() {
console.log('hello');
});
});
As others have mentioned, the click function requires its own callback function. You can also use this, without requiring the use of document:
$("#search-button").on('click', function() {
console.log('hello')
})
I hope You're using jQuery version 3 or up. if you use 3 or up jquery version the good practice is you use Document binding Example:
jQuery(document).on('click', '#search-button', function(event) {
//your Code here...
console.log('hello');
});
I have a DotNetNuke website. Baked into the DNN code is the following script
<script type="text/javascript">
//<![CDATA[
function WebForm_OnSubmit() {
dnn.controls.submitComp.onsubmit();
return true;
}
//]]>
</script>
The problem is, I put a form on a page on my website that performs a search, and I wired up a jquery listener that says if the enter key is pushed, fire my button click event. The problem is, the parent script above ALSO fires that WebForm_OnSubmit() function, and whatever that onsubmit() function\return true does is causing my page to just refresh.
So, if there anything i can do so "override" or "prevent" that WebForm_OnSubmit() function from also triggering?
Edit 1: In response to the question "how is your listener setup":
I have a function called canISearch:
function canISearch() {
if (event.keyCode == 13) {
event.stopPropagation();
$("#btnSearch").click();
}
}
and I fire this function using my onkeydown attribute:
<input type="text" id="txtblah" onkeydown="canISearch()" />
If WebForm_OnSubmit is in the global space, you can overwrite it and create an exception for your case. Sometime after the original function is defined, redefine it. Maybe something like this:
(NOTE: updated to incorporate information from Samy's answer below)
(function () {
var originalFn = dnn.controls.submitComp.onsubmit;
dnn.controls.submitComp.onsubmit = function() {
if ([your element is in focus]) {
... do your thing ...
} else {
originalFn();
}
};
})()
You could either monkey patch the dnn code in order for the method to do nothing when your function is present on the page:
dnn.controls.submitComp.onsubmit = function() {/*doing nothing, ladida*/};
Which may be a bit harsh since your modification can have an impact on other behaviors. You can instead add a method that checks that your control has focus before routing the code accordingly. This is most likely the simplest hack.
You could also prevent the event from bubbling up, as Brennan suggests; it really depends how events are attached. If I remember correctly DNN can intrude on your events in so many ways this may not be easy to do.
Or you could create your own skin in order to control all the components that are pushed onto the page and prevent the auto submit from the wrapping form.
How is your listener set up? You should be able to stop propagation of the event to keep it from moving up the event hierarchy:
$(".element").keyup(function(e){
e.stopPropagation();
});
I'm trying to do a simple button rollover, changing it's icon when it's vclicked, but really don't get why the vclick event is only fired once, can someone shed some light on this? I get the same result if I use "click" or attach the event directly to the button element.
JSFiddle at: http://jsfiddle.net/w7quoyn4/
$('#btnAddToCart').on('vclick', function () {
console.log("btnAddToCart vclick event fired");
if ($(this).attr('data-icon', "plus")) {
$(this).attr('data-icon', "minus").button().button("refresh");
} else {
$(this).attr('data-icon', "plus").button().button("refresh");
}
});
Thanks in advance :)
There are two issues in your code.
First, the conditional expression $(this).attr('data-icon', "plus") invokes the setter form of attr(), which will always return the jQuery object its is called on. Since objects are always true in a boolean context, your else branch will never be taken.
To fix that, you could invoke the getter form of attr() and compare the result:
if ($(this).attr("data-icon") == "plus") {
// ...
}
Then again, the calls to button() are the heart of the matter. The appropriate method to use would be buttonMarkup(), but it is deprecated since release 1.4 (and will be removed in 1.5).
The actual solution is to add and remove the appropriate classes yourself, as in:
$(document).on("vclick", "#btnAddToCart", function () {
console.log("btnAddToCart vclick event fired");
$(this).toggleClass("ui-icon-plus ui-icon-minus");
});
You can see the results in this updated fiddle.
This question is for the purposes of developing jQuery plugins and other self-contained JavaScript snippets that don't require modifying other script files for compatibility.
We all know that event.preventDefault() will prevent the default event so we can run a custom function. But what if we want to simply delay the default event before invoking it? I've seen various, case-specific ninja tricks and workarounds to re-invoke the default action, but like I said, my interest is in a universal way to re-trigger the default, and not deal with default triggers on a case-by-case basis.
$(submitButton).click(function (e) {
e.preventDefault();
// Do custom code here.
e.invokeDefault(); // Imaginary... :(
});
Even for something as simple as form submission, there seems to be no universal answer. The $(selector).closest("form").submit() workaround assumes that the default action is a standard form submission, and not something wacky like a __doPostBack() function in ASP.NET. To the end of invoking ASP.NET callbacks, this is the closest I've come to a universal, set-it-and-forget-it solution:
$(submitButton).click(function (e) {
e.preventDefault();
// Do custom code here.
var javascriptCommand = e.currentTarget.attributes.href.nodeValue;
evalLinkJs(javascriptCommand);
});
function evalLinkJs(link) {
// Eat it, Crockford. :)
eval(link.replace(/^javascript:/g, ""));
}
I suppose I could start writing special cases to handle normal links with a window.location redirect, but then we're opening a whole new can of worms--piling on more and more cases for default event invocation creates more problems than solutions.
So how about it? Who has the magic bullet that I've been searching for?
Don't call preventDefault() in the first place. Then the default action will happen after your event handler.
Take a look at this one:
You could try
if(!event.mySecretVariableName) {
event.preventDefault();
} else {
return; // do nothing, let the event go
}
// your handling code goes here
event.originalEvent.mySecretVariableName = "i handled it";
if (document.createEvent) {
this.dispatchEvent(event.originalEvent);
} else {
this.fireEvent(event.originalEvent.eventType, event.originalEvent);
}
Using this answer: How to trigger event in JavaScript? and the jQuery event reference: http://api.jquery.com/category/events/event-object/
Tag the event object you receive so if you receive it again you don't loop.
This should work. I've only tested in firefox though.
<html>
<head>
<script>
window.addEventListener("click",handleClick,false);
function handleClick(e){
if (e.useDefault != true){
alert("we're preventing");
e.preventDefault();
alert(e.screenX);
//Firing the regular action
var evt = document.createEvent("HTMLEvents");
evt.initEvent(e.type,e.bubbles,e.cancelable);
evt["useDefault"] = true;
//Add other "e" attributes like screenX, pageX, etc...
this.dispatchEvent(evt);
}
else{
alert("we're not preventing");
}
}
</script>
</head>
<body>
</body>
</html>
Of course, you'd have to copy over all the old event variables attributes too. I just didn't code that part, but it should be easy enough.
It's not possible like JamWaffles has already proven. Simple explanation why it's impossible: if you re-trigger the default action your event listener intercept again and you have an infinite loop.
And this
click(function (e) {
e.preventDefault();
// Do custom code here.
e.invokeDefault(); // Imaginary... :(
});
is the same like this (with your imaginary function).
click(function (e) {
// Do custom code here.
});
It seems that you want to manipulate the url of your clicked element. If you do it like this it just works fine. Example.
I needed to disable a button after click and then fire the default event, this is my solution
$(document).on('click', '.disabled-after-submit', function(event) {
event.preventDefault();
$(event.currentTarget).addClass('disabled');
$(event.currentTarget).removeClass('disabled-after-submit');
$(event.currentTarget).click();
$(event.currentTarget).prop('disabled', true);
});
I have a timed event I want to behave differently accordingly to what HTML element the mouse pointer is on.
Is there a way, assuming I have the HTML element, to know if the mouse pointer is currently on top of it.
I am well aware of the onmouseover/onmouseout events and how to use them.
I am using JQuery.
I am obviously looking for some kind of flag, as I need to check a state and not handle an event.
again, I know how to implement this with events.
I'm not aware of any built-in way to ping an element for the status of mouse hovering.
However, you can create one by updating a flag at mouseenter and mouseleave -- which is where Brian Driscoll's suggestion of .hover comes in:
jQuery.fn.tracking = function () {
this.data('hovering', false);
this.hover(function () {
$(this).data('hovering', true);
}, function () {
$(this).data('hovering', false);
});
return this;
};
jQuery.fn.hovering = function () {
return this.data('hovering');
}
You'll need to initialize tracking for each element you care about:
$('#elem1,#elem2').tracking();
But then you can get the status of any of them:
if ($('#elem1').hovering()) {
// ...
} else if ($('#elem2').hovering()) {
// ...
}
Demo: http://jsbin.com/amaxu3/edit
Have you looked into jQuery.hover()? http://api.jquery.com/hover/
You need to give name to html andme and on mouseover you need to check document.getelementsbyName. Then check what your are getting as output. Now you can take decision is it html control or asp.net.
When you use collObjects = object.getElementsByName("htmlcontrol") then compare id of both.
1 morething why you needed to check this in javascript. there may be some other solution for that. Just share with us.
You might have some luck with document.elementFromPoint, although I believe there are some inconsistencies in older browser implementations (http://www.quirksmode.org/dom/w3c_cssom.html#documentview).
$('#elem').mousemove(function(e){
if (this == document.elementFromPoint(e.clientX, e.clientY)) {
// Do stuff
}
});
Or outside of a handler
if ($('#elem').get(0) == document.elementFromPoint(x, y)) {
// Do stuff
}
Aside from that, the only other option that comes to mind is using event handlers to keep track of which element the mouse is over.