I'm trying to implement a search bar on my website. I already have the back end processing working correctly, and I have the html and CSS in place for the search bar, all I have left to do is get my JavaScript to trigger the search to execute. Here is the html for the search bar:
<div id="search_field_container">
<input type="text" name="search_field" id="search_field" maxlength="100" placeholder="Search by item name or #tag" value="Search by item name or #tag" onclick="value=''" />
<button id="search" name="search_button">s</button>
</div>
What I'm trying to do is set up jQuery event handlers to trigger a JavaScript function called search when the user either presses enter while the text bar is focused or when they click the search button. However, I absolutely cannot seem to get the event handlers to trigger. Here is my JavaScript:
//Search function
$(document).ready(function(){
console.log("In anonymous function.");
$("#search").on('click', function(event){
alert("In click handler");
search();
});
});
$("#search_field").bind('keyup', function(event){
alert("In keyup handler");
if(event.keyCode == 13){
alert("In enter handler");
search();
}
});
function search(){
alert("Something happened!");
var searchTerm = $("#search_field").val();
alert("You're trying to search for "+searchTerm);
}
Currently, nothing happens when I either hit enter with the cursor in the text bar or press the search button. I know it isn't JavaScript errors preventing execution of everything, because all of the other JavaScript on the page executes perfectly fine.
I know the search function works and that the at least the search_field id on the text input is correct because if I add an onclick to the button and call search through that, it executes correctly and it always echoes the value from the text field correctly.
The search bar is in a separate header file so I don't have to include it in the html of every page, but that shouldn't make a difference because I'm including the file with PHP, so it should already be in place before the file even gets to the user. Just in case though, I've already tried using .bind and document.ready as you can see, as well as .on and an anonymous wrapper function, to no avail.
I don't get any error messages in the console or anything, it just silently fails. I know there are tons of similar questions on this site, but I've already tried every solution I could find to about a dozen of them. If anyone knows what the problem is and how to fix it, or even just additional tests to help figure out why this is failing so I can narrow my searches down, that would be greatly appreciated.
EDIT:
Huangism created this JSfiddle using my code and showed that the code works properly, so there must be something about the context of my site causing it to not function.
Fiddle - http://jsfiddle.net/3m5Mp/
I added a fiddle to your question. You should move #search_field handler inside of doc ready. In fiddle it works because it is already assuming doc ready. The click works for me in the fiddle.
Which browser are you testing on?
For enter
code= (e.keyCode ? e.keyCode : e.which);
if (code == 13) alert('Enter key was pressed.');
Got this from another question
Here is a fiddle with the handlers all in doc ready and not assuming doc ready
http://jsfiddle.net/PFcnx/2/
It seems to work in FF, please test in other browsers and see if it works
Your js error probably has something to do with the extra comma at the end
$("#grid").masonry({
itemSelector : '.entry',
isFitWidth : 'true',
isResizable : 'true',
});
remove comma after the last 'true'
Use event.which instead. I'm also not 100% sure, but you may want to try .keydown or .keypress instead. I am looking at some JS code on a site of mine where I trap enter key presses and I only use those two. I remember having trouble with .keyup for some stuff.
Related
This question already has an answer here:
Can't trigger click with jQuery in a Chrome extension
(1 answer)
Closed 7 years ago.
I'm trying to submit a field with jquery, normally in the page you would click on a submit button or press enter in the field.
I'm doing this in a chrome script.
Now if I type:
$('#myButton').click()
In the Console, this actually works fine, but when i call the same code from my script function, it doesn't work.
I tried also to use this:
var e = jQuery.Event("keydown");
e.which = 50;
e.keyCode = 50;
$("#myButotn").trigger(e);
but still no results.
To be specific, the button that i'm willing to click has an onClick="submitFunction()"
Here is a much better way to trigger a click on keypress.
$(window).keydown(function (e) {
if ( e.which === 50 ) {
$("#myButton").click();
}
});
Demo: http://jsfiddle.net/bc7r3vq1/1/
By the way, keycode 50 is the number 2
Now, i've found a solution, but i'm not sure which one was the problem.
First of all I started using tampermonkeys, from there i used
$('#textField').submit();
and it worked fine.
I'm going to check now if I had to use this method, or if it was just something related with my extension.
EDIT: It works only if I use tampermonkeys, as they saied..
I believe your issue comes from the browser policy preventing your code from faking a user action. Chrome only allows you to fake a user action if its called directly from another user action handler like an actual user click of keydown. Try your code from within a click handler and if it works its because of this policy block.
I'm catching paste events with $('selector').on('input', function(event) { ... });
Then I'm trying to test what's been pasted and if it doesn't pass validation, cancel the paste with event.preventDefault(). Unfortunately, by the time the listener function is executed, the text has already been pasted and event.preventDefault() does nothing.
So what's a good way to catch paste events, and if what's been pasted doesn't validate, undo/prevent the paste?
I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste, unless I use setTimeout() with some minute wait time, and I'd like to avoid using setTimeout().
First of all some background on event trigger order for the input element:
keydown -> keypress -> paste -> input -> keyup -> change
Whenever you call preventDefault it stops the chains, like nothing happened.
So my suggestion is to catch the paste event, prevent its default behavior and do your logic there.
I know I can use .on('paste', function(event) { ... }), but that
doesn't give me the text that's been pasted or the contents of the
input element after the paste
Actually you can retrieve the content of the clipboard. See this doc. Support is all major browser (but only IE11+). I do not know if by the time of the writing of the question this functionality was available or not.
Fiddle example
$('#myInput').on('paste', function(e) {
// Cancel the event - this prevents the text from being entered into the input and stops the event chain
e.preventDefault();
// Get the content of the clipboard
let paste = (event.clipboardData || window.clipboardData).getData('text');
// Validate what it is pasted
if (paste == "text to paste") {
// If condition is satisfied manually set the value of the input
$(this)
.val(paste)
// Manually trigger events if you want
.trigger('input')
.trigger('change');
}
});
Notes on the code:
This solution does not include setTimeout. Whenever you make it with setTimeout you see for a very short time the text being pasted, like a blinking effect.
If text meets condition I manually set it in the input. However this does not trigger input and change events. If you need them, just manually trigger them
Similar approach is to first check the text and if it does not meet requirements then call preventDefault, otherwise do nothing. This way you avoid manually setting value in the input and triggering events afterward.
Try using .change event of jquery.
Set value to blank if value doesn't satisfy your condition.
Using
$('selector').on('input', function(event) { ... });
and in case the validation does not pass deleting the pasted text seems to work for me.
Sadly accessing the clipboard has some flaws (browser asking if it is allowed to inspect the clipboard, cross browser compatibility, etc.)
If you are okay with saving the last value of the input, the pasted text can be calculated anyway.
Here is my approach for calculating the pasted text
https://jsfiddle.net/f710o9qd/2/
I hope this helps you :)
(Feel free to refine the calculation of the pasted text if you find any flaws)
My understanding from the question is, we must not allow any data to be pasted inside the text box until and unless it pass a specific validation. Instead of using event.preventDefault(), we can capture the value when user input any content, using on('input') listener and validate it against the specific condition and if the validation gets failed, empty the text box value.
(This is the workaround if we still need to use on('input') event listener)
Sample Code (I am using console.log() for printing the pasted value):
HTML:
<input type='text' id="selector" />
JS:
$(document).ready(function() {
$('#selector').on('input', function (e){
if(e.target.value !== "myValue"){
$('#selector').val('');
}
else{
console.log(e.target.value);
}
});
});
I've installed a handler for the click JavaScript event of a <button> element using the jQuery API, but the handler doesn't get called when the button is in fact clicked. How can I debug why the event handler isn't invoked? I'm developing in Visual Studio 2010 and debugging with the help of Google Chrome Developer Tools.
I'm new to JavaScript and don't know the debugging methods :)
EDIT
This is the HTML declaration of the button in question:
<button id="start-lint">Submit</button>
The relevant JavaScript:
$('button').button();
var btn = $("button#start-lint");
log.debug("Button: %s", btn);
btn.click(function () {
log.debug("Button clicked");
});
Let me know if more information is needed.
EDIT 2
Somehow I got it working, not sure what was wrong in the first place, but at least now I know how to tell if an element was found or not!
You can only debug if the code is actually fired, which it seems to not be.
You could try to see if its even finding the selector using length.
alert($("#myselector").length);
or
console.log($("#myselector").length);
For debugging javascript i recommend you to use FIREBUG for Firefox (http://getfirebug.com/) - you can set breakpoints, write to console etc, and it gives all possible displays of variables, objects etc.
Tutorial can be found here: http://www.youtube.com/watch?v=2xxfvuZFHsM
(You said you where new to jQuery/Javascript, so hope it helped :D)
Inline JavaScript is executed as the page loads, so if the button is defined after the JavaScript the code won't find it and so can't attach the handler. You need to put that JavaScript in the document ready (or onload) function, which means it will be executed after the button (and everything else on the page) has loaded, and/or put it after the button in the source.
I'm guessing that the $('button').button(); throws an exception, and the rest of your code isn't executed. Comment out that line and see if it works.
Original reply:
Paste your code, or the relevant parts of it.
Add a debugger; statement to your handler function to see if you are entering it.
If not, then there is a problem with how you're registering the handler.
If you are entering it, maybe there is a problem with the handler itself.
your button may look like this
<input type="button" value="Click" />
for this you bind a click handler like
$(document).ready(function(){
$("input[type='button']").click(function(e){
alert("somebody clicked a button");
});
});
http://jsfiddle.net/6gCRF/5/
but the drawback of this approach is it will get called for every button click, to prevent that you might want to add an id to your button and select that specific button e.g.
<input type="button" value="Click" id="specific" />
attach a click handler to it like
$(document).ready(function(){
$("#specific").click(function(){
alert("specific button clicked");
});
});
http://jsfiddle.net/6gCRF/4/
EDIT
in your case select the button by id
$(document).ready(function(){
$("#start-lint").clcik(function(){
console.log("clicked");
});
});
you can also use the pseudo :button selector
$(document).ready(function(){
$(":button").click(function(e){
console.log("clicked");
});
});
have a look at jquery selectors
Let's say I have a web page with a header menu, when I click the header menu, it calls a servlet that creates the sidebar. Is it possible that without using the document.getElementById? And just simulate keystrokes tab and enter via JavaScript so I don't have to click the menu to view the sidebar?
Could you describe what you want to achieve a bit more?
What I understood is that you want to be able to show ( and may be also hide) the sidebar with the tab button.
You could use the .keypress() function in jQuery - http://api.jquery.com/keypress/
Also check out this tutorial on Nettuts, I think it may be useful for you -
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-create-a-keypress-navigation-using-jquery/
You can use the attribute tabindex on the elements that makes your menu.
eg: <ul tabindex="1">... and set the focus on the first one when opening the page.
They will act as form field when you press tab.
Then for the enter place a single onkeyup listener on a parent node common to all menus items:
menuParent.onkeyup = function(ev){
var selectedMenu = ev.target || ev.srcElement,
keycode = ev.keyCode;
if(keycode === 13){
//the user pressed enter
}
...
}
You can do what you want using JavaScript, but there's a much easier way to do it than by simulating keystrokes.
I am assuming that what happens when you click the link is that a JavaScript function is called, which causes the submenu to appear. All you need to do is to find out what that function call is (let's say it's called "callTheFunction"), and then call it onload, like this:
<script type="text/javascript">
window.onload=callTheFunction;
</script>
Hopefully that will give you the idea. If you need any more help, please provide a URL or code sample.
This is driving me nuts. Its a tough one to explain but I'll have a go.
I have one input text field on the front page of my site. I have coded a keydown event observer which checks the keyCode and if its ENTER (or equiv), itll check the input value (email). If the email is valid and unique in the DB itll submit the form. Basic stuff, or so you would think.
If I type my email address in the field and hit enter, it works fine in all browsers. However, if I type the first couple of letters, and then use the arrow keys to select the email from the history dropdown box (hope you know what I mean here), and then press enter the result is different. The value of the form field is being captured as just the couple of letters I typed, and therefore the validation is failing. It seems that when I press the enter key to "select" the email from the history dropdown, the browser is interrupting that as if I was typing.
In Chrome and Safari it works as it should. As it should means that when you press enter to "select" the email from the history dropdown, all it does is puts that email address into the text box. Only on the second ENTER key press does it then trigger the event observer, and the email is validated.
Hope somebody can shed some light on why this is happening... My gut feeling is its a browser thing and will be something I cant fix.
Thanks
Lee
EDIT:
To add clarification to my question let me add that Im using the "keydown" event to capture the moment when the enter key is pressed. I have tried the "keyup" event and this solved my problem above, but then I cant seem to stop the form submitting by itself. The "keyup" event triggers AFTER the default behaviour, therefore its not the right choice for this.
FURTHER EDIT:
Thank you again, and btw, your English is excellent (in response to your comment about bad English).
I have changed my event handler from this:
$("emailInputBox").observe("keydown", function(event) {
return submitViaEnter(event, submitSignupFormOne);
});
to this:
$("emailInputBox").observe("keydown", function(event) {
setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0);
});
submitViaEnter:
function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
event.stop();
return callback(event);
}
return true;
}
Seems to work but the problem now is that the browser is permitted to carry out the default action before running the submitViaEnter function which means the form is being submitted when I hit ENTER.
Answer to the original question
Yeah, it's a Gecko bug (not Mac-specific though).
The last part of this comment contains the description of the work-around: use the time-out.
[edit] since you asked for the clarification of the bug
When you press Enter and the auto-complete is active, Firefox (erroneously) first fires the page's key handler, then the browser's internal key handler that closes the autocomplete popup and updates the text area value, while it arguably should just fire it at the autocomplete popup and only let the page know the textbox value changed.
This means that when your key handler is called, the autocomplete's handler hasn't run yet -- the autocomplete popup is still open and the textbox value is like it was just before the auto-completion happened.
When you add a setTimeout call to your key handler you're saying to the browser "hey, run this function right after you finished doing stuff already in your P1 to-do list". So the autocomplete's handler runs, since it's already in the to-do list, then the code you put on a time-out runs -- when the autocomplete popup is already closed and the textbox's value updated.
[edit] answering the question in "Further edit"
Right. You need to cancel the default action in the event handler, not in the timeout, if you want it to work:
function onKeyPress(ev) {
if (... enter pressed ...) {
setTimeout(function() {
... check the new textbox value after letting autocomplete work ...
}, 0);
// but cancel the default behavior (submitting the form) directly in the event listener
ev.preventDefault();
return false;
}
}
If you still wanted to submit the form on Enter, it would be a more interesting exercise, but it doesn't seem you do.
ok sorted it. Thanks so much for your help. It was the curry function that I was missing before. I was trying to work on the event inside the scope of the setTimeout function.
This works below. The submitViaEnter is called from the eventobserver and responds to the keyDown event:
function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
event.stop();
setTimeout(callback.curry(event),0);
// return callback(event);
// return false;
}
return true;
}
Stopping the default action inside the eventObserver meant that no characters could be typed. So I stuck inside the if ENTER key clause.