[Unique Plugin] adds unique checking according to the node title AND the node type #168

Closed
Kobee1203 opened this Issue Feb 9, 2012 · 1 comment

Projects

None yet

3 participants

I changed the "unique" plugin to prevent from nodes with same titles AND same type coexisting in the same parent.
I added the boolean 'unique_by_type'. If this boolean is true, the plugin checks the title AND the type.
It is useful when you create a tree with folders and files. You can have a folder named 'foo' and also a file named 'foo'.
I don't know if you are interested in this improvement, but I share it anyway because I did it ;)

Below is the modified code :

(function ($) {
    $.jstree.plugin("unique", {
        __init : function () {
            this.get_container()
                .bind("before.jstree", $.proxy(function (e, data) { 
                        var nms = [], res = true, p, t;
                        if(data.func == "move_node") {
                            // obj, ref, position, is_copy, is_prepared, skip_check
                            if(data.args[4] === true) {
                                if(data.args[0].o && data.args[0].o.length) {
                                    var selector = this._get_selector(data.args[0].o.attr(this._get_settings().types.type_attr));
                                    data.args[0].o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); });
                                    res = this._check_unique(nms, data.args[0].np.find(selector).not(data.args[0].o), "move_node");
                                }
                            }
                        }
                        if(data.func == "create_node") {
                            // obj, position, js, callback, is_loaded
                            if(data.args[4] || this._is_loaded(data.args[0])) {
                                p = this._get_node(data.args[0]);
                                var selector = this._get_selector(data.args[2] && data.args[2].attr ? data.args[2].attr.rel : "default");
                                if(data.args[1] && (data.args[1] === "before" || data.args[1] === "after")) {
                                    p = this._get_parent(data.args[0]);
                                    if(!p || p === -1) { p = this.get_container(); }
                                }
                                if(typeof data.args[2] === "string") { nms.push(data.args[2]); }
                                else if(!data.args[2] || !data.args[2].data) { nms.push(this._get_string("new_node")); }
                                else { nms.push(data.args[2].data); }
                                res = this._check_unique(nms, p.find(selector), "create_node");
                            }
                        }
                        if(data.func == "rename_node") {
                            // obj, val
                            nms.push(data.args[1]);
                            t = this._get_node(data.args[0]);
                            p = this._get_parent(t);
                            var selector = this._get_selector(t.attr('rel'));
                            if(!p || p === -1) { p = this.get_container(); }
                            res = this._check_unique(nms, p.find(selector).not(t), "rename_node");
                        }
                        if(!res) {
                            e.stopPropagation();
                            return false;
                        }
                    }, this));
        },
        defaults : { 
            error_callback : $.noop,
            unique_by_type : false
        },
        _fn : { 
            _get_selector : function(type) {
                var selector;
                var s = this._get_settings();
                if(s.unique.unique_by_type) {
                    var typeAttr = s.types.type_attr;
                    if(type == "default") {
                        selector = '> ul > li:not([' + typeAttr + ']),> ul > li[' + typeAttr + '="' + type + '"]';
                    } else {
                        selector = '> ul > li[' + typeAttr + '="' + type + '"]';
                    }
                } else {
                    selector = '> ul > li';
                }
                return selector;
            },
            _check_unique : function (nms, p, func) {
                var cnms = [];
                p.children("a").each(function () { cnms.push($(this).text().replace(/^\s+/g,"")); });
                if(!cnms.length || !nms.length) { return true; }
                cnms = cnms.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",");
                if((cnms.length + nms.length) != cnms.concat(nms).sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",").length) {
                    this._get_settings().unique.error_callback.call(null, nms, p, func);
                    return false;
                }
                return true;
            },
            check_move : function () {
                if(!this.__call_old()) { return false; }
                var p = this._get_move(), nms = [];
                if(p.o && p.o.length) {
                    p.o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); });
                    return this._check_unique(nms, p.np.find("> ul > li").not(p.o), "check_move");
                }
                return true;
            }
        }
    });
})(jQuery);
@vakata vakata closed this Dec 30, 2013
Contributor

I ran into the same issue with the latest jsTree, is there a resolution to this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment