Can bind be useful here? Duplication of code - javascript

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?

Related

Push older text while fading in new text

I would like new text, as it is fading in, to push the older text down instead of having new text appear after old text. Is this possible? Have been having a lot of difficulty figuring this out.
Here is the javascript:
var $el= $('.fader').map(function() {
return this;
}).get();
$el.forEach(function (eachdiv){
var text = $(eachdiv).text(),
words = text.split(".");
var html = "";
for (var i = 0; i < words.length; i++) {
html += "<span>" + words[i] + " </span>" + '<br/>';
$(eachdiv).html(html).children().hide().each(function(i){
return $(this).delay(i*200).fadeIn(200);
});
}
});
The solution does seem to involve the use of prepend, but I'm not sure where to place prepend within the code.
Try For loop like this instead of yours. Just Giving you an idea. give fadeIn effect as per your data arrives.
for (var i = 0; i < words.length; i++) {
html.prepend("<span>" + words[i] + " </span>" + '<br/>');
$(eachdiv).html(html).children().hide().each(function(i){
return $(this).fadeIn(200);
});
}
This seemed to work in the return line:
return $(this).delay(i*200).prependTo(eachdiv).fadeIn(200);
Thanks for introducing me to prepend, Sindhoor!

Issue when trying to use jQuery's window.open function in combination with a for-loop to iterate through an array

Let's say I have an array of links like this:
var playlist = [
"",
"https://www.youtube.com",
"https://www.google.com",
"https://www.facebook.com",
"https://www.instagram.com"
];
And a bunch of boxes generated in the following way:
for(var i = 1; i < 5; i++) {
$(".container").append("<div class='luke luke-" + i + "'>" + "<h3 class='nummer'>Luke " + i + "</h3> " + "</div>");
}
I then want to iterate through this array to open a specific link when a box is clicked.
for(var i = 1; i < 5; i++) {
$(".luke-" + i).click(function(){
window.open(playlist[i], "_blank");
})
}
That doesn't seem to work at all, however the example below does exactly what I want.
$(".luke-1").click(function(){
window.open(playlist[1], "_blank");
})
$(".luke-2").click(function(){
window.open(playlist[2], "_blank");
})
$(".luke-3").click(function(){
window.open(playlist[3], "_blank");
})
$(".luke-4").click(function(){
window.open(playlist[4], "_blank");
})
$(".luke-5").click(function(){
window.open(playlist[5], "_blank");
})
So this works, but it's a pain in the ass to setup as I want to have 25 boxes in total and this solution offers little to no flexibility if I want to increase or decrease that amount at a later time. What am I doing wrong with the for-loop that's causing issues here?
If I use
console.log(playlist[i]);
inside of the for-loop, it simply returns "undefined" regardless of what box I click in case that helps.
You can do this much easier and simpler using a data attribute.
HTML
<div class="container"></div>
Javascript/jQuery
var playlist = [
"",
"https://www.youtube.com",
"https://www.google.com",
"https://www.facebook.com",
"https://www.instagram.com"
];
for(var i = 1; i < 5; i++) {
$(".container").append("<div class='luke' data-url='" + playlist[i] + "'>" + "<h3 class='nummer'>Luke " + i + "</h3> " + "</div>");
}
$('.luke').click(function() {
window.open($(this).data('url'));
});
Demo Here
You are not doing right.
EXAMPLE FIDDLE
var playlist = [
"https://www.youtube.com",
"https://www.google.com",
"https://www.facebook.com",
"https://www.instagram.com"
];
var container = $("#container");
for(var i = 1; i < 5; i++) {
container.append('<div class="luke" db-id="'+ i + '"><h3 class="nummer">Luke ' + i + '</h3></div>');
}
$(".luke").click(function(i){
window.open(playlist[$(this).attr('db-id')], "_blank");
});
for(var i = 1; i < 5; i++) {
$(".luke-" + i).click(function(i){
window.open(playlist[i], "_blank");
})
}
The click event will launch your function only inside the scope of the loop. This means that once the loop have finished, ( and counting from 0 to 5 is insanely fast for your computer ) there's no more function attached to your click event. In other terms, as long as i < 5, your click function will work as you expect, but after that, the click event will no longer call the function you created.
One solution could to be attach a function to the onclick attribute in the HTML like this :
for(var i = 1; i < 5; i++) {
$('<div/>', {
'class': 'luke luke-' + i,
'click': yourFunction(i)
}).appendTo(${'.container'});
$('<h3/>', {
'class':'nummer',
'html': 'Luke' + i
}).appendTo(${'.luke-'+i})
}
and then write a function like this :
function yourFunction(index){
window.open(playlist[index], "_blank");
}
Simple way by using Hyperlink
hyperlinks
Demo Here

