Pergunta

I am using Prototype JavaScript, I have a button and I want to use the Event.observe method to observe for a click action.

The issue is that I want to call one of two functions depending on an if statement in the PHP code. My understanding of Javascript and the Event.observe method is quite limited but it seems like the code doesn't work when trying to observe for an element that isn't present. I can get this to work in a very hacky way, as follows:

<?php if ($_type == "forward_second"):?>
    <input type="button" id="week_backward_second" value="&lt;&lt;" disabled/>
    <input type="hidden" id="week_backward" value="&lt;&lt;" />
<?php else: ?>
    <input type="button" id="week_backward" value="&lt;&lt;" disabled/>
    <input type="hidden" id="week_backward_second" value="&lt;&lt;" />
<?php endif; ?>

And in the JavaScript:

initialize: function {    
    Event.observe('week_backward', 'click', this.backward.bind(this));
    Event.observe('week_backward_second', 'click', this.backwardSecond.bind(this));
},

By having a hidden field the 'unnecessary' Event.observe has an element to observe and the code works.

Can anyone suggest a better way of doing this?

Foi útil?

Solução

I hope that I understood your question :)

var element = $('week_backward'),
    method = this.backward;

// Get a second element if first doesn't exist.
if (!element) {
    element = $('week_backward_second');
    method = this.backwardSecond;
}

element.observe('click', method.bind(this));

I used shorter Prototype API - unless you don't have conflicts with other libs I recommend it.

PS. I forgot to mention that now you'll only have to print one button, without the hidden one.

Outras dicas

  1. No hidden fields. Check existence of element before observing (as Reinmar wrote):

    initialize: function {    
        if ($('week_backward')) $('week_backward').observe('click', this.backward.bind(this));
        if ($('week_backward_second')) $('week_backward_second').observe('click', this.backwardSecond.bind(this));
    },
    
  2. No hidden fields. Use event delegation:

    initialize: function {
        document.on('click', '#week_backward', this.backward.bind(this));
        document.on('click', '#week_backward_second', this.backwardSecond.bind(this));
    },
    

    Observer is attached to document and receives click events bubbled from your element if it exists.

Another way to handle this is with $$ and invoke. That way you are iterating over an array of one or no elements, and applying the method if it's called for.

$$('#week_backward').invoke('observe', 'click', this.backward);
$$('#week_backward_second').invoke('observe', 'click', this.backwardSecond);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top