qooxdoo: Binding more than one proberty to a label - qooxdoo

Is it possible to bind more than one proberty to a label?
I have qx-Object with the proberties "value" and "unit" and I would like to bind both proberties to a label. If I do it like this
this.bind("tag.value", label, "value");
this.bind("tag.unit", label, "value");
than only the unit gets displayed in the label.

Sure, this is possible using a converter in both bindings which reads the other value:
var tag = qx.data.marshal.Json.createModel({value: 12, unit: "px"});
var l = new qx.ui.basic.Label();
this.getRoot().add(l);
tag.bind("value", l, "value", {converter : function(data, source) {
return data + tag.getUnit();
}});
tag.bind("unit", l, "value", {converter : function(data, source) {
return tag.getValue() + data;
}});

Related

Why does my angular directed work on one table cell but none others?

I am using a ContextMenu directive within a kendo grid. I have made one change to it so I can include icons in the text (changed $a.text(text) to $a.html(text).
I have one in the first cell (I highjacked the hierarchical cell) that has row operations (add, clone& delete) and one on a span within each cell that changes the cell values operation (addition, subtraction, equals, etc...)
Both of these were working. I am unsure what I changed that stopped it from working because I last checked it several changes ago (I'm still locked out of TFS so I can't revert).
One change I made was to include a disabled/enabled check to the working contextMenu. I tried adding the same to the broken one and no dice.
I do perform a $compile on the working menu and the broken one is only included in the kendo field template.
If I must compile the field template (and I didn't need to before), how can this be done?
So here is some code.
working menu:
$scope.getRowContextMenu = function (event) {
var options =
[[
"<span class='fa fa-files-o'></span>Clone Rule", function (scope, cmEvent) {/*omitted for brevity*/}),rowContextDisableFunction]]
}
var setHierarchyCell = function (grid) {
var element = grid.element;
var hCells = element.find("td.k-hierarchy-cell");
hCells.empty();
var spanStr = "<span context-menu='getRowContextMenu()' class='fa fa-bars'></span>";
hCells.append($compile(spanStr)($scope));
var span = hCells.find("span.fa");
span.on('click', function (event) {
$(this).trigger('contextmenu', event);
});
}
kendo template:
var mutliFormTemplate = function (fieldName, type) {
var result = "";
result += "<span context-menu='getOperationContextMenuItems()' class='fa #= " + fieldName + "_Obj.OperationSymbol # type-" + type + "'> </span>\n";
/*The rest pertains to the cell value. excluded for brevity*/
return result;
}
$scope.getOperationContextMenuItems = function () {
//I trimmed this all the way down to see if I could get it working. Still no joy
return [
["test", function () { }, true]
];
}
Creating the kendo columns dynamically:
$scope.model = {
id: "RuleId",
fields: {}
};
$scope.fieldsLoaded = function (data, fields) {
var column = {}
$.each(fields, function () {
var field = this;
$scope.columns.push({
field: field.Name,
title: field.Name,
template: mutliFormTemplate(field.Name, "selector")
});
column[field.Name ] = { type: getFieldType(field.Type.BaseTypeId) }
});
$scope.model.fields = column;
}
Thanks for any and all help ^_^

How do I put a checkbox in the title/label of a Dojo TabContainer?

I want to put a checkbox in the label of a Dojo TabContainer. I found an example here:
http://telliott.net/dojoExamples/dojo-checkboxTabExample.html
However, the example only shows html. I would like to do this programmatically. This is what I have so far:
function(response){
var json_response = JSON.parse(response);
var fields_dict = json_response['fields_dict'];
var names_dict = json_response['names_dict'];
var tc = new TabContainer({
style: "height: 495px; width: 100%;",
tabPosition: "left",
tabStrip: true
}, "report_tab_container");
for(var key in fields_dict) {
var content_string = '';
var fields = fields_dict[key];
for(var field in fields) content_string += '<div>' + fields[field][0] + fields[field][1] + '</div>';
var checkBox = new CheckBox({
name: "checkBox",
value: "agreed",
checked: false,
onChange: function(b){ alert('onChange called with parameter = ' + b + ', and widget value = ' + this.get('value') ); }
}).startup();
var tcp = new ContentPane({
//title: names_dict[key],
title: checkBox,
content: content_string
});
tc.addChild(tcp);
}
tc.startup();
tc.resize();
},
However, this doesn't work. When I load my page, the TabContainer doesn't show up. If I set the title of my ContentPane to something other than my check box, it works fine.
What am I doing wrong and how do I get the checkbox to appear in the TabContainer title?
This is what worked:
cb.placeAt('report_tab_container_tablist_dijit_layout_ContentPane_'+ i.toString(), "first");
I'm doing this blindly here, but comparing the example on your link to your code, I would say, add this before tc.addChild(tcp) :
checkBox.placeAt(tcp.domNode, "first");

search field in a dataview in extjs

Am trying to put a search field with respect to a data view. There is a toolbar on top of the data view, which consists of a text field. On entering some text in the field, i want to call a search functionality. As of now, i have got hold of the listener to the text field, but the listener is called immediately after the user starts typing something in the text field.
But, what am trying to do is to start the search functionality only when the user has entered at least 3 characters in the text field.How could i do this?
Code below
View
var DownloadsPanel = {
xtype : 'panel',
border : false,
title : LANG.BTDOWNLOADS,
items : [{
xtype : 'toolbar',
border : true,
baseCls : 'subMenu',
cls : 'effect1',
dock : 'top',
height : 25,
items : [{
xtype : 'textfield',
name : 'SearchDownload',
itemId : 'SearchDownload',
enableKeyEvents : true,
fieldLabel : LANG.DOWNLOADSF3,
allowBlank : true,
minLength : 3
}],
{
xtype : 'dataview',
border : false,
cls : 'catalogue',
autoScroll : true,
emptyText : 'No links to display',
selModel : {
deselectOnContainerClick : false
},
store : DownloadsStore,
overItemCls : 'courseView-over',
itemSelector : 'div.x-item',
tpl : DownloadsTpl,
id : 'cataloguedownloads'
}]
Controller:
init : function() {
this.control({
// reference to the text field in the view
'#SearchDownload' :{
change: this.SearchDownloads
}
});
SearchDownloads : function(){
console.log('Search functionality')
}
UPDATE 1: i was able to get hold of the listener after three characters have been entered using the below code:
Controller
'#SearchDownload' :{
keyup : this.handleonChange,
},
handleonChange : function(textfield, e, eOpts){
if(textfield.getValue().length > 3){
console.log('Three');
}
}
any guidance or examples on how to perform the search in the store of the data view would be appreciated.
A proper way would be to subscribe yourself to the change event of the field and check if the new value has at least 3 chars before proceeding.
'#SearchDownload' :{ change: this.handleonChange }
// othoer code
handleonChange : function(textfield, newValue, oldValue, eOpts ){
if(newValue.length >= 3){
console.log('Three');
}
}
Btw. I recommend you to use lowercase and '-' separated names for id's. In your case
itemId : 'search-download'
Edit apply the filter
To apply the filter I would use filter I guess you now the field you want to filter on? Lets pretend store is a variable within your controller than you may replace the console.log() with
this.store.filter('YourFieldName', newValue);
Second param can also be a regex using the value like in the example
this.store.filter('YourFieldName', new RegExp("/\"+newValue+"$/") );
For sure you can also use a Function
this.store.filter({filterFn: function(rec) { return rec.get("YourFieldName") > 10; }});
Thanks you so much sra for your answers. Here is what i did, based on your comments
filterDownloads : function(val, filterWh){
if(filterWh == 1){
var store = Ext.getStore('CatalogueDownloads');
store.clearFilter();
store.filterBy(function (r){
var retval = false;
var rv = r.get('title');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
if(!retval){
var rv = r.get('shortD');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
}
if(retval){
return true;
}
return retval;
})
}
}
i think there is an example of exactly what you are trying to achive .. http://docs.sencha.com/ext-js/4-0/#!/example/form/forum-search.html

Itemclick and itemmove in EXTJS MVC

Am having a tree panel in my view, and its corresponding controllers. What is happening is that am having two controllers, one for the itemdblclick and another for itemmove. The itemdblclick is working ok, but when i add the controller for itemmove, itemmove is working, but on the other hand, itemdbclick is not working. And if i remove the itemmove controller, itemdblclick is working. Hope am not confusing:) In simple words, the two controllers are working separately but not together.
Could anyone please tell me what am i doing wrong here.
Also, in the function editRegion in the controller, am trying to reload the tree by using the getStore.load() method, but the tree is not loading even though am able to see the store being invoked in the firebug
EDIT:
Am opening a form on double-clicking the tree node, and on closing the form, i want the tree panel to be reloaded. This is what i want to happen in editregion function
View
{
xtype : 'treepanel',
title : '',
id : 'hierarchyTree',
border : false,
alias : 'widget.hierarchyTree',
height : 1000,
viewConfig : {
enableDD : true,
plugins : {
ptype : 'treeviewdragdrop'
}
},
collapsible : false,
useArrows : true,
rootVisible : false,
store : Ext.create('App.store.HierarchyTree'),
displayField : 'Title',
multiSelect : false,
singleExpand : false,
}
Controller
refs : [{
ref : 'myHierarchyTree',
selector : '#hierarchyTree'
}
init : function() {
this.getHierarchyTreeStore().load();
'#hierarchyTree' : {
itemdblclick : this.itemdblclick
},
'#hierarchyTree' : {
itemmove : this.itemmove
}
itemdblclick : function(view, record, level) {
if (record.get('LevelID') == 1) {
this.erWin = Ext.create('App.view.EditRegions');
var f = this.getEditregionform().getForm();
f.loadRecord(record);
this.erWin.showWin();
}
else if (record.get('LevelID') == 2) {
this.eaWin = Ext.create('App.view.EditAreas');
var f = this.getEditareaform().getForm();
f.loadRecord(record);
this.eaWin.showWin();
}
itemmove : function(v, oldParent, newParent, index, eOpts) {
var nodeID = v.data.id;
var oldParent = oldParent.data.id;
var newParent = newParent.data.id;
var index = index;
var level = v.data.LevelID;
Ext.Ajax.request({
url : 'data/Locations.aspx',
params : {
mode : 'MOVENODE',
currentNode : nodeID,
oldParentNode : oldParent,
newParentNode : newParent
},
success : function() {
alert(LANG.SUC);
Ext.getStore('HierarchyTree').load();
},
failure : function() {
}
});
editRegion : function(button, record) {
var fp = button.up('form');
if (fp.getForm().isValid()) {
fp.getForm().submit({
url : 'data/Locations.aspx',
params : {
mode : 'EDITREGION',
userID : ME.UserID,
RegionID : ME.RegionID
},
success : function(response) {
alert(LANG.SUC);
this.getHierarchyTreeStore().load();
},
failure : function(response) {
alert('Try again');
}
});
}
}
adding them separately will cause the first listener object to be overridden.
Fix:
'#hierarchyTree' : {
itemdblclick : this.itemdblclick,
itemmove : this.itemmove
},
You should check if the store is the same. Meaning check the id because i think the contoller initializes one store and the panel another. so check if this.getHierarchyTreeStore().id is equal with the one from treepanel. you can navigate to it from the button something like button.up().down('treepanel').getStore().id. If they are different then you should use the second method to get the store.
tried doing the following code, as using up and down will not refer to the correct view, since the tree and the forms are completely different views
var view = Ext.widget('hierarchy');
view.down('treepanel').getStore.load();
Now, even though the store is re-loading, am geting an error
TypeError: view.down("treepanel") is null
view.down('treepanel').getStore.load();

ExtJS 4 > Row Editor Grid > How to Change "Update" Button Text

Is there any way to change the text of "Update" button in ExtJS-4 Row Editor Grid ?
Good question, I had a look through the source code and whilst there is nothing inside the RowEditing plugin, in the class it extends 'RowEditor.js' there is the following:
Ext.define('Ext.grid.RowEditor', {
extend: 'Ext.form.Panel',
requires: [
'Ext.tip.ToolTip',
'Ext.util.HashMap',
'Ext.util.KeyNav'
],
saveBtnText : 'Update',
cancelBtnText: 'Cancel',
...
});
So I'd assume you'd just need to override the 'saveBtnText' in your instance of 'Ext.grid.plugin.RowEditing' as it calls the parent constructor with callParent(arguments) in the RowEditing class
Not that easy and not without hacking in undocumented areas. The problem is, that the Ext.grid.plugin.RowEditing directly instantiates the Ext.grid.RowEditor without allowing you to pass in configuration options. So in general you have to override the initEditor() method in the plugin and instantiate your own row editor:
// ...
plugins: [{
ptype: 'rowediting',
clicksToEdit: 2,
initEditor: function() {
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt;
return Ext.create('Ext.grid.RowEditor', {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
// keep a reference..
editingPlugin: me,
renderTo: view.el,
saveBtnText: 'This is my save button text', // <<---
cancelBtnText: 'This is my cancel button text' // <<---
});
},
}],
// ...
For ExtJS 4
Ext.grid.RowEditor.prototype.cancelBtnText = "This is cancel";
Ext.grid.RowEditor.prototype.saveBtnText = "This is update";
This solution is to define the prototype of rowEditors. that means that this config is than general.
If you want to change it just for one editor, or if you want to get different configs , the prototype is definitely not the solution.
look at source code :
initEditorConfig: function(){
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt,
btns = ['saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText'],
b,
bLen = btns.length,
cfg = {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
view: view,
// keep a reference..
editingPlugin: me
},
item;
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
return cfg;
}`
this method inits the rowEditor, and there's a loop on btns Array:
btns Array :
btns = ['saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText']
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
In this loop foreach string in btnArray it's searched if exists in cfg the same string property, if it's found it's added to config. You just have to manage that this loop finds what you want to modify:
Example: we want to change the text of save button:
the property saveBtnText which is the first item of btns Array must exists in cfg:
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
this search if property exists : if (Ext.isDefined(me[item]))
if saveBtnText already exists in rowEditor properties then:
cfg[item] = me[item];
and the additional config property will be set!!

Resources