ViewModel bind record phantom - extjs

I want to hide a checkbox depending on wheter a record is phantom. Trying to implement this using viewmodels, but it doesn't seem to work.
See below for the related code. I've left out unrelated code for brevity.
The binding of the viewModel to the view is working as expected. When I try to bind activeRecord.name to the title attribute 2-way data binding is working correctly.
Viewmodel
Ext.define('MyApp.view.content.ContentViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.content',
data: {
activeRecord: null
}
});
Controller
var contentWindow = Ext.widget('content-details');
contentWindow.getViewModel().set('activeRecord', contentBlock);
View
viewmodel: 'content',
items: [
{
xtype: 'checkbox',
boxLabel: 'My checkbox',
bind: {
hidden: '{!activeRecord.phantom}'
}
}
]

We ended up using the following base class for a Model, which is more convenient rather than a formula in a ViewModel.
// Use your own name instead of BaseModel
Ext.define('BaseModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'phantom',
persist: false,
convert: function (v, rec) {
var id = rec.data[rec.idProperty];
return !id || (Ext.isString(id) && id.indexOf(rec.entityName) == 0);
}
}],
commit: function (silent, modifiedFieldNames) {
this.data.phantom = false;
this.callParent(arguments);
}
});
Then you'll be able to use the binding you want
bind: {
hidden: '{!activeRecord.phantom}'
}

Try to use formulas:
data: {
rec: null,
callback: null
},
formulas: {
isNew: function (get) {
return !get('rec') || get('rec').phantom;
}
}
Then in your view:
bind: {
disabled: '{!isNew}'
},

Related

Best way to use checkboxes inside a Extjs Pivot Grid

I have a pivot grid which display if the users have create,read,update,delete" permissions, the users are agrouped in this way departaments > estabilishments > sectors > users and i want the user to be able to edit this fields.
I already tried using with a renderer:
aggregate: [{
renderer: function(value, record, dataIndex, cell, column) {
var id = Ext.id();
Ext.defer(function() {
Ext.widget('checkbox', {
renderTo: id,
checked: value,
listeners: {
change: {
fn: function(event, target) {
//some function here
}
}
}
});
}, 100);
return Ext.String.format('<div id="{0}"></div>', id);
},
aggregator: 'aggCheckBoxR',
dataIndex: 'Incluir',
header: 'Incluir'
}]
and with a widget column:
aggregate: [{
aggregator: 'aggCheckBoxR',
column: {
xtype: 'widgetcolumn',
widget: {
xtype: 'checkbox',
listeners: {
change: function(cb) {
//some function here
}
}
}
},
dataIndex: 'Incluir',
header: 'Incluir'
}]
My Aggregator:
aggCheckBoxR: function(records, measure, matrix, rowGroupKey, colGroupKey) {
if (records.length > 1) {
let checkAllTrue = true;
for (var i = 0; i < records.length; i++) {
if (records[i].get('Incluir') === false || records[i].get('Incluir') === 0) {
checkAllTrue = false;
}
}
return checkAllTrue;
} else {
return records[0].get('Incluir');
}
}
The checkbox apears on the grid but my problem is the data "dont persist", whenever i expand or collapse a left axis on the pivot grid the value of the checkbox returns to its original value, how can i persist this data?
Already tried update the record manualy
change: function(cb) {
var nomeCmp = cb.getWidgetRecord().data._compactview_;
Ext.getStore('acesso.ColabStore').findRecord('Nome', nomeCmp).data.Incluir = true;
}
But still, it doestn't work.
EDIT: Had to change the column object event listener to:
{
xtype: 'widgetcolumn',
widget: {
xtype: 'checkbox',
listeners: {
afterrender: function(component, eOpts) {
console.log('after,render');
component.getEl().on('change', function(e, el) {
console.log('change func here');
})
}
}
}
}
With this, the change event is only fired when the users check a checkbox, and finally, I could use
norbeq's answer
You can update the record manually using:
record.set('Incluir',true);
and if you dont wan't to send changes to server:
record.commit();

ExtJS 6 - Bind disabled property to new records in a store

