So I'm working on a pre-existing site and I'm trying to add in a point where the code sends out some data. When it gets to my .post() I get the following error:
too much recursion
http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js
Line 16
Here's the flow:
Some link text has the following onclick handler:
<a class="lucida_12pxBlueLH16" onclick="changeCipherAdmin(6); return false;" href="#">Keyword: SLEEP</a>
function changeCipherAdmin(num) {
tempHTML = '';
tempHTML += '<select id="select_cipher' + num + '" name="select_cipher' + num + '" class="select_tanbg" onchange="updateKeyFieldsAdmin(this.value,' + num + ',1);">';
tempHTML += ' <option id="option' + num + '_admin1" value="1">Additive</option>';
tempHTML += ' <option id="option' + num + '_admin2" value="2">Affine</option>';
tempHTML += ' <option id="option' + num + '_admin3" value="3">Caesar</option>';
tempHTML += ' <option id="option' + num + '_admin4" value="4">Keyword</option>';
tempHTML += ' <option id="option' + num + '_admin5" value="5">Multiplicative</option>';
tempHTML += ' <option id="option' + num + '_admin6" value="6">Vigenère</option>';
tempHTML += '</select>';
document.getElementById('admin_cipher' + num).innerHTML = tempHTML;
document.getElementById('option' + num + '_admin' + ciphers[num]).selected = true;
updateKeyFieldsAdmin(ciphers[num], num, 0);
}
Based on that it runs the following function
function updateKeyFieldsAdmin(cipherNum, selectNum, resetNum) {
//tempHTML=''+possible_ciphers[cipherNum]+'';
//document.getElementById('admin_cipher'+selectNum).innerHTML=tempHTML;
if (resetNum == 0) {
keyA = keysA[selectNum];
keyB = keysB[selectNum];
}
if (cipherNum == 1) {
//0-25
//change letter to number, add encryption key (two characters?), reduce mod 26
//additive: use a:number
if (resetNum == 1) {
keyA = "";
keyB = "";
}
tempHTML = '<strong class="helvetica11pxTanB">Key (0-25)</strong> <input type="text" id="key_a' + selectNum + '" maxlength="2" class="form_field11px" style="width:19px; height:12px; text-align:right; color:#000000;" value="' + keyA + '" onkeyup="checkKeysAdmin(1,' + selectNum + '); return false;" autocapitalize="off" autocorrect="off" />';
}
else if (cipherNum == 6) {
//vigenere: use a:word--26 letters or less
if (resetNum == 1) {
keyA = "";
keyB = "";
}
tempHTML = '<strong class="helvetica11pxTanB">Keyword</strong> <input type="text" id="key_a' + selectNum + '" maxlength="26" class="form_field11px" style="width:99px; height:12px; text-align:right; color:#000000;" value="' + keyA + '" onkeyup="checkKeysAdmin(event,6,' + selectNum + '); return false;" autocapitalize="off" autocorrect="off" />';
}
document.getElementById('admin_key' + selectNum).innerHTML = tempHTML;
if ((cipherNum == 2 || cipherNum == 5) && !isNaN(keyA) && keyA != "") {
//update select field
if (cipherNum == 2) {
$('#key_a' + selectNum).val(keyA);
}
else {
for (i = 1; i < odd_nums_prime26.length; i++) {
if (keyA * 1 == odd_nums_prime26[i]) {
document.getElementById('key_a' + selectNum).selectedIndex = i;
document.getElementById('option' + selectNum + '_mult' + i).selected = true;
break;
}
}
}
}
if (resetNum == 1) {
checkKeysAdmin(cipherNum, selectNum);
}
}
Which then calls the below:
function checkKeysAdmin(e, cipherNum, row) {
encrypt_ready = true;
if (encrypt_ready == true) {
//keyA and keyB should already be updated...so:
keysA[row] = keysA;
keysB[row] = keysB;
ciphers[row] = cipherNum;
ciphertext[row] = encryptTextAdmin(plaintext[row], cipherNum);
document.getElementById('cipher' + row).innerHTML = ciphertext[row];
// This is my code where Im trying to send my data out
if (e.keyCode == 13 ) {
alert( 'here2' );
$.post('/challenges/save.php', { action:'updateJokeMessage',
messageId:message_ids[row],
joke:message_text[row],
punchline:plaintext[row],
encryptedPunchline:ciphertext[row],
cipherId:cipherNum,
keyA:keysA[row],
keyB:keysB[row]
});
alert( 'Done' );
}
return;
}
else {
//alert("not ready to encrypt");
document.getElementById('cipher' + row).innerHTML = '';
}
// me trying to stop the recursion
event.stopPropagation();
}
I've tried adding in a call back and putting in event.stopPropagation or returning etc. But can't figure out why. Any thoughts/help would be appreciated.
So it ended up being a var typo:
keysA[row] = keysA;
keysB[row] = keysB;
Which was basically assigning the object to one of it's elements, which caused the recursion when jquery tried to process that.
I strongly suspect that your problem is here:
keysA[row] = keysA;
keysB[row] = keysB;
You're making a circular structure, and jQuery is losing its mind when it's trying to trace its way through the parameter object.
Related
I have this javascript function here, the routeno variable will pass a Chinese value
routeno: 粤ZX123港
function getRouteLegNoList()
{
var data = "host="+lphost
+ "&user="+user
+ "&gateway="+gateway
+ "&routedate="+routedate.value
+ "&routeno="+routeno.value
+ "&action=GETROUTELEGNOLIST";
alert(lphost+'|'+user+'|'+gateway+'|'+routedate.value+'|'+routeno.value);
callAjax("../restartAndMoveDeclaration.cgi?"+data, "GET", "",
function(text) {
alert(text);
var html = "<select id=routelegno>";
var count = 0;
var lines = text.split("\n");
for(var i = 0; i < lines.length; i ++)
{
var line = lines[i];
var c;
if(line.indexOf("Data|") == 0) {
count += 1;
c = line.split("|");
html += "<option value=\"" + c[1]
+ "\"";
if(c[1]==origRouteLegNo) {
html += " selected ";
}
html += ">" + c[1] + "</option>";
}
}
html += "</select>";
dvroutelegno.innerHTML = html;
if(count==0){
alert('No Route Legs were found for [' +
gateway + '] [' +
routedate.value + '] [' +
routeno.value + ']');
} else {
if(count==1) {
trroutelegno.style.visibility = 'hidden';
} else {
// More than one, display the select box
trroutelegno.style.visibility = 'visible';
}
}
}
);
}
but when shell script captured the variable it does not read the Chinese character and replaced it as question mark
routeno: ?ZX123?
I've already tried to set different NLS_LANG but encountered the same output
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
NLS_LANG=AMERICAN_AMERICA.AL32UTF8
I have a
TextBox (id=txtFilterValue),
Add button (id=btnAdd) and
Table (id=queryTable)
once user enter the value in text box, they may press the enter key. So when they press the enter key, it should call the Add Button which is already defined in jquery.
This is What I tried
Jquery Code
//Preventing ENTER Key
$('#form1').on('keyup keypress', function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode === 13) {
//$('input[name = btnAdd]').click();
$("#btnAdd").trigger('click');
e.preventDefault();
return false;
}
});
The above code to prevent the enter key and it will call the Add Button.
As I thought it's working. But it's calling two times and the values are adding 2 times. It shouldn't add two times.
when I click the Add button directly, it's entering the record only one to my table.
This is my button Add code
//Filter Query Add to TABLE and TEXTBOX
$("#btnAdd").click(function () {
var selectedField = $("#FilterField option:selected").text();
var operator = $("#ddlOperator :selected").val();
var filterValue = $("#txtFilterValue").val();
var query;
var textFilterRecord = $("#txtFilterRecord").val();
//values seperated by COMMA
var arrayTxtConditionValue = filterValue.split(',');
if (operator == 'equalTo') {
if ($("#txtFilterRecord").val().length == 0) {
//put the single quotation( ' ) in between values
var filterCommaValue = '';
for (var i = 0; i < arrayTxtConditionValue.length; i++) {
if (i == 0) {
filterCommaValue = filterCommaValue + "'" + arrayTxtConditionValue[i] + "'";
}
else {
filterCommaValue = filterCommaValue + ",'" + arrayTxtConditionValue[i] + "'";
}
}
query = selectedField + ' IN(' + filterCommaValue + ') ';
$("#txtFilterRecord").val($("#txtFilterRecord").val() + query);
$("#queryTable > tbody:last-child").append('<tr><td class="FieldNameID">' + selectedField + '</td><td class="OperatorID"> IN(' + filterCommaValue + ')</td></tr>');
}
else {
var filterCommaValue = '';
for (var i = 0; i < arrayTxtConditionValue.length; i++) {
if (i == 0) {
filterCommaValue = filterCommaValue + "'" + arrayTxtConditionValue[i] + "'";
}
else {
filterCommaValue = filterCommaValue + ",'" + arrayTxtConditionValue[i] + "'";
}
}
var radioButton = $('input[name=group]:checked').val();
query = radioButton + ' ' + selectedField + ' IN(' + filterCommaValue + ') ';
$("#txtFilterRecord").val($("#txtFilterRecord").val() + query);
$('#queryTable > tbody:last-child').append('<tr><td class="FieldNameID">' + radioButton + ' ' + selectedField + '</td><td class="OperatorID"> IN(' + filterCommaValue + ')</td></tr>');
}
}
});
$('#form1').on('keyup keypress', function (e) {
// ...
Here you are listening for two events with the same callback. That means whenever one of them occur the callback will be called. Since they're both related to the key events (both are pretty much the same), the callback will be called twice.
So just remove one of them like this:
$('#form1').on('keypress', function (e) {
// ...
Basically, I'm using JavaScript to dynamically generate a form that allows from multiple entries within a single submission. Here's the code I'm using for that:
function addEvent()
{
var ni = document.getElementById('myDiv');
var numi = document.getElementById('theValue');
var num = (document.getElementById('theValue').value - 1) + 2;
numi.value = num;
var divIdName = 'my' + num + 'Div';
var newdiv = document.createElement('div');
newdiv.setAttribute('id', divIdName);
newdiv.innerHTML = '<table id="style" style="background-color: #ffffff;"><tr><td colspan="2">Entry ' + num + '<hr \/><\/td><\/tr><tr><td><label>Item 1: <\/td><td><input name="item1_' + num + '" value="" type="text" id="item1" \/><\/label><\/td><\/tr><tr><td><label>Item 2: <\/td><td><input name="item2_' + num + '" type="text" id="item2" \/><\/label><\/td><\/tr><tr><td><label>Item 3: <\/td><td><input type="text" name="item3_' + num + '" id="item3" \/><\/label><\/td><\/tr><tr><td><label>Item 4: <\/td><td><select name="item4_' + num + '" id="item4"><option value="---">---<\/option><option value="opt_1">1<\/option><option value="opt_2">2<\/option><option value="opt_3">3<\/option><option value="opt_4">4<\/option><\/select><\/label><\/td><\/tr><\/table>';
ni.appendChild(newdiv);
}
This works just fine, generating the entries fields I need. Using console in-browser, I've even verified all the names are correct. The issue is that I need to then take the selections and generate output. I've tried several methods, but everything resulted in null values.
function generateVideo()
{
var entries = document.getElementById('theValue').value;
var item1 = {};
var item2 = {};
var item3 = {};
var item4 = {};
for(i = 1; i <= entries; i++)
{
item1[i - 1] = document.getElementById('item1_' + i);
item2[i - 1] = document.getElementById('item2_' + i);
item3[i - 1] = document.getElementById('item3_' + i);
item4[i - 1] = document.getElementById('item4_' + i);
}
var code = 'Copy code and paste it into Notepad<br \/>"Save as" filename.html<br \/><textarea name="" cols="45" rows="34">header template\n';
for(i = 0; i < entries; i++)
{
if(i != (entries - 1))
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"],\n';
}
else
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"]\n';
}
}
code = code + 'footer template<\/textarea>';
var result = document.getElementById("result");
result.innerHTML = code;
}
The output is as follows:
Copy code and paste it into Notepad<br />"Save as" CourseName_Unit_Chapter.html<br /><textarea name="" cols="45" rows="34">header template
["null", "null", "null", "null"]
footer template</textarea>
Now, certain fields can be null, that's fine (I'll do form validation after I get it working), but I'm getting null for every field regardless of what is entered.
I, originally, had the .value on the getElementByIds, but that only results in the script not running when the entries variable is greater than 0 (default), which is why I tried removing them.
function generateVideo()
{
var entries = document.getElementById('theValue').value;
var item1 = {};
var item2 = {};
var item3 = {};
var item4 = {};
for(i = 1; i <= entries; i++)
{
item1[i - 1] = document.getElementById('item1_' + i).value;
item2[i - 1] = document.getElementById('item2_' + i).value;
item3[i - 1] = document.getElementById('item3_' + i).value;
item4[i - 1] = document.getElementById('item4_' + i).value;
}
var code = 'Copy code and paste it into Notepad<br \/>"Save as" filename.html<br \/><textarea name="" cols="45" rows="34">header template\n';
for(i = 0; i < entries; i++)
{
if(i != (entries - 1))
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"],\n';
}
else
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"]\n';
}
}
code = code + 'footer template<\/textarea>';
var result = document.getElementById("result");
result.innerHTML = code;
}
I've also tried variations of multidimensional arrays, instead of four arrays, but got the same results.
The output, as indicated by the removal of the .value on the getElementByIds, is good. Basically, there is something wrong with my attempts to populate the arrays using the dynamically generated forms.
I suspect that the issue with the declaration of the element ID, but I'm not sure how else to declare it. This style of scripting is not my norm. ^^'
Anyone have any ideas on how to fix the for loop to generate the array?
replace all occurences of
itemN[i]
with
itemN[i].value
if that doesnt work add
console.log( itemN[i] )
and see what it outputs
experts! I have some problems with two dynamic dropdown menus. Here is my fiddle:
Demo
Here is my jQuery and Javascript:
var num_rows = 1;
var num_tests = 1;
var myArray = new Array();
function firstSelection(id) {
var index = id.replace( /\D+/g, '');
var item = $("#select" + index + "").val();
var object = item.replace(/\d/g, "");
var table = $("#test");
if(object == 'analize') {
table.find('tr').each(function(i) {
$("#selectTest" + i + "").empty();
$("#selectTest" + i + "").append("<option value=''/><option value='analizetest1'>AnalizeTest1</option><option value='analizetest2'>AnalizeTest2</option><option value='analizetest3'>AnalizeTest3</option>");
});
}
else if(object == 'create') {
table.find('tr').each(function(i) {
$("#selectTest" + i + "").empty();
$("#selectTest" + i + "").append("<option value=''/><option value='createtest1'>CreateTest1</option><option value='createtest2'>CreateTest2</option>");
});
}
else if(object == 'draft') {
table.find('tr').each(function(i) {
$("#selectTest" + i + "").empty();
$("#selectTest" + i + "").append("<option value=''/><option value='drafttest1'>DraftTest1</option><option value='drafttest2'>DraftTest2</option><option value='drafttest3'>DraftTest3</option>");
});
}
else {
table.find('tr').each(function(i) {
$("#selectTest" + i + "").empty();
});
}
}
$(document).ready(function() {
$("#addObjekt").click(function() {
num_rows = $("#objectTable tr").length;
$("#objectTable").append("<tr id='objectRow" + num_rows + "'><td><input class='text' type='text' id='pbz" + num_rows + "' name='pbz" + num_rows + "' value='" + num_rows + "' readonly/></td><td><select id='select" + num_rows + "'><option/><option value='analize" + num_rows + "'>Analize</option><option value='create" + num_rows + "'>Create</option><option value='draft" + num_rows + "'>Draft</option></select></td><td><button type='button' id='selectButton" + num_rows + "' onclick='firstSelection(id);'>Select</button></td><td><button type='button' id='copy" + num_rows + "'>Copy</button></td></tr>");
});
$("#deleteObjekt").click(function() {
var row = $("#objectTable tr").length - 1;
if(row > 1) {
$("#objectRow" + row + "").remove();
return false;
}
else {
// do nothing
}
});
$("#addTest").click(function() {
num_tests = $("#test tr").length;
$("#test").append("<tr id='testRow" + num_tests + "'><td><input class='text' type='text' id='zaehler" + num_tests + "' name='zaehler" + num_tests + "' value='" + num_rows + "-" + num_tests + "' readonly/></td><td><select id='selectTest" + num_tests + "'></select></td><td><button type='button' id='parameter" + num_tests + "'>Parameter</button></td><td></td><td></td></tr>");
});
$("#deleteTest").click(function() {
var test_row = $("#test tr").length - 1;
if(test_row > 1) {
$("#testRow" + test_row + "").remove();
return false;
}
else {
// do nothing
}
});
});
function showMatrix() {
num_rows = $("#objectTable tr").length - 1;
num_tests = $("#test tr").length;
for(var x = 0; x < num_rows; x++) {
myArray[x] = new Array();
myArray[x] = $("#select" + (x + 1) + "").val();
for(var z = 0; z < num_tests; z++) {
myArray[x][z] = firstSelection.item + firstSelection.index;
}
}
alert(myArray);
}
The problems are:
The second dropdown list doesn't get populated based on the selection of the first one yet. For some reason it is not working properly in the fiddle, it is running fine in the environment I use.
How can I change the code, so that I see the second dropdown populated also for the new rows added later, not only for the already existing ones?
Last, I want the rows on the right side to be "attached" only to the single object they are linked to on the left side. Which means that selecting an object on the left side should only display its respective tests. I am not fluent in Javascript, I started with the idea of creating a two-dimensional array, but got stuck.
I know this might be a bit too much to ask, but I would deeply appreciate any advice. Thanks!
Method showMatrix can not access local variables of method firstSelection like that.
To make a variable in function showMatrix visible in function firstSelection, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling firstSelection from showMatrix.
The third option is probably the best options, globals are not recommended to work with and even though project properties are very optimal it's maybe not the best fit for your case.
Just make sure that firstSelection returns the variables you need from it and access them within showMatrix. You can also make it return an object which holds the values of the variables that you need.
function firstSelection(id) {
var index = id.replace( /\D+/g, '');
var item = $("#select" + index + "").val();
// ... some code
var vars = {index: index, item: item};
return vars;
Ensure that the function firstSelection is in the scope. Move that function inside
$(document).ready(function()
{
//...
});;
It will work if your code is correct.
I suggest this because I got the following error while running your code:
Uncaught ReferenceError: firstSelection is not defined
Ok Try this. It is working. Before that edit the HTML and JS like the following:
HTML:
<table id="panel" class="panel">
<tr>
<td>
<table id="objectTable" class="objectTable">
<tr id="initial">
<td width="20px">Number</td>
<td>Object</td>
<td align="right"><button type="button" id="addObjekt" href="#">+</button><button type="button" id="deleteObjekt" href="#">-</button></td>
<td></td>
</tr>
<tr id="objectRow1">
<td><input class="text" type="text" id="pbz1" name="pbz1" value="1" readonly/></td>
<td><select id="select1">
<option/>
<option value="analize1">Analize</option>
<option value="create1">Create</option>
<option value="draft1">Draft</option>
</select></td>
<td><button type="button" id="selectButton1">Select</button></td>
<td><button type="button" id="copy1">Copy</button></td>
</tr>
</table>
</td>
<td>
<table id="test" class="test">
<tr>
<td>Subnumber</td>
<td>Test <button type="button" id="addTest" href="#">+</button><button type="button" id="deleteTest" href="#">-</button></td>
<td></td>
<td></td>
</tr>
<tr id="testRow1">
<td><input class="text" type="text" id="zaehler1" name="zaehler1" value="1-1" readonly/></td>
<td><select id="selectTest1">
</select></td>
<td><button type="button" id="parameter1">Parameter</button></td>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
JS:
var num_rows = 1;
var num_tests = 1;
var myArray = new Array();
var globalIndex = 0;
var globalObject = '';
$(document).ready(function() {
$('#selectButton1').click(function(){
firstSelection(this.id);
});
function firstSelection(id) {
var index = id.replace( /\D+/g, '');
var item = $("#select" + index + "").val();
var object = item.replace(/\d/g, "");
globalIndex = index;
globalObject = object;
var vars = {index: index, item: item};
//var table = $("#test");
document.getElementById("zaehler1").value = index + '-1';
if(object == 'analize') {
$("#selectTest1").empty();
$("#selectTest1").append("<option value=''/><option value='analizetest1'>AnalizeTest1</option><option value='analizetest2'>AnalizeTest2</option><option value='analizetest3'>AnalizeTest3</option>");
}
else if(object == 'create') {
$("#selectTest1").empty();
$("#selectTest1").append("<option value=''/><option value='createtest1'>CreateTest1</option><option value='createtest2'>CreateTest2</option>");
}
else if(object == 'draft') {
$("#selectTest1").empty();
$("#selectTest1").append("<option value=''/><option value='drafttest1'>DraftTest1</option><option value='drafttest2'>DraftTest2</option><option value='drafttest3'>DraftTest3</option>");
}
else {
$("#selectTest1").empty();
}
return vars;
}
$("#addObjekt").click(function() {
num_rows = $("#objectTable tr").length;
$("#objectTable").append("<tr id='objectRow" + num_rows + "'><td><input class='text' type='text' id='pbz" + num_rows + "' name='pbz" + num_rows + "' value='" + num_rows + "' readonly/></td><td><select id='select" + num_rows + "'><option/><option value='analize" + num_rows + "'>Analize</option><option value='create" + num_rows + "'>Create</option><option value='draft" + num_rows + "'>Draft</option></select></td><td><button type='button' id='selectButton" + num_rows + "' onclick='firstSelection(id);'>Select</button></td><td><button type='button' id='copy" + num_rows + "'>Copy</button></td></tr>");
});
$("#deleteObjekt").click(function() {
var row = $("#objectTable tr").length - 1;
if(row > 1) {
$("#objectRow" + row + "").remove();
return false;
}
else {
// do nothing
}
});
$("#addTest").click(function() {
num_tests = $("#test tr").length;
$("#test").append("<tr id='testRow" + num_tests + "'><td><input class='text' type='text' id='zaehler" + num_tests + "' name='zaehler" + num_tests + "' value='" + globalIndex + "-" + num_tests + "' readonly/></td><td><select id='selectTest" + num_tests + "'></select></td><td><button type='button' id='parameter" + num_tests + "'>Parameter</button></td><td></td><td></td></tr>");
$("#test").find('tr').each(function(i) {
if(globalObject == 'analize') {
$("#selectTest" + i + "").append("<option value=''/><option value='analizetest1'>AnalizeTest1</option><option value='analizetest2'>AnalizeTest2</option><option value='analizetest3'>AnalizeTest3</option>");
}
else if(globalObject == 'create') {
$("#selectTest" + i + "").append("<option value=''/><option value='createtest1'>CreateTest1</option><option value='createtest2'>CreateTest2</option>");
}
else if(globalObject == 'draft') {
$("#selectTest" + i + "").append("<option value=''/><option value='drafttest1'>DraftTest1</option><option value='drafttest2'>DraftTest2</option><option value='drafttest3'>DraftTest3</option>");
}
else {
//nothing
}
});
});
$("#deleteTest").click(function() {
var test_row = $("#test tr").length - 1;
if(test_row > 1) {
$("#testRow" + test_row + "").remove();
return false;
}
else {
// do nothing
}
});
});
function showMatrix() {
num_rows = $("#objectTable tr").length - 1;
num_tests = $("#test tr").length;
for(var x = 0; x < num_rows; x++) {
myArray[x] = new Array();
myArray[x] = $("#select" + (x + 1) + "").val();
for(var z = 0; z < num_tests; z++) {
myArray[x][z] = firstSelection.item + firstSelection.index;
}
}
alert(myArray);
}
Demo
I have a small problem with a function that calls itself from within itself.
The following function pretty much works, as can be seen here ...
http://jsfiddle.net/justinayles/frPZ8/2/
but if you click a square and after that click the back link and go back and forth a few times, eventually it will slow down and ultimately crash with a 'too much recursion error'. I cant really see any other way to achieve what I am trying to do here ? I kind of understand what the problem is, but was wondering if there was another way to do this, maybe rename the function? im trying to avoid duplication too much code. any help appreciated, thanks.
var questionArray = [];
var cardArray = [];
// extend array for IE !!
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun /*, thisp*/) {
var len = this.length >>> 0;
if (typeof fun != "function")
throw new TypeError();
var res = [];
var thisp = arguments[1];
for (var i = 0; i < len; i++) {
if (i in this) {
var val = this[i]; // in case fun mutates this
if (fun.call(thisp, val, i, this))
res.push(val);
}
}
return res;
};
}
function setupPage(whichpage, questionArray) {
var html = "",
backlink = "",
activestep = "",
undertext = "",
qArray = questionArray;
switch(whichpage) {
case '1':
var pg1 = questionArray.filter(function (el) {
return el.page == "step1";
});
$.each(pg1, function(key,val) {
html += '<a class="quest ' + val.star + '" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a>';
});
backlink = "0";
activestep = "1";
undertext = "";
break;
case '2a':
var pg2a = questionArray.filter(function (el) {
return el.page == "step2a";
});
$.each(pg2a, function(key,val) {
html += '<a class="quest ' + val.star + '" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a>';
});
backlink = "1";
activestep = "2";
undertext = "";
break;
case '2b':
var pg2b = questionArray.filter(function (el) {
return el.page == "step2b";
});
$.each(pg2b, function(key,val) {
html += '<a class="quest ' + val.star + '" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a>';
});
backlink = "1";
activestep = "2";
undertext = "";
break;
case '3a':
var pg3a = cardArray.filter(function (el) {
return el.page == "3a";
});
$.each(pg3a, function(key,val) {
html += '<div class="cardblock"><a class="wrapcard" href="' + val.path + '" target="' + val.target + '"><img border="0" alt="' + val.title + '" src="http://dummyimage.com/178x112/000/00ffd5.png" alt="placeholder image" /></a>';
html += '<a class="cardtitle" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a></div>';
});
backlink = "2a";
activestep = "3";
undertext = "Choose a programme";
break;
case '3b':
var pg3b = cardArray.filter(function (el) {
return el.page == "3b";
});
$.each(pg3b, function(key,val) {
html += '<div class="cardblock"><a class="wrapcard" href="' + val.path + '" target="' + val.target + '"><img border="0" alt="' + val.title + '" src="http://dummyimage.com/178x112/000/00ffd5.png" /></a>';
html += '<a class="cardtitle" href="' + val.path + '" target="' + val.target + '">' + val.title + '</a></div>';
});
backlink = "2b";
activestep = "3";
undertext = "Choose a programme";
break;
}
// make the dom changes..
if ( backlink !== "0" ) {
html += '<a id="backlink" href="' + backlink + '"><< back a step</a>';
}
$('.wrapdots span').removeClass('active');
$('.wrapdots span.step'+activestep).addClass('active');
$('p.underdots').html(undertext);
$('#wrapper').fadeOut('fast', function() {
$(this).html(html).fadeIn('fast');
});
$('#wrapper').on('click', '#backlink', function(e) {
e = e || window.event;
e.target = e.target || e.srcElement;
var goto = e.target.href;
goto = goto.split('/');
goto = goto.pop();
switch(goto) {
case '1':
e.preventDefault();
setupPage('1', qArray);
break;
case '2a':
e.preventDefault();
setupPage('2a', qArray);
break;
case '2b':
e.preventDefault();
setupPage('2b', qArray);
break;
case '3a':
e.preventDefault();
setupPage('3a', qArray);
break;
case '3b':
e.preventDefault();
setupPage('3b', qArray);
break;
}
});
$('#wrapper').on('click', '.quest', function(e) {
e = e || window.event;
e.target = e.target || e.srcElement;
var goto = e.target.href;
goto = goto.split('/');
goto = goto.pop();
switch(goto) {
case '1':
e.preventDefault();
setupPage('1', qArray);
break;
case '2a':
e.preventDefault();
setupPage('2a', qArray);
break;
case '2b':
e.preventDefault();
setupPage('2b', qArray);
break;
case '3a':
e.preventDefault();
setupPage('3a', qArray);
break;
case '3b':
e.preventDefault();
setupPage('3b', qArray);
break;
default:
e.preventDefault();
break;
}
});
}
// doc ready...
$(function() {
// do questions
$('question').each(function() {
var qobj = {
title : $(this).attr('qTitle'),
star : $(this).attr('class'),
path : $(this).attr('path'),
page : $(this).attr('page'),
target : $(this).attr('target')
}
questionArray.push(qobj);
});
// got the questions, lets now setup page 1 !!
setupPage('1', questionArray);
// do cards
$('card').each(function() {
var cobj = {
title : $(this).attr('cTitle'),
path : $(this).attr('path'),
img : $(this).attr('img'),
page : $(this).attr('page'),
target : $(this).attr('target')
}
cardArray.push(cobj);
});
});
This isn't a case you'd want to use recursion. Every click binds more events to the DOM but never releases them. I'd recommend pulling your $('#wrapper').on('click'... code out of your setupPage function that way your click events are only bound once.
Recursive functions are best used for situations like scanning list trees where you don't know how deep they go. FYI, Code Academy has section on recursion that I found helpful.