Codd Wrench Codd Wrench - 2 months ago 11
Javascript Question

how to link base type variable in JsViews custom tag

I use JsViews + spectrumjs colorpicker and i had to create custom tag like this:

$.views.tags({
spectrum : {
template : "<input/>",
onAfterLink : function (tagCtx, linkCtx) {
var tag = this;
var props = tagCtx.props;
var options = {
color : tagCtx.args[0]
};
var linkedElem;
if (tag._.unlinked) {
if (!tag.linkedElem) {
tag.linkedElem = tag._.inline ? tag.contents("*").first() : $(linkCtx.elem);
}
linkedElem = tag.linkedElem;
$.each(props, function (key, prop) {
var option;
if (key.charAt(0) === "_") {
key = key.slice(1);
options[key] = prop;
}
});
this.linkedElem.spectrum(options);
}
},
onUpdate : function () {
return false;
},
onDispose : function () {
this.linkedElem.spectrum("destroy");
}
}
});


It works see example, but i need to dynamically update color.
In spectrumjs there is event
move.spectrum
and sign up on him like that:

tag.spectrum = tag.linkedElem.spectrum(options);
tag.spectrum.on("move.spectrum", $.proxy(tag.moveEvent, tag));


And add handlers:

moveEvent : function (e, val) {
// update model.color
console.log(val.toRgbString());
this.linkedElem.val(val.toRgbString());
},

onDispose : function () {
this.spectrum.off("move.spectrum", $.proxy(this.moveEvent, this));
this.spectrum.spectrum("destroy");
}


See example.
So I have not tried it, I can not track changes or apply changes to
model.color
becose color is base type
string


Update

I made an example without use custom tag of how things should work.

Answer

Here is an update of your example page: https://jsfiddle.net/BorisMoore/g4vs23v1/5/

I changed the onAfterLink code as follows:

onAfterLink : function (tagCtx, linkCtx) {
    var tag = this;
    var props = tagCtx.props;
    var options = {
        color: tagCtx.args[0]
    };
    var linkedElem;
    if (tag._.unlinked) {
        if (!tag.linkedElem) {
            tag.linkedElem = tag._.inline ? tag.contents("*").first() : $(linkCtx.elem);
        }
        linkedElem = tag.linkedElem;
        $.each(props, function (key, prop) {
            var option;
            if (key.charAt(0) === "_") {
                key = key.slice(1);
                options[key] = prop;
            }
        });
        tag.spectrum = linkedElem.spectrum(options);
        //tag.spectrum.on("move.spectrum", $.proxy(tag.moveEvent, tag));
        linkedElem.on("move.spectrum", $.proxy(tag.moveEvent, tag));
    } else {
        tag.linkedElem.spectrum("set", options.color);
    }
},

Specifically I corrected the binding to move.spectrum as follows

linkedElem.on("move.spectrum", $.proxy(tag.moveEvent, tag));

And when color is updated observably, such as by changing the "rgb(...)" string in the textbox, the new value needs to be set on the spectrum tag, which happens on this line:

tag.linkedElem.spectrum("set", options.color);

So now you should have two-way binding between the input binding to color and the input binding to the {{spectrum}} tag.

Comments