jquery .focus(func) doing process several times - javascript

EDIT:
Thanks to Puneet who created this fiddle: http://jsfiddle.net/G3vSK/
It seems that it doesn't work on Chrome Version 28
On Firefox (v22) the alert comes once, but you can't enter anything in the boxes
Another problem I can't solve:
This is my Javsacript-Code:
function updateFieldsetStyleAdjustment(){
alert("update");
$('fieldset').not('[data-style=\'none\']').find('input, select, textarea, button') //find input-fields
.focus(function(){
alert("active: "+$(this).attr('id'));
});
}
This function should add an onfocus-Handler to some input-fields on my site.
Whenever I focus an field to insert a value, it should be called.
My problem is that, when I focus an input-field, the function is called several times. The number of calls/alerts varies from 3 to 16 or more per focus-Event.
However, my field never looses focus.
I apply the onfocus-event 2 times (The "update"-alert appears twice), but this is normal.
(I don't add 16 onfocus-event listeners to the input-fields).
Anyone knows what I'm doing wrong?
EDIT:
Here's the HTML-snipped:
<fieldset id="fs_1" data-style="data" d class="">
<legend>General Information</legend>
<div class="lineWrapper inputTooltip" data-tooltippos="left">
<label for="fs_1_form51f37d255fb35_name">Name</label>
<span class="inputWrapper">
<input type="text" id="fs_1_form51f37d255fb35_name" name="name" autofocus="" maxlength="40" tabindex="50">
</span>
</div>
<div class="lineWrapper inputTooltip" data-tooltippos="left">
<label for="fs_1_form51f37d255fb35_ansprechperson">Ansprechperson</label>
<span class="inputWrapper">
<input type="text" id="fs_1_form51f37d255fb35_ansprechperson" name="ansprechperson" maxlength="40" tabindex="51">
</span>
</div>
<!-- ...more Wrappers with input-fields... -->
</fieldset>
<!-- ...more fieldsets... -->
How I call it:
1.) $(document).ready(function() { updateFieldsetStyleAdjustment(); });
2.) After every Ajax-Request I call it again (the input-fields are loaded via Ajax)
unbind:
When I put $(this).unbind('focus'); inside my focus-eventhandler, it is triggered only once. But when I focus the same field again, it doesn't work anymore (as expected).
When I put $('*').unbind('focus'); on the beginning of my updateFieldsetStyleAdjustment()-Function, it doesn't change anything.

The alert() was the bug.
Realised that everything was working fine without the alert(). And the event was also only triggered once.
The alert always unfocused the input-field, and so a new alert was created.
I hate it, when my debugging-code is the only bug in the program.

I think your problem lies here.
After every Ajax-Request I call it again (the input-fields are loaded via Ajax).
Try binding focus with only the new fieldset generated after ajax calls (try using jQuery.on() function). Alternatively try
$('fieldset').not('[data-style=\'none\']').find('input, select, textarea, button').unbind('focus');
//unbind focus from previously binded dom elements.
and then call
updateFieldsetStyleAdjustment

Related

How do I permanently store input from an HTML text field into a jQuery variable?

