Get all files for all .uploadedFiles - javascript

Im looking for a javascript/jquery (doesn't matter which way) to collect all the files i've uploaded.
I have the following code, where .afbeelding is the class for a couple of file input fields
var geuploadeAfbeeldingen = $('.afbeeldingen').files;
for (var i = 0; i < geuploadeAfbeeldingen.length; i++) {
}
This somehow doesnt seem to work. When i try document.getElementsByClassName it also doesn't work. The funny thing however is, that document.getElementById seem to work on one input field
Any ideas?

This should do what you want
var files = [],
geuploadeAfbeeldingen = $('.afbeeldingen').each(function(){
for (var i = 0; i < this.files.length; i++){
files.push(this.files[i]);
}
});
You end up with an array (files) that holds each file you have selected through the input elements..
Demo at http://jsfiddle.net/gaby/GJW7Y/1/
If you only want the filenames then change
files.push(this.files[i]);
with
files.push(this.files[i].name);

Try this way :
var geuploadeAfbeeldingen = $('.afbeeldingen');
for (var i = 0; i < geuploadeAfbeeldingen.length; i++) {
alert(geuploadeAfbeeldingen[i].files[0].name);
}
This may help you.
Edit :
$('.afbeeldingen').files is not work and document.getElementById().files is worked because first one return JQuery object( array of objects) and second one return DOM object.The jQuery object (created by the $ method) is a wrapper around a DOM element or a set of DOM elements. The normal properties and methods are not available with JQuery object.

You need to loop through each input element and return the files property.
Something like this is probably the shortest way, using map to iterate through an array:
var geuploadeAfbeeldingen = $('.afbeeldingen').map(function(k, v) { return v.files[0]; }).get();

Related

getElementsByClassName isn't returning all elements

I'm creating a button that I should highlight certain words within a specified class, but I am having issues with it returning all elements within the class. It will only work if I specify an index, so I'm assuming there may be something wrong with the existing "for loop". Any help is appreciated!
This will work, but only "highlights" the first element in the class, of course:
var bodyText = document.getElementsByClassName('test')[0].innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag,
highlightEndTag);}
document.getElementsByClassName('test')[0].innerHTML = bodyText;
return true;
This will not work at all:
var bodyText = document.getElementsByClassName('test').innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag,
highlightEndTag);}
document.getElementsByClassName('test').innerHTML = bodyText;
return true;
If you want to replace multiple words in multiple elements, you need two loops:
const testElements = document.getElementsByClassName('test');
for (const element of testElements) {
for (const search of searchArray) {
element.innerHTML = doHighlight(element.innerHTML, search, highlightStartTag, highlightEndTag);
}
}
As you can see getElementsByClassName is pluralized (Elements). Indeed a same class can be assigned to multiple HTML elements. You won't find any way to ommit the [0] and you shouldn't anyway as it might mean you're getting data from the wrong node. If you need data from a specific element that you can ensure is unique then you need to give it an id and use getElementById instead.
You cannot access innerHTML in something which returns an htmlcollection
document.getElementsByClassName('test').innerHTML
Because it's written in plain english: getElementsByClassName. plural.
"Elements".
with an "s" at the end...
meaning it's a (sort of) Array (an htmlcollection)

Select and add class in javascript

