cammil
cammil

Reputation: 9929

How to associate javascript code with dom elements?

I have various dom elements that have their contents updated at page load time. Typically they are updated by ajax with data from the server. They usually show things like charts and tabular information.

To keep things clean, I have reused the code that generates the final html for common tasks such as displaying a chart. I put options in the html attributes and have an attribute for the data url. e.g.

<div class="standard_chart"
     chart_title="Trend of X vs. Y"
     data_url="/data/x_vs_y"></div>

This organisation has significantly improved my js code.

The Problem

Sometimes I need to process the data first. For example, to filter it:

var filter_outliers_for_x_vs_y_data = function(data){
    data = data.filter(function(d){
        return -1000 < d.y && d.y < 1000;
    });
    return data;
};

I am loath to put an id attribute on the div just to re-write the data processing function for that particular dom id. Consider this:

$(document).ready(function(){
    $('#my_x_vs_y_chart').each(function(){
         // ... reworked code just for this element
    });
});

I'd much rather, in that html document, put the pre-processing function right next to the html element (or in it). That seems like the best place for it.

What would be the best way to associate javascript with particular dom elements?

My ideas so far:

1.
<div class="standard_chart"
     chart_title="Trend of X vs. Y"
     data_url="/data/x_vs_y"
     pre_process_fn="...some js code..."></div>
// then use `eval` to use the js code in the attribute


2.
<div class="standard_chart"
     chart_title="Trend of X vs. Y"
     data_url="/data/x_vs_y"
     pre_process_fn="...some js code...">
    <pre_process_fn>
        <script>... function definitions ... </script>
    </pre_process_fn>
</div>
// then somehow get and associate the js internal to the element

I'm not sure what the other options are, and what their relative benefits are.

Upvotes: 2

Views: 1279

Answers (1)

metadings
metadings

Reputation: 3848

You could use this idea, without rendering javascript into the attribute, but a fn name:

<div class="standard_chart"
     chart_title="Trend of X vs. Y"
     data_url="/data/x_vs_y"
     preprocess_fn="preprocess_x_vs_y"></div>

And then define an object holding your preprocessor functions:

var preprocessors = {
    "preprocess_x_vs_y": function () {
        var dataUrl = $(this).attr("data_url");
        var chartTitle = $(this).attr("chart_title");
        // do the processing
    }
};

When var preprocessors = { }; is predefined (in the head section), you can also later render the function into an html script element:

<script type="text/javascript">
preprocessors["preprocess_x_vs_y"] = function () {
    var dataUrl = $(this).attr("data_url");
    var chartTitle = $(this).attr("chart_title");
    // do the processing
};
</script>

Now in the document ready event, do

$(document).ready(function () {
    $('.standard_chart').each(function () {
         var preproc_fn = $(this).attr("preprocess_fn");

         // now call the preprocessor (with this === dom element)
         if (preprocessors[preproc_fn] instanceof Function) {
             preprocessors[preproc_fn].call(this);
         }

    });
});

Upvotes: 2

Related Questions