Set global setOptions for Backbone.Stickit.js bindings - javascript

Is there any way of setting global setOptions for Backbone.Stickit.js?
That way I can avoid having to set validate: true as well as other custom options on every binding:
bindings = {
'.someEl': {
observe: 'prop1'
, setOptions: {
validate: true
}
}
, '.someOtherEl': {
observe: 'prop2'
, setOptions: {
validate: true
}
}
, '.yetAnotherEl': {
observe: 'prop3'
, setOptions: {
validate: true
}
}
};
I had seen some post about using the * selector with .addHandler:
Backbone.Stickit.addHandler({
selector: '*',
setOptions: {validate: true}
});
But that didn't work for me.
I'm sure there's a simple way that I'm missing but for now my hack was to create a method that parses my property name:
function stickTo(propName, options) {
_.extend({observe: propName}, {setOptions: {validate: true}}, options);
}
...
bindings: {
'.someEl': stickTo('prop1')
}
stickTo sets all my default options and takes an optional parameter that overrides my defaults...

The handler should have worked. I setup a fiddle which logs the arguments of Model.set to the console, every time input changes:
http://jsfiddle.net/px6UP/39/
Backbone.Stickit.addHandler({
selector: '*',
setOptions: {validate:true}
});

Related

Vue Watchers for multiple button clicks

