3

I have a page that takes information from MySQL database and using PHP generates HTML.

Since this is only a test run, I began to wonder about using the ID's like this, because the final page would be using upwards of 400 different #td[i]'s and #bubble[i]'s.

Questions:

  1. Is there a better practice I should be using?

  2. What whould be a viable option for showing the bubble tables temporarily on mouse hover, but permanently (until another td is hovered/clicked) on click.

Script:

$(document).ready(function(){
    $("#maintable").show();

    $( "#td1" ).click(function() {
        $("#bubble1").toggle();
        $("#bubble1").css("background-color", "yellow");
    }); 
    $( "#td2" ).click(function() {
        $("#bubble2").toggle();
        $("#bubble2").css("background-color", "yellow");
    }); 
    $( "#td3" ).click(function() {
        $("#bubble3").toggle();
        $("#bubble3").css("background-color", "yellow");
    }); 
    $( "#td4" ).click(function() {
        $("#bubble4").toggle();
        $("#bubble4").css("background-color", "yellow");
    }); 
    $( "#td5" ).click(function() {
        $("#bubble5").toggle();
        $("#bubble5").css("background-color", "yellow");
    }); 
    $( "#td6" ).click(function() {
        $("#bubble6").toggle();
        $("#bubble6").css("background-color", "yellow");
    });     
    });

</head>
<body>
  <h1>Dynamic tables</h1>
  <br>
  <table id="maintable" border="1">
    <tr>
      <td id="td1">TD1</td>
      <td id="td2">TD2</td>
      <td id="td3">TD3</td>
      <tr>

      <td id="td4">TD4</td>
      <td id="td5">TD5</td>
      <td id="td6">TD6</td>
    </tr>
  </table>
  <br><br>

  <table id="bubble1" border="1">
    <td>
    Selected tablepart:<br>
    <b>TD1</b><br>
    Location:<br>
    <b>R1F:D3-4:E1</b><br>
    Connection:<br>
    none <button id="create1">Create</button>
    </td>
  </table>

  <table id="bubble2" border="1">
    <td>
    Selected tablepart:<br>
    <b>TD2</b><br>
    Location:<br>
    <b>R1F:D3-4:E2</b><br>
    Connection:<br>
    none <button id="create2">Create</button>
    </td>
  </table>

  <table id="bubble3" border="1">
    <td>
    Selected tablepart:<br>
    <b>TB3</b><br>
    Location:<br>
    <b>R1F:D3-4:E3</b><br>
    Connection:<br>
    none <button id="create3">Create</button>
    </td>
  </table>

  <table id="bubble4" border="1">
    <td>
    Selected tablepart:<br>
    <b>TB4</b><br>
    Location:<br>
    <b>R1F:D3-4:E4</b><br>
    Connection:<br>
    none <button id="create4">Create</button>
    </td>
  </table>

  <table id="bubble5" border="1">
    <td>
    Selected tablepart:<br>
    <b>TB5</b><br>
    Location:<br>
    <b>R1F:D3-4:E5</b><br>
    Connection:<br>
    none <button id="create5">Create</button>
    </td>
  </table>

  <table id="bubble6" border="1">
    <td>
    Selected tablepart:<br>
    <b>TB6</b><br>
    Location:<br>
    <b>R1F:D3-4:E6</b><br>
    Connection:<br>
    none <button id="create6">Create</button>
    </td>
  </table>

And my CSS:

table {
    margin-left:auto; 
    margin-right:auto;
    display: none;
    border: 1px solid black;
    border-collapse: collapse;
}

EDIT: The best solution so far: (Combined from several answers) https://jsfiddle.net/Zimpari/3wm01nmL/

Zimpari
  • 45
  • 9
  • Definitely not a best practice i guess. – Riddler May 18 '15 at 13:17
  • Yeah, I wasn't trying to imply that it is... just looking for the right one :) – Zimpari May 18 '15 at 13:18
  • looking from a javascript perspective, the solution has been provided. But from a PHP perspective you should may be reconsider. – Riddler May 18 '15 at 13:19
  • 1
    Why are you repeating the Bubble table. You know you can use a single table and fill content dynamically. – Riddler May 18 '15 at 13:25
  • @Riddler I don't think I can. I have a database that contains about 20 rows which each contain about 20 values. Each of those values needs to be available upon hovering. Basically it will be a graphical representation of a MySQL table (red background td's = missing link, green background td's = all okay, yellow = maintenance ongoing, etc) Upon hovering on a specific TD it should show a balloon/bubble with some specific information. For me the best way to achieve this is the php loop which outputs the given HTML. If you happen to know a better solution then I'm all ears. :) – Zimpari May 18 '15 at 14:57
  • Well i will put up a solution but managing to achieve it in PHP is your burden as the PHP solution is not been shared. – Riddler May 18 '15 at 15:47

