undefined breaking code processing when using sharepointplus - javascript

EDIT: please see John S. answer below for the real issue behind this apparent problem!
I am building a dynamic expression with sharepointplus. It should return a logical value and it does just that. I have moved it into a variable, as I use it often (reference it as a condition for if). The problem is, apparently the plus sign is stopping the processing of the rest of the code. Here's two faulty snippets (no errors in console):
for (var i=0; i < data.length; i++){
var category_equal_test = ((data[i].getAttribute("category")) == (data[i+1].getAttribute("category")));
or
for (var i=0; i < data.length; i++){
var j=i+1;
var category_equal_test = ((data[i].getAttribute("category")) == (data[j].getAttribute("category")));
No difference between them really, but for a moment I thought I would get away with this.
Here's a snippet of code that does NOT break processing (But of course this code is pointless):
for (var i=0; i < data.length; i++){
var category_equal_test = ((data[i].getAttribute("category")) == (data[i].getAttribute("category")));
In both cases of the broken code, console.log(category_equal_test) outputs the set of logical values I am looking for.
I assume it is some kind of icompetence on my part, so please enlighten me! Thanks.

This is happening because at the very end of the loop, data[i + 1] becomes undefined and you can't do getAttribute of undefined, so it throws a TypeError.
var x; x.getAttribute('foo');
// TypeError: Cannot call method 'getAttribute' of undefined
To fix this, make your loop end an iteration earlier;
for (var i = 0; i < data.length - 1; i++) {
// ...
}
As for why you're not getting an error in the console, the code must be contained within a try..catch somewhere.

Here's what I have ended up using. I hope this is useful to somebody!
function osDrawPageMenuLeft() {
var spquery = "";
$SP().list("menu","/content").get({fields:"name, link, Level, Order, category"},function(data) {
spquery += "<ul>";
var j=0;
for (var i=0; i < data.length; i++){
if( i < data.length-1){
j=i+1;
var category_equal_test = ((data[i].getAttribute("category")) == (data[j].getAttribute("category")));
}
else{
category_equal_test=false;
}
var link_empty_test = (data[i].getAttribute("link") == null);
var header = data[i].getAttribute("name");
var header_link = "<a href='" + data[i].getAttribute("link") + "'>" + header + "</a>";
var row = "<li><a href='"+data[i].getAttribute("link")+"'>"+data[i].getAttribute("name")+"</a></li>";
if(data[i].getAttribute('Level') == 'Header'){
if (((category_equal_test)&&(!link_empty_test))){
spquery += "<li>" + header_link + "<ul>";
}
else if(((!category_equal_test)&&(!link_empty_test))){
spquery += "<li>" + header_link + "</li>";
}
else if(((category_equal_test)&&(link_empty_test))){
spquery += "<li>" + header + "<ul>";
}
else if(((!category_equal_test)&&(link_empty_test))){
spquery += "<li>" + header + "</li>";
}
}
else{
if((!category_equal_test)){
spquery += row + "</ul></li>";
}
else{
spquery += row;
}
}
};
spquery += "</ul>";
$('#newleftNav').append(spquery);
});
}

Related

Javascript printing html tags as part of innerHTML output to screen

I have a javascript segment that prints output to a div.
output.textContent = "";
for(i=0; i<14; i++){
output.append(document.createElement("p").innerHTML = net_words(sonnet[i]));
output.append(document.createElement("br"));
}
The function net_words that generates the output is as follows:
function net_words(line) {
var net_line = Math.floor(Math.random()*4)
var ret = ""
if (net_line != 1) {
ret += "<span class=\"netno\">"
ret += line
}
else {
var net_list = line.split(" ")
var rand_word = Math.floor(Math.random() * net_list.length)
ret += "<span class=\"netno\">"
for (var i=0; i<net_list.length; i++) {
if (i == rand_word) {
ret += "<span class=\"netyes\">"
ret += net_list[i]
ret += " "
ret += "</span>"
}
else {
ret += net_list[i]
ret += " "
}
}
}
ret += "</span>"
return ret
}
The problem is, it prints the line as follows:
<span class="netno">From fairest creatures we desire increase</span>
That is, it prints it with the HTML tag visible, rather than applied to the code. When I paste it into the text editor for stack overflow, it prints as normal (no tags) unless I put it as a code snippet. What is the cause of this error?
The problem is here:
output.append(document.createElement("p").innerHTML = net_words(sonnet[i]));
You think that you appended <p>, but in fact you appended the result of the assignment. To fix it do:
var p = document.createElement("p");
p.innerHTML = net_words(sonnet[i]);
output.append(p);
or
output.innerHTML += '<p>' + net_words(sonnet[i]) + '</p>';

Can bind be useful here? Duplication of code

I am new to javascript and thats my pen: pen
so i have faced such problem as duplication of code. how can I avoid it? I have tried this new fuction instead of old ones but its not working:
//populatePosition($("#positionElement"));
populate1($("#positionElement"), positionList, 'position');
function populate1(dd, list, elem) {
var temp="";
for (var i = 0; i < list.length; i++) {
temp += "<option value='" + list[i]["id"] + "'>" + list[i][''+elem] + "</option>\n";
//console.log(temp);
}
dd.append(temp);
}
I guess bind can be used here. is it possible?

when i call str.replace() in javascript it goes to error ir is not defined

See my code
for (var i = 0; i < allTextLines.length; i++) {
var row_data = allTextLines[i];
console.log(row_data);
row_data = row_data.replace(/ /g,'');
try {
ir(row_data == "")
{
continue;
}
if (document.getElementById("devicesList").value.length > 0) {
document.getElementById("devicesList").value += ",";
}
document.getElementById("devicesList").value += row_data;
}
catch (oErr) {
not_read += 1;
console.log(oErr.message);
str_error_detail_rows += "<tr><td colspan='2'>Error :" + oErr.message + " could not read line# " + i + " while reading from file.</td></tr>";
}
}
when i run the code, in the console i got "ir is not defind" please someone help me. the code goes smooth when i remove str.replace. thanks.
ir(row_data == "")
should be
if(row_data == "")
The ir should be an if, I reckon - it's a typo.
To be perfectly frank, you really could have read through and practically immediately noticed the problem while paying attention.

change the order js inserts the text into the html

I need to change the where the js inserts the text into the html currently it is always putting at the end and I need it to insert it at the start and push the others down. That is, if it inserts
<li>1</li>, <li>2</li>, <li>3</li>
it will keep it in that order I need the last one to always be listed first like
<li>3</li>, <li>2</li>, <li>1</li>
Here is the html
<div class="data">
<div class="stackleft" id="p1_stack"></div>
<div class="stackright" id="p2_stack"></div>
</div>
Here is the JavaScript
function drawStack(isFinal) {
var stackLength = Oscore[currentPlayer].stack.length;
var temp = "";
var tot = 0;
for (var i = 0; i < stackLength; i++) {
var val = Oscore[currentPlayer].stack[i];
temp += "<li>" + val + "</li>";
tot += val;
}
//if(!isFinal){
//temp = '<div class="workingScore">'+scoreTemp+'</div><br>' + temp;
//}
var writeSore = document.form1.game.value - tot;
writeit(writeSore, currentPlayer + "_score");
writeit(temp, currentPlayer + "_stack");
}
Try to loop backward:
for (var i = stackLength; i--; ) {
var val = Oscore[currentPlayer].stack[i];
temp += "<li>" + val + "</li>";
tot += val;
}
How about this:
temp = "<li>" + val + "</li>" + temp;
You were missing a quote in the code shown too (now fixed by someone's edit), probably wouldn't have worked at all as written originally.
EDIT: I think I like the loop backward approach better, but it's up to you what you think is clearest.
use prepend() from JQuery.....

Jquery help needed- infinite loop?

i have a problem with this code:
var par = [];
$('a[name]').each(function() {
if (($(this).attr('name')).indexOf("searchword") == -1) {
par.push($(this).attr('name'));
$('.content').empty();
for (var i = 0; i < par.length; i++) {
$(".content").append('<a id="par" href="#' + par[i] + '">' + par[i] + '</a><br />');
}
}
});
It causes ie and firefox to popup the warning window "Stop running this script". But it happens only when there is a very very large amount of data on page. Any ideas how to fix it?
Your code should look like this:
var par = [];
$('a[name]').each(function() {
if (($(this).attr('name')).indexOf("searchword") == -1) {
par.push($(this).attr('name'));
}
});
$('.content').empty();
for (var i = 0; i < par.length; i++) {
$(".content").append('<a id="par" href="#' + par[i] + '">' + par[i] + '</a><br />');
}
There is no reason for the second loop to be inside the first - that will just cause a lot of unneeded work.
You can make this code a bit simpler by removing the par array and the second loop, and just creating the content inside the first loop:
$('.content').empty();
$('a[name]').each(function() {
var name = $(this).attr('name');
if (name.indexOf("searchword") == -1) {
$(".content").append('<a id="par" href="#' + name + '">' + name + '</a><br />');
}
});
Browsers run all javascript (and most page interaction) on a single thread. When you run a long loop like this with no interruptions, the UI is totally frozen. You should try to make your algorithm have to do less, but in case that's not possible you can use this trick where you do a bit of work, then pause and give the browser control of the UI thread for a bit, then do more work.
var $targets = $('a[name]');
var current = 0;
var i = 0;
function doSomeWork() {
if (i == $targets.length) return;
var $t = $targets[i];
if (($t.attr('name')).indexOf("searchword") == -1) {
par.push($t.attr('name'));
$('.content').empty();
for (var i = 0; i < par.length; i++) {
$(".content").append('<a id="par" href="#' + par[i] + '">' + par[i] + '</a><br />');
}
}
i++;
window.setTimeout(arguments.callee, 0);
}
This does one iteration of your loop in a function before yielding. It might be a good idea to do more than just one in a function call, but you can experiment with that. An article on this idea: http://www.julienlecomte.net/blog/2007/10/28/

Categories