Page 1 of 1 [ 6 posts ] 

Jon81
Snowy Owl
Snowy Owl

Joined: 4 Jul 2018
Age: 43
Gender: Male
Posts: 168
Location: Sweden

16 Jun 2021, 4:38 pm

My teacher seem to be gone on vacation and I'm really late trying to finish my html course due to my boys being the highest priority (both autistic) and then there are of course my own ADD struggles :skull:

I'm stuck trying to figure out how to manipulate elements using javascript. I have 18 <td> elements that are displayed as boxes, and whenever you click one it will need to change color.

There are some restrictions to the task. We are not allowed to use any javascript directly in the html code and no attributes, so stuff like onclick is not an option. That sucks because I had a solution based on the attribute onclick... 8O

I know it's possible to use document.getElementById("cell-id"), but that way I'd need to code one for each of the 18 cells. That just don't seem to be the way to go. Is there any way I can make the cell-id dynamic? Adding eventListener(click, function(){}) is also a dead end to me as a function call still requires the "id" to be parsed and passed into the javascript function...

In short: is there a way to parse the id of a specific html-element when clicking on the element so I can manipulate the html attributes and set a new background color? Perhaps that's not even the way to go about solving the problem? I am pretty new to Html and javascript so there might be totally off track here approaching the task.


_________________
Din Aspie poäng: 102 av 200
Din neurotypiska (icke-autistiska) poäng: 108 av 200
Du verkar ha både Aspie och neurotypiska drag
Diagnosed with ADHD 2022


Fenn
Veteran
Veteran

User avatar

Joined: 1 Sep 2014
Gender: Male
Posts: 2,404
Location: Pennsylvania

18 Jun 2021, 4:26 pm

I write javascript a bit like a play piano. When I play piano I start with a tune in my head and I just start hitting keys until I get something that sounds like the tune in my head then keep going one note at a time.

Here are some thoughts. Browsers are all alike and they are all different. Every browser has quirks. Using a javascript library can help to smooth out the differences.

A web page has basically 3 things - the HTML document, the java script and the css.
New browsers have css and javascript built in. I usually start with the html. The one thing I can think of that responds to clicks without fancy javascripts is a form - so in this case I would start by reading the "barebones guide to html" - http://werbach.com/barebones/download.html - for the form elements. The other is a hyperlink - a hyperlink will respond to a click the moment you touch it by going to that page so I would look at the hooks / events related to hyperlinks. If every cell in your table contained a hyperlink with it's x/y co-ords as part of the url (after the question mark or after the hash symbol) but the rest of the url led back to the same page, you could keep state in the query part of the url and use that to drive you javascript behavior.

each html tag (like xml) contains three things: one is the tag name (like HEAD or BODY or A or TD) the second is the attributes, and the third is the set of other elements (and non-element body text) that it contains.

That is IT. Every element tag has JUST those three things. To change colors you need to change the attributes set on the correct elements.


The other thing is that there are standard hooks / events in a page that will run javascript after the whole page is loaded - I forget the names - but basically google for that and then your javascript can change the page by changing the DOM.

The other thing I am thinking is that a html table can be warped around a form before CSS tables were used to format pages, kind of like graph paper. A Table element contains one or more tr elements which contain one or more td elements. A td element can contain just about anything - including another table. I wrote a page once using no images and only nested tables to draw tabs at the top of my page a bit like on the wikipedia. The trick was to create a one cell table inside each cell that I wanted to be a specific size and shape, and set the colors of the table to be the color I wanted the cell to be. I would have to look up the details and do some trial and error to do it again. It was a good trick and addressed the idea that a empty TD renders differently than a TD with something in it.

The last thing is that making a table have a 1 pixel black line between all the cells required several different tricks to make it work in all browsers. I looked for pages on browser marked share and installed the top 3 and then tried everything in all three browsers. Most people only develop using one browser and don't bother to try more than one browser - many flaky web sites have bugs because of this. If you have more time try the top 5 or top 10. The top three is a good number because after that the browsers makers start to work harder to make the "lesser known" browsers work "just like" the leaders. Opera is a good example.

The last thing is DOM and sets. You can identify the cells in your table by pulling all the cells of a given tag into a list and counting until you get to the one you want. You don't have to mark the cells uniquely at all.
HTML in the DOM is a tree structure, and the elements contained inside another element have a fixed order and order is important. That is why your teacher said that you shouldn't mark each cell with unique identifiers. All you have to do is climb up and down the tree and count.

If these ideas don't give you enough to go on ask again and I will try to look up more specific answers.

Also look at code for "fly-over" effects - it may be similar to what you want.

Here are some links that might help:

https://stackoverflow.com/questions/324 ... -td-and-tr

https://stackoverflow.com/questions/193 ... -clickable

https://stackoverflow.com/questions/173 ... javascript

