0

I have researched my question and not come up with any thing. I may be lacking the proper buzz words that relate to the question...

I have a method inside of an object that creates p elements and then appends them to an unorderedlist, it works fine, but I am not able to figure out how to clean up my code by not repeatedly typing document.createElement('p') or repeatedly typing node.appendChild('p') methods.

NOTE: I have omitted some parts of the code that would show the functionality but I think the point can still be made for my question.

When typing out my code I either end up with multiple vars holding document.createElement('p') as you see with the pEl1, pEl2, and PEl3.

var totalCompletedTodos = 0,
    totalRemainingTodos = 0,
    todosUl = document.querySelector('ul'),
    todosLi = todosUl.appendChild(document.createElement('li')),
    pEl1 = document.createElement('p'),
    pEl2 = document.createElement('p'),
    pEl3 = document.createElement('p');

todosLi.appendChild(pEl1).textContent = "Toggle All ";
todosLi.appendChild(pEl2).textContent = "Completed: ";
todosLi.appendChild(pEl3).textContent = "Remaining: ";
todosLi.className = 'liInfoBar';
document.querySelector('.liInfoBar > p').className = "toggleAllButton";

Or I end up with continuously writing out multiple todosLi.appendChild(document.createElement('p')).textContent = "string";

var totalCompletedTodos = 0,
    totalRemainingTodos = 0,
    todosUl = document.querySelector('ul'),
    todosLi = todosUl.appendChild(document.createElement('li'));

todosLi.appendChild(document.createElement('p')).textContent = "Toggle All";
todosLi.appendChild(document.createElement('p')).textContent = "Completed: ";
todosLi.appendChild(document.createElement('p')).textContent = "Remaining: ";
todosLi.className = 'liInfoBar';
document.querySelector('.liInfoBar > p').className = "toggleAllButton";

AGAIN: I am not looking for help on functionality I am seeking help on how to produce reusable code to keep it minimal. As a beginner I am striving to dedicate time to producing minimal,clean, readable code as well as producing functionality which is why I am asking the question.

There may not be and an answer to what I am looking for and the only way is to continuously write that out but I find myself doing that a lot through my entire script and I feel like there would have to be a way.

Disclaimer: This is my first post on Stackoverflow hopefully I have worded my question in an understandable manner. If not I will also accept feedback on the topic of properly asking questions as well.

Thank you!

Tylor
  • 309
  • 4
  • 9
  • 1
    I’d recommend [`Object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Methods_of_the_Object_constructor) and [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Methods) methods, e.g. `["Toggle All", "Completed: ", "Remaining: "].map((textContent) => Object.assign(document.createElement("p"), {textContent}))` creates an array with three `

    ` elements with their respective text.

    – Sebastian Simon Jul 15 '18 at 04:43
  • Right now this looks like it should be something like `for (let str of ["Toggle All ", "Completed: ", "Remaining: "]) { todosLi.appendChild(document.CreateElement('p')).textContent = str }` – Tibrogargan Jul 15 '18 at 04:50

2 Answers2

0

To repeat yourself less, make a function to which you can pass the parent, the created node's type, and whatever other properties you need. For example:

const append = (
  parent,
  childType,
  otherProps
) => {
  const child = parent.appendChild(document.createElement(childType));
  if (otherProps) Object.assign(child, otherProps);
  return child;
};
const ul = document.querySelector('ul');
const li = append(ul, 'li', { className: 'liInfoBar' });
append(li, 'p', { textContent: 'Toggle All' });
append(li, 'p', { textContent: 'Completed' });
append(li, 'p', { textContent: 'Remaining' });
.liInfoBar {
  background-color: yellow;
}
<ul></ul>

Or you can use one of the libraries that does this sort of thing as well. (but are you sure you want ps to be children of a li like that? as is, it looks a bit strange)

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Ok that makes sense so this would be almost like making a personalized library like JQuery? I know there are libraries but I am trying to avoid them while I get down the fundamentals of just javascript. Also I think I should be appending spans instead of p's now that you mention it. I have multiple items that are appended to a single li so a span would probably make more sense. Thank you for the help! – Tylor Jul 15 '18 at 04:53
  • Yeah, it's a bit like that. But if you're just learning, there's absolutely nothing wrong with writing your own functions that accomplish something similar, so that your code looks more abstract and terse, and so that you have a grasp on how things work without libraries. – CertainPerformance Jul 15 '18 at 04:55
0

When you need the same thing done for multiple pieces of data, it is time for a loop!

const paragraphs = [
    'Toggle All',
    'Completed: ',
    'Remaining: '
];
paragraphs.forEach((text) => {
    todosLi.appendChild(document.createElement('p')).textContent = text;
});
Seth Holladay
  • 8,951
  • 3
  • 34
  • 43