0

I have the following javascript class (really don't know if it is the best solution) and I wan't to call a function that is definded in this class, insinde another function defined in the same class.

step1 = {
    init: function(){
        this.events();
    },

    events: function(){
        fct = this; // i stored this in a variable so that i don't lose it
        $(document).on('click', '.form-line li', function(e) {
            e.preventDefault();
            fct.changeCategoryValue($(this));
        });

        $(document).on('click', '.alert-form .confirm', function(e) {
        e.preventDefault();
        $.fancybox.close(true);
        });
    },

    changeCategoryValue: function(el) {
        cat = el.hasClass('has-sub') ? '' : el.data('id');
        title = el.hasClass('has-sub') ? '' : el.data('title');
        $('#cat-title').val(title);
        $("input[name='category']").val(cat);
    }

As you an see I wan't to call the changeCategoryValue function but if I call it with this.changeCategoryValue it won't work. Any suggestions on how to improve the code?

Tudor Ravoiu
  • 1,981
  • 7
  • 31
  • 50
  • I don't see what the problem is. Is there an error, or are you requesting an optimization? `fct = this` and then later `function(){ fct.changeCategoryValue }` is typical. – zamnuts Oct 25 '13 at 05:58
  • You are right, there is not problem. That is why I asked for an improvement. I don't know, but it doesen't seem right (usual) the solution i implemented. – Tudor Ravoiu Oct 25 '13 at 06:00

5 Answers5

2

Alternatively, you may change the scope of the function callback:

$(document).on('click', '.form-line li', function(e) {
    e.preventDefault();
    this.changeCategoryValue($(e.currentTarget));
}.bind(this));

Use .bind(this) so the scope of function(e){...} will be the instance of step1 instead of $('.form-line li',document). Now, to still target the clicked/selected .form-line li, you can access the object via e.currentTarget.

zamnuts
  • 9,004
  • 3
  • 33
  • 44
  • @TudorRavoiu oops, I left out the most important detail! Answer updated. – zamnuts Oct 25 '13 at 06:23
  • Ok, this works now. I had to make a little modification in the changeCategoryValue function because it seems that $(e.target) is in fact the "a" element inside of "li" and not the clicked "form-line li" element. – Tudor Ravoiu Oct 25 '13 at 06:30
  • @TudorRavoiu in your case it might be `e.currentTarget` instead of `e.target` - I always get them mixed up! – zamnuts Oct 25 '13 at 06:33
0

try to use:

step1.changeCategoryValue($(this));
StaleMartyr
  • 748
  • 5
  • 18
  • ok, this works, but is it also another solution? so that if the classname will change than the calling won't change? – Tudor Ravoiu Oct 25 '13 at 05:57
0

you have added property to the class why don't you call it using class name like this :

step1.changeCategoryValue('any_element_ref');
Bharat Soni
  • 2,419
  • 4
  • 19
  • 36
0

You could create a proper object. This even allows you call init in the constructor if you wan't.

function Step() { this.init(); }

Step.prototype.init = function() { this.events(); };

Step.prototype.events = function() {
    var self = this;
    $(document).on('click', '.form-line li', function(e) {
        e.preventDefault();
        self.changeCategoryValue($(this));
    });

    $(document).on('click', '.alert-form .confirm', function(e) {
        e.preventDefault();
        $.fancybox.close(true);
    });
};

Step.prototype.changeCategoryValue = function(el) {
    cat = el.hasClass('has-sub') ? '' : el.data('id');
    title = el.hasClass('has-sub') ? '' : el.data('title');
    $('#cat-title').val(title);
    $("input[name='category']").val(cat);
};

var step1 = new Step();
David Ewen
  • 3,212
  • 1
  • 16
  • 28
  • Overall this is best, but still has the `self` variable which the OP doesn't want (`fct` in their implementation). – zamnuts Oct 25 '13 at 06:24
  • In case the OP is worried about using self it is quite a standard javascript pattern http://stackoverflow.com/questions/962033/what-underlies-this-javascript-idiom-var-self-this – David Ewen Oct 25 '13 at 06:32
  • I agree, per my comment on the question itself, but nevertheless OP would like to see alternatives. – zamnuts Oct 25 '13 at 06:35
0

you can try use clojure like this:

step1 = (function(){
            function events(){
                $(document).on('click', '.form-line li', function(e) {
                    e.preventDefault();
                    changeCategoryValue($(this));
                });

                $(document).on('click', '.alert-form .confirm', function(e) {
                    e.preventDefault();
                    $.fancybox.close(true);
                });
            }
            function changeCategoryValue(el) {
                cat = el.hasClass('has-sub') ? '' : el.data('id');
                title = el.hasClass('has-sub') ? '' : el.data('title');
                $('#cat-title').val(title);
                $("input[name='category']").val(cat);
            }
            function init(){
                events();
            }

            return {
                init:init,
                changeCategoryValue: changeCategoryValue
            }
        })()
Grundy
  • 13,060
  • 3
  • 33
  • 51