javascriptjqueryfunctionanonymous-methodsmodularization

How can I make this anonymous function into a named function so I can move it to an external JS file for possible reuse


If I double posted this question, I'm sorry. I did not see it pop up under my questions that I'd asked in my profile, so I figured it didn't actually post. Anyway. I found the main logic for this code somewhere on stack overflow and modified it for my own use (can't remember where I found it). While this code is working as intended, due to scalability issues, I'd like to convert this into a standard function of the format function serializeObject(form_name){...} without the jQuery and without encapsulating in the parentheses, so I can move this function to another javascript file which can then be used by multiple forms on multiple pages on my site. Is there a way to do this? Basically, it needs to be able to take a form name as a parameter and operate on that form. As it is encapsulated now, it works if and only if it is in the same file as the function that calls it. This is terrible practice, as this code is repeated multiple times, but as far as I can see, the only way to break the JS apart is to rewrite this function in every file.

   (function($) {
        $.fn.serializeObject = function() {
            var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
            };
            this.build = function(base, key, value) {
                base[key] = value;
                return base;
            };
            this.push_counter = function(key) {
                if(push_counters[key] === undefined) {
                    push_counters[key] = 0;
                }
                return push_counters[key]++;
            };
            $.each($(this).serializeArray(), function() {
                // skip invalid keys
                if(!patterns.validate.test(this.name)) {
                    return;
                }
                var k,
                keys = this.name.match(patterns.key),
                merge = this.value,
                reverse_key = this.name;
                while((k = keys.pop()) !== undefined) {
                    // adjust reverse_key
                    reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');
                    // push
                    if(k.match(patterns.push)) {
                        merge = self.build([], self.push_counter(reverse_key), merge);
                    }
                    // fixed
                    else if(k.match(patterns.fixed)) {
                        merge = self.build([], k, merge);
                    }
                    // named
                    else if(k.match(patterns.named)) {
                        merge = self.build({}, k, merge);
                    }
                }
                json = $.extend(true, json, merge);
            });
        return json;
        };
    })(jQuery);

and it is called with

var datObj = $(frm).serializeObject()

But this happens so many times i'd like to be able to only write this function once and then just call it when necessary from multiple separate files, possibly as a step towards creating react-like modules. Any ideas?


Solution

  • ibrahim mahrir's comment here gave me an idea that turned out to be correct. It was not the order of this file and jQuery, but rather the order of this file and my other custom js files. By moving all my custom JS scripts so they load after this file, the problem is solved.