I've an MVC panel with a combobox and I'would remove some elements from the combobox after his store (local or remote) has completed to load.
the combo is declared in the view of this panel as follow:
{
xtype:'combo',
name: 'type',
editable: false,
//a local simple store with two field: 'valueType' and 'text'
store : Ext.create('AM.store.custompropview.propertyType'),
valueField : 'valueType',
fieldLabel: 'combo'
}
I've tried in the controller to control the event 'afterrender' or 'boxready' and in the function to remove some element from the store, but it don't work at all.
'combo[name="type"]' : {
boxready:function(th, width, height, eOpts ){
th.store.removeAt(0);
th.store.removeAt(0);
th.store.removeAt(0);
}
How i can do it?
thank you
I think you should remove your item after store is loaded not just after your combo is rendered so you can code this in controller's init function:
Ext.getStore('AM.store.custompropview.propertyType').on('load', function(store){
store.removeAt(0);
});
Related
I have the ExtJs form combo which shows the values in the dropdown as checkbox and the value to select. I have used the pagination to list all the values with no of pages. I need the selected value to be retained in the current page even when we move to next or previous page and comes back to the same page(without selecting any thing in prev, next pages).
Code:
Ext.create('Ext.form.ComboBox', {
id: 'ageComboPickerReport',
name: 'ageComboPickerReport',
maxHeight: 150,
margin: '0 5 0 0',
width: 150,
emptyText: "Select tags",
listConfig: {
getInnerTpl: function (displayField) {
return '<div class="x-combo-list-item"><img src="" class="chkCombo-default-icon
chkCombo" /> {' + displayField + '}</div>';
},
autoEl: { 'q-name': 'rpt-age-criteria-list'
}, labelAlign: 'top',
pageSize: 25,
displayField: 'age', valueField: 'id', forceSelection: true, store: me.ageStore,
//Disable Typing and Open Combo
onFocus: function () {
if (!this.isExpanded) {
me.ageStore.load()
this.expand()
} this.getPicker().focus();
}
}),
Could any one tell me how to retain the selected value in the page when move to other page and comes back
I faced a very similar issue, in my case I had a grid with checkbox selection model, and I wanted to retain the selected rows during moving between pages. I am quite sure (although not 100%) that there is no built-in functionality for that in ExtJS. I can tell what I did, hope it helps, although you have to adopt it because it is not for ComboBox, but for Grid.
Since this is a paged store, not all of the records are loaded, only the ones that are currently on the displayed page. (I assume your store is remote because I see you call load on it.) So to achieve what you like, you need to:
keep track of the selected record ids to be able the reset selection on page,
keep track the items (records) themselves as well, since you will likely need them,
after a page is loaded and displayed, set the selection accordingly.
(This solution can have issues, so you need to be careful. Depending on the use case, it is possible for example that the user selects something, goes to another page and come back, but the previously selected row is no more available (it was deleted by someone else). You have to consider whether it affects you.)
The complete code is complicated and not general enough to share it, but I can outline the steps I did:
Set up two data entries in viewmodel to track the selected record ids and items (records):
data: {
multiSelection: {
ids: {},
items: [],
},
}
Add listeners to the grid's select and deselect events in the view:
listeners: {
select: 'onGridSelect',
deselect: 'onGridDeselect',
},
Create onGridSelect and onGridDeselect functions in the controller, and also add a isDataChanged variable to the controller to indicate whether the store was changed (it is changed on each paging). It is important because I will programatically change the selection, and I don't want my listeners to be executed in this case, only when the user interacts. Like this:
isDataChanged: false,
onGridSelect: function(selModel, record, index, eOpts) {
if (isDataChanged) {
return;
}
const viewModel = this.getViewModel(),
multiSelection = viewModel.get('multiSelection');
multiSelection.ids[record.getId()] = true;
Ext.Array.push(multiSelection.items, record);
},
onGridDeselect: function(selModel, record, index, eOpts) {
if (isDataChanged) {
return;
}
const viewModel = this.getViewModel(),
multiSelection = viewModel.get('multiSelection');
delete multiSelection.ids[record.getId()];
Ext.Array.remove(multiSelection.items, record);
},
Finally, add a listeners to the store to detect changes, this will be called every time the user moves between pages. This is a little tricky, because I need to access the grid from the store listeners which is not very ExtJS like, but I had to (store needs to be the grid's store:
store.on('datachanged', function(store, eOpts) {
// this part you have to figure out, my solution is way too specific
// for share
const grid = ...;
// this was important for me, if the store is really changed,
// deleted, added rows etc., I deleted the selection, but
// you can consider it
if (store.getUpdatedRecords().length > 0 ||
store.getRemovedRecords().length > 0 ||
store.getNewRecords().length > 0) {
// access the `viewmodel` and reset `multiSelection` data entries to
// default, I `return` here to skip the rest
return;
}
// disable listener
grid.getController().isDataChanged = true;
const selModel = grid.getSelectionModel(),
multiSelection = grid.getViewModel().get('multiSelection');
// deselect everything
selModel.deselectAll();
// get an array of the saved selection and find out, which
// record from the current page is in the saved multiSelection
const selected = [];
Ext.Array.each(grid.getStore().getRange(), function(record) {
if (multiSelection.ids[record.getId()]) {
Ext.Array.push(selected, record);
}
});
// apply selection to current page
selModel.select(selected);
// enable listener
grid.getController().isDataChanged = false;
}
I am trying to create a filefield as a button with an icon. It seems in the documentation that this is not supported in modern 6.2.0. Is there a way?
Link to Docs: http://docs.sencha.com/extjs/6.2.0/modern/Ext.field.File.html
There also doesn't seem to be a way to change the text in the default button or text accompanying it.
there is a good solution for that:
{
xtype : 'button',
text : 'add a file',
handler : 'onAddFile'
},
and then in the controller:
onAddfile: function() {
var me = this;
var fileupload = Ext.create('Ext.form.Panel', {
// renderTo: Ext.getBody(),
title : 'Upload Panel',
height : 0,
width : 0,
items : [ {
xtype : 'filefield',
label : 'any thing',
accept: 'application/zip',//or mediatypes that you want
multiple : false,//or true if you need
controller : me,
listeners : {
change : function(field) {
me.fileSelected(field);
}
}
} ]
});
//this is important to click programmaticallly
fileupload.element.dom.querySelector('.x-button-el').click();
},
fileSelected: function (field) {
let files = field.getFiles();
// now you have the files
}
Thats it...
That is by design.
The file input's text is browser defined and not meant to be changed by the developer.
Usually people work around that by generating a display:hidden file input and a generic button which triggers the file input via JS.
I fear you'll have to divert to similar measures in ExtJS.
For reference here's a discussion on SO about how to change the label of the plain-old HTML file input element: Labeling file upload button
I have two kendo grids (A, B) ...B its loaded by clicking in A and the its data source its loaded by a property of selected row in A ..
A.accounts
dataSource: {
data: this.gridA.dataItem(this.gridA.select()),
},
My problem its that in B I have to change a property using the grid, but when the property its changed the grid its reloaded and if i have 1000 rows when I change the property in the grid (anyrow, 999 i.e), the scroll back to the beginning
...I have read and try to understand it, but a can't fix it... according to the official documentation, the row selected by
var row = this.gridApprovals.select();
var caBean = this.gridApprovals.dataItem(row);
Its a ObservableObject, so, when I try to change a property, some method (of ObservableOject) it's making this behaviour, and the grid its reloaded, its iterating every data source item...
EDITED:
I forgot to mention.. its important keep the relation between the changes of the B grid and its relation in A slection..
Here is a Dojo Project http://dojo.telerik.com/uYemI/2
How about this?
http://dojo.telerik.com/#Stephen/aNije
I removed the k-rebind attribute and instead wire up the dataSource inside your setCarsGrid() method:
$scope.setCarsGrid = function() {
var row = this.brandGrid.select();
var brand = this.brandGrid.dataItem(row);
var brandObj=brand.toJSON();
var dataSource = new kendo.data.DataSource({
data: brand.cars,
schema:{
model:{
fields:{
id:{editable:false},
model:{editable:false},
color:{type:"string"}
}
},
parse: function(response) {
$.each(response, function(idx, elem) {
elem.id = elem.id+10;
//if you put a break point here, every time you try to edit 'color' field.. will be stop because datasourse is iterated again
console.log("Grid has been reloaded and the editable field 'color' can be edited :'( the id property has been added +10")
});
return response;
}
}
});
// This first time this is called, the carsGrid has not been initialized, so it doesn't exist.
// But subsequent times, we just need to set the new datasource.
if (this.carsGrid) {
this.carsGrid.setDataSource(dataSource);
}
$scope.carsGridOptions = {
dataSource: dataSource,
selectable:true,
editable: true,
columns: [{
field: "id",
},{
field: "model",
},{
field: "color",
}]
};
}
Essentially, I am just separating initialization of the GRID from the setting of the grid's DATASOURCE.
The first time through, you set up the grid options AND set the dataSource and then subsequent times through, we just set the grid to the new dataSource.
This avoids the k-rebind behaviour...which I believe is documented: http://docs.telerik.com/kendo-ui/AngularJS/introduction#widget-update-upon-option-changes
This approach is not suitable for dataBound widgets because those widgets are recreated on each change of their data—for example, after paging of the Grid.
Note, I don't really know angular so there may be a better way to organize this code, but it works.
I'm facing a problem in using UI-GRId with row selection and custom cell elements:
The sample plunker is here : http://plnkr.co/edit/Ed6s6CGFGXyUzj2cyx2g?p=preview
$scope.gridOptions = { showGridFooter:true,enableRowSelection: true, enableRowHeaderSelection: false };
$scope.gridOptions.columnDefs = [
{ name: 'id' },
{ name: 'name'},
{ name: 'age', displayName: 'Age (not focusable)', allowCellFocus : false },
{ name: 'address.city' },
{ name:'address.pin',cellTemplate:'<select><option value="122002">122002</option><option value="122001">122001</option></select>'}];
You can see that on row click, the respective row gets selected, while if you tend to select the dropdown options implicitly the row selection event also gets fired, I want that on elements click like dropdown here the row selection event should not be triggered.
Pls guide.
Interesting question, haven't run into it yet, but I am sure it's only time before I do. I've created a plunk to demonstrate my solution.
Basically, what I have do is registered a watcher, as mentioned by AranS. From there, we have two objects to work with: the row, and the event that occured. Since the event object discloses which element was selected (clicked), we can identify if it was a DIV, or something else. In the event of the change in the select list, the value of evt.srcElement.tagName is 'SELECT'.
http://plnkr.co/edit/k2XhHr2QaD1sA5y2hcFd?p=preview
$scope.gridOptions.onRegisterApi = function( gridApi ) {
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope,function(row,evt){
if (evt)
row.isSelected = (evt.srcElement.tagName === 'DIV');
});
};
ui-grid's API allows controlling row selection. Look at this answer from another thread: https://stackoverflow.com/a/33788459/5954939. Basically you can use the event rowSelectionChanged or the isRowSelectable. Let me know if you need an example.
There are scenarios when I have to change some configuration properties of Ext Js components after render. In Api documentation, I don't see getters/setters for most of the configs. Is there any way to change configuration and then re-render component or Update layout?
In the following code I need to change collapsible property to true or false dynamically after the Ext.form.FieldSet is rendered:
var container = Ext.create("Ext.container.Container", {
renderTo: Ext.getBody(),
layout: {
type: "vbox"
}
});
var fieldset = Ext.create("Ext.form.FieldSet", {
renderTo: "fieldset"
});
var text = Ext.create("Ext.form.field.Text", {
renderTo: "text"
});
var button = Ext.create("Ext.Button", {
renderTo: "button",
text: "My Button"
});
fieldset.add(text);
fieldset.add(button);
container.add(fieldset);
Also the below code does not update layout:
Ext.apply(fieldset,{collapsible:true,style:"bakground:red"});
http://jsfiddle.net/2nyhE/
fld.titleCmp.el.on({
'click': fld.toggle,
scope: fld
});
fld.titleCmp.el.addCls(me.baseCls + '-header-text-collapsible');
fld.legend.items.add(fld.createToggleCmp());
fld.legend.updateLayout();
http://jsbin.com/IFUZut/1/
there is methods collapse and expand which you could call on your field set to collapse or expand it.
You can try this. Set an id property for the desired fieldset (id:'anyId') and use Ext.apply(Ext.getCmp('anyId'), {your config object});
Ext.applay documentation
You can see this post
And also you can read about what is the difference between Ext.apply and simple javascript parameter adding here.