EXTJS - How to target rendered checkbox input in grid - extjs

I have an EXT grid that has an additional checkbox and radio in the last 2 columns using the renderer. When I check an item in the grid and view the source I am not seeing the checked:checked designation in the HTML so I am having a hard time targeting the element.
When a row is selected I want to be able to check to see if the checkbox is checked, I am doing something like this:
if (document.getElementById("#isFull-"+record['index']+"").checked == true){
var myVar = true;
}
Is there another way I can target this element to see if it is checked?
Here is the full code:
Ext.onReady(function () {
Ext.QuickTips.init();
// Data store
var data = Ext.create('Ext.data.JsonStore', {
autoLoad: true,
fields: ['name', 'market', 'expertise', 'id', 'isFull', 'isPrimary'],
proxy: {
type: 'ajax',
url: '/opsLibrary/getLibraryJson'
}
});
// Selection model
var selModel = Ext.create('Ext.selection.CheckboxModel', {
columns: [{
xtype: 'checkcolumn',
text: 'Active',
dataIndex: 'id'
}],
listeners: {
selectionchange: function (value, meta, record, rowIndex, colIndex) {
var selectedRecords = grid4.getSelectionModel().getSelection();
var selectedParams = [];
// Clear hidden input
$('#selected-libraries').empty();
var record = null;
var myVar = null;
var myVar2 = null;
for (var i = 0, len = selectedRecords.length; i < len; i++) {
record = selectedRecords[i];
// Is full library checked?
myVar = !Ext.fly("isFull-" + data.indexOf(record)).dom.checked;
// Build data object
selectedParams.push({
id: record.getId(),
full: myVar
});
}
// JSON encode object and set hidden input
$('#selected-libraries').val(JSON.stringify(selectedParams));
}
}
});
// Render library grid
var grid4 = Ext.create('Ext.grid.Panel', {
xtype: 'gridpanel',
id: 'button-grid',
store: data,
columns: [{
text: "Library",
width: 170,
sortable: true,
dataIndex: 'name'
}, {
text: "Market",
width: 125,
sortable: true,
dataIndex: 'market'
}, {
text: "Expertise",
width: 125,
sortable: true,
dataIndex: 'expertise'
}, {
text: 'Full',
dataIndex: 'isFull',
width: 72,
renderer: function (value, meta, record, rowIndex, colIndex) {
return '<center><input type="checkbox" onclick="var s = Ext.getCmp(\'button-grid\').store; s.getAt(s.findExact(\'id\',\'' + record.get('id') + '\')).set(\'isFull\', this.value)"'
}
}, {
text: 'Primary',
dataIndex: 'isPrimary',
width: 72,
renderer: function (value, meta, record, rowIndex, colIndex) {
return '<center><input type="radio" id="isPrimary-' + rowIndex + '"/></center>';
}
}, ],
columnLines: false,
selModel: selModel,
width: 600,
height: 300,
frame: true,
title: 'Available Libraries',
iconCls: 'icon-grid',
renderTo: Ext.get('library-grid')
});
});
UPDATED SELECTION MODEL:
// Selection model
var selModel = Ext.create('Ext.selection.CheckboxModel', {
columns: [{
xtype: 'checkcolumn',
text: 'Active',
dataIndex: 'id'
}],
listeners: {
selectionchange: function (value, meta, record, rowIndex, colIndex) {
var selectedRecords = grid4.getSelectionModel().getSelection();
var LastSelectedRecords = grid4.getSelectionModel().getLastSelected();
var selectedParams = [];
// If user unselected ID then make sure Full & Primary boxes cleared
if (grid4.getSelectionModel().getSelection() == "") {
// Get row ID
Ext.fly('isFull-' + LastSelectedRecords['index']).dom.checked = false;
Ext.fly('isPrimary-' + LastSelectedRecords['index']).dom.checked = false;
}
// Clear input and reset vars
$('#selected-libraries').empty();
var record = null;
var myVar = null;
var myVar2 = null;
// Loop through selected records
for (var i = 0, len = selectedRecords.length; i < len; i++) {
record = selectedRecords[i];
// Is full library checked?
myVar = record.get('isFull');
// Is this primary library?
myVar2 = record.get('isPrimary');
// Build data object
selectedParams.push({
id: record.getId(),
full: myVar,
primary: myVar2
});
}
// JSON encode object and set hidden input
$('#selected-libraries').val(JSON.stringify(selectedParams));
console.log(JSON.stringify(selectedParams));
}
}
});

