JavaScript 'input multiple' file duplication - javascript

This is my code:
var rowData = [];
var showFiles = function () {
var input = document.getElementById('doc-upload');
if (input.files.length > 0) {
for (var i = 0; i < input.files.length; i += 1) {
rowData.push([input.files[i].name]);
};
console.log(rowData);
};
};
document.getElementById('doc-upload').addEventListener('change', showFiles, this);
'rowData' recives a normal value for the first time i upload some thing.
At the second try it starts to duplicate incoming values.
If i uploaded 1 file first try it's ok.
Second time i wold get 2 same files.
Third 4 files, exetera.
Why this is happening?
UPD:
More explanations:
What happaning is: i upload x.doc my array is [x.doc], now i want to upload y.doc. I choose y.doc and my array turns in to [x.doc, y.doc, y.doc], then i upload z.doc and aaray looks like [x.doc, y.doc, y.doc, z.doc, z.doc, z.doc, z.doc]. And so on. It have to do some thing with length property, i messed it up some how.
UPD2:
Now the full version of the code:
//file upload
var rowData = [];
docAddButton.addListener('click', function () {
var showFiles = function () {
var input = document.getElementById('doc-upload');
if (input.files.length > 0) {
for (var i = 0; i < input.files.length; i += 1) {
if (rowData.indexOf(true, input.files[i].name, Math.round(input.files[i].size * 0.001) + ' кб') === -1) {
rowData.push([
true,
input.files[i].name,
Math.round(input.files[i].size * 0.001) + ' кб'
]);
}
}
console.log(rowData);
tableModel.setData(rowData);
};
};
document.getElementById('doc-upload').addEventListener('change', showFiles, this);
});
Thanx every one who helped!
Solution:
You can see from UPD2 that I have my function inside eventListener 'click'. What was happening is every time I pressed my input button it was reciving extra 'change' listener.
I changed .addListener for input to .addListenerOnce.

