I have code working fine but I wanna simplify:
<script type="text/javascript">
function RenderPager(items) {
for (var i = 0; i < items.length; i++) {
var li = "<li";
if(i == 0){
li += " class='first'";
}
li +=">" + i + "</li>";
// do something else
}
}
</script>
I would like to have condition inline something like this:
for (var i = 0; i < items.length; i++) {
var li = "<li" + if(i == 0){ li += " class='first'" }; + ">" + i + "</li>";
// do something else
}
But this is not working and I tried everything but I don't know how to combine javascript condition in text variable. Is it possible?
You can use the conditional operator (?..:), also known as the ternary operator:
var li = "<li" + (i == 0 ? " class='first'" : "") + ">" + i + "</li>";
Also note, this could probably also be done using a little CSS with the :fist-child pseudo-class, but it's not supported by older versions of IE. See this compatibility chart:
li:first-child {
/* applies only to the first <li> element in a list */
}
Related
I want to change the class of an element depending on the value. Is it possible to do this inside the loop?
Javascript:
$.post(url, filteredObject, function (data2) {
for (i = 0; i < 7; i++) {
$('#ty' + (i + 1).toString()).text(numberWithCommas(data2[i].TY));
$('#sdly' + (i + 1).toString()).text(numberWithCommas(data2[i].SDLY));
$('#fcst' + (i + 1).toString()).text(numberWithCommas(data2[i].FCSTYTD));
}
});
I tried something like this but didn't work.
var textvalue = parseInt($('#ty' + (i + 1).toString()).text)
if (textvalue < 0) {
$('#ty' + (i + 1).toString()).toggleClass("fa fa-level-down");
}
else {
$('#ty' + (i + 1).toString()).toggleClass("fa fa-level-up");
}
Can anyone help me.
you should not use "toggleClass"
.toggleClass( className )
Description: Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence [...]
it removes the class if it is present and adds it if it is not, so achieve that you only have one of fa-level-down and fa-level-up you should use .addClass( className ) and .removeClass( className )
var textvalue = parseInt($('#ty' + (i + 1).toString()).text)
if (textvalue < 0) {
$('#ty' + (i + 1).toString()).addClass("fa-level-down");
$('#ty' + (i + 1).toString()).removeClass("fa-level-up");
}
else {
$('#ty' + (i + 1).toString()).addClass("fa-level-up");
$('#ty' + (i + 1).toString()).removeClass("fa-level-down");
}
You are missing brackets after .text on the line:
var textvalue = parseInt($('#ty' + (i + 1).toString()).text)
You should use .text() to get the text of a jQuery object.
var textvalue = parseInt($('#ty' + (i + 1).toString()).text())
I try to create a dynamic menu using jquery:
function createMenu(array) {
var main = $("#mainUl");
for (var i = 0; i < array.length; i++) {
main.append("<li>");
$('li').append("<a href='#" + myArray[i].id + "'><span>" + myArray[i].id + "</span></a>");
main.append("</li>");
}
}
The menu is created, but in each li i get more than one span, there is an "inside" loop (I think...)
createing more spans than needed... how can i solve/control it so each li gets
one span according to the for - loop index ?
You are seeing that behaviour because you are appending that anchor with span in selecting all the li elements.
Try,
function createMenu(array) {
var main = $("#mainUl");
for (var i = 0; i < array.length; i++) {
var xLi =("<li>").appendTo(main);
xLi.append("<a href='#" + myArray[i].id + "'><span>" + myArray[i].id + "</span></a>");
main.append(xLi);
}
}
you can do it simply as below
function createMenu(array) {
var main = $("#mainUl");
for (var i = 0; i < array.length; i++) {
main.append($("<li>").append("<a href='#" + myArray[i].id + "'><span>" + myArray[i].id + "</span></a>"));
}
}
$('li') this selector will get every li on the html so every time you iterate to create a new li element you gonna add a new span to all of them.
Try like this:
function createMenu(array) {
var main = $("#mainUl");
for (var i = 0; i < array.length; i++) {
var menuLine = $('<li>');
menuLine.html("<a href='#" + myArray[i].id + "'><span>" + myArray[i].id + " </span></a>" );
main.append(menuLine);
}
}
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);
});
}
I have a script
var firstImg = row.getElementsByTagName('img')[0];
and later
if (x){ firstImg.src='/images/checked.png'; }
I'd like to define that the img should be of class='something'
(Get first img with class='something')
Use the
querySelectorAll('img.classname')[0]
this returns first image with class set to class name. However jQuery is better!!
$('img.classname')
Just set it...
firstImg.className += "something";
...or...
firstImg.classList.add("something");
If you can get away with not supporting older browsers.
Further Reading (disclaimer: link to my own blog).
If you're intending to get elements with a certain class name, you can use...
document.getElementsByClassName("something");
...or...
document.querySelectorAll(".something");
Keep in mind getElementsByClassName() isn't in <= IE8.
You can use...
var getElementsByClassName(nodeList, className) {
var i, results = [];
for (i = 0; i < nodeList.length; i++) {
if ((" " + nodeList[i].className + " ").indexOf(" " + className + " ") > -1) {
results.push(nodeList[i]);
}
}
return results;
}
Of course, it's super simple if you're using jQuery...
$(".something");
this selects the first img with class='something':
var firstImg = $('img.something')[0];
If you could not throw away the old browsers, then you need a loop.
var imgs = row.getElementsByTagName('img'),
some_class = 'something',
i, first_img;
for (i = 0; i < imgs.length; i++) {
if ((' ' + imgs[i].className + ' ').indexOf(' ' + some_class + ' ') > -1) {
first_img = imgs[i];
break;
}
}
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/