haromy
haromy

Reputation: 13

keyup event resets input field

Every time I press a key on my keyboard, it sets $(this).val(""); to null and the score variable will be -2.

initialize: function() {
    var score = 0;
    var wrapper = $('<div>')
        .css({
            position:'fixed',
            top:'0',
            left:'0',
            width:'100%',
            height:'100%'
        });
    this.wrapper = wrapper;

    var self = this;
    var text_input = $('<input>')
        .addClass('form-control')
        .css({
            'border-radius':'4px',
            position:'absolute',
            bottom:'0',
            'min-width':'80%',
            width:'80%',
            'margin-bottom':'10px',
            'z-index':'1000'
        }).keyup(function() {
            var words = self.model.get('words');
            for(var i = 0;i < words.length;i++) {
                var word = words.at(i);
                var typed_string = $(this).val();
                var string = word.get('string');
                if(string.toLowerCase().indexOf(typed_string.toLowerCase()) === 0) {
                    word.set({highlight:typed_string.length});
                    if(typed_string.length === string.length) {
                        $(this).val("");
                        score+=10;
                        $("#dialog").dialog('option', 'title', 'Score : '+score);
                    }
                }
                else {
                    word.set({highlight:0});
                    $(this).val(""); // problem
                    score-=2; // problem
                    $("#dialog").dialog('option', 'title', 'Score : '+score); // problem
                }
            }
        });

    $(this.el)
        .append(wrapper
            .append($('<form>')
                .attr({
                    role:'form'
                })
                .submit(function() {
                    return false;
                })
                .append(text_input)));

    text_input.css({left:((wrapper.width() - text_input.width()) / 2) + 'px'});
    text_input.focus();

    this.listenTo(this.model, 'change', this.render);
},

When I remove the code that causes the problem, it works perfectly every time. inputting the right word and giving the var score score of +10.

Upvotes: 0

Views: 542

Answers (1)

Emile Bergeron
Emile Bergeron

Reputation: 17429

How the keyup event works?

The keyup event is triggered every time a key is released.

This means that if the target word is haromy, when typing the h, the event is triggered and the code in the callback is run.

It means that the following will always be false if typing the first letter wrong.

"haromy".toLowerCase().indexOf("f".toLowerCase()) === 0

So the user types a letter, it's not the same first letter, so the field is emptied immediatly by $(this).val("").

Maybe use another event?

If you want to check once the user unfocus the input, the blur event would work.

If you want to make the check when the user clicks a button, use a click event on a new button.

How to stylize a JavaScript application?

Do not set the initial CSS using jQuery's css function. Keep the styling in a CSS file linked in the HTML.

Using the css function only clutters your application logic, makes it difficult to maintain and delay the application of the style to after the JavaScript execution.

How to bind jQuery events with Backbone?

I removed the tag from the question as it's irrelevant, but seeing that you're using it and that it could be improved a lot, I'll throw additional information here.

When using Backbone, don't bind events using jQuery directly. Use the Backbone view's events hash.

Your view could look like this:

var View = Backbone.View.extend({
    template: '<div class="wrapper"><input class="form-control" /></div>'
    events: {
        "blur input": "onInputBlur"
    },
    onInputBlur: function() {
        var words = this.model.get('words').each(function(word) {
            var typed_string = this.$input.val(),
                string = word.get('string');
            // Check each word and score here
        }, this);
    },


    initialize: function() {
        this.score = 0;
        this.listenTo(this.model, 'change', this.render);
    },

    render: function() {
        this.$el.html(this.template);
        this.$wrapper = this.$('.wrapper');
        this.$input = this.$('input').focus();
        return this;
    },
});

With styles out, the CSS file would be:

.wrapper {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.input {
    border-radius: 4px;
    position: absolute;
    bottom: 0;
    min-width: 80%;
    width: 80%;
    margin-bottom: 10px;
    z-index: 1000;
}

Upvotes: 1

Related Questions