Let's try a different approach. What if you set your check columns to do something like this:
{
text: 'Full',
dataIndex:'isFull',
width: 70,
renderer: function (value, meta, record, rowIndex, colIndex) {
return '<center><input type="checkbox" onclick="var s = Ext.getCmp(\'button-grid\').store; s.getAt(s.findExact(\'id\',\'' + record.get('id') + '\')).set(\'isFull\', this.value)" /></center>';
}
},
This should set the value directly into the record.

Data in records is accessed using the get() function, not object notation:
if (document.getElementById("isFull-"+record.get('index')).checked == true)
{
var myVar = true;
}
A couple other points... You are checking a truth value using == true, which will return true for any "truthie". You'll want to use === if you want to check that it equals true.
Also, you may want to consider Ext.fly() to get your element, it's more Ext-friendly:
if (Ext.fly("isFull-"+record.get('index')).dom.checked === true)
{
var myVar = true;
}
For simplicity, you can even just do this:
var myVar = Ext.fly("isFull-"+record.get('index')).dom.checked;
EDIT:
I was under the impression that you had index as one of your store fields, but I just noticed that it is not. You will want to use store.indexOf(record) to get the index you need:
var myVar = Ext.fly("isFull-" + data.indexOf(record)).dom.checked;

Maybe, you can use one listener on grid view:
Sencha api [4.2]: Listeners on grid/columns
listeners: {
click: {
element: 'el', //bind to the underlying el property on the panel
fn: function(){
console.log('click el');
}
},

Related

How to set grid row getSelectionModel data in ext window

I am not bale to set row elected data in ext window, can you please give solution for this. my code is here..
var shiftWindow = Ext.create('Ext.window.Window', {
title: 'Edit Shift',
resizable: false,
id: 'shiftwindow',
width: 465,
//bodyPadding: 5,
modal: true,
store: shiftStorePlanner,
items: {
xtype: 'form',
id: 'idFormShift',
bodyPadding: 10,
items: shiftViewModelPlannerData
},
buttons: [{
text: 'Save',
cls: 'planner-save-button',
overCls: 'planner-save-button-over',
handler: function() {
var wi = this.up('.window')
var form = Ext.getCmp('idFormShift');
if (form.isValid()) {
shiftTimemappingarray = [];
getShiftTime();
//this.up('.window').close();
}
}
}, {
text: 'Cancel',
handler: function() {
this.up('.window').close();
}
}]
});
var host1 = Ext.getCmp('plannershifteditor');
var selection = host1._shiftPlannerGrid.getSelectionModel().getSelection();
if (selection.length === 0) {
return;
}
Ext.getCmp('shiftWindow').getForm().setValues(selection[0].data);
shiftWindow.show();
}
Depending on your ExtJS Version:
var selection = grid.getSelectionModel().getSelection();
grid.getForm().loadRecord(selection[0]);
Later you can use updateRecord() to update the model with the form values.
More Infos:
http://docs.sencha.com/extjs/6.0.2/classic/Ext.form.Basic.html#method-loadRecord
http://docs.sencha.com/extjs/6.0.2/classic/Ext.form.Basic.html#method-updateRecord
ExtJS 5 and later supports also viewmodel binding. This will do the job automatically.

Unable to Filter Local Records in ExtJs

I have the data in the format as array of hashes. The 3 fields are id, value and production_group_id. Now what I want to do is filter combo box based on production_group_id of records.
Basically, out of the initial populated data in store. I want to filter fields. Somehow the listener is not working.
Ext.define('fabmin.view.ComboColumn', {
extend: 'Ext.grid.column.Column',
alias: 'widget.comboboxcolumn',
width: 100,
isEditable: true,
list: [], // list = [{id: 'id1', value: 'value1', production_group_id: 'production_group_id1 }, {id: 'id1', value: 'value1', production_group_id: 'production_group_id1 }]
initComponent: function(){
var me = this,
list = me.list || [];
if(me.isEditable){
me.editor = Ext.create('Ext.form.ComboBox',{
forceSelection: true,
typeAhead: true,
queryMode: 'local',
displayField: 'value',
valueField: 'id',
store: Ext.create('Ext.data.ArrayStore', {
fields: ['id', 'value','production_group_id'],
data: list
}),
allowBlank: false,
listeners: {
click: function (v, p, record, rowIndex, colIndex, store, view) {
debugger
var newdata = [];;
for (i = 0; i < me.store.length; i++) {
if (me.store[i].production_group_id == record.production_group_id){
newdata.push(me.store[i])
}
}
debugger
me.store.load(newdata);
},
scope: me
}
});
}
me.renderer = function(v, p, record, rowIndex, colIndex, store, view) {
var len = list.length,
currOpt;
while( len-- ) {
currOpt = list[ len ];
if ( v == currOpt.id ) {
return currOpt.value;
}
}
return v;
}
me.callParent(arguments);
}
});
If you use any field (including Ext.form.ComboBox) then you should listen to change event. It is fired after value is changed in field, so also when you select something from list.

