The table is refreshed regularly on the page, and each row in the table has details. When each row is refreshed, the Set Method of record is executed, and the details are disabled. It was strange at first. Because I always think that if I refresh a field in a row, it should only update the DOM of this field.
I checked it in the background.Source codeIt turns out that when each record data changes, a new Dom is actually generated. SourceCodeFirst Insert a new row, and then Delete and replace the row Dom of the old data.
Because the details belong to rows, the rows are re-generated after the set of record is executed each time, so the details will be deleted.
To solve the problem of not disabling details, we want to customize a replace method for record.
Its function is to use the record replace method to update a single field.
It seems very spatial, but in order to implement this function, many "Classes" of extjs are rewritten to implement it. The following code is used to implement this function,
It also provides a function to add the bubble prompt provided by extjs to the field value of the table.
Ext. onready (function (){
// To use the bubble prompt provided by extjs, add the following sentence:
Ext. quicktips. INIT ();
Ext. Override (ext. Grid. columnmodel ,{
// Based on the ID given when the column is defined, the rendering method of the column is obtained, in fact, to update a single cell, the display is consistent with the definition
Getrendererbyid: function (ID ){
Return this. getrenderer (this. getindexbyid (ID ));
}
});
// Step 4:
Ext. Data. Record. Replace = 'repalce '; // defines a record replacement command.
Ext. Override (ext. Data. Record ,{
// Method for replacing the value of a single Field
Replace: function (name, value ){
VaR encode = ext. isprimitive (value )? String: Ext. encode;
If (encode (this. Data [name]) = encode (value )){
Return;
}
This. Dirty = true;
If (! This. Modified ){
This. Modified = {};
}
If (this. Modified [name] === undefined ){
This. Modified [name] = This. Data [name];
}
This. Data [name] = value; // model update
This. afterreplace (name, value); // notify the gridview view update through store
},
// Notify the gridview view update method through store
Afterreplace: function (name, value ){
If (this. Store! = Undefined & typeof this. Store. afterreplace = "function "){
This. Store. afterreplace (this, name, value );
}
}
});
// Step 5:
Ext. Override (ext. Data. Store ,{
// The newly defined method for notifying the updated gridview View
Afterreplace: function (record, name, value ){
If (this. Modified. indexof (record) =-1 ){
This. Modified. Push (record );
}
// Update the Notification View
This. fireevent ('repalce ', record, name, value, ext. Data. Record. Replace );
}
}
);
VaR mydata = [
['3 M co', 71.72, 0.02, 0.03, '2017 am '],
['Alcoa inc', 29.01, 0.42, 1.47, '2017 am '],
['Altria group inc', 83.81, 0.28, 0.34, '2017 am ']
];
// Example of custom Renderer Function
Function Change (VAL ){
If (Val> 0 ){
Return '<span QTip = "' + Val + '" style = "color: green;">' + Val + '</span> ';
} Else if (Val <0 ){
Return '<span QTip = "' + Val + '" style = "color: red;">' + Val + '</span> ';
}
Return val;
}
// Use the bubble prompt provided by extjs
Function titleqtip (VAL) {freight expert
Return '<span QTip = "' + Val + '">' + Val + '</span> ';
}
// Example of custom Renderer Function
Function pctchange (VAL ){
If (Val> 0 ){
Return '<span style = "color: green;">' + Val + '% </span> ';
} Else if (Val <0 ){
Return '<span style = "color: red;">' + Val + '% </span> ';
}
Return val;
}
// Create the Data Store
VaR store = new Ext. Data. Store ({
Proxy: New Ext. UX. Data. pagingmemoryproxy (mydata ),
Remotesort: True,
Sortinfo: {field: 'price', direction: 'asc '},
Reader: New Ext. Data. arrayreader ({
Fields :[
{Name: 'company '},
{Name: 'price', type: 'float '},
{Name: 'change', type: 'float '},
{Name: 'pctchang', type: 'float '},
{Name: 'lastchang', type: 'date', dateformat: 'n'/j h: '}
]
})
});
Ext. Override (ext. Grid. gridview ,{
/// Step 7: implement the method of updating a single cell in the gridview
Onreplace: function (record, name, value ){
VaR DS = This. DS, index;
If (ext. isnumber (record )){
Index = record;
Record = Ds. getat (INDEX );
If (! Record ){
Return;
}
} Else {
Index = Ds. indexof (record );
If (index <0 ){
Return;
}
}
// Update a single Field
Document. getelementbyid (index + name). innerhtml = This. cm. getrendererbyid (name). Call (this, value );
},
// Step 6:
Initdata: function (DS, CM ){
If (this. DS ){
This. Ds. UN ('load', this. onload, this );
This. Ds. UN ('datachanged', this. ondatachange, this );
This. Ds. UN ('add', this. onadd, this );
This. Ds. UN ('delete', this. onremove, this );
This. Ds. UN ('update', this. onupdate, this );
This. Ds. UN ('clear', this. onclear, this );
// Discard this listener when the table is destroyed
This. Ds. UN ('repalce ', this. onreplace, this );
If (this. Ds! = DS & this. Ds. autodestroy ){
This. Ds. Destroy ();
}
}
If (DS ){
DS. On ({
Scope: This,
Load: This. onload,
Datachanged: This. ondatachange,
Add: This. onadd,
Remove: This. onremove,
Update: This. onupdate,
Clear: This. onclear,
// When the table loads the store, add the listener
Repalce: This. onreplace
});
}
This. DS = Ds;
If (this. cm ){
This. cm. UN ('configchang', this. oncolconfigchange, this );
This. cm. UN ('widthchang', this. oncolwidthchange, this );
This. cm. UN ('headerchang', this. onheaderchange, this );
This. cm. UN ('hiddenchang', this. onhiddenchange, this );
This. cm. UN ('columnmoved', this. oncolumnmove, this );
} Software Development
If (CM ){
Delete this. lastviewwidth;
Cm. On ({
Scope: This,
Configchange: This. oncolconfigchange,
Widthchange: This. oncolwidthchange,
Headerchange: This. onheaderchange,
Hiddenchange: This. onhiddenchange,
Columnmoved: This. oncolumnmove
});
}
This. CM = cm;
},
Dorender: function (columns, records, store, startrow, colcount, stripe ){
VaR templates = This. templates,
Celltemplate = templates. cell,
Rowtemplate = templates. Row,
Last = colcount-1;
VaR tstyle = 'width: '+ this. gettotalwidth () + ';';
// Buffers
VaR rowbuffer = [],
Colbuffer = [],
Rowparams = {tstyle: tstyle },
Meta = {},
Column,
Record;
// Build up each row's html
For (var j = 0, Len = records. length; j <Len; j ++ ){
Record = records [J];
Colbuffer = [];
VaR rowindex = J + startrow;
// Build up each column's html
For (VAR I = 0; I <colcount; I ++ ){
Column = columns [I];
Meta. ID = column. ID;
Meta.css = I === 0? 'X-grid3-cell-first ': (I = last? 'X-grid3-cell-last ':'');
Meta. ATTR = meta. cellattr = '';
Meta. Style = column. style;
Meta. value = column. Renderer. Call (column. Scope, record. Data [column. name], Meta, record, rowindex, I, store );
// Step 2: Define the ID of the DIV of this field. This is the key. Otherwise, we cannot find this Div through document. getelementbyid, so we cannot implement this function.
Meta. divid = J + column. Name;
If (ext. isempty (meta. Value )){
Meta. value = '& #160 ;';
}
If (this. markdirty & record. Dirty & Ext. isdefined (record. Modified [column. Name]) {
Meta.css + = 'x-grid3-dirty-cell ';
}
colbuffer [colbuffer. Length] = celltemplate. Apply (Meta);
}
// Set up row striping and row dirtiness CSS classes
VaR alt = [];
If (stripe & (rowindex + 1) % 2 = 0 )){
Alt [0] = 'x-grid3-row-alt ';
}
If (record. Dirty ){
Alt [1] = 'x-grid3-dirty-row ';
}
Rowparams. Cols = colcount;
If (this. getrowclass ){
Alt [2] = This. getrowclass (record, rowindex, rowparams, store );
}
Rowparams. Alt = alt. Join ('');
Rowparams. Cells = colbuffer. Join ('');
Rowbuffer [rowbuffer. Length] = rowtemplate. Apply (rowparams );
}
Return rowbuffer. Join ('');
}
});
VaR ts = {};
Ts. cell = new Ext. template ('<TD class = "x-grid3-col x-grid3-cell x-grid3-td-{ID} {CSS}" style = "{style}" tabindex = "0" {cellattr}> ',
// Step 1: this part was originally opened in the gridview, but it was found that there are too many code and it is unnecessary. You can simply add an ID attribute to the DIV here.
'<Div id = \' {divid} \ 'class = "x-grid3-cell-inner x-grid3-col-{ID}" unselectable = "on" {ATTR }>{ value} </div> ', '</TD> ');
// Create the grid
VaR grid = new Ext. Grid. gridpanel ({
Store: store,
// Step 3: note that this attribute is added.
Viewconfig :{
Templates: TS
},
Columns :[
{ID: 'company', header: "company", width: 160, sortable: True, Renderer: titleqtip, dataindex: 'company '},
{Header: "price", width: 75, sortable: True, Renderer: 'usmoney', dataindex: 'price '},
{ID: 'change', header: "change", width: 75, sortable: True, Renderer: Change, dataindex: 'change '},
{Header: "% change", width: 75, sortable: True, Renderer: pctchange, dataindex: 'pctchang '},
{Header: "Last updated", width: 85, sortable: True, Renderer: ext. util. format. daterenderer ('m/D/Y'), dataindex: 'lastchange '}
],
Striperows: True,
Autoexpandcolumn: 'company ',
Height: 320,
Width: 600,
Frame: True,
Title: 'sliding pager ',
ID: 'maingrid ',
Plugins: New Ext. UX. panelresizer ({
Min Height: 100
}),
Bbar: New Ext. pagingtoolbar ({
Pagesize: 10,
Store: store,
Displayinfo: True
})
});
Grid. Render ('grid-example ');
Store. Load ({Params: {start: 0, limit: 10 }});
// Alert (document. getelementbyid ('1pctchang'). innerhtml );
});
// Code for testing this function
Function Change (){
// Modify the value of the company field in Row 3
Ext. getcmp ('maingrid'). Store. getat (1). Replace ('company', 'ddddd ');
}