jQuery
$(document).ready(function(){
var guess;
$('#submit').on("click", function() {
guess = $('#guess-value').val();
$("#value").text(guess);
alert(guess);
});
alert(guess);
});
HTML
<div id='game'>
<form id='user-input'>
<input type='text' id='guess-value' placeholder='1-100'></input>
<button id='submit'>Submit</button>
</form>
<h4 id='guess-count'>Attempts left: <span id="attempts">6</span></h4>
</div>
<h4 id='checker'>The value entered is <span id="value">?</span></h4>
I've provided snippets of my HTML and jQuery code above. I am trying to store a number that has been entered into a text field, into a jQuery variable called guess after pressing a submit button.
The following happens occurs:
When I enter a number into the field and press submit, I get an alert showing the value I entered. After closing the event I get another alert that is supposed to show the value of 'guess' and the value is undefined.
This happens even though I declared the variable guess outside of the click event. Why is this and how do I permanently store the value?
You are using a <form> element to ask for user input. The problem with a form, is that when it submits, it wants to navigate away from (or refresh) the page. When the page refreshes, all js is lost.
Simple fix: don't use a form (you can use a DIV instead).
Alternatively, you can tell the form to NOT do its default action of submitting by using event.preventDefault():
jsFiddle Demo
HTML:
<div id='game'>
<form id='user-input'>
<input type='text' id='guess-value' placeholder='1-100'></input>
<button id='submit'>Submit</button>
</form>
<h4 id='guess-count'>Attempts left: <span id="attempts">6</span></h4>
</div>
<h4 id='checker'>The value entered is <span id="value">?</span></h4>
<input type="button" id="myButt" value="Show Value" />
jQuery:
var guess;
$('#submit').on("click", function (evnt) {
guess = $('#guess-value').val();
$("#value").text(guess);
alert(guess);
evnt.preventDefault();
});
$('#myButt').click(function(){
alert( guess );
});
Further Notes:
Note that the 2nd alert(guess) in your posted code will occur immediately upon document.ready. I mean, immediately -- as soon as the DOM is ready. Before anything has been put into guess. That is why it returns undefined.
That is probably not what you want. Code example above adds a button to allow you to view that variable's contents when desired.
The function : $("#value").text(guess) is not corret in this case, replace it with :
$("#value").empty().append(guess);
you should wait to be .ready() in order to submit();
give me feedback please. enjoy :)
The 'guess' variable is out of the click event handler but it's in the ready event handler; So the second alert box will be shown exactly once when the page is loaded. It will then be undefined. The click events will occur later.

Accidental JavaScript redirct?

