0

In jQuery I'm creating a whole suite of elements to include in my project. The suite will contain various elements such as buttons, input elements, modal popups and others.

Now, the first control which I'm writing is a select (dropdown), which has the following syntax:

<div class="dropdown" style="height: 20px; width: 100px;">
    <div class="legend"></div>
    <ul class="elements">
        <li>Blue</li>
        <li>Green</li>
        <li>LightBlue</li>
        <li>Orange</li>
        <li>Purple</li>
        <li>Red</li>
        <li>Turquoise</li>
    </ul>
</div>

Now, I have various JavaScript methods to lets this work, adding the necessary classes and other things to ensure a proper working.

Now, I do have created a method that should execute a piece of code, placed as an attribute on the element.

$('.elements li', dropdownElement).click(function() {
    var selectedLiText = $(this).html();
    $('.legend', dropdownElement).html(selectedLiText);

    var attribute = $(dropdownElement).attr('data-on-change');
    if (typeof attribute !== 'undefined' && attribute != '') { eval(attribute); }

    $(dropdownElement).ToggleOpen();
});

So, the code above does show that when there's an attribute called 'data-on-change' on the element, it will translate it into a JavaScript function and execute it.

In order to make it work, the HTML should be adapted like the following:

<div class="dropdown" style="height: 20px; width: 100px;" data-on-change="alert('demo');">
    <div class="legend"></div>
    <ul class="elements">
        <li>Blue</li>
        <li>Green</li>
        <li>LightBlue</li>
        <li>Orange</li>
        <li>Purple</li>
        <li>Red</li>
        <li>Turquoise</li>
    </ul>
</div>

This would make a popup open with the text 'Demo'.

See this JsFiddle for the workings. Note: There's no styling so it doesn't really looks like a DropDown but just click an element in the UL and the popup will show.

What I would like to do is the following, expose something in my plugin that enables me to get the selected item.

So I would like to be able to form my data-on-change function like so:

data-on-change="alert(selectedItem)"

Or maybe

data-on-change="alert(this.selectedItem)".

All ideas are welcome.

Complexity
  • 5,682
  • 6
  • 41
  • 84
  • I'm personally not 100% that using eval() for such things is actually good practice. – briosheje Mar 17 '15 at 08:04
  • Do you have another idea. So I mean by not using eval? – Complexity Mar 17 '15 at 08:05
  • I would use generic events and try to not self-inject my own code.. despite it sounds good, whenever you parse something wrong the eval will fail. instead of evaluating that content, you may want to use a sort of callback to an existing function (or a user-defined function). Perhaps that's just my idea, I would personally wait to read some javascript professionists though :P. Meanwhile, take a look at this: http://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea – briosheje Mar 17 '15 at 08:13

1 Answers1

0

I would probably go with function name definition instead of eval(). Simply put a function name to be invoked by event and pass desired arguments.

Something like..

if (typeof attribute !== 'undefined' && attribute != '') { 
    //eval(attribute); 
    if (typeof(window[attribute]) == 'function'){
        // you can pass anything as the argument here..
        window[attribute].call(this, {selectedText: selectedLiText});
    }
}

with HTML being like so

<div class="dropdown" style="height: 20px; width: 100px;" data-on-change="InvokeFunction">

and event handler itself

window.InvokeFunction = function(args){
    alert(args.selectedText);
}

I updated the jsfiddle: https://jsfiddle.net/xq0d0y6r/2/

Ivan Sivak
  • 7,178
  • 3
  • 36
  • 42
  • This is going in the right direction. However, not exactely what I needed since you call a general function for all the methods. I might have different dropdown elements and each select might execute another function. However, I accept your answer as accepted. – Complexity Mar 17 '15 at 09:07
  • Thank you. Perhaps the invoked function can be always the same with only changing the passed argument to determine or distinguish what to do next. I might be talking rubbish though as I'm not sure if I follow. Anyway, glad it helped you a bit. – Ivan Sivak Mar 17 '15 at 09:12