Autoexpanding textarea with jquery - javascript

I need the <textarea> to vertically grows as the user types in and I found this code on the net http://perplexed.co.uk/596_expanding_textarea_as_you_type.htm
I want it to be written in jQuery but as I turn the code into jQuery it does not work.
This is the javascript version:
<textarea id="text"></textarea>
var textArea = document.getElementById('text')
textArea.addEventListener('input', function () {
while (
textArea.rows > 1 && textArea.scrollHeight < textArea.offsetHeight) {
textArea.rows--;
}
var h = 0;
while (textArea.scrollHeight > textArea.offsetHeight && h !== textArea.offsetHeight) {
h = textArea.offsetHeight;
textArea.rows++;
}
textArea.rows++
});
fiddle http://jsfiddle.net/dcdeiv/dsL6g/3/
however I don't want to use an ID or a class, I want that to work for each textarea, so I tryed to use an each function:
<textarea></textarea>
$.fn.growRows = function() {
return this.each(function() {
var textArea = $( this ),
scrollHeight = textArea.scrollTop(),
offsetHeight = textArea.height(),
rows = textArea.attr( rows ),
h = 0;
textArea.keyup(function() {
while ( rows > 1 && scrollHeight < offsetHeight ) {
rows--;
}
while ( scrollHeight > offsetHeight && h !== offsetHeight ) {
h = offsetHeight;
rows++;
}
rows++;
});
});
}
$( 'textarea' ).growRows();
but it does not work anyway.
fiddle http://jsfiddle.net/dcdeiv/BQB4M/

This might not be what you're looking for but check out my fiddle. Code below as well:
$.fn.growRows = function() {
return this.each(function() {
var textArea = $(this);
textArea.on('keyup', function() {
textArea[0].rows = textArea.val().split('\n').length || 1;
});
textArea.trigger('keyup'); //set initial size
});
};
$('textarea').growRows();
Also, in your fiddle, you had a few javascript errors that could prevent you from getting it working. You need to include jQuery as a library in JSFiddle and textArea.attr( rows ) needs to actually be textArea.attr( 'rows' ). Please note that even if you make these changes, your fiddle does not work. When you inc/dec your rows variable, nothing will happen.

If your only concern is about getting all textarea's not depending of classes/ids, it is still possible to do without jquery by using getElementsByTagName('textarea'). Then, to achieve the autoexpanding we need to bind an event listener to each of the textarea's obtained, doing some changes to original code, we get:
HTML:
<textarea></textarea>
<textarea></textarea>
Javascript:
var textArea = document.getElementsByTagName('textarea'); //get all textareas
for (var i = 0; i <= textArea.length-1; i++) { //loop through textareas
textArea[i].addEventListener('input', function () { //binds listener
while (
this.rows > 1 && this.scrollHeight < this.offsetHeight) {
this.rows--;
}
var h = 0;
while (this.scrollHeight > this.offsetHeight && h !== this.offsetHeight) {
h = this.offsetHeight;
this.rows++;
}
this.rows++
});
}
FIDDLE: http://jsfiddle.net/dsL6g/6/

Related

Javascript scroll and validation form

i would like to inform guest that he skip important form section.
That's why i want to change background color div to some else when he scroll and did not checked anyone input or write text to input
I wrote some like this
$(function(){
$(document).scroll(function(){
if($(this).scrollTop() >= $('#questrow1').offset().top - -100) && document.getElementsByClassName("wiztype").checked = false; {
$("#questrow1").addClass('redback');
}
});
});
Without that
&& document.getElementsByClassName("wiztype").checked = false;
Colorize is fine but checking inputs must works.
= will not compare value and rather assign it. Here's updated expression -
$(function() {
$(document).scroll(function() {
if (($(this).scrollTop() >= ($('#questrow1').offset().top - -100)) && !document.getElementsByClassName("wiztype").checked) {
$("#questrow1").addClass('redback');
}
});
});
= false is not a comparison but an assignment. You'll want == (or simply a negation of the checked property since you want false).
However, getElementsByClassName returns a collection of elements, so you'll need to loop over all of them.
Also - -100 is just + 100
$(function(){
$(document).scroll(function(){
var checkboxes = document.getElementsByClassName("wiztype");
var hasChecked = false;
for(var i = 0; i < checkboxes.length; ++i) {
if(checkboxes.item(i).checked) {
hasChecked = true;
break;
}
}
if($(this).scrollTop() >= $('#questrow1').offset().top + 100 && !hasChecked) {
$("#questrow1").addClass('redback');
}
});
});

