ExtJs 4 GridPanel with CellEditing: data entered is lost on failed validation - javascript

I am using a ExtJs Grid with the CellEditing plugin. It works perfectly except that invalid values are lost when it fails the validation I imposed on it.
For example, if I have a editable textfield in the grid that doesn't allow values over 10 characters, and the user enters "olympicssucks" the validation will fail and a red box will appear around the textfield. When the user clicks out of the field the value "olympicssucks" will be lost.
I want the grid to still save the invalid data, and keep the red box around it.
Another (maybe more clear) example:
http://dev.sencha.com/deploy/ext-4.0.0/examples/grid/cell-editing.html
Try editing the first cellvalue: "Adder's-Tongue" and make it empty. Notice the red box and validation message. Now click out of the box. The failed validation will revert the cell back to its original value, Adder's-Tongue.
tl;dr: My question, restated, is that I want to keep the invalid value, and yet still have validation displaying a red box around it. I'm sure its possible, but how is it done?
What I've tried:
I've looked into Ext.Editor and it seems promising because it has a config property called revertInvalid that does exactly what I want. Unfortunately, it seems that the CellEditing plugin does not seem to use Ext.Editor. I've tried providing a Ext.Editor into the Editor field of the grid column, but that produced un-editable text.
I've tried placing revertInvalid everywhere I could but this was always a far-shot.
Code:
var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
});
var grid = {
xtype: 'grid', store: dataStore, plugins: [cellEditing],
columns: [
{
text: 'Items', dataIndex: 'items', flex: 1, sortable : false,
editor: {
xtype: 'textfield',
validator: function(value) { //custom validator to return false when value is empty and other conditions}
},
//...
],
tbar: [{
xtype: 'button', text: 'Add ' + type,
handler: function() {
dataStore.insert(0, {items: 'New ' + type});
cellEditing.startEditByPosition({row: 0, column: 0});
}
}]
}

This worked for me (Extjs 4.2):
Ext.override(Ext.Editor, { revertInvalid: false });

It very may well be that Sencha has not yet fully developed the revertInvalid field, and that its simple functionality does not yet work. To those looking for a workaround, you may have to mess with the CSS of the grid cell itself to custom-mark it as invalid.

see http://www.sencha.com/forum/showthread.php?271318-Ext.Editor-revertInvalid-false-what-is-the-expected-behavior&p=994118#post994118
to me it is a bug in ExtJs that you can fix by overriding the completeEdit function of Ext.editor

Related

Ext JS Grid Filters in Header checkbox not working

I am trying to implement filtering in my grid.Panel component. The filtering works fine (date, string and numbers) but I can not uncheck the "Filters" checkbox by clicking on it. As far as I have seen in the Ext js documentation there is nothing that I should add extra to be able to uncheck the Filters checkbox (see image below)
When I click on the Filters checkbox, nothing happens, no error also. The only way to disable this particular "Wholesaler" filter is if I go to the text box and remove the entry. This of course would be just fine, but at the date filters, I also can not click the checkbox and thus can not remove the filter once applied (see image below) The only way to remove it is to refresh the page.
I am using Ext JS version 5.1.2, and here is the sample code:
{
dataIndex: 'Wholesaler',
text: 'Wholesaler',
filter: {
type: 'string'
},
}
And the Panel componenet itself:
Ext.apply(this, {
region: 'center',
api: new Dextop.api('sample'),
border: false,
plugins: 'gridfilters',
columns: sample.getController().getGridColumns(),
storeOptions: {
autoLoad: false
}
});
Any help is appreciated!

I'm struggling to determine what dropdown element is selected

I am trying to display input fields when the user selects a certain element from the dropdown component. I tried to do this by adding an eventListener onto the dropdown component but this does not seem to work.
When I inspect the page and go to sources -> event listener breakpoint I see that it detects the mouse click event but when I try to add an eventListener I get the following error "Cannot read property 'addEventListener' of null". This is the code for the dropdown component:
{
PlaceHSolder: "",
Fields:[{
Name:"The color of the car",
Label: 'The color of the car',
Type:'Lookup',
Fields: ['id', 'color'],
FieldValues:[
{"id":"1", "color":"red",id: '1red'},
{"id":"2", "color":"blue",id: '2blue'},
{"id":"3", "color":"green",id: '3green'}
],
LabelField: 'color',
ValueField: 'id',
IsSingle: true,
triggerAction: 'all' ,
queryParam: 'q',
queryMode: 'remote',
listeners: {
select: function () {
console.log( this.getValue());
}
},
renderTo: document.body
}],
Required: false
}
I am unsure as to what exactly is wrong in my code as I am relatively new. To give a more clear explanation of what I want to do, here is a picture:
https://imgur.com/KVDh2Xp
In this picture I have a dropdown component where I want to select the blue element. After that I am planning to let go the dropdown and show various other labels and components depending on which text the user selects.
Using the inspection tool in Google Chrome shows me the following error:
https://imgur.com/a/SzSIKxr
Any help would be appreciated. Thanks.

KendoUI Grid: How to programmatically make a specific column non editable

I want to make a KendoUI Grid column programmatically non editable.
The information which column should be non editable, I will get after the grid was created and filled with data in my application. Thats why I have to set it programmatically.
First I created the grid on this way:
var dataSource = new kendo.data.DataSource({
schema: {
model: {
fields: {
field1: {
editable: true,
},
field2: {
editable: true,
}
}
}
}
});
$(domNode).kendoGrid({
editable: true,
dataSource: dataSource,
columns: [{
field: 'field1',
title: 'First column'
},
{
field: 'field2',
title: 'Second column'
}
]
});
Then I add some data (I know its not realy necessary to show this here):
var grid = $(domNode).data('kendoGrid');
grid.dataSource.add({
field1: 'Some value',
field2: 'Some other value'
});
Later in my application, I will get the information which column should be non editable. Then I've tried the following:
grid.dataSource.options.schema.model.fields['field1'].editable = false;
grid.dataSource.read(); // No changes, cloumn is still editable
grid.refresh(); // No changes, cloumn is still editable
grid.setDataSouce(grid.dataSouce); // No changes, cloumn is still editable
I'm desperately. Whats the correct way to porogrammaticly make a column non editable?
I would suggest two approaches:
Define an editor function for each field and when invoked decide on how to render it it if should be an input or a plain div / span. This might be a lot of work since you need to repeat this for each field that can be both editable and not editable depending on that information that you receive latter.
Whenever you receive the information about which fields are editable, create a new grid that contains the actual information about which fields are editable and which ones are not. You might opt for destroying the previous grid definition or just hide it and make the new one visible in the same place.
Unless there are just a few fields which might be editable or not, I would go with the second approach.

DGrid - Single Selection Mode while using Drag and Drop -> Results in multiple selections

I am trying to get a DGrid working using the following properties:
Drag and Drop
Single Selection
Unfortionatly, this doesn't work quite as easily as I was hoping. I am declaring my DGrid like this:
this._grid = new (declare([OnDemandGrid, DijitRegistry, Selection, DnDGrid]))({
store: this.store,
columns: [
{label: "ID", field:"id", sortable: false},
...
],
touchesToScroll: 2, // Required to enable d&d on mobile
dndSourceType: "grid-row",
getObjectDndType: function(item){
return [item.type ? item.type : this.dndSourceType];
},
selectionMode: "single"
}, this.gridDiv);
this._grid.startup();
For the most part this works well. DnD is working. Selection is mostly working. There is just some strange state on occasion. These are the cases:
Shift Select:
If I perform a shift select then I will get multiple items looking as if they are selected. They will have the following css classes attached to them:
.claro .dojoDndItemAnchor, .claro .dojoDndItemSelected { ... }
When listening to the dgrid-select event, it reports the selected elements correctly.
Attempting to drag the selected elements also works correctly -> only one of them is moved.
Edit: I have found a solution to the Shift Select issue. It is posted as answer below. I still haven't been able to figure out the next issue.
Programmatic Deselect:
If I do the following:
Select an item
Programmaticlly deselect all: this._grid.clearSelection();
Programmatically select another item: this._grid.select(row);
Leaves two items looking selected.
The two items have different styles. The incorrect one has:
.claro .dojoDndItemAnchor, .claro .dojoDndItemSelected { ... }
The correct one has:
.dgrid-selected
As before, when listening to the dgrid-select event, it reports the selected elements correctly.
It seems like this is the default dojo DnD moduel that is causing me issues. Looking at the doc it seems like I need to do something with the selector. Selector has a property called singular but I haven't been able to figure out how/where to set this.
Info on singular: https://dojotoolkit.org/reference-guide/1.9/dojo/dnd.html#id2
RE programmatic deselect, I think you've found a legit dgrid bug. I took a quick look at this and issued a pull request. See if that changeset resolves the issue for you.
It is possible to prevent Shift Select the multiple selection issue by using the dndParams field.
Instantiating the grid like this will solve the issue:
this._grid = new (declare([OnDemandGrid, DijitRegistry, Selection, DnDGrid]))({
store: this.store,
columns: [
{label: "ID", field:"id", sortable: false},
...
],
touchesToScroll: 2, // Required to enable d&d on mobile
dndSourceType: "grid-row",
getObjectDndType: function(item){
return [item.type ? item.type : this.dndSourceType];
},
selectionMode: "single",
dndParams:{singular: true} // ADDED THIS.
}, this.gridDiv);
this._grid.startup();
Still haven't figured out how to deal with programmatic changes.

Kendo UI: Not able to add footerTemplate to grid

I am trying to display the count of the field in the footerTemplate.
Follow is the fiddle:
http://jsbin.com/ajoyug/8/edit
However, without the footerTemplate it works fine. But as soon as I add the footerTemplate, it stops working.
Inside the aggregateResult object I am getting the value of count. But then how shall I add it to the footerTemplate?
Kindly help me out.
Thanks!!
The problem is with your approach the grid is rendered twice, the first time on Kendo UI initialization (implicit during the first bind) and the second when you bind the actual data.
The first time the data is still not available and then it fails.
If anyway you want to follow that path you should do:
<div id="myListView" data-role="grid" class="transaction-grid"
data-columns="[
{ field: 'name', title: 'Name', width:'20%' },
{
field: 'age',
title: 'Age' ,
width:'35%',
footerTemplate: 'Total Count: # if (data.age) { # #= age.count # # } #'
}
]"
data-bind="source: dataSource">
</div>
i.e. check if data.age is available and then is when you print it.
Otherwise, I recommend following #UmankantPatil suggestion and do not use data-* but JavaScript for initializing the widgets and binding data.
Check it in the modified version of your JSBin here
I could not explain why it's not working. But I have tried doing your example by other way and it works well.
Here goes the link.
http://jsbin.com/ajoyug/35/edit

Categories