Extjs: progressBar in cell grid not displaying

I'm using Extjs 4.1
In my application, i'm displaying a grid with some actionColumns, when a task is launched through those actioncolumns, i want to display a progress bar in the grid. There should be a progress bar for each record in the grid.
This how I had it:
columns: [{...}
{
header:'In Progress',
dataIndex : 'inProgress',
flex: 1,
renderer: function(value, meta, record){
if (value){
var id = Ext.id();
Ext.defer(function(){
var pBar=Ext.widget('ProgressBar',{
renderTo: id,
rec: record,
});
},150);
return Ext.String.format('<div id="{0}"></div>', id);
}else{
return value;
}
}
}],
The progress bar is correctly created (the code of the progress bar is running, see below) but it is not displayed/rendered.
Any idea as where my code is wrong?
here is the code of the custom progressbar:
Ext.define('V_ProgressBar', {
extend: 'Ext.ProgressBar',
alias: 'widget.ProgressBar',
height: 50,
layout:'fit',
constructor:function(param){
var rec=param.rec;
barConfig = this.config;
value=0.5
this.value=value;
this.callParent([barConfig]);
this.update(this, value);
},
update:function(pbar, value){
console.log(pbar.value)
if (value<1){
console.log(value)
value+=0.1;
pbar.updateProgress(value);
Ext.Function.defer(pbar.update, 3000, this, [pbar,value]);
}
else{
pbar.updateText("done");
}
}
Use Ext.defer
header: "Porcentual Concluído",
flex:0.3,
dataIndex: 'porcentualtotal',
renderer: function(value, meta, record){
if(record.data.porcentualtotal == null){
record.data.porcentualtotal = 0;
}
pt = record.data.porcentualtotal/100;
var id = Ext.id();
Ext.defer(function (id,pt) {
var p = Ext.create('Ext.ProgressBar',{
renderTo: id,
animate: true,
width: '100%',
value: pt,
text: (pt*100)+"%",
});
}, 50, undefined, [id,pt]);
return "<div id='" + id + "'></div>";
},

Adding link against each row in grid

I need to display a 'Delete' link against each row in a editorgridpanel.
How do I create this link;as it is not mapped to any particular column in the store?
I tried the following but it does not display the link against the added records:
var sampleRecord = new Ext.data.Record.create([
{mapping: 'organizationId',name:'organizationId', type:'int'},
{mapping: 'name',name:'name', type:'string'},
{mapping: 'address',name:'address' , type:'int'}
]);
var s_grid= new Ext.grid.EditorGridPanel ({
.........
columns: [
{header: 'id', width: 120, sortable: false, dataIndex: 'organizationId'},
{header: 'name',width: 120, sortable: false, dataIndex: 'name'},
{header: 'address', sortable: false,width: 45, dataIndex: 'address'},
{header: '',width: 50, sortable: false, renderer:this.delRenderer }
],
.....
,
delRenderer:function (val, meta, rec, rowIdx) {
var tempStr="<div onclick=\"javascript:Ext.getCmp('" +"s_grid" + "').deAllocate(" + rowIdx + ");\" class='pointer'><span style='color:#0000FF'><u>Delete</u></span></div>";
return tempStr ;
},
deAllocate:function (rowIdx ) {
Ext.getCmp('s_grid').getStore().removeAt(rowIdx);
Ext.getCmp('s_grid').getView().refresh();
}
});
Help is appreciated.
You'd be better off using an ActionColumn. Anyway, you can also wrap a solution around custom element (link...) with the cellclick event. Here's an example showing both methods:
var grid = new Ext.grid.GridPanel({
renderTo: Ext.getBody()
,height: 300
,store: new Ext.data.JsonStore({
fields: ['id', 'name']
,data: [
{id: 1, name: 'Foo'}
,{id: 2, name: 'Bar'}
,{id: 3, name: 'Baz'}
]
})
,columns: [
{dataIndex: 'name'}
,{
xtype: 'actioncolumn'
,icon: 'http://images.agoramedia.com/everydayhealth/gcms/icon_delete_16px.gif'
,handler: function(grid, row) {
grid.store.removeAt(row);
}
}
,{
renderer: function(value, md, record, row, col, store) {
return '<a class="delete-link" href="#delete-record-' + record.id + '">Delete</a>';
}
}
]
,listeners: {
cellclick: function(grid, row, col, e) {
var el = e.getTarget('a.delete-link');
if (el) {
e.preventDefault();
grid.store.removeAt(row);
}
}
}
});
var lastId = 3;
setInterval(function() {
var store = grid.store,
record = new store.recordType({id: ++lastId, name: 'New record #' + lastId}, lastId);
store.add(record);
}, 3000);
Update
And just because I may be completely off topic on your question, I think your code is not working because when you call this:
renderer: this.delRenderer
Your not in a scope where this points to your grid (since it has not even been created at this point...). What you want to do is rather something like this:
var s_grid = new Ext.grid.EditorGridPanel ({
...
columns: [..., {
...
renderer: delRenderer
}]
});
function delRenderer() {
// FYI, `this` will be the column here
...
}
Or put the function inline in the grid definition...
You can change model by adding delete field :
{
name: 'delete',
convert: function () {
return 'delete';
}
You can then add extra column in your grid and check for link click by 'cellclick' event of the grid with some modifications.Here is the working example :
Working Fiddle.
Have a nice day :-)
The dataIndex config is required on your column, so just provide any field there (e.g. the id) and in your renderer function just ignore the value argument (as you are already doing).

ExtJs bufferedrenderer plugin and locked column conflict

I need to lock some columns in grid. Here is my code with configuration of grid:
Ext.define('Crm.view.tables.baseTable', {
extend: 'Ext.grid.Panel',
alias : 'widget.baseTable',
columnLines: true,
initComponent: function(){
var that = this;
var $this = that;
this.selType = 'checkboxmodel',
this.selModel = {
allowDeselect: true,
mode: "MULTI"
};
this.plugins = [
new Ext.grid.plugin.CellEditing({
clicksToEdit: 2
}),
{
ptype: 'bufferedrenderer',
numFromEdge: 8,
trailingBufferZone: 10,
leadingBufferZone: 10
}
];
var filters = {
ftype: 'filters',
encode: true,
local: true
};
this.features = [filters];
var columns = [
new Ext.grid.RowNumberer(),
{
header : 'ID',
dataIndex: 'id',
locked : true,
filterable: true,
width : 30
},{
header : 'ФИО',
width : 100,
dataIndex: 'name',
filterable: true,
filter: {
type: 'string'
},
editor: 'textfield'
},{
header : 'Телефон',
dataIndex: 'phone',
filterable: true,
width : 75,
editor: 'textfield'
},{
header : 'Email',
dataIndex: 'email',
filterable: true,
width : 90,
editor: 'textfield'
}
];
this.columns = columns
var tbar = [{
text: 'Обновить',
handler: function(){
$this.getStore().reload();
}
},'-',{
text: 'Очистить фильтр',
handler: function () {
that.filters.clearFilters();
}
},'-']
this.tbar = tbar;
this.callParent();
}
});
But I get an error:
Uncaught TypeError: Cannot call method 'on' of undefined ext-all-debug.js:115013
When I remove bufferedrenderer plugin from config, the locked column
works. What is the problem? Thanks for answers!
This is for EXTJS 4.2.1.
Following code is init function of "Ext.data.grid.plugin.Bufferedrenderer"
When you use locking feature for grid, ExtJs wraps grid.view with "Ext.grid.locking.View".
Then init function try to find properties of grid.view which are not available through the wrapper. So I added a few line to init function (find it below with "// replace locking.View with grid.View" ) then it solves the issue.
Simply create class by extending "Ext.data.grid.plugin.Bufferedrenderer" with below init function.
Martin.P - EMH Consulting.
init: function(grid) {
var me = this,
view = grid.view,
viewListeners = {
scroll: {
fn: me.onViewScroll,
element: 'el',
scope: me
},
boxready: me.onViewResize,
resize: me.onViewResize,
refresh: me.onViewRefresh,
scope: me,
destroyable: true
};
//********************************************************************
// replace locking.View with grid.View - hayangae#gmail.com
if (view.isLockingView){
view = view.getViewForColumn();
}
//********************************************************************
// If we are using default row heights, then do not sync row heights for efficiency
if (!me.variableRowHeight && grid.ownerLockable) {
grid.ownerLockable.syncRowHeight = false;
}
// If we are going to be handling a NodeStore then it's driven by node addition and removal, *not* refreshing.
// The view overrides required above change the view's onAdd and onRemove behaviour to call onDataRefresh when necessary.
if (grid.isTree || grid.ownerLockable && grid.ownerLockable.isTree) {
view.blockRefresh = false;
view.loadMask = true;
}
if (view.positionBody) {
viewListeners.refresh = me.onViewRefresh;
}
me.grid = grid;
me.view = view;
view.bufferedRenderer = me;
view.preserveScrollOnRefresh = true;
me.bindStore(view.getStore());
view.getViewRange = function() {
return me.getViewRange();
};
me.position = 0;
me.gridListeners = grid.on('reconfigure', me.onReconfigure, me);
me.viewListeners = view.on(viewListeners);
},

Resources