large form or javascript locks up browser - javascript

I have a html form with about 105 fields, which includes some javascript activity:
1) expand/collapse sections
http://www.adipalaz.com/experiments/jquery/nested_accordion.html
2) date picker
3) AutoSave functionality
<script type="text/javascript">
function counter() {
email = document.getElementById("applicant-email").value;
if (email.match(emregex) || cd == cdLength){
if (email.match(emregex)){
document.getElementById("countdown").innerHTML = left + cd-- + right + button;
if (cd < 0){
formAutosave();
}
}else{
document.getElementById("countdown").innerHTML = "Enter your email address for AutoSave <a onclick=\"javascript:alert(\'Please enter an email address\');\"><span><b></b>Save Now</span></a>";
}
}
};
function formAutosave() {
window.clearInterval(timer);
email = document.getElementById("applicant-email").value;
if (email.match(emregex)){
document.getElementById("countdown").innerHTML = \'<a><span><b></b>Saving ...</span></a>\';
var values = "";
for (var i = 0; i < userForm.length; i++) {
if (userForm.elements[i].value != null) {
if (userForm.elements[i].name == "form[autosave]") {
userForm.elements[i].value = "TRUE";
}
if (userForm.elements[i].id == "'.$fieldId.'"){
userForm.elements[i].value = email;
}
if (userForm.elements[i].id != "finished"){
values += userForm.elements[i].name + "=" + encodeURI(userForm.elements[i].value) + "&";
}
}
}
values = values.substring(0, values.length - 1);
jQuery.post(
"http://'.$_SERVER['SERVER_NAME'].
$uri.strstr($uri,'?')?'&':'?').'autosave=1&format=raw",
values,
function (submissionId){
if (parseInt(submissionId) > 0){
jQuery("#continue").val(parseInt(submissionId));
}
cd = cdLength;
timer = window.setInterval("counter()", 1000);
}
);
};
};
var userForm = document.getElementById("userForm");
var emregex = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
cdLength = '.self::SAVEINTERVAL.';
var left = \'Automatically saving in \';
var cd = cdLength;
var right = \' seconds or \';
var button = \'<a onclick="javascript: formAutosave();"><span><b></b>Save Now</span></a>\';
jQuery("#applicant-email").val(jQuery("#'.$fieldId.'").val());
var timer = window.setInterval("counter()", 1000);
';
We have recorded 3 testing videos (Chrome, Firefox, IE9), in all of which there is a visible slowdown using dropdowns in the form, even though the user has not used expand/collapse or date picker. SO I'm expecting that we are causing a lock up or memory leak in the auto save routine.
Advice on refactoring would be appreciated.

The comments above are great and I'd recommended following the advice posted by #Adam and #Alex (pass a named function instead). Also, you might try implementing a bit differently (i.e. the Module design pattern or some other best practices). Take a look at this StackOverflow question: https://stackoverflow.com/questions/4840420/recommended-javascript-annotated-source-code-for-learning

Related

How to utilize if function to select which rows of data to consider in Google Sheets?

So, I'm trying to create a script for Google Sheets that sends an e-mail to A*, with the subject B*, and body C*, and that writes "Sent" (or whatever else) on column D*, and checks for that column to know when to jump to the next one or not. So far I got:
function sendMailtest() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet=ss.getSheetByName('Sheet');
var n=sheet.getLastRow();
for (var i = 2; i < n+1 ; i++ )
{
var check = sheet.getRange(i,4);
if (check == "Sent") {
break;
} else {
var emailAddress = sheet.getRange(i,1).getValue();
var subject = sheet.getRange(i,2).getValue();
var message = sheet.getRange(i,3).getValue();
MailApp.sendEmail(emailAddress, subject, message);
check.setValue("Sent");
}
}
}
It actually works perfectly for how simple it is, my only problem is that no matter what I do with the IF statement, it always completely ignores it and sends an email for each row regardless of the information in column D. I've tried using break, continue, both with and without else{} so far, without any success. What am I missing here?
var check = sheet.getRange (i, 4);
Here check is a range, but in
if (check == "Sent")
you are comparing it to text, so the equality is never satisfied.
If you fix the code like this, then everything works well:
function sendMailtest() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet=ss.getSheetByName('Sheet');
var n=sheet.getLastRow();
for (var i = 2; i < n+1 ; i++ )
{
var check = sheet.getRange(i,4).getValue();
if (check != "Sent") {
var emailAddress = sheet.getRange(i,1).getValue();
var subject = sheet.getRange(i,2).getValue();
var message = sheet.getRange(i,3).getValue();
// MailApp.sendEmail(emailAddress, subject, message);
Logger.log(emailAddress + ":" + subject + ":" + message);
sheet.getRange(i,4).setValue("Sent");
}
}
}