I have multiple filters that are set to false and if clicked turn to true and must implement the specific filter. How can I use a watchers to look for the changing of my filter from false to true. Currently as I have all my functions in one watcher if one filter is clicked all filters are implemented. Whereas I need it to be only the specific filter that is related to the filter button.
<sankey-filter
label="string1"
v-model="filters.string1"
/>
<sankey-filter
label="string2"
v-model="filters.string2"
/>
<sankey-filter
label="string3"
v-model="filters.string3"
/>
data() {
return {
filters: {
statusString1: false,
statusString2: false,
statusString3: false,
}
watch: {
filters: {
handler: function(){
this.filterString1(),
this.filterString2(),
this.filterString2(),
},
deep: true
Vue $watch provide callback function two parameters (newValue, oldValue) so U can check new value each filter if true for each filter action
watch: {
filters: {
handler: function({statusString1, statusString2, statusString3}){
if (statusString1)
this.filterString1()
if (statusString2)
this.filterString2()
if (statusString3)
this.filterString3()
},
deep: true
}
}
Use a dot-delimited path as the watcher key.
watch: {
'filters.string1' () {
this.filterString1(),
},
'filters.string2' () {
this.filterString2(),
},
'filters.string3' () {
this.filterString3(),
},
}

How to pass a function to component to handle a drag event

I want to use v-for and is to render the components I need. So I create the component Cube.vue like this:
<script>
export default {
name: 'cube',
render: function(createElement) {
return createElement("div",{
props: {
style: {
type: Object
},
dragstartHandler: {
type: Function
},
classNames: {
type: Array|String|Object
}
},
style: this.style,
attrs: {
draggable: "true",
},
on: {
dragstart: this.dragstartHandler
},
'class': this.classNames
},[
createElement("div",{
class: ["resizer", "top-left"]
}),
createElement("div",{
class: ["resizer", "top-right"]
}),
createElement("div",{
class: ["resizer", "bottom-left"]
}),
createElement("div",{
class: ["resizer", "bottom-right"]
}),
])
}
}
</script>
And then, I use it like this
<component
v-for="component in components"
:class="component.classes"
:key="component.refValue"
:is="component.type"
:style="component.style"
:dragstartHandler="component.dragstartHandler"
:ref="component.refValue"
>
</component>
Everything as I expected, except the dragstartHandler. It throws an error
[Vue warn]: Invalid handler for event "dragstart": got undefined
I try to console.log() the components. The result is :
[{…}, __ob__: Observer]
0:
classes: Array(2)
dragstartHandler: ƒ ()
refValue: "cube-0"
style: Object
type: "cube"
It really is a function. But I don't know why it go to undefined in the render. I have checked I didn't spell wrong.
I just want pass the function to the component to handle the drag event. So how does it happened and what should I do to resolve it.
The dragHandler function is these:
dragstartCopyHandler(event) {
event.dataTransfer.setData("elementId", event.target.id);
event.dataTransfer.setData("componentOffsetX", event.offsetX);
event.dataTransfer.setData("componnetOffsetY", event.offsetY);
event.dataTransfer.setData("dropEffect", "copy");
event.dataTransfer.dropEffect = "copy";
},
dragstartMoveHandler(event) {
console.log("move start")
event.dataTransfer.setData("elementId", event.target.id);
event.dataTransfer.setData("componentOffsetX", event.offsetX);
event.dataTransfer.setData("componnetOffsetY", event.offsetY);
event.dataTransfer.setData("dropEffect", "move");
event.dataTransfer.dropEffect = "move";
},
And I pass the dragstartMoveHandler to the component.
this.components.push({
refValue: `${elementId}-${this.count}`,
type: elementId,
style: style,
dragstartHandler: this.dragstartMoveHandler,
classes: ["component", elementId]
});
I write the pages use js to control Dom before. And today I want to rewrite it with vue. So here might something wrong with the function, but the problem now is the function passed is undefined.
The cube component needs to define a prop for dragstartHandler so that it receives it from the parent for passing it on to the div. The same is true of the style and class bindings, which are also not working as you expect, but you don't see an error there because those are built-in bindings which get transferred to the root element.
Cube.vue
render() {
...
},
props: {
dragstartHandler: {
type: Function,
},
}

Polymer one-way-binding not working

After hours of trying I'm clueless. Maybe some of you have the answer. I've create a Polymer template like this:
<dom>
</dom>
<script>
Polymer ({
is: 'foo',
proprties: {
timeRange: {
type: String,
value: 'day',
readOnly: true,
observer: "_refresh",
},
...
},
...
});
</script>
The observer function is just for debugging. The calling host uses this like that:
<dom>
<foo time-range='[[timeRange]]'></foo>
</dom>
<script>
Polymer ({
is: 'host',
proprties: {
timeRange: {
type: String,
value: 'day',
readOnly: true,
notify: true,
observer: "timeRangeChanged",
},
...
},
onDayTap: function() {
this._setTimeRange('day');
},
onMonthTap: function() {
this._setTimeRange('month');
},
onYearTap: function() {
this._setTimeRange('year');
},
...
});
</script>
The 'timeRangeChanged' observer refreshes a chart. But the timeRange-property in foo never gets changed - the _refresh-observer gets called only once on start. What am I doing wrong.
Hope somebody can help me out here
PS. I'm using Polymer 1.0
Hope this will help:
https://jsfiddle.net/fLbp26kp/
Polymer ({
is: 'foo',
properties: {
timeRange: {
type: String,
value: 'day'
observer: "_refresh",
}
}
});
If you're trying to update foo.timeRange you would need to remove readOnly from timeRange in order for it to be set from somewhere else.
Foo without readOnly.

ExtJS 5: Initial ViewModel data not firing formula

I have a ViewModel that contains some initial data... this initial data is based off of a global variable that I have created. In the ViewModel, I have a formula that does some logic based on the data set from the global variable. The interesting thing is, this formula does not fire when the ViewModel is created. I'm assuming this is because the Something.Test property does not exist, so the ViewModel internals have some smarts to not fire the method if that property does not exist.
If the property doesn't exist, how do I fire the formula anyway? I know I could look for Something check to see if it has the property Test, but I'm curious why this example wouldn't work. Here's the example:
Ext.application({
name : 'Fiddle',
launch : function() {
// Define global var Something
Ext.define('Something', {
singleton: true
});
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myView',
data: {
Something: window.Something
},
formulas: {
testSomething: function(getter) {
console.log('here', getter('Something.Test'));
return getter('Something.Test');
},
myTitle: function(getter) {
return 'My Title';
}
}
});
Ext.define('MyView', {
extend: 'Ext.panel.Panel',
bind: {
title: '{myTitle}'
},
viewModel: {
type: 'myView'
}
});
var view = Ext.create('MyView', {
renderTo: Ext.getBody()
});
// This will fire the ViewModel formula
//view.getViewModel().set('Something', window.Something);
console.log(Something, window.Something)
}
});
You can workout some logic to handle when Something.Test is not available, something like:
data: {
Something: window.Something && window.Something.Test || {Test: null}
},
formulas: {
testSomething: function(get) {
var val = get('Something.Test');
console.log('Test');
return val;
},
myTitle: function(getter) {
return 'My Title';
}
}

Knockout Validation on Nested View Model

I am looking to use a combination of the KnockoutJS libarary, the Knockout.Mapping plugin, and the Knockout-Validation plugin to display some data that the user can manipulate.
My data is coming over as a nested object from an AJAX call, and I run that data through the mapping plugin to create a Knockout view model, customizing the validation rules with the mapping options object in ko.mapping.fromJS.
I have been successful in getting objects at the first layer (name in the Fiddle below) to show a message if the field is empty, however objects that are nested (IntroData.PlanName) do not show the validation message. Do I need to setup the mapping object differently for these nested objects?
ViewModel (sample of what is coming in my AJAX call):
var stuff = {
IntroData: {
PlanName: 'Test'
},
name: 'tes2s3t'
};
Mapping:
var validationMapping = {
IntroData: {
PlanName: {
create: function (options) {
return ko.observable(options.data).extend({
required: true
});
}
}
},
name: {
create: function (options) {
return ko.observable(options.data).extend({
required: true
});
}
}
};
Hookup:
ko.validation.init({
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true,
messageTemplate: null,
grouping: {
deep: true
}
}, true);
window.viewModel = ko.validatedObservable(ko.mapping.fromJS(stuff, validationMapping));
ko.applyBindings(window.viewModel);
Fiddle: http://jsfiddle.net/odxv53g9/5/
Thanks!
The documentation is not clear on this, but apparently ko.mapping.fromJS() ignores nested mappings, so the "create" method for PlanName never gets called.
You could add an explicit mapping for IntroData instead:
IntroData: {
create: function (options) {
var nestedMapping = {
PlanName: {
create: function (options) {
return ko.observable(options.data).extend({
required: true
});
}
}
}
return ko.mapping.fromJS(options.data, nestedMapping);
}
}
Here is a working fiddle: http://jsfiddle.net/odxv53g9/6/

Categories

Resources