undefined breaking code processing when using sharepointplus

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);
});
}

Strange for-loop behavior in Javascript

I have next problem: arr has only two elements. Next loop tries to execute his body 3 times:
var selectHTML = "";
for (var i = 0; i< arr.length; i++) {
selectHTML += '<option value="' + arr[i].id + '">' + arr[i].name + '</option>';
}
Next loop tries to execute his body only 2 times as I expect:
var selectHTML = "";
for (var i = 0; i< arr.length; i++) {
alert(i);
selectHTML += '<option value="' + arr[i].id + '">' + arr[i].name + '</option>';
}
Why (tested in Firefox 14.0.1)?
Updated: sorry for the semicolon after counter increment, it's a typo. But the code still doesn't work event without it.
Updated: Ok, this code was simplified. Whole code itself:
var selectHTML = "";
timeSheet.steps = [ { name:"Leave as is", id:-1}, { name:"Approved", id:2} ];
for (var counter = 0; counter < timeSheet.steps.length; counter++) {
selectHTML += '<option value="' + timeSheet.steps[counter].id + '">' + timeSheet.steps[counter].name + '</option>';
}
In Firebug I can see that timeSheet.steps.length equals 2. By the way, instead of placing "alert(i)" I've added a comment and body executes 2 times. Magic...
You have an extra semicolon in the loop
for (var i = 0; i< arr.length; i++;) {
Try it without:
for (var i = 0; i< arr.length; i++) {
This works fine for me (Tested in Firefox 14.0.1):
var arr = [{id:1, name: 'test2'}, {id:2, name: 'test2'}];
var selectHTML = "";
for (var i = 0; i< arr.length; i++) {
selectHTML += '<option value="' + arr[i].id + '">' + arr[i].name + '</option>';
}
console.log(selectHTML);
var selectHTML = "";
for (var i = 0; i< arr.length; i++) {
selectHTML += '<option value="' + arr[i].id + '">' + arr[i].name + '</option>';
}
console.log(selectHTML);
Returns
<option value="1">test2</option><option value="2">test2</option>
<option value="1">test2</option><option value="2">test2</option>
Please elaborate what you meant by the body running three times. If your array contains only 2 elements, when i == 2, arr[i] is undefined and hence accessing id and name will throw an error.
If this is what is happening, then at some point in the looping, the length of the array is being modified with/without an element being added.
Issues that fixed by adding an alert are usually timing issues. See this section on Alerts
Alert boxes (and the related confirm and prompt-boxes) have some
strange properties.
They are synchronous in the sense that the script that initiates the
dialog is suspended until the dialog is closed. The script waits for
the alert()-function to return before it continues.
The tricky part is that some browsers allow events to be dispatched
while the dialog is visible and waiting for some user action. This
means that while one script is suspended, waiting for the alert
function to return, another function might be executed as part of a
different event dispatch.
User interface events like mouseup and click will not fire during the
alert, as the alert is modal and captures all user input, but
non-user-initiated events like page load, timeout handlers, and
asynchronous XMLHttpRequest return handlers, might fire.
You have not shown code that modifies the arr variable. Chances are you have a ajax call some where that is modifying the arr. In the first code sample there is no alert, so maybe the entire for loop gets over before the ajax success handler fires. In the second sample, the alert prevents the for loop from executing till you discard the alert. In the time it took for you to discard it, the ajax success handler must have fired.
Please share all relevant code that modifies the arr variable.

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