change textbox width based on it's value - javascript

I am trying to change my textbox's width according to textbox's value but it does not seems like working.
Here is my aspx:
<asp:TextBox ID="TxtbSizeOzel" runat="server" CssClass="text-center"></asp:TextBox>$
I create an onKeyUp event for resizing method in codebehind:
TxtbSizeOzel.Attributes.Add("onKeyUp", "Expand(this)");
And lastly my javascript method:
function Expand(obj)
{
if (!obj.savesize) obj.savesize = obj.size;
obj.size = Math.max(obj.savesize, obj.value.length);
}
I don't get any error but it just doesn't working.

UPDATED WITH CODE EXPLANATION:
here you go, the input will always be as long as its characters, whether you type, remove or give it a value before running the script: Demo here
//this is a plugin snippet (or function) to check if the element has
//horizontal scrollbar
$.fn.hasHorizontalScrollBar = function() {
if (this[0].clientWidth < this[0].scrollWidth) {
return true
} else {
return false
}
}
//the end of plugin
var originalWidth=$('.txt').width(); //we store the original width
//(the width of the input at the page load) in a variable to use it as a
//measurement in order to not let the input get smaller than this size
//this function checks the width of `.txt` (the input) to see if it has
//horizontal scrollbar or not, if it does then expands the width of the input to
//the scroll size, else it checks to see if the width is added to the
//original width, if so, removes one character (depending on the font size it'll
//change - here it is 7 px)
function changeWidth(){
if($('.txt').hasHorizontalScrollBar()){
$('.txt').width(document.getElementsByClassName('txt')[0].scrollWidth);
}
else if(originalWidth<$('.txt').width()){
$('.txt').width($('.txt').width()-7);
}
};
//end of the function
changeWidth(); //run the function at page load, to give the input a size as wide as its
// character's length
$('.txt').keydown(changeWidth); //assign the function to the keydown event of the input
//so whenever a character is added or removed the function will run again

Try using .width() property of JQuery. It supports the get and set operations for width manipulation of controls or elements in your HTML.
And you can try this if you want to go with JavaScript :
document.getElementById("yourControlId").style.width = "300px";
Hope this helps.

Related

Scrolling first occurence to top position inside div