I'm trying to enable/disable a button when the store getNewRecords() function return the length, but not work!
bind: {
disabled: "{!grid.getStore().getNewRecords().length}"
}
Fiddle: https://fiddle.sencha.com/fiddle/1sj5
Someone have idea to how resolve this?
You need to create a formula in your viewmodel:
viewModel: {
formulas: {
hasNewRecords: function (r) {
return this.getView().down("treepanel").getStore().getNewRecords().length > 0;
}
}
}
then you can use it for your bindings:
bind: {
disabled: "{hasNewRecords}"
}
(probably not the best way to get the data you want).
You can read about it here, here and here .
What you're wanting to do here is currently not possible in the framework. Instead, you should create a ViewModel data value and modify that where need be, like this:
var form = Ext.create("Ext.form.Panel", {
viewModel: {
data: {
newRecords: false
}
},
items: [{
xtype: "textfield",
labelField: "Add Child",
name: "col1",
value: "Teste 123"
}],
tbar: {
xtype: "button",
text: "Add new record",
handler: function () {
var data = this.up("form").getForm().getFieldValues();
var rec = grid.getStore().getAt(0);
data["treeCol"] = rec.childNodes.length + 1;
// setting value, so binding updates
this.lookupViewModel().set('newRecords', true);
rec.appendChild(data);
}
},
bbar: {
xtype: "button",
text: "button to disabled when new records",
bind: {
disabled: "{newRecords}"
}
},
renderTo: Ext.getBody()
});
Or by simply doing this.
In your controller:
me.getView().getViewModel().set('storeLen', store.getNewRecords().length);
In your ViewModel, simply do this:
formulas : {
hasNewRecords : {
get : function(get){
var length = get('storeLen') // --> gets the one you set at your controller
return length > 0 ? true : false;
}
}
}
In your View:
bind : {
disabled : '{hasNewRecords}'
}

ExtJS Store.filterBy Fails where Store.filter Works

Ive checked the docs and cant seem to wrap my head around why the store.filter() works until I add a function to it and also the filterBy() fails.
I need the filter to check for 2 things from the record(s).
I need to check:
if(deviceMsgId == 1 || messageType == 'TEXT_MESSAGE')
Store:
var msgStore = Ext.create('p7_ui_static.store.DeviceMessageStore', {
id: 'messageLogStore',
storeId: storeId,
remoteFilter: false,
autoLoad:false,
...
...
});
Model:
Ext.define('p7_ui_static.model.DeviceMessage', {
extend: 'Ext.data.Model',
...
...
fields: [
{
name: 'deviceMessageTypeId'
},
{
name: 'messageType'
},
{
...
}
]
});
THIS FILTER WORKS ->
filter( filters, [value] )
msgStore.clearFilter(true);
msgStore.filter([
{ property: 'deviceMsgId', value : 1 }
]);
BUT THIS FILTER FAILS ->
filterBy( fn, [scope] )
msgStore.filterBy(function(record){
return record.get('deviceMsgId' == 1)
});
Here's an example of using filterBy.
msgStore.filterBy(function (record){
if ((record.get('deviceMsgId'))===1 ||
record.get('messageType')==='TEXT_MESSAGE'){
return true;
}
});
Also, as a bonus, you can easily filter a store by a property by the following code:
msgStore.filter('deviceMsgId',1);
Edit: After reviewing the documentation again, it looks like you are correct in returning true. If the function isn't being called, are there any errors being thrown in the console?

ExtJS: Custom ComboBox

