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?

2
  • 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. Commented Oct 25, 2013 at 5: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. Commented Oct 25, 2013 at 6:00

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

@TudorRavoiu oops, I left out the most important detail! Answer updated.
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.
@TudorRavoiu in your case it might be e.currentTarget instead of e.target - I always get them mixed up!
0

try to use:

step1.changeCategoryValue($(this));

1 Comment

ok, this works, but is it also another solution? so that if the classname will change than the calling won't change?
0

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

step1.changeCategoryValue('any_element_ref');

Comments

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();

3 Comments

Overall this is best, but still has the self variable which the OP doesn't want (fct in their implementation).
In case the OP is worried about using self it is quite a standard javascript pattern stackoverflow.com/questions/962033/…
I agree, per my comment on the question itself, but nevertheless OP would like to see alternatives.
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
            }
        })()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.