After I clicked on link, which navigate to another page I have to scroll the first (the earliest) alarm occurrence (which is marked as a red text) at the top of "tbody" div. Each row have id='tab_content' and a table data class = 'td_list_row_center'. When alarm occurs, tds are changing color from black to red and a name class = 'td_list_row_center font-red".
I've tried to handle red occurrence and if it was found, scroll at the top inside "tbody" div. The second row should be with black font (non-alarm)
<script>
function scrollToFirstRedAlarmOccurence(red_occurrence) {
$('tbody').animate({
scrollTop: red_occurrence.offset().top
}, 2000);
}
var red_occurrence = document.getElementsByClassName("td_list_row_center font-red");
if(red_occurrence)
scrollToFirstRedAlarmOccurence(red_occurrence);
else
null
</script>
After clicking on the link and table shows, nothing happens (like script doesn't work). I expect it to scroll to the first red occurrence from a huge dataset. After I scroll the table up I would see another later red occurrencies. Below actual and expected results as pics:
[Actual res.] -> https://ibb.co/1zn4ty9
[Expected res.] -> https://ibb.co/Jy6FrL6
Parameters for 'getElementsByClassName' are incorrect. Use them as following.
<script>
function scrollToFirstRedAlarmOccurence(red_occurrence) {
// make jQuery object for first element
$('tbody').animate({
scrollTop: $(red_occurrence[0]).offset().top,
}, 2000);
}
setTimeout(() => {
// select "font-red" classed elements
var red_occurrence = document.getElementsByClassName("font-red"); // you can use jQuery selector too
if(red_occurrence.length) { // check for array length
scrollToFirstRedAlarmOccurence(red_occurrence);
}
}, 1000); // wait for DOM to render
</script>
Basically, you can debug your code to check if they are getting correct values. I have made some correction which would work for your case.

How to prevent jQuery function from being initialized more than once (Drupal behaviours involved)?

My goal:
To enable a user to load a template (which contains preset jquery, html and css) to allow them to click one of five dots to trigger an animation on an image.
My issue:
When I load more than one of these templates to my page, my animation value (margin-left in this case) applies double the number of times that there is an instance of this template on the page. If my template is loaded twice, the margin-left sets to a value, jumps to the correct value, then back before finally setting on the correct value. This means that if I was to add 10 instances to the page, it would take 20 times as long to get that last value.
Before testing I thought that my code would be ok, as due to the context and .once()function, I believed it would only fire once.
All html and CSS are functioning as expected, it's just the jQuery is an issue.
My code:
(function ($) {
Drupal.behaviors.click_the_dots = {
attach: function (context, settings) {
$('.wrapper_class', context).once('click_the_dots', function () {
// Prevent other buttons from being clickable until the
// previous animation is complete.
var animationDone = false;
function clickDots(dotNum) {
$('.dot_class_num_' + dotNum).click(function () {
// Setup context, to keep animations to the container in which the dots exist.
var findElem = $(this).parent().parent().parent().find('.inner_wrapper');
// Prevent other buttons from being clickable until the
// previous animation is complete.
if (animationDone === false) {
animationDone = true;
// Find the visible image.
var animatingImage = findElem.find('.dot_class_num_active');
// Find the image that will be animating in.
var thisImageAnim = findElem.find('.dot_num_img_src_' + dotNum);
if (animatingImage.is(thisImageAnim)) {
// Can't click on the same dot again, until another dot is clicked.
animationDone = false;
return;
} else {
// Animate out the already visible image.
// Remove the visible image class as it's going to be hidden.
findElem.find('.dot_class_num_active').removeClass('dot_class_num_active');
// Animate it to hide to the left.
animatingImage.animate({
marginLeft: '-10%',
opacity: 0
}, 280, 'easeInOutQuad');
// Animate in the image associated with the dot click
// Set the image css to be further right in order to animate to left at 0.
thisImageAnim.css('margin-left', '10%').delay(200).animate({
marginLeft: '0',
opacity: 1
}, 300, 'easeInOutQuad', function () {
// Set the now visible image to the visible image.
thisImageAnim.addClass('dot_class_num_active');
}).promise().done(function () {
// Now allow the other dots to be clicked.
animationDone = false;
});
}
}
});
}
// For each of the five dots.
for (i = 1; i <= 5; i++) {
clickDots(i);
}
});}};})(jQuery);
I would like to add as many instances of this jQuery as required, but only have the function be looped through once. I'm not sure how to check if this has already been done, or how to ensure that once it has been done at least once, it shouldn't happen again.
:)
I figured out what my issue was - I was attaching the behaviour to the wrapper class of my content, i.e. $('.wrapper_class', context).once... - this meant that it attached the behaviour to each instance of this class, of which there could be many.
What I did was attach the behaviour to a higher parent element, of which I knew there would be only one instance. It attaches just once and the code works perfectly.
Thanks to the commenters above who helped me realise my issue!

hide() vs hide("slow")

