I have a vaadin-checkbox:
<vaadin-checkbox id=[[item.id]] disabled="true" checked="[[item.checked]]">[[item.description]]</vaadin-checkbox>
I defined my properties:
static get properties() {
return {
items: {
type: Array,
notify: true,
value: function() {
return [];
}
}
};
}
When I now change the data by pressing some button:
_selectItem(event) {
const item = event.model.item;
if (item.checked === true) {
this.$.grid.deselectItem(item);
} else {
this.$.grid.selectItem(item);
}
item.checked = !item.checked;
}
The state of the checkbox is still checked="true". Why isnt the checkbox getting updated? The same thing when I change the description of the item:
_selectItem(event) {
event.model.item.description = 'test';
}
The test description is never appearing. The checkbox is never getting updated.
The reason why the checkbox does not get updated by the button click handler is in the Polymer 2 data system. Polymer does not detect the change and does not update the template accordingly.
In order to make the change in a way that Polymer would detect it you have two options:
Use this.set(`items.${event.model.index}.checked`, !item.checked) if you can reliably assume that the index used by dom-repeat always matches that elements's index in the items array (it is not the case if you use sorting or filtering features of dom-repeat). See an example here https://jsfiddle.net/vlukashov/epd0dn2j/
If you do not know the index of the updated item in the items array, you can also use the Polymer.MutableData mixin and notify Polymer that something has changed inside the items array without specifying the index of the changed item. This is done by calling this.notifyPath('items') after making a change. However, this requires that your element extends the Polymer.MutableData mixin, and that dom-repeat has the mutable-data attribute set. See an example here: https://jsfiddle.net/vlukashov/epd0dn2j/24/
More information on this in the Polymer 2 docs.
I have a QAbstractListModel called SerialPortList which represents a list of SerialPorts. Each SerialPort has a QList<int> supportedBaudRates property. The SerialPortList model's display role is simply QVariant::fromValue(mSerialPorts[i]), i.e. a SerialPort instance.
I display my list model in a Repeater like this (highly simplified):
SerialPortList {
id: ports
}
Column {
Repeater {
id: portList
// ...
model: ports
Text { text: model.display.portName }
ComboBox {
model: model.display.supportedBaudRates
// ...
}
}
}
That is, a list of the serial ports name, and then a combo box with its supported baud rates.
The weird thing is, although the text is displayed fine, apparently for the combo box model.display is undefined. If I replace the combo box with this:
Text {
text: model.display.supportedBaudRates.join(" ")
}
then it produces the result you'd expect!
What is going on here? I can only assume that model is redefined inside the ComboBox so it thinks it is referring to itself, but I've tried all kinds of id references like portList.model.display.supportedBaudRates that I can think of and none of them work.
Edit
Kakadu pointed out that you can't use a QList<int> as a model. Kind of annoying, but I've changed it to QStringList which you apparently can use. Sadly the error remains the same.
Edit 2
I changed the model: in the ComboBox to model: { console.log("model: " + model); } and it prints 1, which makes me sure that model refers to itself.
Oh I finally got it to work! It's simply a namespace problem - model is something of a magic variable so you can't use id qualifiers on it.
Fortunately model. is implicitly prepended to any variable accesses in the delegate, so I changed my code to this and it worked:
ComboBox {
model: display.supportedBaudRatesAsStrings
// ...
}
(The ...AsStrings property is a QStringList duplicate of the original QList<int> property.)
I have a spider plot in using the graphing library of Dojo defined like this:
require([
"dojox/charting/Chart",
"dojox/charting/themes/Claro",
"dojox/charting/plot2d/Spider",
"dojox/charting/action2d/Tooltip",
"dojox/charting/widget/SelectableLegend",
"dojox/charting/axis2d/Default"
], function (Chart, theme, Spider, Tooltip, Legend, Default) {
var chart = new Chart(element).setTheme(theme).addPlot("default", {
type: Spider,
radius: 200,
fontColor: "black",
labelOffset: "-20"
});
var colors = ["blue", "red", "green", "yellow", "purple", "orange", "teal",
"maroon", "olive", "lime", "aqua", "fuchsia"];
$.each(factors, function (index, factor) {
chart.addAxis(factor.name, {
type: Default,
min: factor.min,
max: factor.max
});
});
$.each(presets, function (pIndex, preset) {
var data = [];
$.each(factors, function (fIndex, factor) {
data[factor.name] = preset.values[fIndex];
});
chart.addSeries(preset.short, data, {
fill: colors[pIndex % colors.length]
});
});
new Tooltip(chart, "default");
chart.render();
new Legend({
chart: chart,
horizontal: false
}, $(element).next(".legend")[0]);
});
I add a series for every member of an array called presets and I use a selectable legend that lets the user turn them on or off as they want. However, what I can't seem to find in the docs is how to start a series in the unselected, not visible state? What I ideally want to do is cap the number of series visible when the page loads because in some cases I have up to 14 presets and it just looks a mess until the user deselects a bunch. So I'd like to have, say, every preset above the first 5 be hidden at the start.
Here's a crude fiddle I've knocked to demonstrate. What I want is to have some of the series unselected when the plot is first displayed.
Update: I tried adding this after adding my series:
var checkboxes = $(".dijitCheckBoxInput").each((index, elem) => {
if (index > 4) {
elem.click();
}
});
Which works, but seems very fragile. If they change the class assigned to checkboxes, it'll break. Also, it prohibits me using more than one set of dojo checkboxes because I don't have a good way to tell the difference. (Note, the IDs of the checkboxes added by the SelectableLegend are dijit_form_CheckBox_0, dijit_form_CheckBox_1, etc, which also gives no useful information as to what they are related to). I thought I might be able to use the legend placeholder div as a way to select the descendant checkboxes, but it appears that Dojo replaces the placeholder entirely with a table.
i looked into the dojo code and found the area in which the shapes are toggled on & off whitin the SelectableLegend.js :
var legendCheckBox = query(".dijitCheckBox", legend)[0];
hub.connect(legendCheckBox, "onclick", this, function(e){
this._toggle(shapes, i, legend.vanished, originalDyn, seriesName, plotName);
legend.vanished = !legend.vanished;
e.stopPropagation();
});
The toggling process is very complex and is based on many local attributes:
_toggle: function(shapes, index, isOff, dyn, seriesName, plotName){
arrayUtil.forEach(shapes, function(shape, i){
var startFill = dyn.fills[i],
endFill = this._getTransitionFill(plotName),
startStroke = dyn.strokes[i],
endStroke = this.transitionStroke;
if(startFill){
if(endFill && (typeof startFill == "string" || startFill instanceof Color)){
fx.animateFill({
shape: shape,
color: {
start: isOff ? endFill : startFill,
end: isOff ? startFill : endFill
}
}).play();
}else{
shape.setFill(isOff ? startFill : endFill);
}
}
if(startStroke && !this.outline){
shape.setStroke(isOff ? startStroke : endStroke);
}
}, this);
}
I tried also checking & unchecking the dijit/form/Checkbox in a legend manually, but that does not trigger the _toggle function in any case, even if you do a render() / fullrender() on the chart.
With that in mind it seems that there is no other possibilty to toggle the series on and off than by firing the onclick events manually.
To make your code less fragile, you could access the Checkbox widgets within the legend manually using:
query(".dijitCheckBox", legend); // Should deliver an array containing
the widgets.
and triggering the onclick event on them. Their keynumber in the array should correspond to the order the series where added...
Dojo is a fine piece of work, please dont stop working with it !
dojox/charting/Series has an attribute called dirty which according to the API docs is a "flag indicating whether or not this element needs to be rendered".
Alternately, if you are limiting the display of some series you can write a separate interface for adding them. For example, loop over the first 5. Then create a select box or list of check boxes with all entries and an onchange event that calls chart.addSeries.
Keeping a reference to each series you create will allow you to later call destroy() or destroyRecursive() on it if the user no longer wishes it displayed.
So while ideally you could toggle the display of these series, the worst case senerio is that you just add, destroy, and read based on some user input.
Using a templated widget will allow you to keep this interface and the chart tightly linked and support reuse.
BTW, consider using "dojo/_base/array" and "dojo/query" in place of the jquery
I think i've got it !
I found another way to access the checkboxes ! It's the same way dojo uses internally to connect the "toggle code" to the onclick event. First take a look at this from SelectableLegend.js (Lines 150 - 156):
// toggle action
var legendCheckBox = query(".dijitCheckBox", legend)[0];
hub.connect(legendCheckBox, "onclick", this, function(e){
this._toggle(shapes, i, legend.vanished, originalDyn, seriesName, plotName);
legend.vanished = !legend.vanished;
e.stopPropagation();
});
It looks like they use the ".dijitCheckBox" class to find the checkbox dom element and connect to it using dojo/connect. Now based on that, i made this function:
function toggleSeries (legend,num) {
dojo.query("*",legend.legends[num])[0].click();
dijit.findWidgets(legend.legends[num])[0]._onClick(); }
It doesn't use any class definition (because of the *) and it accesses the areas where the checkboxes are from within the SelectableLegend. It needs the SelectableLegend and the number of the series you want to deactivate as parameters. Here the jsfiddle example with this function & hiding all 4 of your series with it:
http://jsfiddle.net/luciancd/92Dzv/17/
Also please notice the "onDomReady" Option in jsfiddle, without it: doesnt work in IE.
And the ready function within the code !
Lucian
I have updated your code http://jsfiddle.net/92Dzv/18/
Here is the key to toogle.
dom.byId(le._cbs[0].id).click();
dom.byId(le._cbs[2].id).click();
Choose the index of your legend and set to _cbs.
By this way le._cbs[0].id you will get the real id of checkbox (that inside in the widget) and then just use click()
Note : le is came from here.
var le = new Legend({
chart: chart,
horizontal: false
}, legend);
I have an ExtJS 4 grid with GroupingSummary Feature. ExtJs Default is grid is expanded when user clicks on any cell in grouping row. I want to disable this feature, no expansion should take place except when user clicks on designated 'expand' icon. How do I accomplish this?
There is the 'groupclick' event, is there a way to override its default behaviour and do nothing / remove it?
Thanks in advance
The method for it appears to be inherited from Grouping rather than GroupingSummary, so I suspect you need to override this method to prevent the current behaviour:
onGroupClick: function(view, group, idx, foo, e) {
var me = this,
toggleCls = me.toggleCls,
groupBd = Ext.fly(group.nextSibling, '_grouping');
if (groupBd.hasCls(me.collapsedCls)) {
me.expand(groupBd);
} else {
me.collapse(groupBd);
}
So you will need another file with something similar to the following:
Ext.require('Ext.grid.Grouping');
Ext.define('your.class.here', {
override: 'Ext.grid.Grouping',
onGroupClick: function() {
//do nothing
});
)};
Then you should be able to write a function that mimicks it was doing on groupclick, but instead on your icon click. Hope that helps.
I'm writing my first Qt Quick application and I'm having lots of trouble doing things that are simple in other environments. I want to display n random images from a folder. For this purpose I'm using FolderListModel, but the trouble is that I don't see any methods to access list of files directly. So here's my hackish approach:
Use FolderListModel to read files
Use Text component as delegate
onTextChanged of Text component gets the filename (this part works) and adds it to some ListModel
randomize the ListModel and then use it to display files
I have many problems and questions, but first of all, what is the sane way to do this (please make it so that the list part doesn't have to be written in c++)?
There are 2 problems for now - I can't figure out how to access the ListModel from Text component; and I can' t figure out how to make the ListModel public/accessible from another component that will display the images.
Below is the code:
import QtQuick 1.0
import Qt.labs.folderlistmodel 1.0
ListView {
width: 200; height: 300
FolderListModel {
folder: "file:///C:/somefolder"
id: folderModel
nameFilters: ["*.jpg"]
}
Component {
id: fileDelegate
Text { id: intext
text: fileName
//the next line fails, Can't find variable: anotherModel
onTextChanged: anotherModel.append([{name: intext.text}]
)
}
}
model: folderModel
delegate: fileDelegate
ListModel {
id: anotherModel
}
}
Your code almost works for me. I get the error "QML ListModel: append: value is not an object". This is because you append arrays.
If you remove the brackets in line
anotherModel.append([{name: intext.text}])
it works. To make anotherModel a public property write it as
property ListModel anotherModel: ListModel {}