This might be a stupid question, but I can't seem to find an answer. I'm pretty new to Javascript, and I want to know how to declare files/file paths as a variable, so I can put them in an array.
Like, if I have a lot of images in a folder (as in, several hundred) and I want to display certain ones based on the tags the user selects, there must be a way to have those image files in an array so a For loop can cycle through them, right?
(Even better would be if it could somehow parse an int into a filename like [i].png if I have the files named 1.png, 2.png, etc but I don't know if that's possible)
Anyway, basically all I need to know is how to make an array of files, so that "Pictures[245]" refers to "images/small/245.png"
I feel like I must be overlooking something obvious.
There it is:
var Pictures = [];
Pictures.push("/images/small/0.png");
Pictures.push("/images/small/1.png");
Pictures.push("/images/small/2.png");
Then you can get them by calling Pictures[0], Pictures[1], etc.
Notice that array index starts from zero, so if you would use above solution and if you would add images in order, then your image 245.png would be under index 244 not 245.
If you just want to create URL to an image by file name or some identifier, then do not use array, simply use function:
getImageUrl(index) {
return "/images/small/" + index + ".png";
}
Essentially you just want to do.
var picture = []; //Define array pictures
//loop through all pictures
for (i = 0; i < (amount of images); i++) {
picture.push("/images/small/" + i + ".png"); //Add to array
}
Now you can call picture[0] ... picture[1] ... etc...
Related
I have a JSON response from a server, which returns me a array with 32 objects (in this case). Something like this:
[{object1},{ object2},{ object3}, etc].
Each object have some info that I use to populate an html template. For that, I just use a simple loop:
for(var i = 0; i < api_empresaListar.length; i++)
{
var item = api_empresaListar[i];
var htmls;
htmls = $('...lots of html code');
...
Then it’s just a simple matter of finding/changing the values, and append items on the DOM. Everything works fine. BUT, for some next parts of the code, I would like to access all the info from the object I used to build the html elements (I just show part of the info). So, after searching a lot, I tried to use data, like this:
var tp = htmls.find(".rl_grupo"); // the main div of each html element created in the loop
$(tp).data('key', api_empresaListar[i]); // here, I expected to just insert the object data in each created item.
But when I try it in the console, I got the object info as expected, but always from the last element in the array. Why is that happening? I believe it might be something stupid, but I can’t figure it out.
So, any ideas on how to solve this, or another method to make this work is appreciated. I made it work by setting some "display:none" placeholder html tags and populate those with the info I need later, but looks like a poor solution...
You should not set your htmls variable in the loop. I think that you crush its content every turn, that's why you only have the last item. You should do something like this:
var htmls = $('<div></div>');
for(var i = 0; i < api_empresaListar.length; i++) {
htmls.append($('...lots of html code'));
}
How about setting an index number on each element inside of your html creating code, then iterating over the $('.rl_grupo') elements, like this?
$('.rl_grupo').each(function(){
var index = $(this).data('index');
var currentData = api_empresaListar[index];
$(this).data('key', currentData);
})
I came across this random image rotator
var theImages = new Array()
theImages[0] = 'img1"' theImages[1] = 'img2"'......
var shuffled = [];
while (theImages.length) {
shuffled.push(theImages.splice(Math.random() * theImages.length, 1));
}
$(document).ready(function(){
//Runs Script each time there is an <li>
$("#news li").each(function(index){
//Puts Image in front of everything in <li>
$(this).prepend('<img src="'+shuffled[index]+'">');
});
});
And I integrated it into a jQuery Carousel. You can see (my fiddle) here. The problem is that the array structure I want to use for the Carousel is different from the rotator's. The rotator uses:
var theImages = new Array()
theImages[0] = 'img1"'
theImages[1] = 'img2"'
theImages[2] = 'img3"'
But I want to use the following for the Carousel because I want to input a link to each picture as well.
var theImages = [
['img1','url_1'],
['img2','url_2'],
['img3','url_3']];
The outcome I'm looking for would be like:
<div id="carousel1">
<div class="1"><img src="img1"></div>
<div class="1"><img src="img2"></div>......
From what I've read, I have to use for in loop to assign the data and can't simply use what the image rotator is using:
$("#carousel1 .1").each(function(index){
$(this).prepend('<a href="'+imgPath+''+shuffled[index]+'"><img
src="'+urlPath+''+shuffled[?url](?url)+'"></a>');
Is that true? Is there any way that allows me to populate the images as well as the urls in the Carousel?
No, never use for ... in for arrays. All you have to do is change
'<img src="'+shuffled[index]+'">'
to
'<img src="'+urlPath+shuffled[index][0]+'">'
since the image path is the first element of the inner array, and the link is the second one.
See Access / process (nested) objects, arrays or JSON for more info.
(I assume imgPath and urlPath are actually defined somewhere and contain URLs. If not, you should remove them.)
Your problem is that your source array (the shuffled values) only contains one value but the final resulting one you want to have pairs of values. That extra data needs to come from somewhere, the computer can't just invent it.
The easiest way to do this is to modify the shuffle code and instead of shuffling single strings shuffle pairs of strings instead.
i.e. something like
var theImages = new Array()
theImages[0] = ['img1"', data1]
theImages[1] = ['img2"', data2]
for(var i=0;i<theImages.length;i++){
newTheImagesArray.push([theImages[i],theImages[i]])
}
This should work for what you want
First question ever, new to programming. I'll try to be as concise as possible.
What I want to do is to create a bunch of children inside a selected div and give each of them specific html content (from a predefined array) and a different id to each child.
I created this loop for the effect:
Game.showOptions = function() {
var i = 0;
Game.choiceElement.html("");
for (i=0; i<Game.event[Game.state].options.length; i++) {
Game.choiceElement.append(Game.event[Game.state].options[i].response);
Game.choiceElement.children()[i].attr("id","choice1");
}
};
Using the predefined values of an array:
Game.event[0] = { text: "Hello, welcome.",
options: [{response: "<a><p>1. Um, hello...</p></a>"},
{response: "<a><p>2. How are you?</p></a>"}]
};
This method does not seem to be working, because the loop stops running after only one iteration. I sincerely have no idea why. If there is a completely different way of getting what I need, I'm all ears.
If I define the id attribute of each individual p inside the array, it works, but I want to avoid that.
The idea is creating a fully functional algorithm for dialogue choices (text-based rpg style) that would work with a predefined array.
Thanks in advance.
The problem with your loop as I see it could be in a couple different places. Here are three things you should check for, and that I am assuming you have but just didn't show us...
Is Game defined as an object?
var Game = {};
Is event defined as an array?
Game.event = new Array();
Is Game.state returning a number, and the appropriate number at that? I imagine this would be a little more dynamic then I have written here, but hopefully you'll get the idea.
Game.state = 0;
Now assuming all of the above is working properly...
Use eq(i) instead of [i].
for (var i = 0; i<Game.event[Game.state].options.length; i++) {
Game.choiceElement.append(Game.event[Game.state].options[i].response);
Game.choiceElement.children().eq(i).attr("id","choice" + (i + 1));
}
Here is the JSFiddle.
How to apply category to document in Alfresco with javascript?
tried like this:
document.properties["cm:categories"] = "testCat";
UPDATE:
like this I am able to get "root categories" but not "sub categories":
var rootCats = classification.getRootCategories("cm:generalclassifiable");
document. properties["cm:categories"] = rootCats[3];
this doesnt work:
document. properties["cm:categories"] = rootCats[3][1];
I found it out, if someone need it this is the way how it cana be done
get all root categories [audio, video, image, ...]
var rootCats = classification.getRootCategories("cm:generalclassifiable");
get subcategories from desired root category -> sub category from "video" [horror, comedy, ...]
var singleCat = rootCats[1].subCategories;
apply category to document -> apply "horror" to document
doc. properties["cm:categories"] = singleCat[0]; //app
save it
doc.save();
First make sure that the document has the aspect classifiable (ie having the cm:generalClassifiable aspect).
Then look up the category you want to add ie:
UPDATE: an example query to find a node of type category of a certain name:
Search for your category like this for example, you could add a PATH clause as well to be sure your in the right hierarchy.
var nodes = var categories= search.luceneSearch('+TYPE:"http://www.alfresco.org/model/content/1.0}category" +#name:testCat');
then get the element out of the returned array...
Get the existing categories for the node:
categories= document.properties["cm:categories"];
Push the new category onto the array:
categories.push(categoryToAdd);
Assign this to the document:
document.properties["cm:categories"] = categories;
document.save();
We had a similar requirement, and although slightly different to OP question, it is close enough to warrant inclusion here we feel.
We occasionally have a need to bulk apply categories. ie:new business acquired, migrate all their docs in, add categories to match existing content.
Adding categories to large numbers of documents is tedious in the interface. It needs to enable the aspect (classifiable), then edit properties to select the categories required. For every document individually. Worse, the add aspect isn't available for documents from the explorer view in share, so entering the preview is required. For large docs, entering the preview is itself a few more seconds delay.
So we built a simple script that applies the categories of the parent folder to everything placed under it. Then we only need to set the categories of that folder and start moving content through it (ie:move content in to obtain the category/ies, then move back to where it came, but now all have aspect and category/ies applied).
Actually we have 2 at the moment:
The first folder/rule overrides whatever categories the objects had and
replaces them with just those from the parent folder - we name this folder BulkCategorise
The 2nd is cumulative, so it keeps existing categories and only
adds those from the parent folder, which we name AccumulateCategories
We will create a third to selectively remove them when time permits.
A couple of notes:
adding the classifiable aspect is not actually required to be done
manually or in code, it "Just Works" - at least in 5.1.
this may not be the best way to do this
accumulating a category that is already applied doesn't appear to cause any issues, they appear to coalesce/merge automatically
To use these scripts, create 2 folders and apply a rule to each to run the associated script.
The 1st script completely replaces the categories of the object with those of the parent folder and is trivially simple [Set the #name and SITE to match your installation]:
var inheritFromDir = search.luceneSearch('TYPE:"http://www.alfresco.org/model/content/1.0}folder" +#name:BulkCategorise +SITE:YOUR_SITE_NAME');
// We need to deref the array of noderefs result using inheritFromDir[0]
document.properties["cm:categories"] = inheritFromDir[0].properties["cm:categories"];
document.save();
The 2nd script is a bit more involved - we left the logging code in (commented out) for an example to see how to do that, because it took some time to figure out also (and is an extremely useful feature). As before update the #name and SITE on the first line to match your system.
var inheritFromDir = search.luceneSearch('TYPE:"http://www.alfresco.org/model/content/1.0}folder" +#name:AccumulateCategories +SITE:YOUR_SITE_NAME');
// We need to deref the single array result using inheritFromDir[0] to get categories from topmost parent (folder) node
var parentCatArray = inheritFromDir[0].properties["cm:categories"];
//and any existing categories of the doc, or null if none exist
var thisCatArray = document.properties["cm:categories"];
var thisLen = 0;
if (thisCatArray != null) {
thisLen = thisCatArray.length;
} else {
thisCatArray = new Array();
}
// Some logging to find out what is going on...
//var logFile = space.childByNamePath("log.txt");
// If the log file does not already exist, create it in current folder.
//if (logFile == null) {
// logFile = space.createFile("log.txt");
//}
//if (logFile != null) {
// logFile.content += new Date().toGMTString() + "\tRun started. Length of existing array is: " + thisLen + "\r\n";
// logFile.content += new Date().toGMTString() + "\tFound parent node categories:\r\n";
for (var i=0; i < parentCatArray.length; i++)
{
thisCatArray[thisLen]=parentCatArray[i];
thisLen += 1;
}
//}
// Push the new array of categories to the document
thisCatArray.push(document);
// apply and save the doc
document.properties["cm:categories"] = thisCatArray;
document.save();
Et Voila! In a similar way we have implemented BulkTag and BulkAccumulateTags. Now adding arbitrary categories is as simple as applying them to the folder and moving the content through with drag and drop.
I have a database webmethod that I call via Jquery ajax. This returns an array of data objects from the server. For each data object I want to populate a form with maybe a couple dozen fields.
What is the most efficient way to generate and populate these forms.
Right now, I create a string of the html in my javascript code for each record and then add it to the page. Then I add some events to the new elements.
This works OK in firefox, about 700 ms total for an array of 6 elements, and 4500 ms for an array of 30 elements. However, this is an internal app for my company, and the clients can only use IE8 on their machines. In IE8, this takes 2-10 SECONDS! for and array of length 6 and 47 seconds the one time it was actually able to complete for an array of length 30. Not sure what the ##$% IE8 is doing, but anyways... I need something more efficient it seems...
Thanks!
MORE INFO:
Edit: first thing I do is:
$("#approvalContainer").empty();
Web method signature:
[WebMethod]
public List<User> ContractorApprovals()
So I call the method and then do this with the data:
for (var i = 0; i < data.length; i++) {
displayUserResult("#approvalContainer", data[i], false);
}
formEvents("#approvalContainer");
$("#approvalContainer").show("slow");
displayUserResult looks like this:
var div = "<div style=\"width:695px\" class=..........."
fillForm(div,data)
$("#approvalContainer").append(div)
formEvents does things like add click events, create styles buttons and add watermarks.
fillForm does stuff like this:
$(userForm).find(".form-web-userName").text(userObject._web._userName);
where userForm is the div created in the displayUserResult function, and userObject is one of the objects in the array returned by the ajax call.
Please let me know if you need more information.
You are doing too much DOM manipulation. Every .append and .find and .text inside your loop makes it slower.
The most efficient way is to build an entire HTML string and append that once. I'm not going to bother with the displayUserResult function, and just modify your function that handles the data:
var div = "<div style=\"width:695px\" class=...........",
html = "";
for (var i = 0; i < data.length; i++) {
// Keep adding on to the same html string
html += div + data[i]._web._userName + "</div>";
}
// After the loop, replace the entire HTML contents of the container in one go:
$("#approvalContainer").html(html);
However, while this is fast, note that this is only appropriate if _userName doesn't contain special characters, or is already HTML escaped.