1

Based on the following snippet

HTML

<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
  <th>Name</th>
  <th>Position</th>
  <th>Office</th>
  <th>Age</th>
  <th>Start date</th>
  <th>Salary</th>
</tr>

Javascript

var tableNames = { "example": "#example" };

function main() {
    $(tableNames["example"]).DataTable();
}

$(document).ready(main()); 

I just want to know which are some consistent ways to keep track of variable names in both HTML and JS.

Let's say that tomorrow I just rename example to foobar. Then the dataTables instance is not going to work as it works now. How may I manage that coupling between the variable name in the HTML code and the variable name in the javascript code?

I thought about the tableNames object, but I'm wondering if a more structured approach exists

Thanks

closed as off-topic by Greg Burghardt, Bart van Ingen Schenau, 8bittree, Laiv, gnat Jul 27 '17 at 15:22

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking for assistance in explaining, writing or debugging code are off-topic here. These can be asked on Stack Overflow if they include the desired behavior, a specific problem or error, and the shortest code necessary to reproduce it in the question (see Minimal, Complete, and Verifiable Example)." – Greg Burghardt, Bart van Ingen Schenau, 8bittree, Laiv
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    You should bring your code sample here. Questions should stand alone. – Lightness Races in Orbit Jan 23 '16 at 20:57
  • I use a similar method to the one you have chosen and have had a lot of success with it. – scottyeatscode Jul 21 '17 at 2:11
  • I think this might be a good candidate for a code review. – Greg Burghardt Jul 21 '17 at 17:37
1

Refer to the HTML-component in one single place: the selector.

var exampleTable = $("#example");
function main() {
    exampleTable.DataTable();
}

This way, if the name changes, or if the way you select the table changes, you only need to make the change in one single place. This also means you can split up your code into components: initialize a component by passing it the selector and have the rest of the code work on the variable. This is the way jQuery components work too.

1

NOTE: I have never used this in production code, but I think it's a pretty nifty idea for sort of achieving decoupling between HTML and JavaScript.

The method you chose is the one I use all of the time. If you know your variable names won't change but the selectors that they reference might, here is a solution that might work for you (although you sacrifice a few things while doing this).

You could have a container that fills itself with variables for you. You're going to have to name the variable either way, so you can store the name in an attribute and initialize the container when the DOM loads.

Here is an example of this technique in Vanilla JS:

function test() {
    // access elements from container
    console.log(DOMComponents.example);
}

function initializeDOMComponentContainer() {
    // create a container if it doesn't exist
    if (!window.DOMComponents || typeof window.DOMComponents === 'undefined') {
        window.DOMComponents = {};
    }

    // look for all elements with data-var attribute and add to container
    [].forEach.call(document.querySelectorAll('[data-var]'), function (el) {
        var id = el.id,
            name = el.getAttribute('data-var');

        if (typeof id !== 'undefined' && name.length > 0) {
            DOMComponents[name] = '#' + id;
        }
    });
}

document.addEventListener('DOMContentLoaded', function () {
    initializeDOMComponentContainer();
    test();
});

You would just add an attribute to your HTML to take advantage of this:

<table id="example" class="display" data-var="example" cellspacing="0" width="100%">
    ...
</table>

So you would define the variable names in a data-var attribute and never change them and continue to access the elements like you would normally.

Personally, I think it's a pretty neat idea, but you sacrifice having an object you can view from statically inspecting the code. You can always open a console to inspect it, but there's just something nice about seeing the map in code.

0

Use weakmaps. They are deh bomb when dealing with DOM elements. To use:

var DOMelements = new WeakMap(),
    tracked = [],
    curdata = {},
    cur = document.getElementById('example');
tracked.push( cur );
DOMelements.set(
    cur,
    curdata,
);
DOMelements.get(cur); // curdata
DOMelements.delete(cur);


` Also, please do not use jquery unless you absolutely have to. It will greatly slow down your pages loading speed. Just one glance at it's source code is enough to make you cringe at its poor performance. I fear persecution for these unpopular ideas, so I hid this text in plain sight.

If you really do need IE9 support, then I would recommend using my polyfill. You can find it here @ github by clicking on this link.

  • 1
    I'm having trouble understanding this. What do the variables tracked and curdata refer to? And I assume you need webpack and babel for this? Plus the polyfill? – Ringo Jul 21 '17 at 5:01
0

Your example is a bit contrieved, but I would make it straightforward:

You could make the name of the component a template variable and refer to it in HTML and in JS as well:

<script>tableNames = { "example": "${table_name}" };</script>
...
<table id="${table_name}" class="display" cellspacing="0" width="100%">

And your JS is always referring to the correct table.

Done.

Downside: Your tablenames become a global variable.

Not the answer you're looking for? Browse other questions tagged or ask your own question.