I'm currently in the process of passing a javascript array though to a form for submission with a file upload.
As it currently stands i have been able to pass the javascript array though to the form but not quite how i would like.
The initial javascript values i have stored in the array are as follows:
Folder 1/File 1.txt
Folder 1/Folder 2/File 2.txt
Once passed though the array output from the PHP variable is as follows:
Array ( [0] => Folder 1/File 1.txt,Folder 1/Folder 2/File 2.txt )
What i would like to do however if possible is alter the array to the following:
Array ( [0] => Folder 1/File 1.txt,
[1] => Folder 1/Folder 2/File 2.txt )
The HTML code the array is being passed to from javascript:
<input type="hidden" id="pathArray" name="pathArray[]" value="pathArray">
The current javascript code:
let picker = document.getElementById('picker');
var pathStructure = [];
var i = 0;
picker.addEventListener('change', e =>
{
for (let file of Array.from(e.target.files))
{
pathStructure[i] = file.webkitRelativePath;
i++;
};
document.getElementById('pathArray').value = pathStructure.toString();
});
The main issue i'm having and at the moment is setting the array position values of the form for submission. I'm able to input the array into the form but not able to set the individual array positions and as of yet have been unable to find the relevant documentation on how to achieve this somehow like the following:
let picker = document.getElementById('picker');
var pathStructure = [];
var i = 0;
picker.addEventListener('change', e =>
{
for (let file of Array.from(e.target.files))
{
pathStructure[i] = file.webkitRelativePath;
document.getElementById('pathArray').value[i] = pathStructure[i].toString();
i++;
};
});
Any help would be greatly appreciated and if at all there is any further detail that would be required please let me know and i'll do my best to expand or provide any additional information!
toString method joins the array and returns one string containing each array element separated by commas. So you lose the array information.
I usually did something like this with adding multiple inputs:
<form id="form">
<input type="hidden" class="pathArray" name="pathArray[]">
<input type="hidden" class="pathArray" name="pathArray[]">
...
</form>
The idea is that for each value you create a new input. You will have input for Folder 1/File 1.txt, another input for Folder 2/File 2.txt and so on. The final code could look something like this
let picker = document.getElementById('picker');
var pathStructure = [];
var i = 0;
picker.addEventListener('change', e =>
{
for (let file of Array.from(e.target.files))
{
pathStructure[i] = file.webkitRelativePath;
var input = document.createElement("input");
input.type = 'hidden';
input.name = 'pathArray[]';
input.classList.add('pathArray');
document.getElementById("form").appendChild(input);
document.getElementsByClassName('pathArray')[i].value = pathStructure[i].toString();
i++;
};
});
Hope you get the idea.
Related
I have a problem approaching this problem and I'm unsure in how to solve it. My XML looks like this:
<Order>
<OrderLines>
<ProductLine>
<ManufacturerArticleNo>ARTICLENUMBER</ManufacturerArticleNo>
<Serials>
<SerialNumber>
.
.
<SerialNumber>
</Serials>
<ProductLine>
<ManufacturerArticleNo>ARTICLENUMBER</ManufacturerArticleNo>
<Serials>
<SerialNumber>
.
.
<SerialNumber>
</Serials>
What I want to do is create an array, and fill it with objects with articleNumber, serialnumbers. Where I'm stuck is getting all the serialNumbers from a node to the corresponding article number.
Edits after comments:
Expected output: An array filled with the objects with ArticleNumber, Corresponding serial number. One serial number = one object.
Current Code:
//Create Article List
var artList = [];
//Get articles
var nodeArticleNo = xmlDoc.getFirstNode('//ProductLine/ManufacturerArticleNo');
while(nodeArticleNo != null) {
var artNo = xmlDoc.getNodeText('//ProductLine/ManufacturerArticleNo');
//Get Serials
var nodeSerialNumber = xmlDoc.getFirstNode('//Serials/SerialNumber');
while(nodeSerialNumber != null){
var serialNo = xmlDoc.getNodeText('//Serials/SerialNumber');
artList.push({ArticleNumber: artNo, SerialNumber, serialNo});
nodeSerialNumber = xmlDoc.getNextNode(nodeSerialNumber);
}
nodeArticleNo = xmlDoc.getNextNode(nodeArticleNo);
}
This is how I have been trying to solve it but I hate the while in a while and it is not working as intended
Thank you!
i need when i click on input then must prompt and result transferred to storage, help me please, i tried to find this resolve in google but no use:(
const output = document.querySelector('[data-output]');
const LOCAL_STORAGE_LIST_KEY = 'task.lists';
const LOCAL_STORAGE_SELECTED_LIST_ID_KEY = 'task.selectedListId';
let lists = JSON.parse(localStorage.getItem(LOCAL_STORAGE_LIST_KEY)) || [];
let selectedListId = localStorage.getItem(LOCAL_STORAGE_SELECTED_LIST_ID_KEY);
output.addEventListener('click', e => {
let txt = prompt('Enter what you want to do ^^').toString();
lists.push(txt);
saveAndRender();
});
Your error seems to be in the renderLists function, which is on the JSFiddle that you linked in the comments. You're looping over your lists Array, which contains the input String - But you're trying to access properties as if it was an Object; which is instead giving you undefined
You have createListwhich will turn that input into an Object with the current keys, so I assume you meant to include that
output.addEventListener('click', e => {
let txt = prompt('Enter what you want to do ^^').toString();
lists.push(createList(txt));
saveAndRender();
});
Here is an updated JSFiddle
I have an object declared, and I have an html form with some matching fields.
All fields in the form are in the object, but the object also has a couple of additional variables and functions.
I'd like to fill the object with the data entered in the form, what I'm trying right now overwrites the declared object, and so doesn't have the functions nor the other variables.
The object :
var Container = {
nodes: [],
Contains: function (Node) {
for (var i = 0; i < this.nodes.length; i++) {
if (this.nodes[i].nodeID === Node.nodeID)
return (i);
}
return (-1);
}
How I fill it from the form :
const handleContainerForm = event => {
event.preventDefault();
ContainerFormToJSON(form.elements);
var i = JSONData.Contains(Container);
if (i === -1)
JSONData.containers.push(Container);
else
JSONData.container[i] = Container;
output = JSON.stringify(JSONData, null, " ");
displayContents(output);
};
The form has ID, Title, Folder, Image and Description as fields, so this last Container object doesn't have the Contains() function nor the nodes[] array.
How do I end up with a complete, filled version of the object I have declared ?
In ContainerFormToJSON function, before the statement
return Container
define:
//container.nodes and container.contains
You are right, JavaScript is very different from C#, especially in regards to OOP. But that doesn't make it better or worse.
In JavaScript, you don't need to declare an object's properties, like you have to when you use classes. I think that you only want to serialize the form's input values to JSON. I recommend not to use an object that additionally has a nodes property and a Contains method.
If you need to keep a copy of the unserialized object, create two objects:
class Container {
constructor () {
this.nodes = [];
}
indexOf (node) {
return this.nodes.findIndex(n => n.nodeID === node.nodeID);
}
}
Container.nodeID = 0; // think of it as a static property
function extractValues (elements) {
// 'elements' is an array of <input> elements
// the 'container' will be filled and serialized
var container = new Container();
for (var index in elements) {
var element = elements[index];
container[element.name] = element.value;
}
container.nodeID = Container.nodeID++; // give the container a unique ID
return container;
}
var inputs = document.querySelectorAll('input');
var jsonData = new Container();
document.querySelector('button').addEventListener('click', function () {
var newContainer = extractValues(inputs);
var index = jsonData.indexOf(newContainer);
if (index === -1) {
jsonData.nodes.push(newContainer);
} else {
jsonData.nodes[index] = newContainer;
}
var jsonString = JSON.stringify(jsonData, null, ' ');
console.log(jsonString);
});
<input name="containerID">
<input name="containerTitle">
<!-- ... -->
<button>Serialize</button>
Please note: only setting an object's properties doesn't make it to JSON. It's only JSON if it's serialized to a string. I recommend this article. To serialize a JavaScript object, use JSON.stringify.
Edit:
Looking at the edit of your question, I think it might be preferable to create a Container class. Both jsonData and the containers of the form data will be instances of that class. It can contain other containers (nodes), and can get the index of such a nested container using the indexOf method. I implemented this in the above code snippet. Whenever you hit the "Serialize" button, a new container with the current <input>s' contents will be added to jsonData. The JSON form of jsonData will be logged to the console.
I hope this is what you are looking for. To better understand JavaScript OOP,
take a look at some of the articles at MDN.
I am trying to upload a file and read its contents and then output the contents to a table. The information needs to be place on a new row whenever there is a > char in the string.
I am having a bit of an issue wrapping my head around how I can create a new 'tr' and then add data to the a cell 'td' in that row.
I am stuck on the <tr> and <td> and adding them dynamically with the contents from the file. I am sure I can use regex to look for the > char but that isn't really what I need help with. I am struggling with how I take the information after the > char and add it to a new row in the table.
UPDATE: Ok, so I am still not fully functional on what I am trying to do. I am uploading the file, reading it, and storing the information as an object. However, I can only do this for one instance. When I upload a text file there will be multiple DNA sequences in the file. Each sequence will have a sequence_id like this:
9013e1
ACAAGATGCCATTGTCCCCCGGCCTCCTGCTGCTGCTGCTCTCCGGGGCCACGGCCACCGCTGCCCTGCC
CCTGGAGGGTGGCCCCACCGGCCGAGACAGCGAGCATATGCAGGAAGCGGCAGGAATAAGGAAAAGCAGC
CTCCTGACTTTCCTCGCTTGGTGGTTTGAGTGGACCTCCCAGGCCAGTGCCGGGCCCCTCATAGGAGAGG
AAGCTCGGGAGGTGGCCAGGCGGCAGGAAGGCGCACCCCCCCAGCAATCCGCGCGCCGGGACAGAATGCC
CTGCAGGAACTTCTTCTGGAAGACCTTCTCCTCCTGCAAATAAAACCTCACCCATGAATGCTCACGCAAG
TTTAATTACAGACCTGAA
So, I am trying to read the file, find all sequence ID's and then sequences and I want an editable leading and trailing trim like so:
var objArray = [
{
'id': '>9013e1',
'sequence': 'ACAAGATGCCATTGTCCCCCGGCCT...',
'lead_trim': //get the value from a input from the user,
'trail_trim': //same as above
},
{
//another obj like above
}
]
The sequence also needs to have a line break inserted after every 60 characters. Once I have processed the data in the text file correctly I then need to output the data to a table like I stated in my original post. The problem I am having is I am getting stuck on only being able to store information for one obj in my objArray.
Here is a look at my code...
function scanForSequences(event) {
//Get the file from HTML input tag
var file = event.target.files[0];
var output = document.getElementById('table');
if(file) {
var sequenceArray = [];
var objArray = [];
var obj = {};
var str = '';
var subStr = '';
//Create a new file reader
var reader = new FileReader();
//When the file reader loads
reader.onload = function(evt) {
//Add the contents of file to variable contents
var contentsByLine = evt.target.result.split('\n');
//Alert user the file upload has succeeded
alert('File ' + file.name + ' has been uploaded!');
for(var i = 0; i < contentsByLine.length; i++){
if(contentsByLine[i].charAt(i) == '>'){
obj['id'] = contentsByLine[i];
}else{
sequenceArray.push(contentsByLine[i]);
str = sequenceArray.toString();
subStr += str.substring(0, 60) + '\n';
str = str.substring(60);
obj['sequence'] = subStr;
obj['lead_trim'] = 0;
obj['trail_trim'] = 0;
}
objArray.push(obj);
console.log(objArray);
}
}
reader.readAsText(file);
} else {
alert('Failed to upload file!');
}
console.log(obj);
}
document.getElementById('fileItem').addEventListener('change', scanForSequences, false);
Please find my proposed solution in the fiddle below:
https://jsfiddle.net/w6jbuqfy/
Here's an explanation of what's going on:
First we have a input of type file:
<input id="input" type="file">
We then attach an event listener to it to execute a function once a user has selected a file
var inputElement = document.getElementById("input");
inputElement.addEventListener("change", handleFile, false);
Inside the handleFile function, we use a FileReader to read the file.
var fileList = this.files;
var file = fileList[0];
var fr = new FileReader();
fr.readAsText(file);
Now fileReaders are asynchronous in nature, here i've got a simple interval that checks on the status of the filereader every 100ms.
var checkReadyId = setInterval(function(){
if(fr.readyState === 2){ //done
window.clearInterval(checkReadyId);
addFileDataToResults(fr.result);
} else{
console.log('not done yet');
}
}, 100);
FileReaders are done reading when their readyState is 2. So we check for that and once we are done, we can access the result from FileReader.result. As we read this as a text earlier above, we'll get a string back. We then pass this to our addFileDataToResults function.
function addFileDataToResults(fileAsString){
var resultsDiv = document.getElementById('results');
var tr = document.createElement('tr');
var td = document.createElement('td');
var linesInFile = fileAsString.split('\n');
console.log(linesInFile);
td.textContent = linesInFile[0];
tr.appendChild(td);
resultsDiv.appendChild(tr);
}
What is happening here is that we grab the resultsDiv which is a real node in our HTML. We then use createElement which creates virtual nodes and put data into them. IN this case, we are simply putting the text of the first line into our file. Once we are done creating this virtual nodes, we use appendChild to our real node which turns the virtual node into a real node and you can see it in the html.
Hope this helps
:)
Here's what i'm trying to accomplish. Insert an array from php into an HTML form and then have that array be pushed in a JS array.
PHP
$proxiearray = array();
if($row7['attribute_0'] != NULL) { array_push($proxiearray,$row7['attribute_0']);}
if($row7['attribute_1'] != NULL) { array_push($proxiearray,$row7['attribute_1']);}
<input type="hidden" class="proxie_attributes" value="'.htmlspecialchars(json_encode($proxiearray)).'">
Now what i want with that is on uppon a certain task on the client side for my JS to take that aray and push it in another one.
JS
attributesArray[counter] = new Array();
if(proxiearray) { attributesArray[counter] = proxiearray; }
If i alert the array i get
["1","4"],5,6
This just pushed in the array the ["1","4"] but what i would want it to push is have a result like
1,4,5,6
I know i could go with X amount of inputs although that is not a solution since i may have to use a bigger ammount of attributes in the future.
EDIT: The alert is on the attributesArray.
The attributesArray[counter] alert is ["1","4"]
You can use following;
if ($(this).find('div .proxie_attributes').length > 0) {
var proxiearray = JSON.parse($(".proxie_attributes").val());
attributesArray[counter] = new Array();
if(proxiearray) {
attributesArray[counter] = proxiearray;
}
}