Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 297701
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T06:39:50+00:00 2026-05-12T06:39:50+00:00

I have the following plugin, which takes a partial game name, bounces it off

  • 0

I have the following plugin, which takes a partial game name, bounces it off our DataQuery object to get a list of items from the server (basic autocompleter/selector).

The problem I am having is this.

I am using it on a page, where the selector appears in a dialog box. When the user is done, I ‘destroy’ the selector, and then recreate it when they need it again. This is because on this page, the user is sometimes adding a new game, or editing, so I have to change it depending.

The Add ability sets the resultsChange option to true, because the user can change the game selection if they wish.

The Edit ability sets the resultsChange option to false, because it’s locked.

However, all subsequent uses of the selector only have access to the original option object which was passed the first time. It’s like using the destroy method doesn’t actually remove the previous option object.

I am not seeing how I can fix this. Any help would be appreciated.

(function($){

    $.fn.Napalm_GameSelector = function(settings) {
        if (this.length > 1) { return false; }
        var $element = $(this);

        if (settings == 'destroy') {
            if (!$element.data('Napalm_Selector')) { return; }
            $element.data('Napalm_Selector').destroy();
            $element.removeData('Napalm_Selector');
            return;
        }
        if ($element.data('Napalm_Selector')) { return; }

        /* Verify parent element has id */
        if ($element.attr('id').length < 1) {
            Napalm_Error.failure('Base element has no ID');
            return false;
        }

        /* Verify parent element type */
        if ($element.attr('type') !== 'text') {
            Napalm_Error.failure('Must be attached to a text field');
            return false;
        }

        $element.data('Napalm_Selector', new SelectorObject(this, settings));
        delete settings;
        delete $element;
    };

    var defaults = {
            /* General */
        id: false,
        formname: false,
        selectedId: false,
        callTyping: false, 
        callStart: false,
        callComplete: false,
        callResults: false,
        callNoresults: false,
        callSelected: false,
        callUnselected: false,
        classLoader: 'dataselector_loader',
        classResults: 'dataselector_results',
        classNoresults: 'dataselector_noresults',
        classTruncated: 'dataselector_truncated',
        keyDelay: 1500,
        keyLength: 2,
        resultsTimeout: 0,
        resultsOffclick: true,
        resultsAnchor: 'left',
        resultsChange: true,
        resultsChangeText: 'Change Game',
            /* Specific */
        showGamebox: false,
        showGameinfo: true,
        classBoxart: 'boxart',
        infoBackground: false
    };

    var SelectorObject = function(element, settings) {

        var $element = $(element);
        var obj = this;

        var options = $.extend({}, defaults, settings);

        var componentName = 'User_My_GamesLibrary';

        var id = false;
        var menuTimeout = false;
        var keyTimeout = false;

        var typingStarted = false;
        var typingFinished = false;


        /* INIT */

        /* Option: ID */
        if (options.id !== false) {
            id = options.id;
            $element.attr('id', id);
        } else {
            id = $element.attr('id');
        }

        $element.parent().attr('onSubmit','javascript:return false;');
        $element.attr('autocomplete','off');


        /* METHODS */

        this.select = function(element) {
            var self = this;
            $element.val('');
            if (!parseInt(element)) {
                itemid = $(element).attr('rel');
            } else {
                itemid = element;
            }
            $element.hide();
            $('#'+id+'-formelement').attr('value', itemid);
            $element.after(this.templates.selected(id+'-selected', itemid));
            /* Change Link */
            if (options.resultsChange) {
                $('#'+id+'-selected a').click(function() {
                    /* User Callback: callUnselected */
                    if (typeof(options.callUnselected) == 'function') { options.callUnselected(); }

                    self.reset();
                    return false;
                });
            }
            /* Clean up */
            this.clear();
            /* User Callback: callComplete */
            if (typeof(options.callSelected) == 'function') { options.callSelected(itemid); }
        }

        this.binding = function() {
            var self = this;
            $element.bind('keydown click', function(e) {
                clearTimeout(keyTimeout);
                if (e.keyCode == 13 || e.type == 'click') {
                    if ($.trim($element.val()).length >= options.keyLength) { 
                        self.search();
                    }
                } else if (e.keyCode != 38 && e.keyCode != 40) {
                    /* User Callback: callStart */
                    if (!typingStarted) {
                        typingStarted = true;
                        if (typeof(options.callStart) == 'function') { options.callStart(); }
                    }
                    /* User Callback: callTyping */
                    if (typeof(options.callTyping) == 'function') { options.callTyping(); }

                    if ($.trim($element.val()).length >= options.keyLength) {
                        keyTimeout = setTimeout(function() {
                            self.search();
                        },options.keyDelay);
                    }
                }
            });
        }

        this.search = function() {
            var self = this;
            /* User Callback: callEnd */
            if (typeof(options.callEnd) == 'function') { options.callEnd(); }
            /* Remove Any Existing Elements */
            this.clear();
            /* Content Exists? */
            if ($element.val().length < 1) { return false; }
            /* Loading Template */
            $element.after(this.templates.loading(id+'-loading', options.classLoader));
            $('#'+id+'-loading').css('position','absolute');
            $('#'+id+'-loading').css({
                top: ($element.position().top+$element.outerHeight(true))+'px',
                left: $element.position().left+'px'
            });
            /* Get Data */
            Napalm_DataQuery['getGames']($.trim($element.val()), function(data) {
                /* Remove Loading Template */
                $('#'+id+'-loading').remove();
                /* Setup Offclick */
                if (options.resultsOffclick) {
                    $('body').bind('click',function() { self.clear(); });
                }
                if (data['count']) {
                    /* Build Item Data */
                    var items = '';
                    $.each(data['items'], function(k, v) {
                        items += self.templates.resultsitem(id+'-item-'+v['id'], v['id'], v['title']);
                    });
                    if (data['truncated']) {
                        items += self.templates.truncateditem(id+'-item-truncated', options.classTruncated);
                    }
                    /* Inject Results */
                    $('body').append(self.templates.results(id+'-results', items, options.classResults));
                    //$element.after(self.templates.results(id+'-results', items, options.classResults));
                    $results = $('#'+id+'-results');
                    var offset = $element.offset();
                    $results
                        .css({
                            zIndex: 9999,
                            position: 'absolute',
                            minWidth: $element.outerWidth(),
                            top: Math.round(offset.top+$element.innerHeight())+'px',
                            left: Math.round(offset.left)+'px'
                        });

                    /*
                    switch (options.resultsAnchor.toLowerCase()) {
                        case 'right':
                            $results.css('left',(Napalm_Position.absolute($element).right-Napalm_Position.width('#'+id+'-results'))+'px');
                            break;
                        case 'left':
                            $results.css('left',Napalm_Position.absolute($element).left+'px');
                            break;
                    }
                    */

                    $resultsItems = $('ul > li:not(.truncated)', $results);

                    /* Binding Clicks */
                    $resultsItems.click(function() {
                        self.select(this);
                    });
                    /* Handle Arrow Keys */
                    var resultIndex = -1;
                    $(window).keydown(function(e) {
                        switch (e.keyCode) {
                            case 38: /* Up Arrow */
                                $element.blur()
                                if (resultIndex > 0) {
                                    resultIndex--;
                                    /* Release Previous */
                                    if (resultIndex < $resultsItems.size()-1) {
                                        node = $resultsItems[resultIndex+1];
                                        $(node).removeClass('active');
                                        delete node;
                                    }
                                    node = $resultsItems[resultIndex];
                                    $(node).addClass('active');
                                    /* Container Scrolling */
                                    self.scroll(node);
                                    delete node;
                                }
                                return false;
                                break;
                            case 40: /* Down Arrow */
                                $element.blur()
                                if (resultIndex < $resultsItems.size()-1) {
                                    resultIndex++;
                                    /* Release Previous */
                                    if (resultIndex > 0) {
                                        node = $resultsItems[resultIndex-1];
                                        $(node).removeClass('active');
                                        delete node;
                                    }
                                    /* Paint New */
                                    node = $resultsItems[resultIndex];
                                    $(node).addClass('active');
                                    /* Container Scrolling */
                                    self.scroll(node);
                                    delete node;
                                }
                                return false;
                                break;
                            case 13: /* Enter */
                                $element.blur()
                                if (resultIndex > -1) {
                                    self.select($resultsItems[resultIndex]);
                                }
                                return false;
                                break
                        }
                        return true;
                    });
                    /* Setup Menu Timeout */
                    if (options.resultsTimeout > 0) {
                        menuTimeout = setTimeout(function() {
                            self.clear();
                        },options.resultsTimeout);
                    }
                    /* User Callback: callResults */
                    if (typeof(options.callResults) == 'function') { options.callResults(); }
                    /* User Callback: callComplete */
                    if (typeof(options.callComplete) == 'function') { options.callComplete(); }
                } else {
                    /* No Results */
                    /* User Callback: callNoresults */
                    if (typeof(options.callNoresults) == 'function') { options.callNoresults(); }
                    /* Inject Noresults Template */
                    $element.after(self.templates.noresults(id+'-noresults', options.classNoresults));
                    /* User Callback: callComplete */
                    if (typeof(options.callComplete) == 'function') { options.callComplete(); }
                }
            });
        }

        this.scroll = function(node) {
            var self = this;
            var viewport = { top: $('#'+self.id+'-results').scrollTop(),
                             bottom: ($('#'+self.id+'-results').scrollTop() + $('#'+self.id+'-results').height()),
                             height: ($('#'+self.id+'-results').scrollTop() + $('#'+self.id+'-results').height()) - $('#'+self.id+'-results').scrollTop() }

            var pos = Napalm_Position.position(node);
            var item =  { top: $(node).prevAll().size() * (pos.bottom - pos.top),
                          bottom: ($(node).prevAll().size()+1) * (pos.bottom - pos.top),
                          height: pos.bottom - pos.top
                        }
            delete pos;

            /* Check Viewport Boundries */
            if (item.top < viewport.top) { /* Top */
                $('#'+id+'-results').scrollTop(item.top);
            } else if (item.bottom > viewport.bottom) { /* Bottom */
                $('#'+id+'-results').scrollTop(item.bottom - viewport.height);
            }
        }

        this.clear = function() {
            $('#'+id+'-loading').remove();
            $('#'+id+'-results').remove();
            $('#'+id+'-noresults').remove();
            $('body').unbind('click');
            $(window).unbind('keydown');
            clearTimeout(menuTimeout);
            typingStarted = false;
            typingFinished = false;
        }

        this.reset = function() {
            $element.show();
            $('#'+id+'-selected').remove();
            $element.focus();
        }

        this.destroy = function() {
            this.clear();
            this.reset();
            delete $element;
            delete obj;
            delete options;
            delete componentName;
            delete id;
            delete menuTimeout;
            delete keyTimeout;
            delete typingStarted;
            delete typingFinished;
        }

        this.templates = {
            loading: function(_id, _class) {
                return  '<div id="'+_id+'" class="'+_class+'">' +
                        '   <img src="http://i.rebuild.sb.napalmriot.com/common/ajax/spinner2.gif" width="16" height="16" />' +
                        '   Searching..' +
                        '</div>';
            },
            noresults: function(_id, _class) {
                return  '<div id="'+_id+'" class="'+_class+'">' +
                        '   No games found matching your search' +
                        '</div>';
            },
            results: function(_id, _items, _class) {
                return  '<div id="'+_id+'" class="'+_class+'">'+
                        '   <ul class="dieBullets">'+
                        '       '+_items+
                        '   </ul>'+
                        '</div>';
            },
            resultsitem: function(_id, _content_id, _content_value) {
                return  '<li id="'+_id+'" rel="'+_content_id+'">'+
                        '   '+_content_value+
                        '</li>';
            },
            truncateditem: function(_id) {
                return  '<li id="'+_id+'" class="truncated">'+
                        '   Refine your search<br />to see more results'+
                        '</li>';
            },
            selected: function(_id, _content_id) {
                var self = this;

                var gameURL = '';
                var gameTitle = '';

                sendData = JSON.stringify({"gameid":_content_id});

                $.ajax({
                    type:'GET',
                    async:false,
                    url:window.urls['component']+componentName+';getBoxartUrl;'+escape(escape(sendData)),
                    dataType:'json',
                    success:function(data) {
                        if (data.success) {
                            gameURL = data.response.url;
                            gameTitle = data.response.title;
                        } else {
                            Napalm_UI.error(data.response);
                        }
                    }
                });

                if (options.infoBackground) { var bgcolor = options.infoBackground; } else { var bgcolor = ''; }

                var html =  '<div id="'+_id+'">'+
                        '   <img src="'+gameURL+'" title="'+gameTitle+'" class="'+options.classBoxart+'" width="100" height="143" rel="'+_content_id+'" />'+
                        '   <img src="http://i.napalmriot.com/boxart.php?id='+_content_id+'&bgcolor='+bgcolor+'" title="'+gameTitle+'" width="31" height="150" />';
                if (options.resultsChange) {
                    html += '   <br />'+
                            '   <a href="#">'+options.resultsChangeText+'</a>';
                }
                html +=     '</div>';

                delete gameURL;
                delete gameTitle;
                delete bgcolor;
                delete _id;
                delete _content_id;

                return html;
            }
        }      

        /* Option Get/Set */
        this.option = function(key, value) {
            if (typeof(options[key]) == 'undefined') { return false; }
            if (typeof(value) == 'undefined') { return options[key]; }
            if (options[key] = value) { return true; }
            return false;            
        }

        /* Option: SelectedId */
        if (options.selectedId !== false) {
            this.select(options.selectedId);
        }

        this.binding();
    };
})(jQuery);
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T06:39:50+00:00Added an answer on May 12, 2026 at 6:39 am

    This is because of a peculiarity with delete.

    And this is a hard one to understand – even the mozilla documentation makes this unclear:

    The delete operator deletes an object,
    an object’s property, or an element at
    a specified index in an array.

    But later states

    If expression does not evaluate to a
    property, delete does nothing.

    But if we keep reading, finally some clarity

    You can use the delete operator to
    delete variables declared implicitly
    but not those declared with the var
    statement.

    So there you go. Also notice how this page mentions that delete has a return value of true|false depending on the legality of the operation.

    This little script below duplicates similar behavior to your script but in a small, easy-to-see way (requires firebug)

    var a = {foo:'bar',bar:'foo',baz:1};
    var b = {"a":a}
    
    console.log( a );
    console.log( b );
    
    delete a;
    delete b;
    
    console.log( a );
    console.log( b );
    
    delete b.a;
    
    console.log( b );
    

    In short, I think your solution will just be to reset your options as an empty object

    options = {};
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following model class Plugin(models.Model): name = models.CharField(max_length=50) # more fields which
I have the following problem: I need to get a ConfigurationSection - object from
I have some code (it's part of a wordpress plugin) which takes a text
I have modified the buddypress admin bar by creating the following plugin which adds
I have the following struct which will be used to hold plugin information. I
I have the following home-grown jquery plugin: (function($) { $.fn.defaultButton = function(button) { var
I have the following in my .vimrc syntax on filetype plugin indent on #
I have the following setup: eclipse a standard Java project (A) an eclipse plugin
Say I have the following file structure: app/ app.py controllers/ __init__.py project.py plugin.py If
I have a following problems with eclipse, when I installed ClearCase plugin from this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.