Set attribute from Polymer object property value - polymer

I have element and I put in it object with data for it.
<my-element data="{{item.content}}"></my-element>
For now I have not done this so I have all in data property declaration.
properties: {
data: {
type: Object,
value: {
active: false,
name: "Some name."
...
}
}
}
I also have to click handler on child element which should toggle the boolean value.
_handleClickBlock: function () {
this.data.active = !this.data.active;
}
I need to set [active] attribute on my-element to data.active value and make changes every time, because I use it in my CSS styles like :host[active] ....
How can I achieve it? I tried this.setAttribute('active', this.data.active) in event handler, but it change the value only once; console log was toggling.
Edit:
I have tried use this code:
observers: [
'_activeChange(data.active)'
],
_activeChange: function(newValue) {
this.active = newValue;
console.log("change");
},
_handleClickBlock: function () {
console.log("------ click");
this.data.active = !this.data.active;
console.log(this.data.active);
}
But in my console output is only this, so observer is not called.
------ click
false
------ click
true

Try including 'active' as a property in you my-element and set reflectToAttribute to true.
properties: {
data:{...}
active: {
type: Boolean,
reflectToAttribute: true
}
}
observers: [
'_activeChange(data.active)'
],
_activeChange: function(newValue) {
this.active = newValue;
}
Edit: Please go through how to change the path such that observers are notified. You need to update data.active as below
this.set('data.active', !this.data.active);
Below jsbin:
http://jsbin.com/qupoja/4/edit?html,output

Related

How to set an observer on an array property in polymer element?

The history property defined in my sma-canvas element:
static get properties() {
return {
history: {
type: Array,
value: () => {
return [];
},
notify: true
}
};
}
static get observers() {
return [
'_historyChanged(history.*)'
];
}
_historyChanged() {
console.log("History Changed!");
this._redrawCanvas(this.$.canvasEl, this.history);
}
I'm trying to set the history property from another element:
<dom-module id="sma-create-studio">
<template>
<sma-canvas id="shapesCanvasEdit" history={{shapesOnCanvasEdit}}></sma-canvas>
</template>
<dom-module>
...
static get properties() {
return {
shapesOnCanvasEdit: {
type: Array,
value: () => {
return [];
},
notify: true
}
};
}
_selectFrame(e) {
// this.shapesOnCanvasEdit = e.detail.frame.shapes;
// this.shapesOnCanvasEdit.splice(0, this.shapesOnCanvasEdit.length);
// this.shapesOnCanvasEdit.push(e.detail.frame.shapes);
this.set('shapesOnCanvasEdit', e.detail.frame.shapes);
// this.splice('shapesOnCanvasEdit', 0, this.shapesOnCanvasEdit.length, e.detail.frame.shapes);
// this.splice('shapesOnCanvasEdit', 0, this.shapesOnCanvasEdit.length);
// this.push('shapesOnCanvasEdit', e.detail.frame.shapes);
// this.notifyPath('shapesOnCanvasEdit');
// this.notifySpice('shapesOnCanvasEdit');
}
I need to call _historyChanged (the observer in sma-canvas), whenever I change the value of shapesOnCanvasEdit. As you can see from the last code snippet, I tried multiple ways to do that, but all in-vain.
Can anybody please help me in this regard? I have no clue, what I'm doing wrong.
SOLUTION 1
static get properties() {
return {
active: {
type: Boolean,
// Observer method identified by name
observer: '_activeChanged'
}
}
}
// Observer method defined as a class method
_activeChanged(newValue, oldValue) {
this.toggleClass('highlight', newValue);
}
https://www.polymer-project.org/2.0/docs/devguide/observers#change-callbacks
From my experience in 1.93, adding a simple observer for an array updates the array if the length changes. (Change Boolean to Array in the example above.)
SOLUTION 2
You can observe splices:
static get observers() {
return [
'usersAddedOrRemoved(myArray.splices)'
]
https://www.polymer-project.org/2.0/docs/devguide/observers#array-observation
}
It only fires if the array length changes. To force update, reset it array myArray with this.set('myArray', []), if you're desperate.
SOLUTION 3
The truly desperate solution. Add a secondary int variable that you update every time there is a change in the array. So _selectFrame() should first update your array history and then update the integer, and both should be properties in sma-canvas. Set an observer on that integer variable in your sma-canvas element, as shown in solution 1.

How to pass boolean attributes into Vue render function data object?