JS : press enter and go to the next input

(Sorry if my english is bad)
I try to make a little game where you have to answer question in inputs. When you valid with the key "Enter", next input appear, and a new question in.
It is complicated to explain, so I leave you the test URL : nicolaslorand.com/bac.php
Here is my a part of my code :
var i = 1;
var j = 2;
$('#input'+i).keypress(function(event) {
console.log('input actuel :'+i);
console.log('input suivant :'+j);
if (event.which == 13) {
verification();
console.log("Touche entrée");
}
});
function verification(){
document.getElementById('input'+j).style.display = "block";
var index = $(".inputform").index(this) + 1;
$(".inputform").eq(index).focus();
var recup = document.getElementById('input'+i);
var verif = recup.value.toUpperCase();
var divLettre = document.getElementById('lettre');
var premiereLettre = divLettre.innerText || divLettre.textContent;
if ( verif.charAt( 0 ) === premiereLettre ) {
$("#input"+i).addClass('trueanswer');
i++; j++;
scoreTotal++;
console.log(i);console.log(j);
}
else{
$("#input"+i).addClass('falseanswer');
i++; j++;
console.log(i);console.log(j);
}
With this code, when I press enter, next input appear, but I have to write in the first input so that my answer is verified by the function.
You are using this inside function this refers to window object. i think you should use i instead of this
var index = $(".inputform").index(i) + 1;

run an IF statement once

I have an age value which I'm using as a condition to enter an IF statement. The IF statement populates random values in to a field (this is a childs math game). After the fields are populated the user can enter their answers and then check them using a 'Check Answers' button. Once the 'Check Answers' block is run the IF statement gets ran again(!), which causes the math problems to change - new random values are created.
How can I prevent the IF statement from running after the page has already loaded; causing the values to change each time the 'Check Answers' button is clicked?
Here is is the relevant javascript:
$(document).ready(function () {
var getAge = localStorage.getItem('setAge');
var userResponse = new Array();
var answer = new Array();
if (getAge >= 1 && getAge <= 7) {
var operator = new Array('+', '-');
for (var counter = 0; counter <= 2; counter++) {
var index = Math.round(Math.random());
var1 = Math.floor((Math.random() * 5) + 1);
var2 = Math.floor((Math.random() * 10) + 1);
// these add the values to the mathQuestions.aspx
$('#a' + counter).text(var1);
$('#b' + counter).text(operator[index]);
$('#c' + counter).text(var2);
answer[counter] = eval(var1 + operator[index] + var2);
}
// this stores the users answers in userResponse[]
for (var counter = 0; counter <= 2; counter++) {
$('#d' + counter).change(function () {
for (var counter = 0; counter <= 2; counter++) {
userResponse[counter] = $('#d' + counter).val();
// window.alert("userResponse = " + userResponse[counter]);
}
});
}
// Button3 = 'Check Answers'
$('#Button3').click(function () {
for (var counter = 0; counter <= 2; counter++) {
window.alert('userResponse after checking the answers = ' + userResponse[counter]);
if (answer[counter] != userResponse[counter]) {
$('#span' + counter).val(answer[counter]);
}
}
});
});
I'm still learning all of this so I could have others errors that are contributing to my problem. To my knowledge the root problem is caused by the IF statement running again. Also, in case it's relevant I'm using Visual Studio Express 2012 for Web using some ASP controls (table, buttons, input, etc).
My guess is that the issue is not within the code you've posted, but within your HTML; Based on the code you've posted does contain a click-event, but this could never cause the 'randomize'-part to be ran again.
Could it be that your HTML looks like:
<form>
<button>Check answers</button>
</form>
or
<form>
<input type="submit" value="Check answers">
</form>
Having a button or submit inside a form-attribute results in a 'submit-action' when you hit the button. The result is that you first see the alert-message from the click-event. Next the page is reloaded and the whole document.ready() script will be executed again.
A simple solution could be:
$('#Button3').click(function (event) {
event.preventDefault()
/* ... */
}
This stops the form from submitting.
http://api.jquery.com/event.preventdefault/

Javascript Regex optimization

I have two JQuery/Javascript functions that highlights all string occurences in a web page, and then narrows these occurences one by one when clicking on the next/prev buttons.
Here is the current JS code for the next and previous buttons:
var outputHtmlContent;
var posScroll = 0;
// Trigger on search next occurence's button
$('#nextSearchOutputButton').on("click", function (e) {
e.preventDefault();
var searchString = "Command Name";
$("body").highlight(searchString);
$(".highlight").css({ backgroundColor: "#E0FFFF" });
var regex = /Command Name/g, result, indices = [];
var i = 0;
outputHtmlContent = $("#output").html();
if (posScroll == outputHtmlContent.match(/Command Name/g).length - 1) posScroll = 0;
else
posScroll++;
while ((result = regex.exec(outputHtmlContent))) {
if (posScroll == i) {
var index = result.index;
outputHtmlContent = outputHtmlContent.substring(0, index) + "<span class='highlight'>" + outputHtmlContent.substring(index, index + searchString.length) + "</span>" + outputHtmlContent.substring(index + searchString.length);
$("#output").html(outputHtmlContent);
document.getElementById("commandNumber" + posScroll).scrollIntoView();
return;
}
i++;
}
})
// Trigger on search previous occurence's button
$('#prevSearchOutputButton').on("click", function (e) {
e.preventDefault();
var searchString = "Command Name";
$("body").highlight(searchString);
$(".highlight").css({ backgroundColor: "#E0FFFF" });
var regex = /Command Name/g, result, indices = [];
var i = 0;
outputHtmlContent = $("#output").html();
if (posScroll == 0) posScroll = outputHtmlContent.match(/Command Name/g).length - 1;
else
posScroll--;
while ((result = regex.exec(outputHtmlContent)) && i <= posScroll) {
if (posScroll == i) {
var index = result.index;
outputHtmlContent = outputHtmlContent.substring(0, index) + "<span class='highlight'>" + outputHtmlContent.substring(index, index + searchString.length) + "</span>" + outputHtmlContent.substring(index + searchString.length);
$("#output").html(outputHtmlContent);
document.getElementById("commandNumber" + posScroll).scrollIntoView();
return;
}
i++;
}
})
The two functions work well, but I have a very critical issue concerning the time spent when executing the two functions, this time estimated to 10 seconds for IE when moving from one occurence to an other and is estimated to 4 seconds for FF and chrome.
I googled and found that the Regex performance issue is a classic topic. I found this nice atricle http://infrequently.org/2007/02/regexs-are-slow/.
I would rather remove completely this feature than offering it with such a low quality issue. Yet, I want to stick on it because it is very helpful for my user. Can anyone help improve the Regex performance for my functions ?

keeping a innerhtml value from a javascript after a html form submit

I am using below javascript to collect values from some textboxes,do some calculations and display the result as a innerhtml content
window.onload = function () {
var left = document.getElementById('mem_count');
var right = document.getElementById('siz_single');
var result = document.getElementById("disp_siz");
function check(a, b, elem) {
var txt = '';
if (a === 0 && b === 0) {
}
else if (a !== 0 && b === 0) {
txt = "Enter size of single device in above column"
}
else if(a == 0 && b !== 0){
txt = "Enter Meta member count in above column "
}
else {
var c = 1 +a
txt = "Your meta device size is " + (c*b) +" MB" + " = " + (c*b/1024) +" GB ";
}
disp_siz.innerHTML = txt;
}
mem_count.onkeyup = calc;
siz_single.onkeyup = calc;
function calc() {
var a = parseFloat(mem_count.value) || 0;
var b = parseFloat(siz_single.value) || 0;
check(a,b, this);
}
}
and the output will be display in between the div
<div id="disp_siz"><-----above output will come here----></div>
This div is part of a html form. I am able to keep all my other form values in same field after form submission. But not able to display above output. It just clearing my values. Is there anyway I can echo this javascript variable value to the same field after form submision ?
First Option:
Set it on the serverside.
Second Option:
If the page refreshes, it is like cleaning a whiteboard, you got to start over. If the fields are there, trigger the function to run.
Add calc(); to the end of the onload function.
...
...
function calc() {
var a = parseFloat(mem_count.value) || 0;
var b = parseFloat(siz_single.value) || 0;
check(a,b, this);
}
calc(); //<-- added this to trigger the calculation
}
Another problem:
And you should not reference an element by their id directly. You should use
document.getElementById("disp_siz").innerHTML = txt;
You're referencing a variable (disp-siz) that doesn't exist. Use the variable you created earlier, result.
result.innerHTML = txt;

Categories

Resources