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>";
},
Related
I need to do something like web shop where ideas is to have to views on products. One is grid and second is card/tile.
I try to achive this with combination of sencha grid and view with template based on same view model.
If you want just "present" data view is working fine, but if you need bind data into controls there are some issues.
Example pictures:
Grid view
Card/Tile view
Issue 1: If I change quantity in Grid view with + on row level all buttons and numeric field for that row will disappear on Card view
Issue 2: +/- button are not working on card view, they cannot fetch row quantity to increase or decrease value
Any ideas ?
Here is the code of Card View:
cls: "b2bbp-shop-widget-carditemview",
reference: "b2bbp-shop-widget-carditemview",
bind: {
store: "{items}",
record: "{record}"
},
tpl: new Ext.XTemplate(
"<tpl for=\".\">",
"<div class=\"admin-b2bbp-cardview-card\">",
"<div class=\"admin-b2bbp-cardview-content\">",
"<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css\">",
"<img class=\"admin-b2bbp-cardview-image\" src=\"https://dictionary.cambridge.org/images/thumb/lightb_noun_002_21219.jpg?version=5.0.74\" height=190 width=180 />",
"<br/>",
"<div class=\"question-button\"></div>",
"<p class=\"admin-b2bbp-cardview-descripion\"> {description} </p>",
"<div class=\"details\"></div>",
"<span class=\"admin-b2bbp-cardview-left shop-order-summary\">Quantity</span>",
"<span class=\"admin-b2bbp-cardview-right shop-order-summary\">{msrp}</span>",
"<br/>",
"<div class=\"admin-b2bbp-cardview-pricesum\">",
"<span class=\"admin-b2bbp-cardview-left shop-order-summary-value\">Total</span>",
"<span class=\"admin-b2bbp-cardview-right shop-order-summary-value\">{itemTotal}</span>",
"</div><br/>",
"<div class=\"buttons\"></div>",
"</div>",
"</div>",
"</tpl>", {
complied: true
}
),
itemSelector: "div.admin-b2bbp-cardview-card",
listeners: {
refresh: function (a, b) {
var renderSelectorQuestionMark = Ext.query("div.question-button");
for (var i in renderSelectorQuestionMark) {
var rec = b[i];
Ext.create("Ext.form.field.Display", {
bind: {
value: rec.data.name
},
fieldCls: "shop-order-summary",
renderTo: renderSelectorQuestionMark[i]
});
}
var renderSelectorButtons = Ext.query("div.buttons");
for (var j in renderSelectorButtons) {
var rec = b[j];
console.log("Render Buttons records", rec)
Ext.create("Ext.container.Container", {
layout: {
type: "column",
},
height: 50,
padding: "20 0 0 0",
items: [
{
xtype: "container",
padding: "0 10 0 0",
items: [
{
xtype: "button",
glyph: "xf068#FontAwesome",
width: 30,
height: 30,
record: rec,
handler: function(button) {
console.log(button.record)
//button.record.set('quantity',button.record.data.quantity-1);
},
}]
},
{
xtype: "numberfield",
hideTrigger: true,
fieldCls: "store-grid-text",
minValue: 1,
value: rec.data.quantity,
step: 1,
width: 100,
/* bind: {
value: rec.data.quantity,
record: rec
},*/
setRecord: function(record) { // Required for binding to work
this.record = record;
},
getRecord: function() { // Required for binding to work
return this.record;
}
},
{
xtype: "container",
padding: "0 35 20 10",
items: [
{
xtype: "button",
glyph: "xf067#FontAwesome",
width: 30,
height: 30,
record: rec,
handler: function(button) {
console.log(button)
console.log(button.record)
//button.record.set('quantity',button.record.data.quantity+1);
},
setRecord: function(record) { // Required for binding to work
this.record = record;
},
getRecord: function() { // Required for binding to work
return this.record;
}
}]
},
{
xtype: "button",
//text: 'Dodaj',
cls: "shop-button",
iconCls: "x-fa fa-shopping-basket",
maxWidth: 60,
height: 30,
record: rec,
handler: function(button) {
console.log(button.record);
},
}
],
renderTo: renderSelectorButtons[j]
});
}
var renderSelectorDetails = Ext.query("div.details");
for (var k in renderSelectorDetails) {
Ext.create("Ext.button.Button", {
text: "INFO",
iconCls: "x-fa fa-info-circle",
cls: "shop-info-button",
renderTo: renderSelectorDetails[k]
})
}
},
},
In ExtJS, on a menu toolbar button, I am trying to remove the current panel in my center window, then recreate it with the new selection. I do not understand the proper way to do this. So far when I click the menu item, it removes whatever is currently there successfully, then it will add the new panel successfully. The problem is the 2nd time I hit the button I get the following error:
REGISTERING DUPLICATE COMPONENT ID 'mainportalID'.
I realize its telling me I already used this ID, but then what would be the correct way to remove the current panel, and replace with a new one?
Here is my view controller:
selectMenuButton: function (button, e) {
console.log('select menu button section was hit')
console.log(button);
console.log(e);
var optionString = button.text;
var myDetailsPanel = Ext.getCmp('navview');
console.log(myDetailsPanel);
var count = myDetailsPanel.items.items.length;
if (count > 0) {
myDetailsPanel.items.each(function (item, index, len) {
myDetailsPanel.remove(item, false);
});
}
myDetailsPanel.add({
xtype: optionString
});
}
var myStore = Ext.create('ExtApplication1.store.PositionsStore');
var gridSummary = Ext.create('Ext.grid.Panel', {
store: myStore,
width: 600,
title: 'my first grid',
columns: [
{
text: 'AcctNum',
dataIndex: 'AcctNum',
width: 100
},
{
text: 'AcctShortCode',
dataIndex: 'AcctShortCode',
flex: 1
},
{
text: 'Exchange',
dataIndex: 'Exchange',
width: 200
}
]
});
This is my view
Ext.define('ExtApplication1.view.main.MainPortal', {
extend: 'Ext.panel.Panel',
xtype: 'mainportal',
alias: 'widget.mainportal',
id: 'mainportalID',
html: 'user... this is the main portal window',
autoScroll: true,
bodyPadding: 10,
items: [
gridSummary
]
});
adjusted panel
Ext.define('ExtApplication1.view.main.MainPortal', {
extend: 'Ext.panel.Panel',
xtype: 'mainportal',
alias: 'widget.mainportalAlias',
reference: 'gridtextfield',
//id: 'mainportalID',
html: 'user... this is the main portal window',
autoScroll: true,
bodyPadding: 10,
items: [
gridSummary
]
});
adjusted view controller
onComboboxSelect: function (combo, record, eOpts) {
console.log('new listener was hit');
//return selected Item
var selectedValue = record.get('ClientName');
var selectedCID = record.get('ClientID');
//find the grid that was created
var me = this;
console.log(me);
var xxx = this.lookupReference('gridtextfield');
debugger;
//debugger;
var mainPortalView = Ext.getCmp('mainportalID');
var targetGrid = mainPortalView.down('grid');
//find the store associated with that grid
var targetStore = targetGrid.getStore();
//load store
targetStore.load({
params: {
user: 'stephen',
pw: 'forero',
cid: selectedCID
}
//callback: function (records) {
// Ext.each(records, function (record) {
// console.log(record);
// });
// console.log(targetStore);
//}
});
},
added listeners to MainPortal.js
var myStore = Ext.create('ExtApplication1.store.PositionsStore');
var gridSummary = Ext.create('Ext.grid.Panel', {
store: myStore,
width: 600,
title: 'my first grid',
columns: [
{
text: 'AcctNum',
dataIndex: 'AcctNum',
width: 100
},
{
text: 'AcctShortCode',
dataIndex: 'AcctShortCode',
flex: 1
},
{
text: 'Exchange',
dataIndex: 'Exchange',
width: 200
}
],
listeners: {
destroy: function () {
debugger;
}
}
});
Ext.define('ExtApplication1.view.main.MainPortal', {
extend: 'Ext.panel.Panel',
xtype: 'mainportal',
alias: 'widget.mainportalAlias',
//id: 'mainportalID',
itemId: 'mainportalID',
html: 'user... this is the main portal window',
autoScroll: true,
bodyPadding: 10,
items: [
gridSummary
],
listeners: {
destroy: function () {
debugger;
}
}
});
I'm developing an application using Extjs-6. I extend a viewclass from a Ext.form.field.Picker as follow:
Ext.define('Fiddle.MyCombo', function(){
var me;
var initComponent = function()
{
me = this;
Ext.apply(me, {});
me.callParent(arguments);
};
var createPicker = function ()
{
var textfield = {
xtype: 'textfield',
width: '100%',
border: false,
listeners: {
change: function(component, newValue)
{
me.setStr(newValue);
}
}
};
var panel = new Ext.panel.Panel({
rtl: true,
minWidth: 300,
floating: true,
items: [textfield]
});
Ext.Msg.alert('Attension', 'Init Value is : ' + me.getStr());
return Ext.widget(panel);
};
return {
extend: 'Ext.form.field.Picker',
alias: 'widget.mycombo',
initComponent: initComponent,
createPicker: createPicker,
config: {
str: ''
}
};
});
I use this class as follow:
Ext.define('Fiddle.Main', {
extend: 'Ext.panel.Panel',
width: 400,
height: 200,
title: 'Its me!',
items: [{
xtype: 'mycombo',
name: 'item1'
}, {
xtype: 'mycombo',
name: 'item2'
}]
});
When I open first mycombo(item1) and type some word in textfield input, and then open second mycombo item(items2), in createPicker function I alert str value of item, and it show the item1's value.
Why it show item1's str value?
Where is wrong?
My Sample fiddle is here.
Can anyone tell me how I can keep the position of my scroll bar when my datastore reloads? Below is the code I have for the window/grid and refresh code. Everytime refreshActions executes the scroll bar scrolls to the top of the grid:
preserveScrollonRefresh does not work in this scenario
View
Ext.define('Tool.view.ActionView',{
extend: 'Ext.window.Window',
xtype: 'toolactions',
requires:[
'Tool.view.ActionController'
],
controller: 'actions',
viewModel: {},
layout: { type: 'border' },
closeAction: 'hide',
title: 'Actions',
store: 'Task',
width: 1500,
height: 800,
items: [{
id: 'ChangeLog',
xtype: 'grid',
selType: 'rowmodel',
split: true,
title: 'Log',
region: 'south',
width: 600,
height: 300,
bind: {store: '{tasks}'},
columns: {
defaults: {
width: 175
},
items: [
{ text: 'Script Command', dataIndex: 'command_script', flex: 1},
{ text: 'Output', dataIndex: 'command_output', width: 250, flex: 1 },
{ text: 'Status', dataIndex: 'state', width: 250, flex: 1 }]
},
bbar: ['->',{
xtype: 'button',
text: 'Refresh',
listeners: {
click: 'refreshActions'
}
}
]
}]
Refresh Code
refreshActions: function() {
var me = this;
this.currentRecord.tasks().load(function(records, operation, success) {
if(!operation.wasSuccessful()) {
var message = "Failed to load data from server.";
if(operation.hasException())
message = message + " " + operation.getError();
var app = Tool.getApplication();
app.toast(message,'error');
}
else {
me.configureButtons();
me.configureAutoRefresh();
}
});
}
Detect for Auto Refresh
configureAutoRefresh: function() {
var autoRefresh = false;
var maxId = this.getMaximumId(this.currentRecord.tasks());
var maxRecord = this.currentRecord.tasks().getById(maxId);
if(maxRecord.data.state=='1' || maxRecord.data.state=='0') {
autoRefresh = true;
}
if(autoRefresh == true) {
if(this.autoRefreshTask == null) {
var me = this;
var task =
{
run: function() {
me.refreshActions();
return true;
},
interval: 2000 // 2 seconds
};
this.autoRefreshTask = Ext.TaskManager.start(task);
}
}
else if(this.autoRefreshTask != null) {
Ext.TaskManager.stop(this.autoRefreshTask);
this.autoRefreshTask = null;
}
}
As I see it you have 2 options that not necessarily exclude each other:
If a grid row is selected:
Before the store reload get the selected record using getSelection() method and after the action is complete use the ensureVisible( record, [options] ) method to scroll that record into view.
If no row is selected:
Before the store reload get the current scroll position (I assume in your case is X) using the getScrollX() method and after the action is complete use setScrollX(x, [animate]) to get back to the previous scroll position.
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');
}
},