4 Answers4

1

For a case like this, it's best to use event delegation. This can be accomplished by utilizing the delegation style syntax for .on(). For example:

$('#maintable').on('click', 'td', function (evt) {
    var index = this.id.substring(2);
    $('#bubble' + index).toggle();
    $('#bubble' + index).css('background-color', 'yellow');
});

This snippet effectively replaces all the event handlers used above in the $(document).ready block. By attaching the single event to a parent element, you allow the events to bubble up the DOM tree and execute via a single handler.

This also works with dynamically generated content. When new content is added new event handlers are not needed.

Reference: .on()

War10ck
  • 12,387
  • 7
  • 41
  • 54
  • How does this communicate with the #bubble[i] tables? – Zimpari May 18 '15 at 13:20
  • @Zimpari Apologies but I'm not sure what you mean? This event will accomplish the same as the event block that you have above. Is that not the desired output? – War10ck May 18 '15 at 13:23
  • Very nice. This actually answers the first part of my question, but... would you also be able to help with the second part of the question? – Zimpari May 18 '15 at 13:25
  • @Zimpari I'll be happy to try. I may need a little clarification on what you're trying to do. Do you want the table to show and hide when moused in and moused out respectively or do you want the table to show and not hide until another row is hovered? – War10ck May 18 '15 at 13:27
  • Basically, the rules should be as follows: *Show bubble[i] when mouse is over TD[i] *Hide bubble[i] when mouse is moved away. *Show bubble[i] when TD[i] is clicked (and it doesnt get hidden upon mouse moving away) This is so that a user could see "more" information about the TD on hovering, and would be able to click the button in the "bubble" after making the TD active with his click on that one. (Hope this makes sense) – Zimpari May 18 '15 at 13:35
  • @Zimpari It does. I may need to do a little thinking on this one to make sure I don't tell you the wrong thing. Let me see what I can come up with and I'll add it to my post in a little while. – War10ck May 18 '15 at 13:41
1

As i said i have cooked up a version where the data required for bubble table is implicitly stored inside each record.

https://jsfiddle.net/tLqbks0c/

    <table id="maintable" border="1">
    <tr>
      <td id="td1" data-bubble='{"part":"TD1","location":"R1F:D3-4:E1"}'>TD1</td>
      <td id="td2" data-bubble='{"part":"TD2","location":"R2F:D3-4:E1"}'>TD2</td>
      <td id="td3" data-bubble='{"part":"TD3","location":"R3F:D3-4:E1"}'>TD3</td>

    </tr>
  </table>

<table id="bubbleTable" border="1" style="display:none;">
    <td>
    Selected tablepart:<br>
    <b class="part"></b><br>
    Location:<br>
    <b class="location"></b><br>
    Connection:<br>
    none <button id="create3">Create</button>
    </td>
  </table>

 $( "#maintable td" ).click(function() {
        $("#bubbleTable").show();
        var bubData=jQuery.parseJSON($(this).attr("data-bubble"));
        console.log(bubData);
        $("#bubbleTable b.part").text(bubData.part);
        $("#bubbleTable b.location").text(bubData.location);
    }); 

I have to warn you this is a fairly rough draft. You have to handle the server rendering in PHP and MySql . Converting data to JSON format in PHP is fairly easy using json_encode()

