I have code which I don't want to nearly copy paste, instead I want an short alternative.
I have this 4 elements, which all should be manipulated, I want to place an Input inside them and edit some arguments.
Now I want to run the same code for each of these 4.
const tableTaskName = document.getElementById('taskName_' + taskID);
const tableStartTime = document.getElementById('startDate_' + taskID);
const tableEndTime = document.getElementById('endDate_' + taskID);
const tableStatus = document.getElementById('status_' + taskID);
Below are examples where I used tableTaskName.
The task is the parameter my function takes, and is one task of the tasks Array on the bottom.
The type should be text for tableTaskName and tableStatus, for tableStartTime and tableEndTime it should be time.
tableTaskName.innerHTML = ''
tableTaskName.textContent = task.taskName;
const inputTaskName = document.createElement('input');
inputTaskName.type = 'text';
var tasks = [{ 'id': 1, 'taskName': 'INIT', 'startDate': new Date('1970-01-01T00:00:00Z'), 'endDate': new Date('1970-01-01T00:00:10Z'), 'duration': new Date('1970-01-01T00:00:10Z'), 'status': 'RUNNING'},
{ 'id': 2, 'taskName': 'INIT', 'startDate': new Date('1970-01-01T00:00:00Z'), 'endDate': new Date('1970-01-01T00:00:10Z'), 'duration': new Date('1970-01-01T00:00:10Z'), 'status': 'RUNNING'} ]
Is the only possible method to take copy paste the code? I'd like to do it without that, if possible.
In JavaScript you can grab an array of elements by using document.getElementsByClassName().
So if you have multiple elements with the same class name it will fill the array. Then just loop over the array and it will apply the code to all elements.
Like this:
<div class="divElement"></div>
<div class="divElement"></div>
<div class="divElement"></div>
<script>
var elements = document.getElementsByClassName("divElement");
for (var i = 0; i < elements.length; i++){
// code to edit elements
}
</script>
You can make an array of property names and then make two for loops to go through properties and task:
const props = ['taskName', 'startDate', 'endDate', 'status']
...
for (let task of tasks) {
for (let prop of props) {
const tableProp = document.getElementById(prop + '_' + task.id)
tableProp.innerHTML = ''
tableProp.textContent = task[prop]
const inputTaskName = document.createElement('input')
if (prop == 'startDate' || prop == 'endDate') {
inputTaskName.type = 'time'
} else {
inputTaskName.type = 'text'
}
tableProp.appendChild(inputTaskName)
}
}
Here is a working example. I just assumed the html layout:
const props = ['taskName', 'startDate', 'endDate', 'status']
const tasks = [{
id: 1,
taskName: 'INIT',
startDate: new Date('1970-01-01T00:00:00Z'),
endDate: new Date('1970-01-01T00:00:10Z'),
duration: new Date('1970-01-01T00:00:10Z'),
status: 'RUNNING',
},
{
id: 2,
taskName: 'Another task name',
startDate: new Date('1970-01-01T00:00:00Z'),
endDate: new Date('1970-01-01T00:00:10Z'),
duration: new Date('1970-01-01T00:00:10Z'),
status: 'stopped',
},
]
for (let task of tasks) {
for (let prop of props) {
const tableProp = document.getElementById(prop + '_' + task.id)
tableProp.innerHTML = ''
tableProp.textContent = task[prop]
const inputTaskName = document.createElement('input')
if (prop == 'startDate' || prop == 'endDate') {
inputTaskName.type = 'time'
} else {
inputTaskName.type = 'text'
}
tableProp.appendChild(inputTaskName)
}
}
/* Just for demo */
.task-block {
background-color: lightgrey;
padding: 4px;
}
.task-block p {
display: flex;
flex-direction: column;
align-items: flex-start;
margin: 4px;
}
<div class="task-block">
<p id="taskName_1"></p>
<p id="startDate_1"></p>
<p id="endDate_1"></p>
<p id="status_1"></p>
</div>
<br />
<div class="task-block">
<p id="taskName_2"></p>
<p id="startDate_2"></p>
<p id="endDate_2"></p>
<p id="status_2"></p>
</div>
U just take the elements and pass them as an argument to the render function. U can manipulate each element as u wish by adding this or that data. As an output u`ll get the array of those items.
let x = document.querySelector('#taskName');
let y = document.querySelector('#taskName2');
renderElement = (...elements) => {
elements.forEach(element => {
const inputTaskName = document.createElement('input');
inputTaskName.type = 'text';
element.appendChild(inputTaskName)
})
return [elements];
}
console.log(renderElement(x, y))