Trying to convert a project with the state in html, to a project with the state in js, no framework

TYes, it's tedious, and annoying, and I'm sure I know how to do it, I just don't... know... how to do it...? So the HTML version is this: https://codepen.io/Laing91/pen/rNKNaQb What I want to do is re-create this with the state in JS, effecitvely the only HTML I will have written is a div with id="main" in it. similar to root in React, I guess. I am having an almightily difficult time doing this, however. The best I can do so far is https://jsfiddle.net/yehwb25m/1/ and even that doesn't feel anywhere close to what I'm trying to do. My biggest issue is I am not sure how to cycle through my objects and push the data into the html.
Edit fiddle - JSFiddle - Code Playground
Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.
4 Replies
Electronic
Electronicβ€’2y ago
Store the texts in an array to help you iterate over The numerator denominator situation e.g. 0/1 have a pattern you know before hand the value in columns so could just manipulate that into code
Joao
Joaoβ€’2y ago
This is an excellent use case for object oriented programming. At a glance, I see two main entities: Character and Tasks (or Dungeon however you prefer). Create them as classes and instantiate them by looping over the JS object that has the actual data about it; I would recommend having that stored away as JSON somewhere and pull it using fetch but it's fine to keep it as part of the code in a separate file. Characters can have a property tasks which is an array of Tasks they have assigned to them. Each task keeps track of it's own progress. So you can have, inside the Character class, a method to retrieve in progress tasks or completed tasks as needed.
class Character {
constructor(name) {
this.name = name;
this.tasks = [];
}

assignTask(task) {
// error checking to avoid duplicates
this.tasks.push(task);
}

get tasks() {
return this.tasks;
}

get tasksInProgress() {
return this.tasks.filter(task => !task.isCompleted);
}

get tasksCompleted() {
return this.tasks.filter(task => task.isCompleted);
}
}

class Task {
constructor(name, difficulty) {
this.name = name;
this.maxProgress = difficulty;
this.currentProgress = 0;
}

increaseProgress() {
// error checking to avoid overflowing max value
this.currentProgress++;
}

get isCompleted() {
return this.currentProgress === this.maxProgress;
}
}
class Character {
constructor(name) {
this.name = name;
this.tasks = [];
}

assignTask(task) {
// error checking to avoid duplicates
this.tasks.push(task);
}

get tasks() {
return this.tasks;
}

get tasksInProgress() {
return this.tasks.filter(task => !task.isCompleted);
}

get tasksCompleted() {
return this.tasks.filter(task => task.isCompleted);
}
}

class Task {
constructor(name, difficulty) {
this.name = name;
this.maxProgress = difficulty;
this.currentProgress = 0;
}

increaseProgress() {
// error checking to avoid overflowing max value
this.currentProgress++;
}

get isCompleted() {
return this.currentProgress === this.maxProgress;
}
}
I've added a couple of getters which I think would be nice to have to make some common operations easier to manage later on. You'd have to add proper methods to each Character to increase/decrease progress on each task as needed, as well. This way, each task pertains to a Character and keeps track of its own progress, but each Character has their own tasks. As for the table, you can have a new class with all characters available provided in the constructor. Then use a render method that will 1) retrieve character and task data 2) create proper values for the table itself. The Table class should listen to events to update the tasks on each character, so that's another method you should create as an API the Character exposes. Just a few ideas to think about
CDL
CDLβ€’2y ago
I didn't think to do that, thanks @joao6246 ! I did finish it but did it in a different way https://codepen.io/Laing91/pen/RwJwqXz
Joao
Joaoβ€’2y ago
Well done! πŸ™‚ There are as always multiple ways to achieve the same goal, I find the object-oriented easier to reason about but this will do nicely as well