Riddler
  • 566
  • 2
  • 10
  • Awesome, thanks, this really helps keep the amount of tables created to a minimum. Very nice. I guess I should add the button in the same way? Like: TD3 But I'm not sure how to add this to the output? just thinking this: ---&--- ($("#bubbleTable b.button").text(bubData.button);) - Would this work? – Zimpari May 18 '15 at 17:00
  • Ya that will work I guess. Just play around with the fiddle to find out. I am not with my workstation right now. So can't say exactly. If u find this most helpful you can set as correct answer – Riddler May 18 '15 at 19:25
  • I do love your answer the best, but I did combine it with Scelesto's, for it to work with the mouseover, mouseout and click... This seems to be pretty good already, although it can still be made a lot shorter I think: https://jsfiddle.net/Zimpari/3wm01nmL/ – Zimpari May 19 '15 at 08:09
  • Good to know. I didn't really know that you needed mouse over functionality as well. And yes it can be made shorter. there is a lot of space for code re usability in your code. – Riddler May 19 '15 at 08:58
  • I still haven't got the button thing to work so far, though. Would you happen to know how I could get it to "hold" the right type of value in the button part? – Zimpari May 19 '15 at 09:38
  • Yeah, I have managed to get to the same place basically. But all it does is change the text the button displays. What would be needed, however, is the functionality that upon clicking the said button it would print/send the value somewhere. If I could even see it print the value out or something, I would already know where to go from there, actually :D – Zimpari May 19 '15 at 10:06
  • That would be not possible for me to help with without the server code. May be you can pass a parameter to java script function in onClick. But even for that i would have to be making a lot of assumptions. – Riddler May 19 '15 at 10:10
  • All right, I will keep testing stuff and see what happens. Soon I will also show the php part in stackoverflow. This is going to be a fun little project. Thanks for the help! :) – Zimpari May 19 '15 at 10:22
  • w00t, I actually just found what was needed for that purpose, the .text had to be changed with .val. basically this code does exactly what i need it to: `$("#bubbleTable #create").val(bubData.part).button("refresh");` – Zimpari May 19 '15 at 10:29
0

Yup. Here's all-encompassing jQuery. Should work.

@War10ck is right, substring is better.

$('td').each(function(){ //you might want to add a class selector, but whatever
    var mybubble=$('#bubble'+this.id.substring(2));
    $(this).click(function(){
        mybubble.toggle().css('background-color','yellow');
    });
    $(this).mouseover(function(){
        if(mybubble.css('display')=='none'){
            mybubble.toggle().css("background-color", "yellow")
            .attr('data-mouseover','true');
        }
    });
    $(this).mouseout(function(){
        if(mybubble.attr('data-mouseover')=='true'){
            mybubble.toggle().css("background-color", "yellow")
            .attr('data-mouseover','false');
        }
    });
});
Scelesto
  • 775
  • 6
  • 13
  • This almost works, but it does not keep the bubble open after clicking on it, because the mouseout still toggles it off. – Zimpari May 18 '15 at 13:45
0

It is pretty much OK to use 400 different ID's but then if there are certain consistent characteristics of these DOM elements, then you should add a class attribute to such elements. So that when trying to access it via selector calls in jQuery it is easier access.

So, even before trying to build a data heavy DOM, here is what you should do

  • Break your DOM elements into indivisible elements
  • Combine these indivisible elements into more complex objects
  • Build a hierarchy among these complex objects

These three steps should help you pretty much in every application.

Considering the current DOM that you are trying to build above, here are my suggestions:

  • Add a class='bubble' attribute to the <table> elements. Since, all seem to have consistent reason to exist
  • Inside them, they have <button> elements, it could be given a class='bubble-button' to show the similarity in application.
  • So while the button is the indivisible element, combine it with <td> to get the complex table data element.
  • Collection of such table data could make your bubble table.

I hope you see the hierarchy building up. While designing all this, you should realize that JS parsing is not the bottleneck in web applications. It is the modification of the DOM which takes a lot of time. So, you can have a lot of ID's but proper addressing could help you traversing the DOM tree more efficiently. Bad hierarchy in the DOM tree would cost you in the long run.

Now you could add the click and hover handlers as:

$('.bubble').on('yourevent', function(e){
    /* handle the click, or onmouseover, or onmouseout events appropriately
     by adding or removing CSS classes */
});

Let me know for more clarifications.

psiyumm
  • 6,437
  • 3
  • 29
  • 50
  • Since I am pretty new to CSS and JQuery I may not understand all that you said, but building the right kind of hierarchy does seem to be something I should be trying to do here. I will look into it a bit more. Thank you. Basically I would have 3 elements: the TD[i], Bubble[i] and Button[i]. And buttons should be linked (parented [insert right type of word here]) to the bubbletables in a way? – Zimpari May 18 '15 at 13:51
  • 1
    As such Javascript does not provide the OOP kind of structure but all you can say here is that visually `
    `. There exists no linking as such.
    – psiyumm May 18 '15 at 14:11