0

I am using a foreach loop to load data from mysql table using php.

Now I have a button with a javascript function next to each foreeach set of data to display the data.

The problem is, the button only works on the very first fetched data in the foreach loop. I am not sure what the problem is?

Here is my code https://jsfiddle.net/7qL2osp5/

I am using this script btw

<script type="text/javascript">
  function bigger(){
        document.getElementById("approvals-data-box").style.width="95%";
        document.getElementById("actual-data").style.display="block";
  }

</script>

Thanks

2

4 Answers 4

4

This happens because you are not using unique IDs... IDs are meant to be unique. The browser will always return the first they find, hence why you always get the first row.

Try using the event's target, which will be the clicked button, and find its corresponding siblings.

document.body.addEventListener('click',function(e){
if(e.target.className == "clickme"){
 e.target.parentElement.style.backgroundColor="red";
}
});
<ul>
 <li><button class="clickme">Click me</button> A</li>
 <li><button class="clickme">Click me</button> B</li>
 <li><button class="clickme">Click me</button> C</li>
 <li><button class="clickme">Click me</button> D</li>
 <li><button class="clickme">Click me</button> E</li>
</ul>

Here's a minimal example. The script attaches an event to the body, and triggers the effect only if the element's class is "clickme". Then we take the parent of that button and change it's background color.

Note that it is a very minimal example and that is not a very good way to do it. For example if you add another class to your buttons, it will not work... I'd suggest you use jQuery as it will make things a lot easier for you to play with events.

Sign up to request clarification or add additional context in comments.

4 Comments

hmm i see what you're saying, ive tried the event approach but I am unable to get it working. do you mind showing me an example please?
there you go. Added a very minimalistic example that should express what I meant.
Thanks for your efforts. I've using pure javascript, but after seeing how simple jquery makes it, I will reconsider and learn jq. amazing stuff thanks again
jQuery is still javascript! But it abstracts a lot... without counting the fact that every browser is different, you'll learn more using the proper tools I think, as you'll be more focused on your task and not just fighting weird behaviours.
1

id is used for one specific element. You can only have one element with the same id.

What you need to do is give them all different ids and then pass in the id to the function. You also need classes for the styling.

IDs are for specific elements. Classes are for element types.

Here's a working version:

https://jsfiddle.net/7qL2osp5/1/

In CSS, you use the . for classes and the # for ids. This may be a good time to try to learn jQuery since you're just starting out.

7 Comments

Sorry. I provided the wrong link. It's updated now.
I also found overflow: none; and white-space:nowrap; made it look prettier. jsfiddle.net/7qL2osp5/2
Won't it be better passing this inside bigger() than creating so many IDs and passing numbers in each of them?
Yes, but for that you really should use jQuery because jQuery lets you search the descendants of elements. $(this).children('.actual-data').with ...
Believe me, jQuery is a lot easier to learn, though, I give you kudos for now knowing what's happening underneath the hood with getElementById and getElementsByClass
|
0

The problem here is that you're using getElementById and non unique ids on your document. I see you have id="approvals-data-box" many times.

You should either assign unique ids or use a different type of selection (eg. document.getElementsByClassName or document.querySelectorAll if you want to affect multiple elements.

Hint: Since you're generating your DOM with php, you can use the uniqid() function to append random content to your ids

Another approach would be using the element itself, without querying the DOM by applying something like onclick="..." which would use the event's target

2 Comments

Thanks for your help @fotis I've tried using something like this but its not working var x = event.target; document.getElementById("demo").innerHTML = "Triggered by a " + x.tagName + " element"; }
If you change onmouseover="bigger()" to onmouseover="bigger(this)" you'll be getting the element as the first argument, if you also change to onmouseover="bigger('#approvals-data-box-1 #actual-data'") you'll get the target selector as the argument. You can then alter your bigger function to use the target accordingly. eg. document.querySelector(target)
0

IDs are unique, you should use class. You need to pass it like onmouseover="bigger(this)", so that only selector is considered. Below is an updated code:

.approvals-data-box {
  width: 00px;
  height: 20px;
  background-color: lightgray;
  -webkit-transition: 400ms linear;
  -moz-transition: 400ms linear;
  -o-transition: 400ms linear;
  -ms-transition: 400ms linear;
  transition: 400ms linear;
  border: 1px dotted transparent;
  margin: 2px;
}

.actual-data {
  display: none;
}

table,
tr,
th,
td {
  border: 1px solid black;
}

#style-button {
  padding: 10px;
  background-color: coral;
  width: 100px;
  color: white;
}
<h1>Fetched data from database</h1>

<table>
  <tr>
    <th>Reveal Button</th>
    <th>Actual Data</th>
  </tr>
  <!--------------------------------------------->
  <tr>
    <td>
      <div onmouseover="bigger(this)" id="style-button">hover me to reveal data 1</div>
    </td>

    <td>
      <div class="approvals-data-box">
        <div class="actual-data">data 1</div>
      </div>
    </td>
  </tr>
  <!--------------------------------------------->
  <tr>
    <td>
      <div onmouseover="bigger(this)" id="style-button">hover me to reveal data 2 (not working)</div>
    </td>

    <td>
      <div class="approvals-data-box">
        <div class="actual-data">data 2</div>
      </div>
    </td>
  </tr>
  <!--------------------------------------------->
  <tr>
    <td>
      <div onmouseover="bigger(this)" id="style-button">hover me to reveal data 3 (not working)</div>
    </td>

    <td>
      <div class="approvals-data-box">
        <div class="actual-data">data 3</div>
      </div>
    </td>
  </tr>
</table>

<script type="text/javascript">
  function bigger(elem) {
    elem.parentNode.parentNode.getElementsByClassName('approvals-data-box')[0].style.width = "95%";
    elem.parentNode.parentNode.getElementsByClassName('actual-data')[0].style.display = "block";
  }
</script>

2 Comments

Thanks but this expands the button itself rather than the actual data.
Ok. I have updated based on you requirements. Please check.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.