Brian Schroeter
Brian Schroeter

Reputation: 1633

Triggering Prototype change event with jQuery

I don't have all that much experience with Prototype and I've been working with jQuery to get things working properly on our site found here. Today I've added a jQuery based script for session handling. The problem I'm having is that even though I've gotten so far today in terms of functionality, I can't seem to get the change event fired via jQuery.

I'm using the following code currently, but it isn't working properly (you can test it on the site.. as soon as you change the year using your mouse, the AJAX is triggered and a Make can be selected)...

var yearSelected = jQuery.jStorage.get("yearSelected");
console.log(yearSelected);

// Set the vars...

if ((jQuery("div.amfinder-horizontal td:nth-child(1) select").val() == "0")) {

    jQuery("div.amfinder-horizontal td:nth-child(1) select option").each(function() { this.selected = (this.text == "2003"); });

    jQuery("div.amfinder-horizontal td:nth-child(1) select").trigger('change');

    console.log('Set the year!');

}

The following code is the Prototype script controlling this and I need to fire off the change event, and would love to do it via jQuery if at all possible.

var amFinder = new Class.create();

amFinder.prototype = {
    initialize: function(containerId, ajaxUrl, loadingText, isNeedLast, autoSubmit)
    {
        this.containerId = containerId;
        this.ajaxUrl     = ajaxUrl;
        this.autoSubmit  = Number(autoSubmit);
        this.loadingText = loadingText;
        this.isNeedLast  = Number(isNeedLast);
        this.selects     = new Array();

        //possible bug if select order in the HTML will be different
        $$('#' + this.containerId + ' select').each(function(select){
            select.observe('change', this.onChange.bindAsEventListener(this));
            this.selects[this.selects.length] = select;
        }.bind(this));
    },

    onChange: function(event)
    {
        var select     = Event.element(event);
        var parentId   = select.value;
        var dropdownId = 0;

        /* should load next element's options only if current is not the last one */
        for (var i = 0; i < this.selects.length; i++){
            if (this.selects[i].id == select.id && i != this.selects.length-1){
                var selectToReload = this.selects[i + 1];
                if (selectToReload){
                    dropdownId = selectToReload.id.substr(selectToReload.id.search('--') + 2);
                }
                break;
            }
        }

        this.clearAllBelow(select);

        if (0 != parentId && dropdownId){
            var postData = 'dropdown_id=' + dropdownId + '&parent_id=' + parentId;
            new Ajax.Request(this.ajaxUrl, {
                method: 'post',
                postBody : postData,
                evalJSON : 'force',

                onLoading: function(){
                    this.showLoading(selectToReload);
                }.bind(this),

                onSuccess: function(transport) {
                    if (transport.responseJSON){
                        this.clearSelectOptions(selectToReload);
                        var itemsFound = false;
                        transport.responseJSON.each(function(item){
                            itemsFound = true;
                            var option = document.createElement('option');
                            option.value = item.value;
                            option.text  = item.label;
                            option.label = item.label;
                            $(selectToReload).appendChild(option);
                        });

                        if (itemsFound){
                            $(selectToReload).disabled = false;
                        }
                    }
                }.bind(this)
            });
        }
    },

    isLast: function(select)
    {
        return (this.selects[this.selects.length-1].id == select.id);    
    },

    isFirst: function(select)
    {
        return (this.selects[0].id == select.id);         
    },

    clearSelectOptions: function(select)
    {
        $(select).descendants().each(function(option){
            option.remove();
        });
    },

    clearAllBelow: function(select)
    {
        var startClearing = false;
        for (var i = 0; i < this.selects.length; i++){
            if (startClearing){
                this.clearSelectOptions(this.selects[i]);
                $(this.selects[i]).disabled = true;
            }
            if (this.selects[i].id == select.id){
                startClearing = true;
            }
        }
        var type = (((this.isLast(select) && !this.isNeedLast) && select.value > 0) || ((this.isNeedLast) && ((select.value > 0) || (!this.isFirst(select))))) ? 'block' : 'none';

        if ('block' == type && this.autoSubmit && this.isLast(select))
        {
            $$('#' + this.containerId + ' .amfinder-buttons button')[0].form.submit();
        } else {
            $$('#' + this.containerId + ' .amfinder-buttons')[0].style.display = type;            
        }


    },

    showLoading: function(selectToReload)
    {
        var option = document.createElement('option');
        option.value = 0;
        option.text  = this.loadingText;
        option.label = this.loadingText;
        $(selectToReload).appendChild(option);        
    },
};

Upvotes: 2

Views: 904

Answers (1)

Nikola Loncar
Nikola Loncar

Reputation: 2671

I had the same problem. Here is solution. When you create : amfinder-horizontal the html goes something like this

<div class="amfinder-horizontal" id="amfinder_5333ffb212b09Container">
   ...
</div>

Look at id element : amfinder_5333ffb212b09 Container, bold part is also the name of variable that is amfinder object (created from prototype). It's a random name. This is from the extension source :

<?php $finderId = 'amfinder_' . uniqid(); ?>
...
<script type="text/javascript">
var <?php echo $finderId ?>  = new amFinder(
    '<?php echo $finderId ?>Container', 
    '<?php echo $this->getAjaxUrl() ?>', 
    '<?php echo $this->__('Loading...')?>',
    '<?php echo Mage::getStoreConfig('amfinder/general/partial_search')?>',
    <?php echo intval(Mage::getStoreConfig('amfinder/general/auto_submit')) ?>
);
</script>

So on every page refresh there is different name. var <?php echo $finderId ?>

Steps :

// Find the name for amfinder object.
var objName = jQuery("div.amfinder-horizontal").attr('id').replace('Container','');

// set Value to that select - copied from your code
jQuery("div.amfinder-horizontal td:nth-child(1) select option").each(function() { this.selected = (this.text == "2003"); });

// call the change event of that object
var targetObj = {
    target : jQuery("div.amfinder-horizontal td:nth-child(1) select")[0]
};
window[objName].onChange(targetObj);

Upvotes: 1

Related Questions