I need to hide a div and, with this code it works fine:
var idObj = $(this).attr('key');
var valH = $(this).attr('hideval');
var valS = $(this).attr('showval');
if ($('div[name='+idObj+']').attr('isdisplay') == 'no') {
$('div[name='+idObj+']').children().show("slow");
$('div[name='+idObj+']').attr('isdisplay','yes');
var divTitle = $('div[name='+idObj+']').children().first();
var divArrow = $(this).children().first();
//.attr('src',prefixImg+valH);
//divTitle.show();
//divArrow.show();
$(this).children().first().attr('src',prefixImg+valH);
} else {
var divTitle = $('div[name='+idObj+']').children().first();
var divArrow = $('div[name='+idObj+']').children().last();
//.attr('src',prefixImg+valS);
$('div[name='+idObj+']').children().hide();
$('div[name='+idObj+']').attr('isdisplay','no');
divTitle.show();
divArrow.show();
$(this).children().first().attr('src',prefixImg+valS);
}
My div is hidden and the Title and arrows to reopen the div are shown. But if I try to use hide("slow") the divTitle and divArrow don't appear when my div is closed. Same problem using hide(1000).
Is there a difference between hide with and without "slow" parameter?
thanks,
Andrea
From the official site
The matched elements will be hidden immediately, with no animation. This is roughly equivalent to calling .css('display', 'none'), except that the value of the display property is saved in jQuery's data cache so that display can later be restored to its initial value. If an element has a display value of inline, then is hidden and shown, it will once again be displayed inline.
When a duration is provided, .hide() becomes an animation method. The .hide() method animates the width, height, and opacity of the matched elements simultaneously. When these properties reach 0, the display style property is set to none to ensure that the element no longer affects the layout of the page.
So, if hide is used without delay, it hides immediately without animating - eg, poof.
If it's used with time, it becomes animated, so it disapears over time.
For your problems, it is difficult to judge without the corresponding html code.
$(element).hide() hides an element instantly, where $(element).hide('slow') will animate its disappearance (slowly).
It looks like (though I'm not sure) you want to do stuff after the animation is finished. In that case, do something like this:
var that = this; // here to preserve scope for the block below
$('div[name='+idObj+']').children().hide('slow', function() {
// This stuff happens after the hide animation is done.
$('div[name='+idObj+']').attr('isdisplay','no');
divTitle.show();
divArrow.show();
$(that).children().first().attr('src',prefixImg+valS); // <= note "that" instead of "this"
});
According to the jQuery documentation
The strings 'fast' and 'slow' can be supplied to indicate durations of
200 and 600 milliseconds, respectively.
Also duration in milliseconds can be supplied to it..

Detect mouse cursor type

I want JavaScript code to detect the mouse cursor type.
For example when the cursor hovers in <textarea> it changes from default to text.
How would I go about detecting this?
You could do this, but its not pretty, and will probably be quite slow depending on how many elements you have on your page.
$('*').mouseenter(function(){
var currentCursor = $(this).css('cursor') ;
//do what you want here, i.e.
console.log( currentCursor );
});
You can detect the cursor type using JavaScript
like
<input id="sample_text" name="one" type="text" value="Sample Text" />
and the JavaScript code should look something like this
$('input[id=sample_text]').click( function() {
alert("test");
var ctl = document.getElementById('sample_text');
var startPos = ctl.selectionStart;
var endPos = ctl.selectionEnd;
alert(startPos + ", " + endPos);
});
you can also look at this Jsfiddle for Js Cursor Detection
the above is the Jquery code written , you can also use the Vanilla JS for that you just need to change it to
<input id="sample_text" name="one" type="text" value="Sample Text" onclick="detect_cursor()" />
and the JavaScript should look something like this
function detect_cursor() {
alert("test");
var ctl = document.getElementById('sample_text');
var startPos = ctl.selectionStart;
var endPos = ctl.selectionEnd;
alert(startPos + ", " + endPos);
};
I have a nice jQuery Extension perfect for this type of thing at this gist:
https://gist.github.com/2206057
To use it just do something like:
$("#eleID").cursor(); // will return current cursor state for that element
$("#eleID").cursor("pointer"); // will change ele cursor to whatever is ""
$("#eleID").cursor("clear"); // will change ele cursor to default
$("#eleID").cursor("ishover"); // will return boolean of if mouse is over element or not
$("#eleID").cursor("position"); // will return cursor's current position in "relation" to element
also
$.cursor("wait") // will change document cursor to whatever is ""
$.cursor($("#eleID"), "wait"); // same as $("#eleID").cursor("wait");
$.cursor("position") // will return current cursor position
should also mention, if you submit multiple elements like $("#eleID1, .elementsWiththisClass") for "position" and "isHover" then it will return an Array containing objects like:
var poses = $("#eleID1, .elementsWiththisClass").cursor("position") // will equal
poses[0] = {
ele: e.fn.e.init[1], // the jquery element
x: XXX, // where XXX is the cursors current position in relation to element
y: XXX
}
poses[1] = { // ...and so on and so forth for each element
I think you can read the cursor css property just like you can set it, but you have to do this from a specific element because AFAIK there's no way to just read the cursor type from the window or document object. Following this logic, to get the current cursor type you would have to find the current element the mouse is over and read its cursor css. However, you'd constantly have to check to see if the cursor changed, which is slow and error prone (As a rule you should almost always try to try to put your code in an event handler to react to something instead of constantly checking if its happened yet and putting your code in that function its more logical, efficient, robust, and clear.)
But the idea of detecting the cursor type still fascinates me, and if anyone knows how I'd love to hear about it. :D
As an alternate solution, rather than reading the cursor type, why don't you just set an event handler for when it enters an element that would change it? This would be a lot less error prone and probably more direct, because I don't think you care so much about the cursor, but if the mouse has entered a specific element.
$("#textbox").mouseover( function() {
//I know the cursor has changed because it is now in a textbox
});
As suggested here, using getComputedStyle worked for me.
const onMouseOver = function (e) {
var cursor = getComputedStyle(e.target).cursor;
console.log({ cursor });
};
document.addEventListener("mouseover", onMouseOver, false);
Although this does not help detect the exact cursor type when cursor is set to auto, we can at least use it when cursor is set to something other than auto.

Jquery function called from $(document).ready takes too long - IE pops up "stop running script" dialog

I have the following script to mimic "freezepane" functionality in html, like in excel, where the right side and the header are both scrolled when the user scrolls the results table.
fnAdjustTable=function(){
var colCount=$('#firstTr>td').length; //get total number of column
var m=0;
var n=0;
var brow='mozilla';
jQuery.each(jQuery.browser, function(i, val) {
if(val==true){
brow=i.toString();
}
});
$('.tableHeader').each(function(i){
if(m<colCount){
if(brow=='mozilla'){
$('#firstTd').css("width",$('.tableFirstCol').innerWidth());//for adjusting first td
$(this).css('width',$('#table_div td:eq('+m+')').innerWidth());//for assigning width to table Header div
}
else if(brow=='msie'){
$('#firstTd').css("width",$('.tableFirstCol').width());
$(this).css('width',$('#table_div td:eq('+m+')').width());//In IE there is difference of 2 px
}
}
m++;
});
$('.tableFirstCol').each(function(i){
if(brow=='mozilla'){
$(this).css('height',$('#table_div td:eq('+colCount*n+')').outerHeight()-1);//for providing height using scrollable table column height
}else if(brow=='msie'){
$(this).css('height',$('#table_div td:eq('+colCount*n+')').innerHeight());
}else{
$(this).css('height',$('#table_div td:eq('+colCount*n+')').height());
}
n++;
});
}
fnScroll=function(){
$('#divHeader').scrollLeft($('#table_div').scrollLeft());
$('#firstcol').scrollTop($('#table_div').scrollTop());
}
The problem is that when iterating through the "tableFirstCol" tds, the error to stop running the script pops up. Is there some more efficient way to do this?
Essentially the script is resizing each top header and side pane to match the width in the first row/column. If I run my report with a large date range (the side header), the script pops up, usually when there are about more than 30 side header rows.
Any help appreciated!
You need to cache your selectors:
var tableDiv = $('#table_div'),
divHeader = $('#divHeader'),
firstcol = $('#firstcol'),
tableFirstCol = $('.tableFirstCol'),
tds = $('td', tableDiv);
You can use for your column selectors .eq(n).
Don't use $(this).css("height", n) when this.style.height = n; is easier and faster.
This:
$('.tableHeader').each(function(i){
if(m<colCount){
/* ... */
}
m++;
});
should be:
$('.tableHeader').each(function(i){
if(i<colCount){
/* ... */
}
});
and I'm not entirely sure you would even need the i<colCount check (but I'd have to see the HTML).
The browser sniffing is probably not necessary. Try applying a reset stylesheet and a valid doctype or use HTML5Boilerplate.
If you HAVE to browser sniff: you could just use:
if($.browser.mozilla){
/* ... */
}
else if ($.browser.msie){
/* ... */
}
else{
/* ... */
}
You could also condense that code down quite a lot. Look up the DRY principle.
Also, as for setting the height of the tableFirstCol, couldn't you just set the height of the row instead?
You could generate the HTML with id tags for each column and row. Then just select by the name instead of using the complicated selectors.
I would say that $('#table_div td:eq('+colCount*n+')') is a complicated selector, while $('#row1') is much easier.
Also - I believe what you are doing for a browser check will not work. The code you have iterates through all properties for the detected browser and sets the brow value to the last one. Instead of the loop you have, use something like $.browser.webkit to check for webkit and $.browser.msie to check for IE. As your code is now, I think you will always be executing the else case. See here for more on the jQuery browser object: http://api.jquery.com/jQuery.browser/

Categories