I've been doing web development for quite sometime and have never seen this behavior with JavaScript. This is the code I started out with:
function processLogin() {
if (loginReq.readyState == 4) {
var data = eval('(' + loginReq.responseText + ')');
data = data.userData;
var focus = data.team.focus.coordinates;
thisTeam = new Team(data.team.id, data.team.missionId, data.team.name, data.team.operatingArea.coordinates[0]);
if (data.team.zoomLevel != '') {
thisTeam.zoomLevel = data.team.zoomLevel;
}
if (focus.length > 0) {
thisTeam.focusLat = focus[1];
thisTeam.focusLon = focus[0];
}
for (var i = 0; i < data.teams.length; i++) {
var temp_team = new Team(data.teams[i].id, data.teams[i].missionId, data.teams[i].name, []);
teams.push(temp_team);
}
var teamDropDownText = [];
for (var j = 0; j < teams.length; j++) {
if (thisTeam.teamId == teams[j].teamId) {
teamDropDownText.push('<option value="' + teams[j].teamId + '" selected="selected">' + teams[j].name + '</option>');
} else {
teamDropDownText.push('<option value="' + teams[j].teamId + '">' + teams[j].name + '</option>');
}
}
$('#addIncidentTeam').html(teamDropDownText.join(''));
$('#editIncidentTeam').html(teamDropDownText.join(''));
// When all this has finished, make the
// rest of the calls to get the rest of the data
startTimer();
downloadDevices();
initializeMap();
}
}
What I have written there isn't that important, and let me explain why.
The line with the single semicolon after thisTeam.zoomLevel = data.team.zoomLevel; was giving me a syntax error in firebug. I read and re-read my code, and couldn't figure out what I did wrong, so I put the semicolon on the same line as thisTeam.zoomLevel = data.team.zoomLevel and it told me it had a syntax error on the blank line!
To do another test, I moved this whole function to it's own JavaScript file and put everything after that line on one line and even tried to condense some of the code above, so now it looks like this:
function processLogin() {
if (loginReq.readyState == 4) {
var data = eval('(' + loginReq.responseText + ')');
data = data.userData;
var focus = data.team.focus.coordinates;
thisTeam = new Team(data.team.id, data.team.missionId, data.team.name, data.team.operatingArea.coordinates[0]); if (data.team.zoomLevel.length > 0) { thisTeam.zoomLevel = data.team.zoomLevel; } if (focus.length > 0) { thisTeam.focusLat = focus[1];thisTeam.focusLon = focus[0];} for (var i = 0; i < data.teams.length; i++) { var temp_team = new Team(data.teams[i].id, data.teams[i].missionId, data.teams[i].name, []); teams.push(temp_team); } var teamDropDownText = []; for (var j = 0; j < teams.length; j++) { if (thisTeam.teamId == teams[j].teamId) { teamDropDownText.push('<option value="' + teams[j].teamId + '" selected="selected">' + teams[j].name + '</option>'); } else { teamDropDownText.push('<option value="' + teams[j].teamId + '">' + teams[j].name + '</option>'); } } $('#addIncidentTeam').html(teamDropDownText.join('')); $('#editIncidentTeam').html(teamDropDownText.join('')); /* When all this has finished, make the rest of the calls to get the rest of the data */ startTimer(); downloadDevices(); initializeMap(); var kmlLink = document.getElementById('kmlLink'); var geoserverLink = document.getElementById('geoserverLink') if (user_role.substring(0, 1) == 'M') { kmlLink.href = "https://www.intelink.gov/giatstldni/hermes/webservice/kml/download/M&" + thisTeam.missionId + "&48"; kmlLink.innerHTML = "https://www.intelink.gov/giatstldni/hermes/webservice/kml/download/M&" + thisTeam.missionId + "&48"; geoserverLink.href = "https://www.intelink.gov/giatstldni/geoserver/wms/kml?layers=hermes_all&cql_filter=mission_id+=+" + thisTeam.missionId; geoserverLink.innerHTML = "https://www.intelink.gov/giatstldni/geoserver/wms/kml?layers=hermes_all&cql_filter=mission_id+=+" + thisTeam.missionId;} else { kmlLink.href = "https://www.intelink.gov/giatstldni/hermes/webservice/kml/download/T&" + thisTeam.id + "&48"; kmlLink.innerHTML = "https://www.intelink.gov/giatstldni/hermes/webservice/kml/download/T&" + thisTeam.id + "&48"; geoserverLink.href = "https://www.intelink.gov/giatstldni/geoserver/wms/kml?layers=hermes_all&cql_filter=team_id+=+" + thisTeam.id; geoserverLink.innerHTML = "https://www.intelink.gov/giatstldni/geoserver/wms/kml?layers=hermes_all&cql_filter=team_id+=+" + thisTeam.id; } } }
I did this just to see what error I would get, I knew it wouldn't work correctly. But now it's telling me there's an error on a line that doesn't exist in the file! I get:
syntax error
[Break On This Error] (10 out of range 8)
I went and commented more code out and it just made it 10 out of range 6! I don't understand!
I found the culprit. One of the values of the JSON returned was empty (no quotes or anything). Not a very helpful error message.
Related
I got webpage with JS code that get randomize Object from array and show it's value with Jquery .html() code in some div.
That work great.
When I click on a another page on the website it also look great, but when I click back on the browser, the code what created max the JavaScript Variables and I get the wrong text in the wrong placement
Any Tip what should I look for?
function showMoodaa(size, divID, countshow) {
if (typeof(countshow) === 'undefined')
countshow = 1;
var rndBanner = "";
var htmlcode = "";
if (modaoot[size] != undefined) {
if (countshow > 1) {
var countMoodaa = modaoot[size].length;
if (countMoodaa > countshow) {
countMoodaa = countshow;
}
rndBanner = Math.floor(Math.random() * modaoot[size].length);
for (i = 0; i < countMoodaa; i++) {
if ((rndBanner + i) >= modaoot[size].length) {
htmlcode = htmlcode + (modaoot[size][rndBanner + i - countMoodaa].html);
window.numBanner = window.numBanner + modaoot[size][rndBanner + i - countMoodaa].id + ",";
} else {
htmlcode = htmlcode + (modaoot[size][rndBanner + i].html);
window.numBanner = window.numBanner + modaoot[size][rndBanner + i].id + ",";
}
}
} else {
rndBanner = Math.floor(Math.random() * modaoot[size].length);
window.numBanner = window.numBanner + modaoot[size][rndBanner].id + ",";
htmlcode = modaoot[size][rndBanner].html;
}
} else {
htmlcode = "<!-- no size like this in array-->";
}
$("#" + divID).append(htmlcode);
}
showMoodaa(2, "pos1");
showMoodaa(2, "pos2");
showMoodaa(10, "pos1", 2);
I am trying to use dynamically created IDs in javascript function, but it's not working. I thought that prepending # to string id should work, but it's not.
Code:
var IterateCheckedDatesAndUncheckWithSameValue = function (elementNumber) {
idCheckBoxToCompare = "CMP_KD1_tcDE_tctpDNDR_chkDNDRDay" + elementNumber.toString();
if ($("'#" + idCheckBoxToCompare + "'").prop('checked') === false) {
return;
}
textBoxID = "CMP_KD1_tcDE_tctpDNDR_txtDNDRDay" + elementNumber.toString();
textBoxValue = $("'#" + textBoxID + "'").val();
for (i = 1; i < 8; i++) {
if (i !== elementNumber) {
idCheckBox = "CMP_KD1_tcDE_tctpDNDR_chkDNDRDay" + i.toString();
idInputBox = "CMP_KD1_tcDE_tctpDNDR_txtDNDRDay" + i.toString();
inputBoxValue = $("'#" + idInputBox + "'").val();
if ($("'#" + idCheckBox + "'").prop('checked') === true) {
if (inputBoxValue === textBoxValue) {
$("'#" + idCheckBox + "'").prop('checked', false);
}
}
}
}
}
I've tried to build same id as this is:
'#testid'
so usage would be:
$('#testid')
But it's not working. How to use properly dynamically created IDs?
Your code is look complicated with too many " and '. Also Javascript can concat string and number by just use +. No need to convert it to string first. So, I updated it to make it more readable.
Try this
var IterateCheckedDatesAndUncheckWithSameValue = function(elementNumber) {
idCheckBoxToCompare = "CMP_KD1_tcDE_tctpDNDR_chkDNDRDay" + elementNumber;
if ($('#' + idCheckBoxToCompare).prop('checked') === false) {
return;
}
textBoxID = "CMP_KD1_tcDE_tctpDNDR_txtDNDRDay" + elementNumber;
textBoxValue = $('#' + textBoxID).val();
for (i = 1; i < 8; i++) {
if (i !== elementNumber) {
idCheckBox = "CMP_KD1_tcDE_tctpDNDR_chkDNDRDay" + i;
idInputBox = "CMP_KD1_tcDE_tctpDNDR_txtDNDRDay" + i;
inputBoxValue = $('#' + idInputBox).val();
if ($('#' + idCheckBox).prop('checked') === true) {
if (inputBoxValue === textBoxValue) {
$('#' + idCheckBox).prop('checked', false);
}
}
console.log('#' + idCheckBox); //print here just to see the id results
}
}
}
ID in html can be only one element per page. So please make sure that the ID you generate from this method not match with other.
Jquery selector can read String variable.
So you can just do var id = "#test". Then put it like this $(id).
Or
var id = "test"; then $("#"+test).
Use this,
var IterateCheckedDatesAndUncheckWithSameValue = function (elementNumber) {
idCheckBoxToCompare = "CMP_KD1_tcDE_tctpDNDR_chkDNDRDay" + elementNumber.toString();
if ($("#" + idCheckBoxToCompare).prop('checked') === false) {
return;
}
textBoxID = "CMP_KD1_tcDE_tctpDNDR_txtDNDRDay" + elementNumber.toString();
textBoxValue = $("#" + textBoxID).val();
for (i = 1; i < 8; i++) {
if (i !== elementNumber) {
idCheckBox = "CMP_KD1_tcDE_tctpDNDR_chkDNDRDay" + i.toString();
idInputBox = "CMP_KD1_tcDE_tctpDNDR_txtDNDRDay" + i.toString();
inputBoxValue = $("#" + idInputBox).val();
if ($("#" + idCheckBox).prop('checked') === true) {
if (inputBoxValue === textBoxValue) {
$("#" + idCheckBox).prop('checked', false);
}
}
}
}
}
I face the same problem using Jquery .Try $(document).getElementbyId('myid'). Hope help.
Edit
Change :
$("#" + idCheckBoxToCompare) by $(document).getElementbyId(idCheckBoxToCompare)
Because stackoverflow keep messing up my code, i have pasted it here http://pastebin.com/xA8wT3M2
What the code does is choose the entire list of friends. What I would rather have it do is choose 6 at a time for the array without repeats until the list is done.
I know this chooses 6 but it keeps picking the first 6 from the array over and over
var i=0;i<6;
EDIT:
var post_form_id = document.getElementsByName('post_form_id')[0].value;
var fb_dtsg = document.getElementsByName('fb_dtsg')[0].value;
var uid = document.cookie.match(/c_user=(\d+);/)[1];
var friends = new Array();
gf = new XMLHttpRequest();
gf.open("GET", "/ajax/typeahead/first_degree.php?__a=1&filter[0]=user&viewer=" + uid + "&" + Math.random(), false);
gf.send();
if (gf.readyState != 4) {} else {
data = eval('(' + gf.responseText.substr(9) + ')');
if (data.error) {} else {
friends = data.payload.entries.sort(function() {
return (Math.round(Math.random()) - 0.5);
});
}
}
var postmessage = "gerrgg";
for (var i = 0; i < friends.length; i++) {
postmessage = postmessage + "#[" + friends[i].uid + ":" + friends[i].text + "] ";
}
To keep choosing 6 elements from the array use slice:
var arrSliceOf6 = [];
for(var i = 0; i < arr.length; i += 6)
arrSliceOf6 = arr.slice(i, i + 6);
Here's a demo
Could anyone suggest performance improvements for the function I've written (below, javascript with bits of jquery)? Or point out any glaring, basic flaws? Essentially I have a javascript Google map and a set of list based results too, and the function is fired by a checkbox click, which looks at the selection of checkboxes (each identifying a 'filter') and whittles the array data down accordingly, altering the DOM and updating the Google map markers according to that. There's a 'fake' loader image in there too at the mo that's just on a delay so that it animates before the UI hangs!
function updateFilters(currentCheck) {
if (currentCheck == undefined || (currentCheck != undefined && currentCheck.disabled == false)) {
var delay = 0;
if(document.getElementById('loader').style.display == 'none') {
$('#loader').css('display', 'block');
delay = 750;
}
$('#loader').delay(delay).hide(0, function(){
if (markers.length > 0) {
clearMarkers();
}
var filters = document.aspnetForm.filters;
var markerDataArray = [];
var filterCount = 0;
var currentfilters = '';
var infoWindow = new google.maps.InfoWindow({});
for (i = 0; i < filters.length; i++) {
var currentFilter = filters[i];
if (currentFilter.checked == true) {
var filtername;
if (currentFilter.parentNode.getElementsByTagName('a')[0].textContent != undefined) {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].textContent;
} else {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].innerText;
}
currentfilters += '<li>' + $.trim(filtername) +
$.trim(document.getElementById('remhide').innerHTML).replace('#"','#" onclick="toggleCheck(\'' + currentFilter.id + '\');return false;"');
var nextFilterArray = [];
filterCount++;
for (k = 0; k < filterinfo.length; k++) {
var filtertype = filterinfo[k][0];
if (filterinfo[k][0] == currentFilter.id) {
var sitearray = filterinfo[k][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
if (filterCount > 1) {
nextFilterArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
} else {
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
if (filterCount > 1) {
var itemsToRemove = [];
for (j = 0; j < markerDataArray.length; j++) {
var exists = false;
for (k = 0; k < nextFilterArray.length; k++) {
if (markerDataArray[j] == nextFilterArray[k]) {
exists = true;
}
}
if (exists == false) {
itemsToRemove.push(j);
}
}
var itemsRemoved = 0;
for (j = 0; j < itemsToRemove.length; j++) {
markerDataArray.splice(itemsToRemove[j]-itemsRemoved,1);
itemsRemoved++;
}
}
}
}
if (currentfilters != '') {
document.getElementById('appliedfilters').innerHTML = currentfilters;
document.getElementById('currentfilters').style.display = 'block';
} else {
document.getElementById('currentfilters').style.display = 'none';
}
if (filterCount < 1) {
for (j = 0; j < filterinfo.length; j++) {
var filtertype = filterinfo[j][0];
if (filterinfo[j][0] == 'allvalidsites') {
var sitearray = filterinfo[j][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
var infoWindow = new google.maps.InfoWindow({});
var resultHTML = '<div id="page1" class="page"><ul>';
var count = 0;
var page = 1;
var paging = '<li class="selected">1</li>';
for (i = 0; i < markerDataArray.length; i++) {
var markerInfArray = markerDataArray[i].split('|');
var url = '';
var name = '';
var placename = '';
var region = '';
var summaryimage = 'images/controls/placeholder.gif';
var summary = '';
var flag = 'images/controls/placeholderf.gif';
for (j = 0; j < tsiteinfo.length; j++) {
var thissite = tsiteinfo[j].split('|');
if (thissite[0] == markerInfArray[2]) {
name = thissite[1];
placename = thissite[2];
region = thissite[3];
if (thissite[4] != '') {
summaryimage = thissite[4];
}
summary = thissite[5];
if (thissite[6] != '') {
flag = thissite[6];
}
}
}
for (k = 0; k < sitemapperinfo.length; k++) {
var thissite = sitemapperinfo[k].split('|');
if (thissite[0] == markerInfArray[2]) {
url = thissite[1];
}
}
var markerLatLng = new google.maps.LatLng(markerInfArray[1].toString(), markerInfArray[0].toString());
var infoWindowContent = '<div class="infowindow">' + markerInfArray[2] + ': ';
var siteurl = approot + '/sites/' + url;
infoWindowContent += '<strong>' + name + '</strong>';
infoWindowContent += '<br /><br/><em>' + placename + ', ' + region + '</em></div>';
marker = new google.maps.Marker({
position: markerLatLng,
title: $("<div/>").html(name).text(),
shadow: shadow,
icon: image
});
addInfo(infoWindow, marker, infoWindowContent);
markers.push(marker);
count++;
if ((count > 20) && ((count % 20) == 1)) { // 20 per page
page++;
resultHTML += '</ul></div><div id="page' + page + '" class="page"><ul>';
paging += '<li>' + page + '</li>';
}
resultHTML += '<li><div class="namehead"><h2>' + name + ' <span>' + placename + ', ' + region + '</span></h2></div>' +
'<div class="codehead"><h2><img alt="' + region + '" src="' + approot +
'/' + flag + '" /> ' + markerInfArray[2] + '</h2></div>' +
'<div class="resultcontent"><img alt="' + name + '" src="' + approot +
'/' + summaryimage +'" />' + '<p>' + summary + '</p>' + document.getElementById('buttonhide').innerHTML.replace('#',siteurl) + '</div></li>';
}
$('#filteredmap .paging').each(function(){
$(this).html(paging);
});
document.getElementById('resultslist').innerHTML = resultHTML + '</ul></div>';
document.getElementById('count').innerHTML = count + ' ';
document.getElementById('page1').style.display = 'block';
for (t = 0; t < markers.length; t++) {
markers[t].setMap(filteredMap);
}
});
}
}
function clearMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setMap(null);
markers[i] = null;
}
markers.length = 0;
}
However, I'm suffering from performance issues (UI hanging) specifically in IE6 and 7 when the number of results is high, but not in any other modern browsers, i.e. FF, Chrome, Safari etc. It is much worse when the Google map markers are being created and added (if I remove this portion it is still slugglish, but not to the same degree). Can you suggest where I'm going wrong with this?
Thanks in advance :) Please be gentle if you can, I don't do much javascript work and I'm pretty new to it and jquery!
This looks like a lot of work to do at the client no matter what.
Why don't you do this at the server instead, constructing all the HTML there, and just refresh the relevant sections with the results of an ajax query?
I am writing a game for Facebook. IN the following code, I have a problem. I have a for loop executing, and in that loop, I call a dialog and implement 'onconfirm' for the dialog. The problem is that I need to access th e loop counter inside of the onconfirm function. But because the onconfirm is called outside of the scope of the for loop, the counter value is no longer valid because it's been incremented. I need some way to pass the counter value to the dialog onconfirm as it was at the time the dialog was displayed, not after the loop has finished. Or maybe someone has a better solution. Any help would be appreciated. Thanks.
function unloadCargo() {
//debugger;
var actionPrompt = document.getElementById('action-prompt');
actionPrompt.setTextValue('Unloading cargo...');
var ajax = new Ajax();
ajax.responseType = Ajax.JSON;
ajax.ondone = function(data) {
debugger;
if(data.unloadableCargo.length == 0) {
loadCargo();
} else {
//console.log('unloadable cargo='+dump(data.unloadableCargo));
var i = 0;
var j = 0;
var ucCount = data.unloadableCargo.length;
for(i = 0; i < ucCount; i++) {
cargoDialog = new Dialog();
cargoDialog.showChoice('Unload Cargo', 'Unload ' + data.unloadableCargo[i].goods_name + ' at ' + data.unloadableCargo[i].city_name + ' for ' + data.unloadableCargo[i].payoff + 'M euros?');
cargoDialog.onconfirm = function() {
//console.log('unloadable cargo onconfirm='+dump(data.unloadableCargo));
var ajax = new Ajax();
var param = {"city_id": data.unloadableCargo[i].city_id, "goods_id": data.unloadableCargo[i].goods_id, "payoff": data.unloadableCargo[i].payoff};
ajax.ondone = function(demandData) {
var demands = document.getElementById('demands');
var innerXhtml = '<span>';
for(var j = 0; j < demandData.demands.length; j++) {
innerXhtml = innerXhtml + ' <div class="demand-item"><div class="demand-city">' + demandData.demands[j].city + '</div><div class="demand-pay">' + demandData.demands[j].cost + '</div><div class="demand-goods">' + demandData.demands[j].goods + '</div></div>';
}
innerXtml = innerXhtml + ' </span>';
demands.setInnerXHTML(innerXhtml);
// update balance
loadCargo();
}
ajax.post(baseURL + "/turn/do-unload-cargo", param);
}
cargoDialog.oncancel = function() { loadCargo(); }
}
//loadCargo();
}
}
ajax.post(baseURL + '/turn/unload-cargo');
}
You need to pass the value to the dialog somehow.
I have never looked at the FBJS, but it seems setContext can be used for that.
Try this:
cargoDialog = new Dialog().setContext({currentIndex: i});
// showChoice is the same
cargoDialog.onconfirm = function() {
alert(this.currentIndex); // Here you should be able to get it
}