Auto Increment width of an input tag

I am trying to code an counter.
Here is my JsFiddle
$('.substract-value').click(function(){
val = $('#how-many').val();
if (val == 1)
{ }
else
$('#how-many').val(val-1);
});
$('.add-value').click(function(){
val = $('#how-many').val();
$('#how-many').val(parseInt(val)+1);
});
I want the size of the input tag to auto-increment when the content inside the input tag will become 2digit or 3digit.
is it possible only with css.
I think the best solution in this case would be not to use input tag, instead replace it with span tag. span is an inline element and the width will auto increment based on its content.
As i am moving to span, the jquery will change. and instead of val() we should use text()
Demo fiddle http://jsfiddle.net/ssxx8/11/
You can do something roughly similar to this:
$(function() {
var $howMany = $('#how-many'); // cache that
$('.substract-value').click(function(){
var val = $howMany.val();
if (val == 1) { }
else {
$howMany.val(val-1);
checkSize(val);
}
});
$('.add-value').click(function(){
var val = $('#how-many').val();
$howMany.val(parseInt(val)+1);
checkSize(val);
});
function checkSize(v) {
if ( v > 9 ) {
$howMany.css('width', '80px');
} else if ( v < 9 ) {
$howMany.css('width', '20px');
};
}
});
Try this
$('.substract-value').click(function(){
val = $('#how-many').val();
if (val == 1) { }
else
$('#how-many').val(val-1);
setWidth();
});
$('.add-value').click(function(){
val = $('#how-many').val();
$('#how-many').val(parseInt(val)+1);
setWidth();
});
var oneLetterWidth = 10;
var minCharacters = 2;
function setWidth() {
var len = $("#how-many").val().length;
if (len > minCharacters) {
// increase width
$("#how-many").width(len * oneLetterWidth);
} else {
// restore minimal width;
$("#how-many").width(50);
}
}
DEMO
Try this
$('.substract-value').click(function(){
val = $('#how-many').val();
if (val == 1) { }
else
$('#how-many').val(val-1);
updateWidth();
});
$('.add-value').click(function(){
val = $('#how-many').val();
$('#how-many').val(parseInt(val)+1);
updateWidth();
});
function updateWidth(){
size = $('#how-many').val().length;
size = size*7; // average width of a char is 7px
$('#how-many').css('width',size);
}
JSFIDDLE : http://jsfiddle.net/ssxx8/9/
You need to approach this way:
var obj = $('#how-many');
$('.substract-value').click(function () {
var content = obj.val();
if (content > 1)
obj.val(parseInt(obj.val()) - 1);
obj.css("width", (obj.val().length * 10) + "px");
});
$('.add-value').click(function () {
obj.val(parseInt(obj.val()) + 1);
obj.css("width", (obj.val().length * 10) + "px");
});
Refer LIVE DEMO

Scroll Bar is moving to top when reaching maxlimit instead of stoping right there on textarea

i am using inputTextArea. Actually i want to limit it's max length. I am using function like
<script type="text/javascript">
function limitTextArea(element, limit) {
if (element.value.length > limit) {
element.value = element.value.substring(0, limit);
}
}
</script>
<textarea id="description" name="description"
onkeyup="limitTextArea(this, 1000);"
onkeydown="limitTextArea(this, 1000)">
</textarea>
But what is happening suppose i write a long text in the textarea. A scrollbar is shown in the textarea. But when i reach the maxlimit and then try to write a character then the textarea scrollbar move to top.
I want that once user reach it's max limit then the scrollbar as well as cursor stuck at that position.
Why it is behaving like textarea scrollbar move to top when i try to write something after max limit?
Thanks
Referred:How to impose maxlength on textArea in HTML using JavaScript
window.onload = function() {
var txts = document.getElementsByTagName('TEXTAREA')
for(var i = 0, l = txts.length; i < l; i++) {
if(/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) {
var func = function() {
var len = parseInt(this.getAttribute("maxlength"), 10);
if(this.value.length > len) {
alert('Maximum length exceeded: ' + len);
this.value = this.value.substr(0, len);
return false;
}
}
txts[i].onkeyup = func;
txts[i].onblur = func;
}
}
}
http://viralpatel.net/blogs/2008/12/set-maxlength-of-textarea-input-using-jquery-javascript.html
You can use this also to prevent the user from writing more than you want in a textarea.
Atleast this code prevents my textarea from scrolling to top
jQuery(document).ready(function($) {
$('textarea.max').keyup(function() {
var $textarea = $(this);
var max = 400;
if ($textarea.val().length > max) {
var top = $textarea.scrollTop();
$textarea.val($textarea.val().substr(0, max));
$textarea.scrollTop(top);
}
});
}); //end if ready(fn)
Here is the reference from which i got the idea to use it like this
How to prevent textarea from scrolling to the top when its value changed?
Better Solution:
jQuery(document).ready(function($) {
var max = 400;
$('textarea.max').keypress(function(event) {
if (event.which < 0x20) {
// e.which < 0x20, then it's not a printable character
// e.which === 0 - Not a character
return; // Do nothing
}
if (this.value.length == max) {
event.preventDefault();
} else if (this.value.length > max) {
// Maximum exceeded
this.value = this.value.substring(0, max);
}
}); //end of keypress(fn)
}); //end if ready(fn)
Thanks