Cross Platform if possible, how can I select classes in Javascript (but not Jquery please -MooTools is fine though-) on code that I can't add an ID?
Specifically, I want to add the class "cf" on any li below:
HTML
<div class="itemRelated">
<ul>
<li class="even">
<li class="odd">
<li class="even">
I tried to fiddle it but something is missing:
Javascript
var list, i;
list = document.getElementsByClassName("even, odd");
for (i = 0; i < list.length; ++i) {
list[index].setAttribute('class', 'cf');
}
JSFiddle
ps. This question phenomenally has possible duplicates, (another one) but none of the answers makes it clear.
Using plain javascript:
var list;
list = document.querySelectorAll("li.even, li.odd");
for (var i = 0; i < list.length; ++i) {
list[i].classList.add('cf');
}
Demo
For older browsers you could use this:
var list = [];
var elements = document.getElementsByTagName('li');
for (var i = 0; i < elements.length; ++i) {
if (elements[i].className == "even" || elements[i].className == "odd") {
list.push(elements[i]);
};
}
for (var i = 0; i < list.length; ++i) {
if (list[i].className.split(' ').indexOf('cf') < 0) {
list[i].className = list[i].className + ' cf';
}
}
Demo
Using Mootools:
$$('.itemRelated li').addClass('cf');
Demo
or if you want to target specific by Class:
$$('li.even, li.odd').addClass('cf');
Demo
I know this is old, but is there any reason not to simply do this (besides potential browser support issues)?
document.querySelectorAll("li.even, li.odd").forEach((el) => {
el.classList.add('cf');
});
Support: https://caniuse.com/#feat=es5
Using some newer browser objects and methods.
Pure JS:
Details: old fashioned way, declaring stuff at the beginging than iterating in one big loop over elements with index 'i', no big science here. One thing is using classList object which is a smart way to add/remove/check classes inside arrays.
var elements = document.querySelectorAll('.even','.odd'),
i, length;
for(i = 0, length = elements.length; i < length; i++) {
elements[i].classList.add('cf');
}
Pure JS - 2:
Details: document.querySelectorAll returns an array-like object which can be accessed via indexes but has no Array methods. Calling slice from Array.prototype returns an array of fetched elements instantly (probably the fastest NodeList -> Array conversion). Than you can use a .forEach method on newly created array object.
Array.prototype.slice.call(document.querySelectorAll('.even','.odd'))
.forEach(function(element) {
element.classList.add('cf');
});
Pure JS - 3:
Details: this is quite similar to v2, [].map is roughly that same as Array.prototype.map except here you declare an empty array to call the map method. It's shorter but more (ok little more) memory consuming. .map method runs a function on every element from the array and returns a new array (adding return in inside function would cause filling the returned values, here it's unused).
[].map.call(document.querySelectorAll('.even','.odd'), function(element) {
element.classList.add('cf');
});
Pick one and use ;)
querySelectorAll is supported in IE8, getElementsByClassName is not, which does not get two classes at the same time either. None of them work in iE7, but who cares.
Then it's just a matter of iterating and adding to the className property.
var list = document.querySelectorAll(".even, .odd");
for (var i = list.length; i--;) {
list[i].className = list[i].className + ' cf';
}
FIDDLE
As others mention for selecting the elements you should use .querySelectorAll() method. DOM also provides classList API which supports adding, removing and toggling classes:
var list, i;
list = document.querySelectorAll('.even, .foo');
for (i = 0; i < list.length; i++) {
list[i].classList.add('cf');
}
As always IE9 and bellow don't support the API, if you want to support those browsers you can use a shim, MDN has one.
If you want to select elements with different classes all together then the best choice is querySelectorAll.
querySelectorAll uses CSS selectors to select elements. As we add the same CSS properties to different elements by separating them by a comma in the same way we can select those elements using this.
.even, .odd {
font-weight: bold;
}
Both elements with class 'even' and 'odd' get bold.
let list = document.querySelectorAll('.even, .odd');
Now, both the elements are selected.
+Point: you should use classList.add() method to add class.
Here is the complete code for you.
let list = document.querySelectorAll('.even, .odd');
for (i = 0; i < list.length; ++i) {
list.classList.add('cf');
}

Getting th ChildNodes from an object variable

I've ran into a small snag with my code - below is my code:
var actionsAllowed = $(packet).find('actionsAllowed');
This returns to me the following in the firebug console:
Object[actionsAllowed]
Clicking "actionsAllowed" takes me into the packet and to the correct section, where I see the two listed actions.
I can expand the object and eventually see the following:
Object[actions]
0
actions
remove
remove()
attributes
[]
baseURI
"http://localhost:9000/testget#"
childElementCount
2
childNodes
NodeList[ActionOne, ActionTwo]
0
ActionOne
1
ActionTwo
length
2
item
item()
iterator
iterator()
__proto__
NodeListPrototype { item=item(), iterator=iterator()}
So under the NodeList I see the correct actions.
The issue I am having is that I don't know how to get those actions out of there and listed or even just have them available as separate variables.
My attempt at getting then logging each child:
function getActionsAllowed() {
var children = actionsAllowed.childNodes;
for (var i = 0; i < children.length; i++) {
console.log(children);
}
}
Problem is, ".childNodes" keeps returning as "undefined".
Is there another, better way to do this? Or is this correct but I've made a mistake?
Thank you.
Kind Regards,
Gary Shergill
EDIT:
working code for just one result:
var currentState = $(packet).find('currentState').text();
var actionsBanned = $(packet).find('actionsBanned').text();
EDIT 2:
Updated code to:
$(packet).find('actionsAllowed').each(function () {
var children = this.childNodes;
for (var i = 0; i < children.length; i++) {
var action = children[i].nodeName
console.log(action);
}
});
This works =) It logs each action one by one, so it's working. Just a matter of choosing how to change the console.log() to something more useful (need to define each one seperately...).
Will create a new thread if I have trouble and link it from here.
(my related thread: Returning Arrays and ChildNodes)
You can always extract the DOM nodes from the jQuery object using toArray or get.
var actionsAllowed = $(packet).find('actionsAllowed').get();
But that's generally not necessary since the jQuery object itself implements an extensive API to manipulate the nodes.
E.g. looping over the nodes
$(packet).find('actionsAllowed').each(function () {
//looping over childnodes
$(this).children().each(function () {
console.log($(this).text());
});
});
If you just want to children of actionsAllowed nodes directly, you can also do:
$(packet).find('actionsAllowed > *').each(function () {
console.log($(this).text());
});

