monarch-initiative / phenogrid

The phenogrid widget
13 stars 14 forks source link

Dividers appear when render multiple containers with the same ID #238

Closed yuanzhou closed 8 years ago

yuanzhou commented 8 years ago

This is an edge case discovered during the Phenogrid/IMPC integration process. When we render Phenogrid to multiple containers with the same ID, depending on the network, we may see the red dividers appear. Guess the multiple containers with same ID made the data rendering confused. Thus Phenogrid may try to render the same data as from multiple species and created the divider lines. We are not supposed to use the same ID to multiple HTML elements, but it's possible maybe the data loading in Phenogrid isn't quite right.

<div id="phenogrid_container1" class="clearfix"></div>
<div id="phenogrid_container1" class="clearfix"></div>
<div id="phenogrid_container1" class="clearfix"></div>
<div id="phenogrid_container1" class="clearfix"></div>

capture

yuanzhou commented 8 years ago

According to HTML5 specification: https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute

The id attribute specifies its element's unique identifier (ID). The value must be unique amongst all the IDs in the element's home subtree

But there's no guarantee of never having duplicated IDs. Ideally, even when there are multiple containers with the same ID, we should only display one same Phenogrid instance without any divider lines since the divider lines are used in cross-comparison mode.

yuanzhou commented 8 years ago

@julesjacobsen

It turned out that this issue was not caused by the multiple html containers with the same ID. I tested with only one container by creating the same/similar Phenogrid instances on this same container and reproduced the divider lines as well.

   // IMPC testing 1
    Phenogrid.createPhenogridForElement(document.getElementById('phenogrid_container1'), {
        serverURL: "http://monarchinitiative.org",
        gridSkeletonDataVendor: 'IMPC',
        gridSkeletonData: IMPCData1,
        gridSkeletonTargetGroup: {name: "Mus musculus", taxon: "10090"},
        singleTargetModeTargetLengthLimit: singleTargetModeTargetLengthLimit,
        sourceLengthLimit: sourceLengthLimit
    });

    // Repeating testing 1 on the same container with IMPCData2
    // But this won't get created because the widget factory protects against multiple instantiations on the same element
    Phenogrid.createPhenogridForElement(document.getElementById('phenogrid_container1'), {
        serverURL: "http://monarchinitiative.org",
        gridSkeletonDataVendor: 'IMPC',
        gridSkeletonData: IMPCData2,
        gridSkeletonTargetGroup: {name: "Mus musculus", taxon: "10090"},
        singleTargetModeTargetLengthLimit: singleTargetModeTargetLengthLimit,
        sourceLengthLimit: sourceLengthLimit
    });

No matter how many duplicated containers we have in HTML, only the first containing div is used to render the widget instance.

The root cause was using both the _create() and _init(). The widget factory automatically fires the _create() and _init() methods during initialization, in that order. Because the widget factory protects against multiple instantiations on the same element, _create() will be called a maximum of one time for each widget instance, whereas _init() will be called each time the widget is called without arguments. Before the fix, we had some variables initialized in _create(), and some data loading functions in _init(). When we created two instances on the same container, _init() got called twice, which caused the data being loaded twice, thus the first divider line was created. Back to the IMPC example, we had 4 instances created on the same container, thus three divider lines showed up.