Scrolling child div scrolls the window, how do I stop that?

I have a div, with a scroll bar, When it reaches the end, my page starts scrolling. Is there anyway I can stop this behavior ?
You can inactivate the scrolling of the whole page by doing something like this:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
Found the solution.
http://jsbin.com/itajok
This is what I needed.
And this is the code.
http://jsbin.com/itajok/edit#javascript,html
Uses a jQuery Plug-in.
Update due to deprecation notice
From jquery-mousewheel:
The old behavior of adding three arguments (delta, deltaX, and deltaY)
to the event handler is now deprecated and will be removed in later
releases.
Then, event.deltaY must now be used:
var toolbox = $('#toolbox'),
height = toolbox.height(),
scrollHeight = toolbox.get(0).scrollHeight;
toolbox.off("mousewheel").on("mousewheel", function (event) {
var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
return !blockScrolling;
});
Demo
The selected solution is a work of art. Thought it was worthy of a plugin....
$.fn.scrollGuard = function() {
return this
.on( 'wheel', function ( e ) {
var event = e.originalEvent;
var d = event.wheelDelta || -event.detail;
this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
e.preventDefault();
});
};
This has been an ongoing inconvenience for me and this solution is so clean compared to other hacks I've seen. Curious to know how more about how it works and how widely supported it would be, but cheers to Jeevan and whoever originally came up with this. BTW - stackoverflow answer editor needs this!
UPDATE
I believe this is better in that it doesn't try to manipulate the DOM at all, only prevents bubbling conditionally...
$.fn.scrollGuard2 = function() {
return this
.on( 'wheel', function ( e ) {
var $this = $(this);
if (e.originalEvent.deltaY < 0) {
/* scrolling up */
return ($this.scrollTop() > 0);
} else {
/* scrolling down */
return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
}
})
;
};
Works great in chrome and much simpler than other solutions... let me know how it fares elsewhere...
FIDDLE
You could use a mouseover event on the div to disable the body scrollbar and then a mouseout event to activate it again?
E.g. The HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
And then the javascript like so:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
As answered here, most modern browsers now support the overscroll-behavior: none; CSS property, that prevents scroll chaining. And that's it, just one line!
Here's a cross-browser way to do this on the Y axis, it works on desktop and mobile. Tested on OSX and iOS.
var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
var scrollTop = this.scrollTop;
var maxScroll = this.scrollHeight - this.offsetHeight;
var deltaY = event.deltaY;
if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
event.preventDefault();
}
}, {passive:false});
scrollArea.addEventListener("touchstart", function(event) {
this.previousClientY = event.touches[0].clientY;
}, {passive:false});
scrollArea.addEventListener("touchmove", function(event) {
var scrollTop = this.scrollTop;
var maxScroll = this.scrollHeight - this.offsetHeight;
var currentClientY = event.touches[0].clientY;
var deltaY = this.previousClientY - currentClientY;
if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
event.preventDefault();
}
this.previousClientY = currentClientY;
}, {passive:false});
I wrote resolving for this issue
var div;
div = document.getElementsByClassName('selector')[0];
div.addEventListener('mousewheel', function(e) {
if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
e.preventDefault();
div.scrollTop = div.scrollHeight;
} else if (div.scrollTop + e.deltaY <= 0) {
e.preventDefault();
div.scrollTop = 0;
}
}, false);
If I understand your question correctly, then you want to prevent scrolling of the main content when the mouse is over a div (let's say a sidebar). For that, the sidebar may not be a child of the scrolling container of the main content (which was the browser window), to prevent the scroll event from bubbling up to its parent.
This possibly requires some markup changes in the following manner:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
See it's working in this sample fiddle and compare that with this sample fiddle which has a slightly different mouse leave behavior of the sidebar.
See also scroll only one particular div with browser's main scrollbar.
this disables the scrolling on the window if you enter the selector element.
works like charms.
elements = $(".selector");
elements.on('mouseenter', function() {
window.currentScrollTop = $(window).scrollTop();
window.currentScrollLeft = $(window).scrollTop();
$(window).on("scroll.prevent", function() {
$(window).scrollTop(window.currentScrollTop);
$(window).scrollLeft(window.currentScrollLeft);
});
});
elements.on('mouseleave', function() {
$(window).off("scroll.prevent");
});
You can inactivate the scrolling of the whole page by doing something like this but display the scrollbar!
<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
var scrollTop = this.scrollTop;
if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
e.preventDefault();
}
});
Based on ceed's answer, here is a version that allows nesting scroll guarded elements. Only the element the mouse is over will scroll, and it scrolls quite smoothly. This version is also re-entrant. It can be used multiple times on the same element and will correctly remove and reinstall the handlers.
jQuery.fn.scrollGuard = function() {
this
.addClass('scroll-guarding')
.off('.scrollGuard').on('mouseenter.scrollGuard', function() {
var $g = $(this).parent().closest('.scroll-guarding');
$g = $g.length ? $g : $(window);
$g[0].myCst = $g.scrollTop();
$g[0].myCsl = $g.scrollLeft();
$g.off("scroll.prevent").on("scroll.prevent", function() {
$g.scrollTop($g[0].myCst);
$g.scrollLeft($g[0].myCsl);
});
})
.on('mouseleave.scrollGuard', function() {
var $g = $(this).parent().closest('.scroll-guarding');
$g = $g.length ? $g : $(window);
$g.off("scroll.prevent");
});
};
One easy way to use is to add a class, such as scroll-guard, to all the elements in the page that you allow scrolling on. Then use $('.scroll-guard').scrollGuard() to guard them.
If you apply an overflow: hidden style it should go away
edit: actually I read your question wrong, that will only hide the scroll bar but I don't think that's what you are looking for.
I couldn't get any of the answers to work in Chrome and Firefox, so I came up with this amalgamation:
$someElement.on('mousewheel DOMMouseScroll', scrollProtection);
function scrollProtection(event) {
var $this = $(this);
event = event.originalEvent;
var direction = (event.wheelDelta * -1) || (event.detail);
if (direction < 0) {
if ($this.scrollTop() <= 0) {
return false;
}
} else {
if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
return false;
}
}
}

