I've read all the posts here about textareas - and, yes, I too feel that it's been beat-to-death... but I've got a situation which I can't find a post about and it's driven me crazy for 5 days now.
Situation:
Multiple (hundreds of) textareas with a normal state of display:none which become visible as needed.
I save work in process via a database... and re-open the form to continue entering data. (yes, there's code to change the display state if the textareas have data in them - but that's not relevant to the situation.
I currently have a very good widget for expanding my textareas AS I ENTER the data - my problem is that when I re-open the form the textareas go back to their initial height.
I've attempted creating a function which processes ALL textareas when the form loads by triggering the keyup event in all of the textareas - but it doesn't make them expand... however, if I simply click into the field and then use an arrow key they open right up. Unfortunately this is NOT an option... like I said HUNDREDS of textareas.
Here's the code I've got for the keyup event / trigger:
$("textarea").each(function() {
$(this).keyup(function() {
var target = $(this).attr("id");
var tElement = document.getElementById(target);
GrowUP(tElement);
});
});
$("textarea").trigger('keyup');
and the code for my expansion of textareas:
function GrowUP(oTextArea){
var nMaxChars = 2000;
var nTextLength = oTextArea.value.length;
setTextAreaHeightWidth(oTextArea);
if (nTextLength >= nMaxChars){
oTextArea.value = oTextArea.value.substring(0, nMaxChars);
return;
}
}
function setTextAreaHeightWidth(oTextArea){
var nTA5Height = 20;
var nTextLength = oTextArea.value.length;
var sTextAreaType = oTextArea.className;
var nHeight;
var nWidth;
if (sTextAreaType.indexOf("long") >= 0){
nHeight = nTA5Height;
}
// setting default height for the text area
oTextArea.style.height = nHeight + "px";
if (nTextLength > 0 && oTextArea.scrollHeight >= nHeight){
oTextArea.style.height = oTextArea.scrollHeight + "px";
if (navigator.userAgent.indexOf("Firefox") > 0){
oTextArea.style.height = oTextArea.scrollHeight + 20 +"px";
}
}
}
I'm open to any suggestions.
OK - update:
I've found a way to fool JSFiddle into having the data already entered in the field... Just select the 2nd checkbox to get it to show the textarea.
The textarea opens in the initial height - which I need to be the EXPANDED height (and it SHOULD if the code I wrote actually worked!)
P.S. In JSFIDDLE, under "Frameworks & Extension" you have to make sure it says "No wrap - in " ... it's been automatically changing this to "On DOM ready" which doesn't work! Here's the link: http://jsfiddle.net/MitchinThailand/fqcppux8/6/
For a quick and simple fix, instead of triggering the keyup event in your afterOnLoad() function, trigger it after the switch statement in your Summary(obj) function.
Here is a working fiddle: https://jsfiddle.net/uwzo25fs/1/
In general, just trigger the event(s) that modify element heights AFTER you have stopped hiding the corresponding element(s).
Related
Photos of Problem [Please refer to this if my below explanation is confusing)
http://imgur.com/a/t2nkD
I'm attempting to get values (answers) from a page and inject those values (answers) into text-areas on the same page. So far this script is able to do exactly that, however even though the correct values (answers) are entered into the text-area, checking the answer results in the page telling me its incorrect.
However, if I type, let's say a 'space' in each text-area after all the correct values (answers) are injected and then re-check the answers the answer returns correct.
Additionally, physically clicking into the text-area and pressing enter results in it being incorrect, however clicking enter in the same text-area a second time then changes the answer to correct.
I'm not very experienced with jquery, or javascript in fact this is the first time I've used jquery.
However, some possible problems that came to my mind were:
The page uses some other way other than html form-validation(?) to check values entered in the text-area
The text-area does not get updated until the user clicks in the text-area and types something into the box
2a. I've attempted to use .focus, .sendkeys and keypress events to simulate the user typing in the box. (didn't work)
Eventually, I intend to make it so that it automatically submits all answers, which shouldn't be too difficult.
So I guess my main question is, how do I update the text-area's value even though the text-area's values have already been changed by
$( txtArea ).eq(h).val(ansTrim);.
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse)
{
if( request.message === "clicked_browser_action" )
{
//Amount of text-area elements on page (found by class)
var n = $(
'.ember-view.ember-text-area.question-answer-textarea.min-width-text-area'
).length;
for (var i = n; i >= 0; i--)
//click "Show Answer" for the amount of text-area elements there are
{
//The page requires you click Show Answer twice to confirm that you
//want to see the answer
$( ".ember-view.question-answer-show-button" ).eq(i).click();
$( ".ember-view.question-answer-show-button" ).eq(i).click();
for (var h = 0; h <= n; h++)\
{
//save all elements with the class
var txtArea = $(
".ember-view.ember-text-area.question-answer-textarea.min-width-text-area"
);
//after answer is revealed stores the answer's text in firstAnswer
var firstAnswer = $( ".question-answer" ).eq(h).text();
//Orange check button stored in submitBTN for later functionality
var submitBTN = $(".ember-view.question-answer-check-button")
//Originally I thought that the answers weren't going through because
//the string saved in firstAnswer had an additional space
//in front and on the end
var ansTrim = $.trim(firstAnswer);
//store keypress event in var press
var press = jQuery.Event("keypress");
press.ctrlKey = false;
press.which = 32;
console.log(ansTrim);
//Fill each text area with the respective answer
$( txtArea ).eq(h).val(ansTrim);
/*
$(submitBTN).click(function() {
$(txtArea).change();
});
*/
//Above is my attempt at updating the textboxes with the values
//in them (didn't work)
}
}
}
}
);
I cannot figure out why my javascript doesn't work.
//Update Progress Bar
$('#photoUpload-name').blur(function () {
var validName = $('#photoUpload-name').val();
if (validName > 1) {
$(function () {
$(".progress-bar").css("width", "50%");
});
}
});
I know my project is set up correctly because $(".progress-bar").css("width", "50%"); works outside the function.
After the user, in this case, fills out their name and the input loses focus, I want it to check that there was at least 2 characters entered (validName > 1) then if there is, to update the progress bar.
I've tried different variations of this, using focusout and it still doesn't work.
To check lenght you need:
$('#photoUpload-name').val().length;
Because $('#photoUpload-name').val() just get the value.
DEMO
I needed a jQuery function to fix my div when the page is scrolled.
I found this:
var fixed = false;
var topTrigger = $('#sticker').offset().top;
$(document).scroll(function() {
if( $(this).scrollTop() >= topTrigger ) {
if( !fixed ) {
fixed = true;
$('#sticker').css({'position':'fixed', 'top':'0'});
}
} else {
if( fixed ) {
fixed = false;
$('#sticker').css({'position':'relative'});
}
}
});
Now, since I'm not a super beginner with jQuery, I tried to skim it and understand it. The only things I don't understand are the things related to the var:fixed. I tried to delete the var and the if statement related to that and the function works perfectly.
My question : why is that variable there, what does it mean, what feature does it add to the entire function?
Why should I keep it there instead of deleting everything related to that variable?
The scroll event will be fired multiple times as the user scrolls. If you keep on changing the DOM attributes, then the performance of the site may slow down.
To avoid applying the style multiple times, they are having a flag called fixed. So once the user has scrolled a particular height, they will trigger change the DOM to be fixed. Later they need not again change the CSS style.
Only if the user scrolls back less than the threshold they need to change the style again.
I want to add a toolbar button before the firefox search container in my addon. But it is completely clearing my navigation bar.
I suspect the offending code is due to an empty array or something but i cant be certain.
//insert before search container
if(navBar && navBar.currentSet.indexOf("mybutton-id")== -1 )//navBar exist and our button doesnt
{
var arrayCurrentSet= navBar.currentSet.split(',');
var arrayFinalSet= [];//empty at first
if(arrayCurrentSet.indexOf("search-container") != -1)//if search-container exists in current set
{
// check item by item in current set
var i= null;
while(i=arrayCurrentSet.shift() != undefined)
{
if(i == "search-container")//"search-container" found !!
{
/*insert our button after it but only if our button does not already exist*/
if(arrayFinalSet.indexOf("mybutton-id") == -1) arrayFinalSet.push("mybutton-id");
}
arrayFinalSet.push(i);
dump("arrayFinalSet "+ i);
}
}
else //damn search-container doesnt exist
{
arrayFinalSet= arrayCurrentSet;
arrayFinalSet.push("mybutton-id");//add our button to the end of whatever is available in nav bar
}
//set new navBar
navBar.currentSet= arrayFinalSet.join(',');
}
The full code is available
https://builder.addons.mozilla.org/addon/1052494/latest/
http://jsfiddle.net/CQ4wA/
I'm not too sure why the navigation bar has been removed, but I think it would be better to approach this from a different angle. Rather than messing around with an array of strings, try using DOM methods instead.
e.g.
var sC=navBar.querySelector("#search-container");
navBar.insertBefore(btn, sC);
The code you have here seems to work - but the toolbar needs to find your button somehow. Your current code doesn't even insert the button into the document, meaning that the toolbar has no chance to find it by its ID. It should be in the toolbar palette palette however, the palette also determines which buttons the user can choose from when customizing the toolbar. So you probably want to do something like this first:
var toolbox = navBar.toolbox;
toolbox.palette.appendChild(btn);
You might also want to simplify your code:
var arrayCurrentSet = navBar.currentSet.split(',');
var insertionPoint = arrayCurrentSet.indexOf("search-container");
if (insertionPoint >= 0)
arrayCurrentSet.splice(insertionPoint, 0, "mybutton-id");
else
arrayCurrentSet.push("mybutton-id");
navBar.currentSet = arrayCurrentSet.join(',');
And finally, you probably want to make the browser remember the current button set, it doesn't happen automatically:
document.persist(navBar.id, "currentset");
Note that the button that will be inserted into the toolbar is not the same as the button you added to the palette - the toolbar code clones the button, with one copy being left in the palette. So event listeners added via addEventListener will sadly be lost. It is better to use a command attribute and insert a <command> element into the document that you will attach your listener to.
Note: in XUL you usually want the command and not the click event - unless you are really interested in mouse clicks only and want to ignore the button being triggered by keyboard or other means.
My problem is a bit off the cuff here, so I'll try to explain this best I can.
I have a text area, having css of #object{overflow:hidden;resize:none;}. I am trying to prevent it from spawning scroll bar while also resizing itself. This textarea is synced with an external script's console meaning it updates. By default however, it will stay at the top unless you highlight text, dragging off to the bottom of the element. This would be the only way to scroll down other than with arrow keys, naturally.
Programmatically, is there any way to keep the text area down to the bottom upon updating? It would be nice to have it auto-scroll to accommodate its use case.
You can do it by javascript. Set the scrollTop property of text area with scrollHeight property like below:
document.getElementById("textarea").scrollTop = document.getElementById("textarea").scrollHeight
By using jQuery, you can find out when the content of the textarea changes using:
$("#object").change(function() {
scrollToBottom();
});
And scroll to the bottom using:
function scrollToBottom() {
$('#object').scrollTop($('#object')[0].scrollHeight);
}
Scroll code taken from jquerybyexample.blogspot.com.
Using Javascript
var textarea = document.getElementById('textarea_id');
textarea.scrollTop = textarea.scrollHeight;
Using Jquery
$('#textarea_id').scrollTop($('#textarea_id')[0].scrollHeight);
Generic JQuery Plugin
Here a generic jquery plugin for scrollBottom of any element:
$.fn.scrollBottom = function() {
return $(this).scrollTop($(this)[0].scrollHeight);
};
usage:
$("#logfile").val( $("#logfile").val() + "this is new line test\n" ).scrollBottom();
function checkTextareaHeight(){
var textarea = document.getElementById("yourTextArea");
if(textarea.selectionStart == textarea.selectionEnd) {
textarea.scrollTop = textarea.scrollHeight;
}
}
Call this function every time when the contents of the textarea are changed. If you cannot edit the external influence, periodically activate this function using setInterval.