The data object for Vue render functions takes HTML attributes and their arguments:
{
// Same API as `v-bind:class`
'class': {
foo: true,
bar: false
},
// Same API as `v-bind:style`
style: {
color: 'red',
fontSize: '14px'
},
...
How do you render an element that takes attributes that don't take arguments (there's probably a proper expression for this but I don't know it). An example would be:
<f7-list accordion>
<f7-list-item>
...
My attempt isn't working:
render: function (createElement){
return createElement('f7-list', {{'attrs': { 'accordion': true }},
this.tree.map(function(item){return createElement('f7-list-item', item.name)}))
How does one include these attributes?
Can you pass it as a prop and then use it? You can try like this I think. (Untested)
render(createElement) {
return createElement('f7-list', {
props: {
'attrs': {'accordion':true}
}
})
}
Or perhaps simply
render(createElement) {
return createElement('f7-list', {
attrs: {
'accordion': true
}
})
}

Polymer update object outside of component and reflect changes to UI

Is it possible to reflect changes to polymer component property without update the value via .set(path, value).
For example I have object with overrided setter which based on this value apply new value to other field.
Polymer({
is: 'x-element',
properties: {
form: {type: Object,
value: {
set name(v) {
this._name = v;
this.additional = v; // change the different property
},
get name() {
return this.name;
},
set additional(v) {
// process v
this._additional = v; // field does not reflect
},
get additional() {
return this._additional;
}
},
reflectToAttribute: true
}
})

ExtJS 4 MVC, Get Checkbox value integer instead of bool

I'm using a form to edit Model. I receive data in JSON. Here's my problem:
I receive data for Checkbox only in INT: 1 or 0, I cannot change it. JSON:
{ "checkboxValue": 1 }
This field in ExtJS model is defined as INT type. Model:
{name: "checkboxValue", type: Ext.data.Types.INT},
then I set values to form this way:
formCmp.loadRecord(loadedStore.getAt(0));
and my checkbox is set correctly: when I receive 1 it's checked, 0 - unchecked.
But when I try to save record and send data to server this way:
form.updateRecord(form.getRecord());
record.save();
I need Checkbox to have also INT value - 1 or 0. But it has only BOOL value - true or false so when JSON is sent that value is NaN.
{
"checkboxValue": NaN
}
I think, that function .updateRecord(..) go through all elements and when it gets to checkbox it tries to get value, and the value is BOOL
Does anybody know how to make checkbox' output value INT?
Ext.form.Basic.updateForm uses getFieldValues method to retrieve new data for the updated record, while getFieldValues method returns only boolean values for checkboxes regardless of such properties as inputValue or uncheckedValue. So I would use convert function for the model's field to transform provided boolean value into an integer in a way like that:
Ext.define('MyModel', {
extend: 'Ext.data.Model',
fields: [
{
name: 'flag',
type: 'int',
convert: function (v, record) {
return typeof v === 'boolean' ? (v === true ? 1 : 0) : v;
}
}
],
...
});
Here is a complete jsfiddle
I think it can be done with some simple overrides
Ext.create('Ext.form.Panel', {
bodyPadding: 10,
width: 300,
title: 'Pizza Order',
items: [
{
xtype: 'fieldcontainer',
fieldLabel: 'Toppings',
defaultType: 'checkboxfield',
items: [
{
boxLabel : 'Topping?',
name : 'topping',
id : 'checkbox1',
// include these two properties in your checkbox config
uncheckedValue: 0,
setValue: function(checked) {
var me = this;
arguments[0] = checked ? 1 : me.uncheckedValue;
me.callParent(arguments);
return me;
}
}
]
}
],
renderTo: Ext.getBody()
});

How to add a tooltip based on a DropDown list

Basically I have a Kendo Grid where a couple of my columns also have Kendo DropDowns.
I would like to attach a ToolTip based on the value the user chooses from the "Instrument" dropdown.
Here's my grid javascript code (using MVVM pattern):
tradesGrid = $("#tradesGrid").kendoGrid({
dataSource: datasource,
toolbar: [
{ name: "create", text: "Add Trade" }
],
columns: [{
field: "TradeId"
},
{
field: "Instrument",
editor: instrumentsDropDownEditor, template: "#=Instrument#"
},
{ command: ["edit", "destroy"] },
],
sortable: true,
editable: "popup",
});
and here's the Editor function for the Instrument dropdown :
function instrumentsDropDownEditor(container, options) {
var instrItems = [{
"optionInstr": "OPTION 22/11/2013 C70 Equity"
}, {
"optionInstr": "OPTION 26/11/2013 C55 Equity"
},
{
"optionInstr": "OPTION 30/11/2013 C80 Equity"
}
];
var input = $('<input id="Instrument" name="Instrument">');
input.appendTo(container);
input.kendoDropDownList({
dataTextField: "optionInstr",
dataValueField: "optionInstr",
dataSource: instrItems, // bind it to the brands array
optionLabel: "Choose an instrument"
}).appendTo(container);
}
and on my Html view file I'm starting with this idea :
<span class="key-button"
title="Instrument Details!!!"
data-role="tooltip"
data-auto-hide="true"
data-position="right"
data-bind="events: { show: onShow, hide: onHide }"
</span>
I don't have time to rig up a jsFiddle right now, but I'm pretty sure this would work...
Init your tooltip in javascript, and specify content that is a function:
var myTooltip = "";
var tooltipWidget = $("#whatever").kendoTooltip({
filter: "a",
content: function (item) { return myTooltip; },
...
}).data("kendoTooltip");
Then on your dropdown widget, specify a change function handler that sets myTooltip to whatever contents you want.
var onSelect = function (e) {
myTooltip = ...;
tooltipWidget.refresh();
};
$("#dropdownlist").kendoDropDownList({
select: onSelect,
...
});
Or you can change the title property on your HTML element, if that is easier. However, the tooltip widget won't refresh its contents after it has been displayed, which is why you need to manually call tooltipWidget.refresh() after you change the contents.