I'm just trying to create a custom ComboBox to reduce some boilerplate:
Ext.define('App.AutoComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.autocombobox',
states: null,
initComponent: function() {
this.callParent(arguments);
if (!this.states) {
this.queryMode = 'remote';
} else {
this.queryMode = 'local';
this.bindStore(Ext.create('Ext.data.Store', {
type: 'array',
fields: ['_placeholder_'],
data: _.map(this.states, function(state) {
return {_placeholder_ : state}; })
}));
this.displayField = this.valueField = '_placeholder_'
}
this.validator = function(v) {
var field = this.displayField,
index = this.getStore().findExact(field, v);
return (index!==-1) ? true : 'Invalid selection';
};
},
listeners: {
select: function(combo, records) {
console.log(combo.getStore().indexOf(records[0])); // !== -1
}
}
});
So that I can use it like:
requires: ['App.AutoComboBox'],
...
items: [{
xtype: 'autocombobox',
name: 'test_local',
fieldLabel: 'test_local',
states: [ 'cat', 'dog' ] // local
}, {
xtype: 'autocombobox',
name: 'test_remote',
fieldLabel: 'test_remote',
store: 'Chipmunks', // a remote store
displayField: 'chipmunk_name'
}]
...
But something is amiss. The AutoComboBox renders OK, shows dropdown of records fine, but when I select an item from the dropdown, the combobox's display field is not set. The store seems to find the selected record (as seen by the select listener), but the value is still not set...
Help? thanks.
Edit: FIXED by moving this.callParent(arguments) after the new store is bound. Now accepting answers that explain why this fixes it... (I don't know why it works.. but it does)
In the parent initComponent method, the displayField is used to create the displayTpl:
if (!me.displayTpl) {
me.displayTpl = new Ext.XTemplate(
'<tpl for=".">' +
'{[typeof values === "string" ? values : values["' + me.displayField + '"]]}' +
'<tpl if="xindex < xcount">' + me.delimiter + '</tpl>' +
'</tpl>'
);
} else if (Ext.isString(me.displayTpl)) {
me.displayTpl = new Ext.XTemplate(me.displayTpl);
}
The bindStore call has probably nothing to do with it, I believe that this is this line that must be put before the call to the parent method:
this.displayField = this.valueField = '_placeholder_';

ExtJS 4: Is there any way to attach a QuickTip to a form field?

I'm trying to add a QuickTip to a form field, but can't find a way to make my code work. Firstly, I tried to use a qtip attribute
{
fieldLabel: 'Last Name',
qtip:'This tip is not showing at all',
name: 'last'
}
and then using Ext.tip.ToolTip class:
Ext.create('Ext.tip.ToolTip', {
target: 'rating_field',
anchor: 'right',
trackMouse: true,
html: 'This tip is not showing at all'
});
Ext.QuickTips.init();
Here is a jsfiddle with the source code: jsfiddle
Yes, use the inputAttrTpl config and the data-qtip attribute:
{
fieldLabel: 'Last Name',
inputAttrTpl: " data-qtip='This is my quick tip!' ",
name: 'last'
}
I found the answer here: How should I add a tooltip to an ExtJS Component?
{
fieldLabel: 'Last Name',
qtip: "This is a tip",
name: 'last',
listeners: {
render: function(c) {
Ext.QuickTips.register({
target: c.getEl(),
text: c.qtip
});
}
}
}
Using vero4ka's answer I wrote a simple plugin which can be used with forms to enable quicktips on child fields.
Ext.define('Ext.form.QtipPlugin', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.qtipfields',
init: function (cmp) {
this.setCmp(cmp);
cmp.on('beforerender', function () {
var fields = cmp.query('field[qtip]');
for (var i = 0; i < fields.length; i++) {
fields[i].on('render', this.register, this);
}
}, this);
},
register: function (field) {
var obj = {
target: field.id
};
if (typeof field.qtip === 'string') {
obj.text = field.qtip;
} else if (typeof field.qtip === 'object') {
// Allow qtip configuration objects.
// i.e. qtip: { text: 'hi', ... }
Ext.applyIf(obj, field.qtip);
}
Ext.tip.QuickTipManager.register(obj);
}
});
For any form field, you can use this:
{
xtype: 'textfield', // or anything else
autoEl: {
'data-qtip': 'This is working tip!'
}
}
You can also use the built-in plugin datatip on a form panel.
in form panel (see http://docs.sencha.com/extjs/6.5.1/classic/Ext.ux.DataTip.html) :
in form config :
plugins = [{ptype : 'datatip'}]
in field text config :
tooltip : "my tooltip text"
If you are generating tooltip dynamically then you can use below snippet:
txtFieldName.el.set({ "data-qtip": Ext.String.htmlDecode("Some Text") });

Resources