I've a simple form with a text input and a button disabled, this button can be enabled if i write on input text, keyup() is the best way but when i use right click and paste this event isn't called and doesn't trigger that event. So i tried event change(), it's work but not immediately, i must unfocus the input text for have the button enabled. How can i enable this button immediately with copy and paste?
$(document).ready(function () {
$('#id_input').bind('keyup paste click', function () {
if ($('#id_input').val().length === 6 ){
$('#btnSubmit').removeAttr('disabled');
}
else
$('#btnSubmit').attr('disabled', 'disabled');
});
});
Rory is right that your code should work in general especially if you paste using Ctrl + V.
I assume that you experience the issue only if you paste using right-click and then select Paste from the context menu.
Try to monitor the property changes:
$(document).ready(function() {
$('#id_input').bind('input propertychange', function() {
if ($('#id_input').val().length === 6) {
$('#btnSubmit').removeAttr('disabled');
} else
$('#btnSubmit').attr('disabled', 'disabled');
});
});
You need to use the onpaste event.
$(document).ready(function () {
$('#id_input').bind('keyup onpaste click', function () {
if ($('#id_input').val().length === 6 ){
$('#btnSubmit').removeAttr('disabled');
} else {
$('#btnSubmit').attr('disabled', 'disabled');
}
});
});
The User should be able to change the Name and then confirm the change. I'm not able to archive it with this code as when I click confirm, it returns like before.
What am I missing?
Any better way to put this together (which I'm sure there's one) ?
Please check the demo where you can also see the changeElementTypefunction
http://jsfiddle.net/dLk6E/
js:
$('.replace').on('click', function () {
$("h2").changeElementType("textarea");
$('.replace').hide();
$('.confirm').show();
//Confermation of the change
$('.confirm').bind('click', function () {
$('.replace').show();
$('.confirm').hide();
$("textarea").changeElementType("h2");
});
if ($('textarea:visible')) {
$(document).keypress(function (e) {
if (e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity', '1');
}
});
}
});
Here are your updated code and working fiddle http://jsfiddle.net/dLk6E/
(function($) {
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
this.replaceWith(function() {
return $("<" + newType + "/>", attrs).append($(this).contents());
});
}
})(jQuery);
$('.replace').on('click', function (){
$("h2").changeElementType("textarea");
$('.replace').hide();
$('.confirm').show();
//Confermation of the change
$('.confirm').on('click', function(){
$('.replace').show();
$('.confirm').hide();
// you are missing this
$('.replaceble').html($("textarea").val());
$("textarea").changeElementType("h2");
});
if ($('textarea:visible')){
$(document).keypress(function(e) {
if(e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity','1');
}
});
}
});
updated
jsfiddle.net/dLk6E/1
I think your code is right but you need to use the value you're entering when replacing it. So the confirmation binding would be something like this (fetching it, and then using it to update the textarea before "transforming" it into an h2 tag.
$('.confirm').bind('click', function(){
var valueEntered = $('textarea').val();
$('.replace').show();
$('.confirm').hide();
$("textarea").html(valueEntered).changeElementType("h2");
});
You could be using .on for this as well as of jQuery 1.7 is prefered to .bind.
Another thing I would suggest is whenever you struggle with something like this just put in google (or whatever...) exactly what you want, in this case "jquery get value of input" will get asw first result the jquery documentation
This way you won't forget it ;)
Update: Maybe a small detail but in the binding I use it would be more efficient to just hit $('textarea') once, so it would be something like this. Something that you may keep in mind (not really an issue here), better to store in a variable than hit the DOM several times.
$('.confirm').on('click', function(){
var $textarea = $('textarea');
$('.replace').show();
$('.confirm').hide();
$textarea.html($textarea.val()).changeElementType("h2");
});
jsfiddle
I'm using this HTML code:
<form action="#" method="post">
<fieldset>
<label class="desc" id="title10" for="Field10">
How many children do you have?
</label>
<select id="Field10" name="Field10" class="field select large" tabindex="5">
<option value="0" selected="selected">0 </option>
<option value="1">1 </option>
<option value="2">2 </option>
<option value="3">3 </option>
<option value="4">4 </option>
<option value="5">5 </option>
<option value="6">6 </option>
<option value="7">7 </option>
<option value="8">8 </option>
<option value="9">9 </option>
</select>
<input type="submit" value="Send message" />
</fieldset>
</form>
<select> is not working on iPhone and Android. When I tap on the selectbox nothing happens.
I'm using iScroll 4 which is creating the problem.
<script type="application/javascript" src="iscroll-lite.js"></script>
<script type="text/javascript">
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper');
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', loaded, false);
</script>
I think this is a solution but I don't know how to implement it.
The problem is that iScroll cancels the default behavior of your select tag (Not a very good implementation if you ask me).
This occurs in the _start() function on line 195:
e.preventDefault();
If you comment that out you'll notice the select tag works again.
But commenting it out means you've hacked the library which might break other desirable iScroll functionality. So here's a better workaround:
var selectField = document.getElementById('Field10');
selectField.addEventListener('touchstart' /*'mousedown'*/, function(e) {
e.stopPropagation();
}, false);
That code will allow the default behavior to occur, without propagating the event to iScroll where it screws everything up.
Since your JS is not inside any jQuery-like onReady() event, you'll have to make sure to you put this code AFTER the HTML where your select elements are defined.
Note that for mobile devices the event is touchstart, but for your PC browser it will be mousedown
I had the same issue on the iScroll 4.1.9 on android, I just replaced the line 95 (on my version) :
onBeforeScrollStart: function (e) { e.preventDefault(); },
by :
onBeforeScrollStart: function (e) {var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target ? e.target.nodeName.toLowerCase():''); if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') e.preventDefault(); },
that enable focus on input, select and textarea tags
Finally fixed this for Android. Ended up modifying a couple of lines in iscroll.js
Here's how we initialize iScroll.
// code from https://github.com/cubiq/iscroll/blob/master/examples/form-fields/index.html
// don't preventDefault for form controls
_menuScroll = new iScroll('menu_wrapper',{
useTransform: false,
onBeforeScrollStart: function (e) {
var target = e.target;
while (target.nodeType != 1) target = target.parentNode;
if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA')
e.preventDefault();
}
});
The onBeforeScrollStart is what allows the controls' default behaviors to take place. Android browser seems to have problem with useTransform, so turn to false.
Finally, some additional iscroll code needed to be excluded when useTransform is false:
// iscroll.js v4.1.9
// line 216:
if (that.options.useTransform) bar.style.cssText += ';pointer-events:none;-' + vendor + '-transition-property:-' + vendor + '-transform;-' + vendor + '-transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);-' + vendor + '-transition-duration:0;-' + vendor + '-transform:' + trnOpen + '0,0' + trnClose;
// line 295:
if (that.options.useTransform) that[dir + 'ScrollbarIndicator'].style[vendor + 'Transform'] = trnOpen + (dir == 'h' ? pos + 'px,0' : '0,' + pos + 'px') + trnClose;
Tried several other methods before realizing that it had to do with the css that iscroll adds.
I Know am late,but it might be helpful for some one,
write the following code in pageshow event,but be sure that div ids not same.
it is because, iscroller prevents the default behaviors of elements
$('#yourpage').bind('pageshow',function (event, ui) {
var myScroll;
if (this.id in myScroll) {
myScroll[this.id].refresh();
}else{
myScroll[this.id] = new iScroll('wrapper', { //wrapper is div id
checkDOMChanges: true,
onBeforeScrollStart: function (e) {
var target = e.target;
while (target.nodeType != 1)
target =target.parentNode;
if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA'){ e.preventDefault(); }
}
});
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
});
Here is the solution
/* on page add this after all scripts */
<script type="text/javascript">
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper');
}
document.addEventListener('DOMContentLoaded', function(){ setTimeout(loaded,500);}, false);
</script>
/* attach a script for fix */
$(document).ready(function(){
var my_select = document.getElementsByTagName('select');
for (var i=0; i<my_select.length; i++) {
my_select[i].addEventListener('touchstart' /*'mousedown'*/, function(e) {
myScroll.destroy();
setTimeout(function(){myScroll = new iScroll('wrapper');},500);
}, false);
}
/*if you have input problems */
var input = document.getElementById('input');
if (input) {
input.addEventListener('touchstart' /*'mousedown'*/, function(e) {
e.stopPropagation();
}, false);
}
});
another code example for solution. and thanks for previous comments!
Using Jquery!
After:
$(document).ready(function() {
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', setTimeout(function () { loaded(); }, 200), false);
});
in loaded function
function loaded() {
var allSelects = $('select');
allSelects.each(function(index, item) {
item.addEventListener('touchstart' /*'mousedown'*/, function(e) { e.stopPropagation(); }, false);
});
}
Replacing line, onBeforeScrollStart: function (e) { e.preventDefault(); },
By
onBeforeScrollStart: function (e) {
var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase():(e.target ? e.target.nodeName.toLowerCase():'');
if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') {
e.preventDefault();
}
},
In iScroll.js Works
Start with this code. This solution worked for me:
<script type="text/javascript">
var myScroll;
function iScrollLoad() {
myScroll = new iScroll('wrapper');
enableFormsInIscroll();
}
function enableFormsInIscroll(){
[].slice.call(document.querySelectorAll('input, select, button, textarea')).forEach(function(el){
el.addEventListener(('ontouchstart' in window)?'touchstart':'mousedown', function(e){
e.stopPropagation();
})
})
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(iScrollLoad, 200); }, false);
</script>
I'm late but I leave you my solution.
If your are using jQuery you can try that.
$('input, textarea, button, a, select').off('touchstart mousedown').on('touchstart mousedown', function(e) {
e.stopPropagation();
});
// Setup myScroll
myScroll = new IScroll('#wrapper', {
scrollX: horizontalSwipe,
scrollY: !horizontalSwipe,
momentum: false,
snap: document.querySelectorAll('#scroller .slide'),
snapSpeed: 400,
bounceEasing: 'back',
keyBindings: true,
click: true
});
For me, I just need to add click: true on the last line...
Spent the whole day debugging and implementing all the suggested solutions to no avail...
he anyone.
i know's about all your answer's but i have new way to offer. without java-script or drop iscroll functions.
the big problems with all this solution is when you scroll on input's element you have no scroll on the page. when you make just one or two input's isn't really matter but when the page is a form you have big problem to scroll the page.
the solution i offering is to wrap the input in label tag or make the label tag with for pointer to the input. then make with absolute positioning and z-index the label above the input. when you touch on the label you focus the input.
and example please
HTML
<fieldset>
<label>
<input type="text" />
</label>
</fieldset>
CSS
fieldset {position:relative;z-index:20;}
label {position:relative;z-index:initial;}
input {position:relative;z-index:-1;}
you can also in this way put the label side of the input and with position absolute of the input put that into the label area
is working in 100%, check it
There is a bug with Android when -webkit-transform:translate3d is applied to a container that has a select box or password box[1]. The boxed area to activate those elements move, and are not where you think they'd be. Additionally, password boxes paint in a different location, so it appears that you have two input elements instead of one.
I work at AppMobi and we have developed a toolkit library that has fixes for these. We've implemented custom select box widgets and a replacement for the password input field. Check it out below.
https://github.com/imaffett/AppMobi.toolkit
[1] I think the author of the comment is talking about this bug https://bugs.webkit.org/show_bug.cgi?id=50552
I'm a bit late to the game, but if anyone is still interested, I took #bastien's approach and tweaked it a bit to get it to work on Android. I'm using JQM with my implementation.
Basically what I did was:
function scrollMe(element) {
var contentID = $wrapper.get(0).id;
var scroller = elm.find('[data-iscroll="scroller"]').get(0);
if (scroller) {
var iscroll = new iScroll(contentID, {
hScroll : false,
vScroll : true,
hScrollbar : false,
vScrollbar : true,
fixedScrollbar : true,
fadeScrollbar : false,
hideScrollbar : false,
bounce : true,
momentum : true,
lockDirection : true,
useTransition : true,
//the preceding options and their values do not have any to do with the fix
//THE FIX:
onBeforeScrollStart: function(e) {
var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase() : (e.target ? e.target.nodeName.toLowerCase():''); //get element node type
if(nodeType !='select' && nodeType !='option' && nodeType !='input' && nodeType!='textarea') e.preventDefault(); //be have normally if clicked element is not a select, option, input, or textarea.
else if (iscroll != null) { //makes sure there is an instance to destory
iscroll.destroy();
iscroll = null;
//when the user clicks on a form element, my previously instanced iscroll element is destroyed
}
},
onScrollStart: function(e) {
if (iscroll == null) { //check to see if iscroll instance was previously destoryed
var elm = $.mobile.activePage; //gets current active page
var scrollIt = setTimeout( function(){ scrollMe(elm) }, 0 );
} //recursively call function that re-instances iscroll element, as long as the user doesn't click on a form element
}
});
elm.data("iscroll-plugin", iscroll);
}
}
Basically all you need to do is destroy your iScroll instance when a form element is selected by the user, but before they actually start scrolling (onBeforeScrollStart) and if the user clicks on anything else within the element with the custom attribute data-iscroll="scroller", they can scroll using iScroll as usual.
<div data-role="page" id="pageNameHere" data-iscroll="enable">
Here's a really easy fix that worked for me. I noticed in the Android browsers that on initial page load I could not click on a select box but I was able to click on a text input field that I was using for Search. Then I noticed that after I clicked on the text input field, it would recognize me clicking a select box. So all I did was add this to the javascript function I was using to load the Search page...
$('#search').focus();
So when the search page gets loaded, it automatically focuses on the text input field but does not pop up the keyboard, which is exactly what I wanted. Sorry my example is not publicly accessible, but hopefully this can still help somebody.
try this solution
if (e.target.nodeName.toLowerCase() == "select" || e.target.tagName.toLowerCase() == 'input' || e.target.tagName.toLowerCase() == 'textarea')
{
return;
}
What about, that works for me!:
$('input, select').on('touchstart', function(e) {
e.stopPropagation();
});
Even if you've excluded form elements in onBeforeScrollStart(), there is another bug in android 2.2/2.3 browser/webview:
https://www.html5dev-software.intel.com/viewtopic.php?f=26&t=1278
https://github.com/01org/appframework/issues/104
You can't input chinese characters in input elements in the div with "-webkit-transform" css style. The iscroll 4 applied the "-webkit-transform" with the scroller div.
The solution is to keep form fields in a absolute div out of the scroller.
Android browser bug is result of very old version of WebKit inside Android, even inside Android 4.3. The root cause of bug - wrong processing of the click event that iScroll sends back to the browser (removing preventDefault just stops sending this click event)
The Android Chrome browser is free from this bug because it has upgraded WebKit library inside.
Waiting for Android WebKit upgrade from Google.
Check this. This fixed my issue
https://github.com/cubiq/iscroll/issues/576
In option I have selected
click:false, preventDefaultException:{tagName:/.*/}
How do you detect which form input has focus using JavaScript or jQuery?
From within a function I want to be able to determine which form input has focus. I'd like to be able to do this in straight JavaScript and/or jQuery.
document.activeElement, it's been supported in IE for a long time and the latest versions of FF and chrome support it also. If nothing has focus, it returns the document.body object.
I am not sure if this is the most efficient way, but you could try:
var selectedInput = null;
$(function() {
$('input, textarea, select').focus(function() {
selectedInput = this;
}).blur(function(){
selectedInput = null;
});
});
If all you want to do is change the CSS for a particular form field when it gets focus, you could use the CSS ":focus" selector. For compatibility with IE6 which doesn't support this, you could use the IE7 library.
Otherwise, you could use the onfocus and onblur events.
something like:
<input type="text" onfocus="txtfocus=1" onblur="txtfocus=0" />
and then have something like this in your javascript
if (txtfocus==1)
{
//Whatever code you want to run
}
if (txtfocus==0)
{
//Something else here
}
But that would just be my way of doing it, and it might not be extremely practical if you have, say 10 inputs :)
I would do it this way: I used a function that would return a 1 if the ID of the element it was sent was one that would trigger my event, and all others would return a 0, and the "if" statement would then just fall-through and not do anything:
function getSender(field) {
switch (field.id) {
case "someID":
case "someOtherID":
return 1;
break;
default:
return 0;
}
}
function doSomething(elem) {
if (getSender(elem) == 1) {
// do your stuff
}
/* else {
// do something else
} */
}
HTML Markup:
<input id="someID" onfocus="doSomething(this)" />
<input id="someOtherID" onfocus="doSomething(this)" />
<input id="someOtherGodForsakenID" onfocus="doSomething(this)" />
The first two will do the event in doSomething, the last one won't (or will do the else clause if uncommented).
-Tom
Here's a solution for text/password/textarea (not sure if I forgot others that can get focus, but they could be easily added by modifying the if clauses... an improvement could be made on the design by putting the if's body in it's own function to determine suitable inputs that can get focus).
Assuming that you can rely on the user sporting a browser that is not pre-historic (http://www.caniuse.com/#feat=dataset):
<script>
//The selector to get the text/password/textarea input that has focus is: jQuery('[data-selected=true]')
jQuery(document).ready(function() {
jQuery('body').bind({'focusin': function(Event){
var Target = jQuery(Event.target);
if(Target.is(':text')||Target.is(':password')||Target.is('textarea'))
{
Target.attr('data-selected', 'true');
}
}, 'focusout': function(Event){
var Target = jQuery(Event.target);
if(Target.is(':text')||Target.is(':password')||Target.is('textarea'))
{
Target.attr('data-selected', 'false');
}
}});
});
</script>
For pre-historic browsers, you can use the uglier:
<script>
//The selector to get the text/password/textarea input that has focus is: jQuery('[name='+jQuery('body').data('Selected_input')+']')
jQuery(document).ready(function() {
jQuery('body').bind({'focusin': function(Event){
var Target = jQuery(Event.target);
if(Target.is(':text')||Target.is(':password')||target.is('textarea'))
{
jQuery('body').data('Selected_input', Target.attr('name'));
}
}, 'focusout': function(Event){
var Target = jQuery(Event.target);
if(Target.is(':text')||Target.is(':password')||target.is('textarea'))
{
jQuery('body').data('Selected_input', null);
}
}});
});
</script>
You only need one listener if you use event bubbling (and bind it to the document); one per form is reasonable, though:
var selectedInput = null;
$(function() {
$('form').on('focus', 'input, textarea, select', function() {
selectedInput = this;
}).on('blur', 'input, textarea, select', function() {
selectedInput = null;
});
});
(Maybe you should move the selectedInput variable to the form.)
You can use this
<input type="text" onfocus="myFunction()">
It triggers the function when the input is focused.
Try
window.getSelection().getRangeAt(0).startContainer