I have a form that adds an item to a list when I press enter or hit a submit button. I'm not sure what I've changed, but suddenly pressing enter seems to redirect the URL, while clicking the button acts normally.
The HTML portion looks like this:
<form id="add-ingr">
<input class="new-ingredient" type="text" size="50" name="new-ingredient" placeholder=" Your ingredient"></input>
<img id="check" src="imgs/check.png" alt=""/>
</form>
The jQuery is:
$('#check').click(function () {
addIngredient('new-ingredient');
});
$('.new-ingredient').keypress(function (e) {
if (e.keyCode == 13) {
addIngredient('new-ingredient');
}
});
So it's running the same function either way. In both cases, it successfully adds the ingredient to the list, but in the 2nd case, the page is redirected from "recipe.html" to "recipe.html?new-ingredient=".
And here's the part that really confuses me: when I add an extra input to the form, this problem doesn't occur when I press enter in either box:
<form id="add-ingr">
<input class="new-ingredient" type="text" size="50" name="new-ingredient" placeholder=" Your ingredient"></input>
<img id="check" src="imgs/check.png" alt=""/>
<input type="text"></input>
</form>
Also, if I add in an actual button (not my clickable image), it redirects like pressing enter, even though I have no code to do anything if the button is pressed. In this case, the extra input field has no effect.
<form id="add-ingr">
<input class="new-ingredient" type="text" size="50" name="new-ingredient" placeholder=" Your ingredient"></input>
<img id="check" src="imgs/check.png" alt=""/>
<button id="button">Add Ingredient</button>
</form>
I have absolutely no idea why this is happening. Even if I get rid of the jQuery to perform an action when I hit enter, this still happens. I'm new to JavaScript, so sorry if this is something obvious, but I'd really appreciate some help.
I can also provide more of my code if it's relevant, but I didn't want to clog things up with a ton of code.
Hitting enter (or clicking the button if its there) is submitting the form (this makes it appear to "redirect the URL"). You need to prevent that from happening with e.preventDefault(). So in the click listener:
$('#button').click(function(e){
e.preventDefault();
addIngredient('new-ingredient');
});
Put that in each of the listeners, or get rid of your form tags so there isn't anything to submit (as was mentioned in the comments).
I don't entirely blame you for being confused. The browser default behavior is to perform the "submit" action, whatever it is, when someone presses enter while a field in the form is highlighted. As elclanrs said, you can override the submit action; in fact, I'm pretty sure in JQuery it's just this:
$('#add-ingr').submit(function(e) {
if ('event is not coming from button')...{
e.preventDefault();
}
});
I'm afraid I couldn't explain why adding a blank input changed the effect, though. Through my laziness, I have also left you the work of determining the best way of allowing actual submissions, though (if the form gets submitted to the server, you won't want to block submit every time)

How to repeat the tabindex from 1 after it has gone to the last element with a tabindex?

So, for example, here's a script:
<!-- Random content above this comment -->
<input type="text" tabindex="1" />
<input type="text" tabindex="2" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<!-- Nothing underneath this comment -->
So, when the user presses tab and goes through the six textboxes, reaches the last one and then presses tab, it would go to the content above the first comment, right? Well, how do I make it start from tabindex="1" again?
Unfortunately, you can't do that without javascript. You can listen to a TAB (and make sure it's not SHIFT+TAB) key press on your last element and manually set the focus to your first element inside the handler. However, binding this logic to keyboard events (i.e. specific input method) is not universal and may not work when using:
A mobile browser
Some other entertainment device (smart tv, gaming console, etc. - they typically use a D-Pad for jumping between focusable elements)
An accessibility service
I suggest a more universal approach which is agnostic of how the focus is changed.
The idea is that you surround your form elements (where you want to create a "tabindex loop") with special "focus guard" elements that are focusable too (they have a tabindex assigned). Here is your modified HTML:
<p>Some sample content here...</p>
<p>Like, another <input type="text" value="input" /> element or a <button>button</button>...</p>
<!-- Random content above this comment -->
<!-- Special "focus guard" elements around your
if you manually set tabindex for your form elements, you should set tabindex for the focus guards as well -->
<div class="focusguard" id="focusguard-1" tabindex="1"></div>
<input id="firstInput" type="text" tabindex="2" class="autofocus" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<input id="lastInput" type="text" tabindex="7" />
<!-- focus guard in the end of the form -->
<div class="focusguard" id="focusguard-2" tabindex="8"></div>
<!-- Nothing underneath this comment -->
Now you just listen to focus events on those guard elements and manually change focus to the appropriate field (jQuery used for the sake of simplicity):
$('#focusguard-2').on('focus', function() {
// "last" focus guard got focus: set focus to the first field
$('#firstInput').focus();
});
$('#focusguard-1').on('focus', function() {
// "first" focus guard got focus: set focus to the last field
$('#lastInput').focus();
});
As you see, I also made sure that we snap back to the last input when the focus moves backwards from the first input (e.g. SHIFT+TAB on the first input). Live example
Note that the focus guards are assigned a tabindex value too to make sure they are focused immediately before/after your input fields. If you don't manually set tabindex to your inputs, then both focus guards can just have tabindex="0" assigned.
Of course you can make this all work in a dynamic environment as well, when your form is generated dynamically. Just figure out your focusable elements (less trivial task) and surround them with the same focus guards.
Hope that helps, let me know if you have any issues.
UPDATE
As nbro pointed out, the above implementation has the unwanted effect of selecting the last element if one hits TAB after the page loads (as this would focus the first focusable element which is #focusguard-1, and that would trigger focusing the last input. To mitigate that, you can specify which element you want initially focused and focus it with another little piece of JavaScript:
$(function() { // can replace the onload function with any other even like showing of a dialog
$('.autofocus').focus();
})
With this, just set the autofocus class on whatever element you want, and it'll be focused on page load (or any other event you listen to).
Here my solution where you no need any other elements. As you can see elements will be looping inside <form> elements.
$('form').each(function(){
var list = $(this).find('*[tabindex]').sort(function(a,b){ return a.tabIndex < b.tabIndex ? -1 : 1; }),
first = list.first();
list.last().on('keydown', function(e){
if( e.keyCode === 9 ) {
first.focus();
return false;
}
});
});
Here is my solution, considering the first input has the "autofocus" attribute set:
Add this after your form element (with HTML5 it can be any tag):
<div tabindex="6" onFocus="document.querySelector('[autofocus]').focus()"></div>
Yes, after tabbing through the inputs it will jump on suitable elements that do not have a tab order specified. But also, after tabbing all "tabbable" elements, the focus will jump "outside" your page content, onto the browser's UI elements (tabs, menus, bookmarks, etc)
I think the easiest way is to handle the keyup event on the last input and intercept TAB usage (and SHIFT+TAB for that matter)
I wd suggest you to increase your tabindex ie. >100
and also give the tabIndex to your "content" container div
please note that your content container must have tabindex less than input boxes for ex.99 .
when you press tab on last input box manually set focus on your content div using javascript (you can use keypress handlers for tab key)
document.getElementById("content").focus();
you must giv tabindex to your "content" to set focus to it.
now if you press tab focus will automatically shift to first input box.
hope this will help.
Thank you

onchange hijacks onclick

Modifying the text and then clicking on the button triggers only the onchange code
But I need to know whether the button has been clicked:
<input type="text" onchange="alert('change')" value="Text">
<input type="button" onclick="alert('click')" value="Button">
What do I need to change to get the click handler?
That works fine, it's alert() that sucks.
I don't know the exact details around it, but I've noticed in the past that alert() can mess with DOM events in strange ways when those events would occur together.
<input type="text" onchange="console.log('change')" value="Text">
<input type="button" onclick="console.log('click')" value="Button">​
See here: http://jsfiddle.net/25EsQ/
(Make sure to bring up the JS console so you can see the output)
The good news is this is a debugging issue only (hopefully) and when you use real and useful JS code instead, it should work as you expect.
The alert comes up between the onmousedown and the onmouseup events, causing an onclick to never trigger

Javascript onsubmit causing page to refresh

Really simple form
<form id="addDonor" name="addDonor" onsubmit="addDonor(); return false;" action="" method="post" enctype="multipart/form-data">
<div class="sectionHeader">Add New Donor</div>
<div class="formRow"><label>Name</label> <input class="inputText fullTextBar" type="text" name="userName">
<div class="formRow"><button style="margin-left:350px; width: 80px" type="button" class="publish">Add Donor</button></div>
</form>
And the addDonor function
<script type="text/javascript">
function addDonor(){
alert("test");
return false;
}
</script>
Eventually that function will include some jquery ajax to submit the info. But, baby, steps. Right now I can't even get the alert to show up. Also, when I hit "Enter" on my keyboard, the whole page refreshes, when I press "Add Donor" nothing happens.
I'm sure it has to be a simple problem. I think it's one of those things that I just need someone else's eyes to point out.
Try assigning the onsubmit event in javascript:
document.getElementById("addDonor").onsubmit = function () {
alert("test");
return false;
}
The problem is that your function is named addDonor and your element is addDonor. Every element with an id has an object created under document to identify it. Try alert(addDonor) in the inline onsubmit to see that it alerts an HTML element, not a function. Inline functions execute in a scope chain inside document, so addDonor points to document.addDonor before it reaches window.addDonor (your function).
you should change your <button> to an <input type="submit"> (as #fireshadow52 suggested) that should fix your problem. you should try the Wc3 Schools online javascript tester to try out simple javascripts before you put it in a page, or any other one that you prefer. google has something along these lines. also, you can normally try the javascript console on your respective browser.
Your button is explicitly set to type="button", which won't make it submit the form. Change it to <button type="submit">, or to <input type="submit"> if you prefer (I like the styling options of <button> myself).

Categories