javascript, remove identical items from array

I do an ajax call in a lightbox script which returns a form.
when the form is loaded I call var initial = $('form').serializeArray();
when the form is submitted I call var final = $('form').serializeArray();
which gives me two arrays of objects,
What I now want to do is compare each object in the arrays and remove those that have not changed.
how would I do this?
I'm assuming that the two arrays will have equal length, and that the elements will be in the same order in both arrays. In this case, what you need to do is look at each element of the first array and compare it to the corresponding element of the second array; if they match, then remove the element in that position from both arrays.
Something like this should work (though I haven't tested it):
var i = 0;
while (i < initial.length) {
if(initial[i] == final[i]) {
initial.splice(i,1);
final.splice(i,1);
}
else {
i++;
}
}
The fastest way to do this I think
var len = initial.length, i=0, changed=[];
/* I hope initial.length==final.length*/
for(i; i<len; i++){
/* 0== '' */
if (initial[i]===final[i])
changed[i] = final[i];
}
//now play with
changed
I've got confused abou the question
does .splice() reorder the indexes?

Sorting Divs in jQuery by Custom Sort Order

I'm trying to re-sort the child elements of the tag input by comparing
their category attribute to the category order in the Javascript
variable category_sort_order. Then I need to remove divs whose category attribute
does not appear in category_sort_order.
The expected result should be:
any
product1
product2
download
The code:
<div id="input">
<div category="download">download</div>
<div category="video">video1</div>
<div category="video">video2</div>
<div category="product">product1</div>
<div category="any">any</div>
<div category="product">product2</div>
</div>
<script type="text/javascript">
var category_sort_order = ['any', 'product', 'download'];
</script>
I really don't even know where to begin with this task but if you could please provide any assistance whatsoever I would be extremely grateful.
I wrote a jQuery plugin to do this kind of thing that can be easily adapted for your use case.
The original plugin is here
Here's a revamp for you question
(function($) {
$.fn.reOrder = function(array) {
return this.each(function() {
if (array) {
for(var i=0; i < array.length; i++)
array[i] = $('div[category="' + array[i] + '"]');
$(this).empty();
for(var i=0; i < array.length; i++)
$(this).append(array[i]);
}
});
}
})(jQuery);
and use like so
var category_sort_order = ['any', 'product', 'download'];
$('#input').reOrder(category_sort_order);
This happens to get the right order for the products this time as product1 appears before product2 in the original list, but it could be changed easily to sort categories first before putting into the array and appending to the DOM. Also, if using this for a number of elements, it could be improved by appending all elements in the array in one go instead of iterating over the array and appending one at a time. This would probably be a good case for DocumentFragments.
Just note,
Since there is jQuery 1.3.2 sorting is simple without any plugin like:
$('#input div').sort(CustomSort).appendTo('#input');
function CustomSort( a ,b ){
//your custom sort function returning -1 or 1
//where a , b are $('#input div') elements
}
This will sort all div that are childs of element with id="input" .
Here is how to do it. I used this SO question as a reference.
I tested this code and it works properly for your example:
$(document).ready(function() {
var categories = new Array();
var content = new Array();
//Get Divs
$('#input > [category]').each(function(i) {
//Add to local array
categories[i] = $(this).attr('category');
content[i] = $(this).html();
});
$('#input').empty();
//Sort Divs
var category_sort_order = ['any', 'product', 'download'];
for(i = 0; i < category_sort_order.length; i++) {
//Grab all divs in this category and add them back to the form
for(j = 0; j < categories.length; j++) {
if(categories[j] == category_sort_order[i]) {
$('#input').append('<div category="' +
category_sort_order[i] + '">'
+ content[j] + '</div>');
}
};
}
});
How it works
First of all, this code requires the JQuery library. If you're not currently using it, I highly recommend it.
The code starts by getting all the child divs of the input div that contain a category attribute. Then it saves their html content and their category to two separate arrays (but in the same location.
Next it clears out all the divs under the input div.
Finally, it goes through your categories in the order you specify in the array and appends the matching child divs in the correct order.
The For loop section
#eyelidlessness does a good job of explaining for loops, but I'll also take a whack at it. in the context of this code.
The first line:
for(i = 0; i < category_sort_order.length; i++) {
Means that the code which follows (everything within the curly brackets { code }) will be repeated a number of times. Though the format looks archaic (and sorta is) it says:
Create a number variable called i and set it equal to zero
If that variable is less than the number of items in the category_sort_order array, then do whats in the brackets
When the brackets finish, add one to the variable i (i++ means add one)
Then it repeats step two and three until i is finally bigger than the number of categories in that array.
A.K.A whatever is in the brackets will be run once for every category.
Moving on... for each category, another loop is called. This one:
for(j = 0; j < categories.length; j++) {
loops through all of the categories of the divs that we just deleted from the screen.
Within this loop, the if statement checks if any of the divs from the screen match the current category. If so, they are appending, if not the loop continues searching till it goes through every div.
Appending (or prepending) the DOM nodes again will actually sort them in the order you want.
Using jQuery, you just have to select them in the order you want and append (or prepend) them to their container again.
$(['any', 'product', 'video'])
.map(function(index, category)
{
return $('[category='+category+']');
})
.prependTo('#input');
Sorry, missed that you wanted to remove nodes not in your category list. Here is the corrected version:
// Create a jQuery from our array of category names,
// it won't be usable in the DOM but still some
// jQuery methods can be used
var divs = $(['any', 'product', 'video'])
// Replace each category name in our array by the
// actual DOM nodes selected using the attribute selector
// syntax of jQuery.
.map(function(index, category)
{
// Here we need to do .get() to return an array of DOM nodes
return $('[category='+category+']').get();
});
// Remove everything in #input and replace them by our DOM nodes.
$('#input').empty().append(divs);
// The trick here is that DOM nodes are selected
// in the order we want them in the end.
// So when we append them again to the document,
// they will be appended in the order we want.
I thought this was a really interesting problem, here is an easy, but not incredibly performant sorting solution that I came up with.
You can view the test page on jsbin here: http://jsbin.com/ocuta
function compare(x, y, context){
if($.inArray(x, context) > $.inArray(y, context)) return 1;
}
function dom_sort(selector, order_list) {
$items = $(selector);
var dirty = false;
for(var i = 0; i < ($items.length - 1); i++) {
if (compare($items.eq(i).attr('category'), $items.eq(i+1).attr('category'), order_list)) {
dirty = true;
$items.eq(i).before($items.eq(i+1).remove());
}
}
if (dirty) setTimeout(function(){ dom_sort(selector, order_list); }, 0);
};
dom_sort('#input div[category]', category_sort_order);
Note that the setTimeout might not be necessary, but it just feels safer. Your call.
You could probably clean up some performance by storing a reference to the parent and just getting children each time, instead of re-running the selector. I was going for simplicity though. You have to call the selector each time, because the order changes in a sort, and I'm not storing a reference to the parent anywhere.
It's seems fairly direct to use the sort method for this one:
var category_sort_order = ['any', 'product', 'download'];
// select your categories
$('#input > div')
// filter the selection down to wanted items
.filter(function(){
// get the categories index in the sort order list ("weight")
var w = $.inArray( $(this).attr('category'), category_sort_order );
// in the sort order list?
if ( w > -1 ) {
// this item should be sorted, we'll store it's sorting index, and keep it
$( this ).data( 'sortindex', w );
return true;
}
else {
// remove the item from the DOM and the selection
$( this ).remove();
return false;
}
})
// sort the remainder of the items
.sort(function(a, b){
// use the previously defined values to compare who goes first
return $( a ).data( 'sortindex' ) -
$( b ).data( 'sortindex' );
})
// reappend the selection into it's parent node to "apply" it
.appendTo( '#input' );
If you happen to be using an old version of jQuery (1.2) that doesn't have the sort method, you can add it with this:
jQuery.fn.sort = Array.prototype.sort;

Categories

Resources