Calculate largest width of a set of elements using jQuery

I have made a quick Jsbin: http://jsbin.com/ujabew/edit#javascript,html,live
What i'm trying to achieve is to find out which is the largest <section> out of the 3 from the link. So what i'd like is to, after the loop runs, is to have var width set to the largest possible number that any of the widths could be.
Code in progress posted in link
Here:
var maxWidth = Math.max.apply( null, $( elems ).map( function () {
return $( this ).outerWidth( true );
}).get() );
Live demo: http://jsfiddle.net/rM4UG/
Fleshing out Marc B's comment, using Math.max():
$(document).ready(function(){
var maxWidth = 0;
$('.content ul li').each(function(){
var itemWidth = $(this).outerWidth(true);
maxWidth = Math.max(maxWidth, itemWidth)
});
});
I believe you want to look into the underscore library. Specifically, the max method
$(document).ready(function(){
var maxWidth = 0;
$('section').each(function(){
w = $(this).outerWidth(true);
if ( w > maxWidth)
maxWidth = w;
});
});
Change the .each() loop to this:
var thisWidth = $(this).outerWidth(true);
if (thisWidth > width) {
width = thisWidth;
}
I have just written a function regarding this. I thought it might help others. (jQuery)
$.fn.largerWidth = function () { //function(p)
// where 'p' can be clientWidth or offsetWidth
// or anything else related to width or height
var s = this,m;
for (var i = 0; i < s.length; i++) {
var w = s[i].offsetWidth; // s[i][p];
(!m || w > m) ? (m = w) : null
}
return m;
}
This was my idea:
$(document).ready(function () {
var elements = $(".content ul li");
var count = elements.length - 1;
var width = [];
elements.each(function (n) {
width.push($(this).outerWidth(true));
if (count == n) {
width = Math.max.apply(Math, width);
}
});
});
I added the count of the number of elements and then runs the Math.max to get the largest number when each loop is done.

Categories

Resources