Presumably you're not reloading the page, and you're not clearing out rowData. You haven't shown how/where you define rowData, but it would appear that the same instance of it is reused between calls to showFiles. (If you haven't declared it anywhere, you're falling prey to The Horror of Implicit Globals.)
From your comments below, it sounds like you want to keep the entries in rowData, but you want to only add new entries. If so, you'll need an explicit check:
var showFiles = function () {
var input, i, file;
input = document.getElementById('doc-upload');
for (i = 0; i < input.files.length; i += 1) {
file = input.files[i].name;
if (indexOfFile(rowData, file) === -1) {
rowData.push([file]);
}
};
console.log(rowData);
};
function indexOfFile(data, file) {
var index;
for (index = 0; index < data.length; ++index) {
// Note that the 0 may need to be changed if the
// `rowData.push([file])` line above doesn't put
// the filename at index 0
if (data[index][0] === file) {
return index;
}
}
return -1;
}
Side note: You've said that the reason you're pushing an array rather than just the filename is that there's other information you're also including in that array but you left it out of your question. That's fine, but it may be delicate, see my note about index 0 above. You might consider using an array of objects instead:
rowData.push({
file: file,
other: "info",
goes: "here"
});
...and then in indexOfFile:
if (data[index].file === file) {
That way, the code is less susceptible to breaking if you change the structure of what you're pushing.

Basically,
rowData.push()
will just keep appending the elements to the end of your variable. You need to have a check if those inputs are already present.
(Edit-)
Try this:-
rowData=[];
var showFiles = function () {
var input = document.getElementById('doc-upload');
if (input.files.length > 0) {
for (var i = 0; i < input.files.length; i += 1) {
var f=[];
for(var j=0;j<rowData.length;j++)
f.push(rowData[j][0]);
if(f.indexOf(input.files[i].name) == -1)
rowData.push([input.files[i].name]);
}
console.log(rowData);
};
};
document.getElementById('doc-upload').addEventListener('change', showFiles, this);

Related

Cannot return a True or Force value out of a variable within an if statement in Angular

I have the following checkbox who is calling a function on launch to get checked based on a value that comes in from an api (cat.term_id)
<input ng-checked="ifCatExcluded(cat.term_id)">
The function works as follows: The first bit sets the checkbox value to true and gets an array which i need to cross check the id.
$scope.ifCatExcluded = function(sent_id){
var doesNotExist = true;
arraytosearch = JSON.parse(localStorage.getItem("categoryListMem"));
The second bit creates an empty array and adds the cat.term_id to this new array to avoid re running this id later.
if($scope.tempArray == undefined || $scope.tempArray.indexOf(undefined) > 0) {
$scope.tempArray = [];
}
if ($scope.tempArray.indexOf(sent_id) < 0) {
$scope.tempArray.push(sent_id);
console.log($scope.tempArray);
for (var i = 0; i < arraytosearch.length; i++) {
if (arraytosearch[i]['id'] == sent_id) {
doesNotExist = false;
console.log(sent_id + " IS EXCLUDED");
}
}
}
Then the last part returns the value for the checkbox and here is the problem. I cannot get a return of true or false from the doesNotExist variable. I noticed that when I take
for (var i = 0; i < arraytosearch.length; i++) {" ecc...
out of the if statement everything works...
return doesNotExist;
console.log(doesNotExist);
};
Any help is much appreciated.

JQGrid refreshIndex() method for local data not clearing previous index array

I have local data delete functionality:
$.each(rowids, function() { // - delete selected rows
$grid.delRowData(this);
});
I noticed that after this call, doing retrieving the _index:
var xref = $grid.jqGrid('getGridParam', '_index');
the _index still contains the deleted row.
I looked into the JQGrid source, after the deletion of the local data, a call to refreshIndex() is made. I noticed that the Index is not removed, but rather the existing array is overwritten:
for (i = 0; i < datalen; i++) {
val = $.jgrid.getAccessor(ts.p.data[i], idname);
if (val === undefined) { val = String(i + 1); }
ts.p._index[val] = i;
}
I added the following right before the loop above:
ts.p._index = [];
This appears to resolve my issue, will this cause problems?
I think that you are right. One could change the line of delRowData to
delete $t.p._index[id];
and one should add the line
ts.p._index = [];
before the loop exactly like you suggested.
I think you should post the corresponding bug report to trirand.

Store score in a variable after an event

Desirable result: After the user choose an answer, I want to modify score variable in:
score += 1 if the answer is right either not changing at all if the answer is wrong.
Current result: For every choice user is making, the score remains the same: 0.
First, I store the paragraph that will be changed in question_paragraph and the button that will be clicked by user in next_button. Also, I stored the value(I put the attribute value on every input using the array notation - 0 first, 1 second etc.) in user_answer.
var question_paragraph = document.getElementById('question');
var next_button = document.getElementById('next');
var i = 0;
var user_answer = getCheckedValue(document.getElementsByName('choice'));
var y = 0;
var score = 0;
The getCheckedValue function will return the value attribute of my input if exists.
function getCheckedValue(radioObj) {
var radioLength = radioObj.length;
for(var z = 0; z < radioLength; z++) {
if(radioObj[z].checked) {
return radioObj[z].value;
}
}
return "Error!";
}
Here is the problem. The function works fine, except the isolated area. allQuestion is my object where I stored the questions, the possible answers and the right answer, correctAnswer(I don't included it here but works correctly). I put a conditional statement to increase y and code>score with one if the allQuestions[y].correctAnswer is qual with the value of the user_choice.
function changeQuestion() {
//PROBLEM
if(allQuestions[y].correctAnswer == user_answer){
score += 1;
y++;
} else{y++;}
//PROBLEM
i = (i < allQuestions.length) ? (i + 1) : 0;
if (i == allQuestions.length) {
i = 0;
return question_paragraph.replaceChild(document.createTextNode(allQuestions[0].question), question_paragraph.firstChild);
}
var newNode = document.createTextNode(allQuestions[i].question);
console.log(score);
return question_paragraph.replaceChild(newNode, question_paragraph.firstChild);
}
Finnaly, I called the addHandler function.
function addHandler(name, type, handler){
if (name.addEventListener){
name.addEventListener(type, handler, false);
} else if (name.attachEvent){
name.attachEvent("on" + type, handler);
} else {
name["on" + type] = handler;
}
}
addHandler(next_button, 'click', changeQuestion);
Well, something just appears to be funny here so far. First of all, I don't see any initialization to the variable y. If y is a global variable that is retaining its value, then maybe there is an issue with your object: allQuestions{}. Could you provide the code for building your object allQuestions{}? Without it, I don't think that I could fully answer this question, but I believe that is where your problem lies.
Oops, this was supposed to be a comment, not an answer, sorry...

Saving a cycling number with localStorage

I've been trying to find an answer to this all morning and can't seem to get it right.
The idea is to have a different array item display when the user clicks the button. The problem is that once they go to a different page, the array resets back to 0 and starts over. I want it to remember where it is in the array and be able to continue even if the user has gone to a different page.
This is what I have so far, but it will break if I switch to a different page before clicking on the button.
function iAmCarousel() {
var describe = document.getElementById("describe");
var describeArray = [];
describeArray[0] = "Front End Web Developer";
describeArray[1] = "Responsive Design nut";
describeArray[2] = "Photoshop nerd";
describeArray[3] = "soon to be husband";
var refreshButton = document.getElementById("refresh");
var index = localStorage.getItem("Index");
describe.innerText = describeArray[index];
refreshButton.onclick = function() {
while(index < describeArray.length) {
index++;
localStorage.setItem("Index", index);
if(index == describeArray.length) {
index = 0;
}
describe.innerText = describeArray[index];
break;
}
}
}
iAmCarousel();
Because "Index" will not be set in localStorage, and calling getIndex() on a non-existant key returns null. You're left with describeArray[null], which won't work (and will give you undefined).
var index = localStorage.getItem("Index");
if (index === null) {
index = 0;
}
describe.innerText = describeArray[index];
... or you can just do var index = localStorage.getItem("Index") || 0; (via short circuit evaluation)

setcellvalue not working on all pages in JQWidget grid

I am using a JQWidget grid with paging to display table data, and I am replacing the values in one column with a string. This works fine for the initial page, but when I open the next page in the table I no longer get the string replacements, only the original value.
My home page uses this code, which works as expected ('A' and 'W' are replaced by 'newString' and 'newString2' in the table):
$("#jqxgrid").bind("bindingcomplete", function (event) {
var numrows = $("#jqxgrid").jqxGrid('getrows');
for (i = 0; i < numrows.length; i++) {
var value = $("#jqxgrid").jqxGrid('getcellvalue', i, 'column');
if (value == 'W') {
$("#jqxgrid").jqxGrid('setcellvalue', i, 'column', 'newString');
}
else if (value == 'A') {
$("#jqxgrid").jqxGrid('setcellvalue', i, 'column', 'newString2');
}
});
I tried a few ideas for the new page, such as placing the above binding function into a loop based on the number of pages:
var paginginfo = $("#jqxgrid").jqxGrid('getpaginginformation');
for (i = 0; i < paginginfo.pagescount; i++) { ...
and I also tried putting the binding function inside another function tied to the page change event:
$("#jqxgrid").bind("pagechanged", function (event) {
$("#jqxgrid").bind("bindingcomplete", function (event) { ...
but neither of these worked.
Perhaps 'numrows' is limiting setcellvalue to the first page?
Thanks //
The "binding function" is not a function, it is an event which is raised usually once the binding is completed, to in general you tried to bind to an event within another event and that normally results in nothing. You loop code - for (i = 0; i < numrows.length; i++) {... would probably not work in case of virtual paging, because the loop should be from the start index to the end index and the start index wouldn't be 0 on the second page.
I found this workaround..I am not sure if this is really foolproof, but it seems to work so far..if you know a more precise solution please post...
$("#jqxgrid").bind("bindingcomplete", function (event) {
var paginginfo = $("#jqxgrid").jqxGrid('getpaginginformation');
var pagenum = paginginfo.pagenum;
var pagesize = paginginfo.pagesize;
var pageRows = (pagenum + 1) * pagesize;
for (var i = 0; i < pageRows; i++) {
var value = $("#jqxgrid").jqxGrid('getcellvalue', i, 'currTrafDir');
if (value == 'W') { ......

Categories