https://www.geeksforgeeks.org/how-to-ch ... avascript/

https://stackoverflow.com/questions/368 ... e-a-td-tag


https://www.w3schools.com/jsref/met_doc ... agname.asp


_________________
ADHD-I(diagnosed) ASD-HF(diagnosed)
RDOS scores - Aspie score 131/200 - neurotypical score 69/200 - very likely Aspie


aspiecoder
Tufted Titmouse
Tufted Titmouse

Joined: 5 Mar 2021
Age: 42
Gender: Male
Posts: 26
Location: Adelaide, Australia

09 Aug 2021, 7:18 am

Can you use something like this?

Code:
let elems = document.getElementsByTagName("td");
for (let i = 0; i < elems.length; i++) {
    let elem = elems[i];

    // If you need the id you can do this (but note the element might not have an id set in the HTML/DOM)
    let elemId = elem.id;

    // set onclick handler on each element.
    elem.onclick = function() {
        // do something here with the element
        elem.style.backgroundColor = "#000000"
    }

    // Alternatively you can do this
    elem.addEventListener('click', function() {
        // do something here with the element
    }
}


I haven't tested this, but something along these lines might work?



Jon81
Snowy Owl
Snowy Owl

Joined: 4 Jul 2018
Age: 43
Gender: Male
Posts: 168
Location: Sweden

26 Aug 2021, 4:35 am

Fenn wrote:
I write javascript a bit like a play piano. When I play piano I start with a tune in my head and I just start hitting keys until I get something that sounds like the tune in my head then keep going one note at a time.

Here are some thoughts. Browsers are all alike and they are all different. Every browser has quirks. Using a javascript library can help to smooth out the differences.

A web page has basically 3 things - the HTML document, the java script and the css.
New browsers have css and javascript built in. I usually start with the html. The one thing I can think of that responds to clicks without fancy javascripts is a form - so in this case I would start by reading the "barebones guide to html" - http://werbach.com/barebones/download.html - for the form elements. The other is a hyperlink - a hyperlink will respond to a click the moment you touch it by going to that page so I would look at the hooks / events related to hyperlinks. If every cell in your table contained a hyperlink with it's x/y co-ords as part of the url (after the question mark or after the hash symbol) but the rest of the url led back to the same page, you could keep state in the query part of the url and use that to drive you javascript behavior.

each html tag (like xml) contains three things: one is the tag name (like HEAD or BODY or A or TD) the second is the attributes, and the third is the set of other elements (and non-element body text) that it contains.

That is IT. Every element tag has JUST those three things. To change colors you need to change the attributes set on the correct elements.


The other thing is that there are standard hooks / events in a page that will run javascript after the whole page is loaded - I forget the names - but basically google for that and then your javascript can change the page by changing the DOM.

The other thing I am thinking is that a html table can be warped around a form before CSS tables were used to format pages, kind of like graph paper. A Table element contains one or more tr elements which contain one or more td elements. A td element can contain just about anything - including another table. I wrote a page once using no images and only nested tables to draw tabs at the top of my page a bit like on the wikipedia. The trick was to create a one cell table inside each cell that I wanted to be a specific size and shape, and set the colors of the table to be the color I wanted the cell to be. I would have to look up the details and do some trial and error to do it again. It was a good trick and addressed the idea that a empty TD renders differently than a TD with something in it.

The last thing is that making a table have a 1 pixel black line between all the cells required several different tricks to make it work in all browsers. I looked for pages on browser marked share and installed the top 3 and then tried everything in all three browsers. Most people only develop using one browser and don't bother to try more than one browser - many flaky web sites have bugs because of this. If you have more time try the top 5 or top 10. The top three is a good number because after that the browsers makers start to work harder to make the "lesser known" browsers work "just like" the leaders. Opera is a good example.

The last thing is DOM and sets. You can identify the cells in your table by pulling all the cells of a given tag into a list and counting until you get to the one you want. You don't have to mark the cells uniquely at all.
HTML in the DOM is a tree structure, and the elements contained inside another element have a fixed order and order is important. That is why your teacher said that you shouldn't mark each cell with unique identifiers. All you have to do is climb up and down the tree and count.

If these ideas don't give you enough to go on ask again and I will try to look up more specific answers.

Also look at code for "fly-over" effects - it may be similar to what you want.

Here are some links that might help:

https://stackoverflow.com/questions/324 ... -td-and-tr

https://stackoverflow.com/questions/193 ... -clickable

https://stackoverflow.com/questions/173 ... javascript

https://www.geeksforgeeks.org/how-to-ch ... avascript/

https://stackoverflow.com/questions/368 ... e-a-td-tag


https://www.w3schools.com/jsref/met_doc ... agname.asp


Sorry for the delay in reply and thanking for your answer and lesson. Now I've managed to understand what I'm actually doing and what a DOM-tree is. I just wish I had the patience to go through the lessons before taking on a task. It's like learning backwards. Just like you said about the piano, a lot of trial and failure until it works. Right now I'm trying to get my head around "this." and all the "append" within a class. It's a lot.

At the beginning I was wondering why there were so many ways of doing the same things. For example:

let targetId = ev.target.id;
let sameTargetId = ev.target.getAttribute('id'); <-- I know it's because you need to reach own made attributes, but why not suggest a shorthand version?

ev.target.getElementById('targetId').setAttribute('class', 'aClass')

targetId.classList.replace('aClass', 'anotherClass')

and many more...

It's really cool stuff all these things and I love it when it works :mrgreen:


aspiecoder wrote:
Can you use something like this?
Code:
let elems = document.getElementsByTagName("td");
for (let i = 0; i < elems.length; i++) {
    let elem = elems[i];

    // If you need the id you can do this (but note the element might not have an id set in the HTML/DOM)
    let elemId = elem.id;

    // set onclick handler on each element.
    elem.onclick = function() {
        // do something here with the element
        elem.style.backgroundColor = "#000000"
    }

    // Alternatively you can do this
    elem.addEventListener('click', function() {
        // do something here with the element
    }
}


I haven't tested this, but something along these lines might work?


I was hoping an aspie coder would arrive and help me out, someone who is more interested in coding than anything else - that's why I wrote the question on this forum. I didn't expect to get the full package with self explanatory username! That's awesome :mrgreen:

Thanks a lot for your answer. I wish I had seen it earlier but I didn't get any ping showing a new message in the thread. Probably need to activate that kind of alert if it's possible.

This was actually the thing I was looking for and where I'm at in the project.
The currently selected target will change class name to a highlighted theme if the target is "not taken". It's a seat booking project... And the previously selected seat will be un-highlighted by getting a class name.

I feel I'm getting closer to the solution - however, today is a migraine day :skull: and only 3 days left before handing it in.

The solution I've got in mind is to pass the previously selected node to a variable to keep track of it. Just happens to be a bit of problem when the value is undefined at the beginning since there was no previously selected seat. Also a bit of trouble when a seat is 'booked'. I'm not gonna go further into this because it's hard for me to explain, let alone getting you to understand what I'm trying to say.


_________________
Din Aspie poäng: 102 av 200
Din neurotypiska (icke-autistiska) poäng: 108 av 200
Du verkar ha både Aspie och neurotypiska drag
Diagnosed with ADHD 2022


badRobot
Veteran
Veteran

User avatar

Joined: 18 Jan 2011
Age: 43
Gender: Male
Posts: 824

26 Aug 2021, 6:05 am

You can add event listener to the whole table element and use event.target to process individual cells. Events propagate up the DOM tree unless further propagation is prevented by event handler of a child element.

Something like that:

Code:
document.getElementById("seats").addEventListener('click', function(e) {
  if (e.target.tagName == 'TD') { // double check in case there are other elements inside the table
    // do something here with the element
    let cell = e.target;
    ...
    e.stopPropagation(); // optional
  }
});



aspiecoder
Tufted Titmouse
Tufted Titmouse

Joined: 5 Mar 2021
Age: 42
Gender: Male
Posts: 26
Location: Adelaide, Australia

28 Aug 2021, 5:02 am

Jon81 wrote:
I was hoping an aspie coder would arrive and help me out, someone who is more interested in coding than anything else - that's why I wrote the question on this forum. I didn't expect to get the full package with self explanatory username! That's awesome :mrgreen:

:D Coding is indeed my special interest and always has been. This reply made my day :D

Jon81 wrote:
The solution I've got in mind is to pass the previously selected node to a variable to keep track of it. Just happens to be a bit of problem when the value is undefined at the beginning since there was no previously selected seat. Also a bit of trouble when a seat is 'booked'. I'm not gonna go further into this because it's hard for me to explain, let alone getting you to understand what I'm trying to say.


Saving an element in a variable will work if the page never refreshes but that variable will be gone if it does, or if that table redraws itself (not sure if you're using a javascript framework at all, but it didn't sound like you were). For a static page it's probably ok.

In a framework such as React this would be handled quite differently. You would store a unique id against each table row and then remember which one was selected. When rendering the rows, the selected one would have some extra CSS applied. If there is no current selection you could default to the first item in the list.

Another way to do it is to remember the selected item by index, but this only works if the page items are static and never change.

Some general tips are:
* Try not to overthink the problem. Often the best solutions are the simple ones.
* Sometimes it's good to just "get it working" and then try to refactor later (refactor means rework the code to make it neater, or more efficient etc)
* Your first attempt need not be your last. Once you've tackled the problem once you will have gained more knowledge than if you had tried to find the perfect solution upfront. My code often goes through several revisions before it looks any good ;)