Related
I have some store, which is formed data. On panel, it looks how "fieldName" and text field (in depension from invoked form).
For example, on one form is displayed "name document" and field, on another: date of selling and date field. Data is formed dynamically.
Here is store:
someStore = new Ext.data.JsonStore({
url: objectUrlAddress,
baseParams: {
'objectID' : objectID
},
root: 'Fields',
fields: [
{name: 'Hint'},
{name:'Type', type: 'int'},
{name: 'Value'},
{name: 'Index', type: 'int'},
{name: 'IsRequired', type:'bool'},
{name: 'Identifier'},
{name: 'EnumList'},
{name: 'Directory'},
{name: 'Data'}
]});
Here's grid
var templateGrids = new Ext.grid.EditorGridPanel({
id: 'tableId',
height:300,
width: '100%',
clicksToEdit:1,
frame: true,
store: tableTempStore,
columns:
[{header: 'Объект', width:200, dataIndex: 'Hint'},
{header: 'Значение',
dataIndex: 'Value',
width:300,
editor: {
xtype: 'textfield'
},
getCellEditor: function(record) {
var xtype = null,
args = {
fieldLabel: record.get('Hint'),
allowBlank: !record.get('IsRequired'),
value: record.get('Data'),
disabled: false
};
switch ('Type') {
case 0: // int
xtype = new Ext.form.NumberField();
args.allowDecimals = false;
break;
case 1: // decimal
xtype = new Ext.form.NumberField();
args.allowDecimals = true;
break;
case 2: // text
xtype = new Ext.form.TextField();
break;
case 3: // date
xtype = new Ext.form.DateField();
args.emptyText = 'дд.мм.гггг чч:мм';
args.format = 'd.m.y H:i';
break;
case 4: // enum
break;
case 5: // sql
var dataValues = Ext.util.JSON.decode(record.get('EnumList'));
var dataArray = Object.keys(dataValues).map(function(k) { return [k, dataValues[k]] });
xtype = 'Ext.form.field.ComboBox ';
args.store = new Ext.data.ArrayStore({
fields: [
{name: 'myId', type: 'string'},
{name: 'displayText'}
],
data: dataArray
});
break;
}
return new Ext.grid.CellEditor ({
field: Ext.create(xtype, args)
});
}
}]
});
Type of cell may be displayed in a grid in dependence from value of 'Type'.
For example if Type == 2, editor of column must be textvalue and etc. But my listener is not working and type is not changing. Besides, i get error "record.get is not a function".
Please help me to understand what wrong am I doing?
I barely know something regarding ExtJS and I'm struggling a lot since some days ago.
I know code presented here might not be the most performatic one, but it's a legacy application that I had to perform support (I did not develop it from scratch).
These below are called to populate a ExtJS combobox - carregaComboVersao makes a get call to server in order to obtain a response.
carregaVAloresCombo parses the response in order to populate combobox.
me.comboVersao is my combobox component, defined in this same javascript file as:
me.comboVersao = me.down('combobox[name=idVersao]');
carregaComboVersao: function(idObra){
var me = this;
KLIFT.model.mOrcamentoVersao.load(0, {
url: '../orcamentoVersao/buscaVersoesOrcamentoPorObra',
params: {
idObra: idObra
},
success: function(record){
alert(JSON.stringify(record));
me.carregaValoresCombo(record);
me.setLoading(false);
}
});
},
carregaValoresCombo: function(record){
var novo = JSON.stringify(record);
var me = this;
if (novo !== null) {
var item = record["raw"]["data"];
var array = new Array();
for(i=0; i<item.length; i++){
obj = Ext.create('KLIFT.model.mOrcamentoVersao', {
id : item[i].id,
dthrCriacao : item[i].dthrCriacao,
descritivoVersao: item[i].descritivoVersao,
versao: item[i].versao
});
}
me.comboVersao.setValue(obj);
}
Here is the combobox defined in a form component:
{
xtype: 'combobox',
fieldLabel: 'Versão',
displayField: 'descritivoVersao',
valueField: 'descritivoVersao',
width: 300,
name: 'idVersao',
editable:false,
model: Ext.create(('KLIFT.model.mOrcamentoVersao'))
}
and here is the model:
Ext.define('KLIFT.model.mOrcamentoVersao', {
extend: 'Ext.data.Model',
fields: [
{name: 'versao', type: 'int'},
{name: 'dthrCriacao', type: 'datetime'},
{name: 'descritivoVersao', type: 'string'},
{name: 'id', type: 'int'}
]
}
);
Any help is welcome.
Just an addition - response from server comes into 'record' variable as:
{"raw":{"data":[{"id":1,"dthrCriacao":"2018-02-25T00:00:00-0300","descritivoVersao":"mais veia","versao":0},{"id":2,"dthrCriacao":"2018-02-25T00:00:00-0300","descritivoVersao":"mais intermediaria","versao":1},{"id":3,"dthrCriacao":"2018-02-25T00:00:00-0300","descritivoVersao":"mais NOVA","versao":2}]},"modified":{},"data":{"versao":0,"dthrCriacao":"","descritivoVersao":"","id":0},"hasListeners":{},"events":{},"stores":[],"phantom":false,"internalId":0,"id":"KLIFT.model.mOrcamentoVersao-ext-record-2","dirty":true}
For pushing multiple values in combobox list, use store and map the store to the combobox.Mention the model in the store definition.
var store = Ext.create('Ext.data.Store', {
model: 'KLIFT.model.mOrcamentoVersao',
});
Add the multiple model instances to the store, which in turn will be added to the combobox.
comboVersao.getStore().add(obj);
For Example:
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('KLIFT.model.mOrcamentoVersao', {
extend: 'Ext.data.Model',
fields: [{
name: 'versao',
type: 'int'
},
{
name: 'dthrCriacao',
type: 'datetime'
},
{
name: 'descritivoVersao',
type: 'string'
},
{
name: 'id',
type: 'int'
}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'KLIFT.model.mOrcamentoVersao',
});
var comboVersao = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Versão',
displayField: 'descritivoVersao',
valueField: 'descritivoVersao',
width: 300,
name: 'idVersao',
editable: false,
store: store,
queryMode: 'local',
renderTo: Ext.getBody()
});
var carregaValoresCombo = function(record) {
var novo = JSON.stringify(record);
var me = this;
if (novo !== null) {
var item = record["raw"]["data"];
var array = new Array();
for (i = 0; i < item.length; i++) {
obj = Ext.create('KLIFT.model.mOrcamentoVersao', {
id: item[i].id,
dthrCriacao: item[i].dthrCriacao,
descritivoVersao: item[i].descritivoVersao,
versao: item[i].versao
});
comboVersao.getStore().add(obj);
}
}
}
carregaValoresCombo({"raw":{"data":[{"id":1,"dthrCriacao":"2018-02-25T00:00:00-0300","descritivoVersao":"mais veia","versao":0},{"id":2,"dthrCriacao":"2018-02-25T00:00:00-0300","descritivoVersao":"mais intermediaria","versao":1},{"id":3,"dthrCriacao":"2018-02-25T00:00:00-0300","descritivoVersao":"mais NOVA","versao":2}]},"modified":{},"data":{"versao":0,"dthrCriacao":"","descritivoVersao":"","id":0},"hasListeners":{},"events":{},"stores":[],"phantom":false,"internalId":0,"id":"KLIFT.model.mOrcamentoVersao-ext-record-2","dirty":true});
}
});
<link rel="stylesheet" href="https://cdn.sencha.com/ext/gpl/4.1.1/resources/css/ext-all.css">
<script type="text/javascript" src="https://cdn.sencha.com/ext/gpl/4.1.1/ext-all-debug.js"></script>
I have grid with checkboxmodel , As per my requirement I have to disable some checkbox in checkbox model and restrict user to select that row. I am able to achieve below code.
viewConfig: {
getRowClass: function (record, rowIndex, rowParams, store) {
return record.data.name == 'Lisa' ? 'bg' : "";
}
},
listeners: {
beforeselect: function ( test , record , index , eOpts ) {
return record.data.name == "Lisa" ? false : true;
}
}
above configs are used in grid and below is my css
.bg .x-grid-cell-row-checker{
background-color: grey;
pointer-events: none;
opacity: 0.4;
}
Everythings work fine only one issue is header checkbox is not working i.e not able deselectAll from header and able to select but not getting checked
Here is my working fiddle
Ext js version 5
Expanding on And-y's answer, I would construct my own class and do something like in this Fiddle. I did add a few things, like the isDisabled flag in the model, but I don't see that as a bad thing, and it greatly helps out with deciding how to show the checkbox/fixing the Check All checkbox logic.
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('MySelectionModel', {
extend: 'Ext.selection.CheckboxModel',
alias: 'selection.mySelectionModel',
// default
disableFieldName: 'isDisabled',
listeners: {
beforeselect: function (test, record, index, eOpts) {
return !record.get(this.disableFieldName);
}
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
if (record.get(this.disableFieldName)) {
metaData.tdCls = 'bg';
}
else {
return this.callParent(arguments);
}
},
updateHeaderState: function () {
// check to see if all records are selected
var me = this,
store = me.store,
storeCount = store.getCount(),
views = me.views,
hdSelectStatus = false,
selectedCount = 0,
selected, len;
var disableFieldName = me.disableFieldName;
if (!store.isBufferedStore && storeCount > 0) {
selected = me.selected;
hdSelectStatus = true;
// loop over all records
for (var i = 0, j = 0; i < storeCount; i++) {
var rec = store.getAt(i);
var selectedRec = selected.getAt(j);
// Check selection collection for current record
if (selectedRec && selected.indexOf(rec) > -1) {
++selectedCount;
// Increment selection counter
j++;
}
// Otherwise, automatically consider disabled as part of selection
else if (rec.get(disableFieldName)) {
++selectedCount;
}
}
hdSelectStatus = storeCount === selectedCount;
}
if (views && views.length) {
me.toggleUiHeader(hdSelectStatus);
}
}
});
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone', 'isDisabled'],
data: {
'items': [{
'name': 'Lisa',
isDisabled: true,
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "homer#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
selModel: {
selType: "mySelectionModel",
showHeaderCheckbox: true,
mode: 'MULTI',
allowDeselect: true,
toggleOnClick: false,
checkOnly: false
},
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
}
});
The problem occurs in the function updateHeaderState of the Ext.selection.CheckboxModel.
The function checks if all checkboxes are selected by hdSelectStatus = storeCount === selectedCount;. In your case selectedCount is not matching the storeCount and the state of the header checkbox is not updated.
You could extend the Ext.selection.CheckboxModel and override the updateHeaderState function to fit your needs.
How prevent this behavior of changing object in observableArray when user modified or edit a row in jqxGrid.
I have a knockout observable array of Users, where each User have all is properties as observables,then I bound that observable array to a jqxGrid (from jqWidgets). And when I updated in the grid a User value, then in the observable array that item is replaced with an object containing the values of the observables of this User.
Below is my code:
HTML Section:
<div class="container">
<div id="jqxGrid"
data-bind="jqxGrid: {
source: Users,
editable: true,
width: '100%',
selectionmode: 'singlecell',
columns: [
{ text: 'IsChecked', columntype: 'checkbox', dataField: 'IsChecked', width: '10%' },
{ text: 'FirstName', dataField: 'FirstName', width: '40%', editable: false, sortable: true },
{ text: 'LastName', dataField: 'LastName', width: '40%', editable: true, sortable: true }
]
}">
</div>
</div>
Javascript code: (Creation of Users array, ViewModel initialization, ko.applyBindings invocation.)
function UserModel (user) {
var self = this;
self.IsChecked = ko.observable(false); // later I will use this proerty in other place
self.Username = ko.observable(user.Username);
self.FirstName = ko.observable(user.FirstName);
self.LastName = ko.observable(user.LastName);
// I want to put a isDirty property here
}
var initialUsers = [
new UserModel({ Username: 'JohnMicrosoft', FirstName: 'John', LastName: 'Microsoft' }),
new UserModel({ Username: 'JohnGoogle', FirstName: 'John', LastName: 'Google' }),
new UserModel({ Username: 'JohnApple', FirstName: 'John', LastName: 'Apple' }),
];
var viewModel = null;
$(document).ready(function () {
viewModel = new UserViewModel(initialUsers);
ko.applyBindings(viewModel);
});
function UserViewModel(initialUsers) {
var self = this;
self.Users = ko.observableArray(initialUsers);
};
This images show how the values changes after I click in the first row in IsChecked checkbox.
Result of clicking IsChecked checbox of first row in jqxGrid
The problem is that I want to add some functions to UserModel object and I want to keep the observables because I want to use them in other part of my page. I have een working in this for days and dont know what to do any help will be appreciated. Thanks.
I made something similar. Maybe it can help you:
var Goods = function (obj) {
var name = ko.observable(obj.name);
var sales = ko.observable(obj.sales);
var price = ko.observable(obj.price);
var extra = ko.observable(obj.extra);
var id = ko.observable(obj.id);
name.subscribe(alert('name changed'));
return {
name: name,
sales: sales,
price: price,
extra: extra,
id: id
};
};
var items = ko.observableArray([
new Goods({ id: 1, name: "Furious Lizard", sales: 152, price: 25.00 }),
new Goods({ id: 2, name: "Indifferent Monkey", sales: 1, price: 99.95 }),
]);
var source = {
localdata: items,
datatype: 'local'
};
In the view I have only this:
<div id="jqxgrid"></div>
In the document ready function I have initialized the grid:
$("#jqxgrid").jqxGrid({
source: source,
....
});
I'm new to ExtJs. I have a GridPanel which is binded with a data store. I have a checkboxgroup, which containts the possible values of the GridPanel row. I want to filter the GridPanel with the checkboxgroup values.
Here is the code -
Store1 = new Ext.data.JsonStore({
url: 'CustomerProfiles/GetDetails',
root: 'rows',
fields:['Name','Id']
});
DetailedResults =
{
xtype: 'grid',
autoHeight: true,
autoWidth: true,
autoScroll: true,
border: false,
trackMouseOver: false,
frame: true,
store: Store1,
columns: [
{ header: 'Name', dataIndex: 'Name', width: 90 },
{ header: 'Id', dataIndex: 'Id', width: 50 }
]
};
Leftpanel = new Ext.Panel({
id: 'Leftpanel',
frame: true,
width: 175,
items: [
{
xtype: 'label'
},
{
xtype: 'checkboxgroup',
columns: 1,
vertical: true,
items: [{
boxLabel: 'ALL',
name: 'chkName',
inputValue: 'all'
}, {
boxLabel: 'N1',
name: 'chkName',
inputValue: 'N1'
}, {
boxLabel: 'N2',
name: 'chkName',
inputValue: 'N2'
}, {
boxLabel: 'N3',
name: 'chkName',
inputValue: 'N3'
}], listeners: {
change: {
fn: function () {
Store1.clearFilter();
var selectedValue = this.getValue();
for (var i = 0; i < selectedValue.length; i++) {
Store1.filter('Name', selectedValue[i].inputValue);
}
}
}
}
}
]});
Where I went wrong?
PS: I am using 3.4 version
The getValue() method is a little tricky, the object it returns has variable structure depending on the resultset, that caused the problem in your code. However, the getChecked() method is more straightforward, I'll use it in the solution.
Then, we use filterBy as it's more useful in this case.
Here you have the solution (comments inline):
change: {
fn: function () {
var checkedBoxes = this.getChecked(), //Array of checked checkboxes
selectedValues = []; //Array of selected values
for (var i = 0; i < checkedBoxes.length; i++) {
selectedValues.push(checkedBoxes[i].inputValue); //Add each inputValue to the array
}
var allSelected = Ext.Array.contains(selectedValues, 'all'); //Whether the 'ALL' option was selected
Store1.filterBy(function(record){
//If all was selected or if the name is included in the selectedValues, include the item in the filter
return allSelected || Ext.Array.contains(selectedValues, record.get('Name'));
});
}
}
Problem solved. Tested and working :)
UPDATE
The above code works on ExtJs >= 4. For Ext 3.4, this is the code:
change: {
fn: function () {
var selectedValues = []; //Array of selected values
this.items.each(function(checkbox){
if(checkbox.checked)
selectedValues.push(checkbox.inputValue);
});
var allSelected = selectedValues.indexOf('all') >= 0; //Whether the 'ALL' option was selected
Store1.filterBy(function(record){
//If all was selected or if the name is included in the selectedValues, include the item in the filter
return allSelected || selectedValues.indexOf(record.get('Name')) >= 0;
});
}
}
OPTIONAL (extra improvements, works only on ExtJs 4.x)
However, checking your app, I think the following improvements could be done:
Create the filter checkboxes dynamically depending on the store data
Sync the ALL checkbox with the rest (i.e. when selecting ALL, select all the other checkboxes)
This is the code with the improvements:
var Store1 = new Ext.data.JsonStore({
proxy: {
type: 'ajax',
url: 'CustomerProfiles/GetDetails',
reader: {
root: 'rows'
}
},
autoLoad: true,
fields: ['Name','Id'],
listeners: {
//Each time the store is loaded, we create the checkboxes dynamically, and add the checking logic in each one
load: function(store, records){
createCheckboxesFromStore(store);
}
}
});
var DetailedResults = {
xtype: 'grid',
autoHeight: true,
autoWidth: true,
autoScroll: true,
border: false,
trackMouseOver: false,
frame: true,
store: Store1,
columns: [
{ header: 'Name', dataIndex: 'Name', width: 90 },
{ header: 'Id', dataIndex: 'Id', width: 50 }
]
};
var Leftpanel = new Ext.Panel({
id: 'Leftpanel',
frame: true,
width: 175,
items: [
{
xtype: 'label'
},
{
xtype: 'checkboxgroup',
columns: 1,
vertical: true,
}
]});
function createCheckboxesFromStore(store){
var checkBoxGroup = Leftpanel.down('checkboxgroup');
checkBoxGroup.removeAll();
checkBoxGroup.add({
itemId: 'allCheckbox',
boxLabel: 'ALL',
name: 'chkName',
inputValue: 'all',
checked: true,
listeners: {
change: function (chbx, newValue) {
console.log("Changed ALL to ", newValue);
if(newValue){ //If ALL is selected, select every checkbox
var allCheckboxes = this.up('checkboxgroup').query("checkbox"); //Array of all checkboxes
for (var i = 0; i < allCheckboxes.length; i++) {
allCheckboxes[i].setValue(true);
}
}
}
}
});
//Create one checkbox per store item
store.each(function(record){
checkBoxGroup.add({
boxLabel: record.get('Id'),
name: 'chkName',
inputValue: record.get('Name'),
checked: true,
listeners: {
change: function (chbx, newValue) {
console.log("Changed ", chbx.inputValue, " to ", newValue);
var checkboxGroup = this.up('checkboxgroup'),
checkedBoxes = checkboxGroup.getChecked(), //Array of checked checkboxes
selectedValues = []; //Array of selected values
//If we uncheck one, also uncheck the ALL checkbox
if(!newValue) checkboxGroup.down("#allCheckbox").setValue(false);
for (var i = 0; i < checkedBoxes.length; i++) {
selectedValues.push(checkedBoxes[i].inputValue); //Add each inputValue to the array
}
Store1.filterBy(function(record){
//If all was selected or if the name is included in the selectedValues, include the item in the filter
return Ext.Array.contains(selectedValues, record.get('Name'));
});
}
}
});
});
}
This is also tested and working :). If you need it, I can pass you a jsfiddle link with the code running (just tell me).
Cheers, from La Paz, Bolivia