Disable Checbox in Ext Js checkbox model - javascript

I have grid with checkboxmodel , As per my requirement I have to disable some checkbox in checkbox model and restrict user to select that row. I am able to achieve below code.
viewConfig: {
getRowClass: function (record, rowIndex, rowParams, store) {
return record.data.name == 'Lisa' ? 'bg' : "";
}
},
listeners: {
beforeselect: function ( test , record , index , eOpts ) {
return record.data.name == "Lisa" ? false : true;
}
}
above configs are used in grid and below is my css
.bg .x-grid-cell-row-checker{
background-color: grey;
pointer-events: none;
opacity: 0.4;
}
Everythings work fine only one issue is header checkbox is not working i.e not able deselectAll from header and able to select but not getting checked
Here is my working fiddle
Ext js version 5

Expanding on And-y's answer, I would construct my own class and do something like in this Fiddle. I did add a few things, like the isDisabled flag in the model, but I don't see that as a bad thing, and it greatly helps out with deciding how to show the checkbox/fixing the Check All checkbox logic.
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('MySelectionModel', {
extend: 'Ext.selection.CheckboxModel',
alias: 'selection.mySelectionModel',
// default
disableFieldName: 'isDisabled',
listeners: {
beforeselect: function (test, record, index, eOpts) {
return !record.get(this.disableFieldName);
}
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
if (record.get(this.disableFieldName)) {
metaData.tdCls = 'bg';
}
else {
return this.callParent(arguments);
}
},
updateHeaderState: function () {
// check to see if all records are selected
var me = this,
store = me.store,
storeCount = store.getCount(),
views = me.views,
hdSelectStatus = false,
selectedCount = 0,
selected, len;
var disableFieldName = me.disableFieldName;
if (!store.isBufferedStore && storeCount > 0) {
selected = me.selected;
hdSelectStatus = true;
// loop over all records
for (var i = 0, j = 0; i < storeCount; i++) {
var rec = store.getAt(i);
var selectedRec = selected.getAt(j);
// Check selection collection for current record
if (selectedRec && selected.indexOf(rec) > -1) {
++selectedCount;
// Increment selection counter
j++;
}
// Otherwise, automatically consider disabled as part of selection
else if (rec.get(disableFieldName)) {
++selectedCount;
}
}
hdSelectStatus = storeCount === selectedCount;
}
if (views && views.length) {
me.toggleUiHeader(hdSelectStatus);
}
}
});
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone', 'isDisabled'],
data: {
'items': [{
'name': 'Lisa',
isDisabled: true,
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "homer#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
},
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
selModel: {
selType: "mySelectionModel",
showHeaderCheckbox: true,
mode: 'MULTI',
allowDeselect: true,
toggleOnClick: false,
checkOnly: false
},
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
}
});

The problem occurs in the function updateHeaderState of the Ext.selection.CheckboxModel.
The function checks if all checkboxes are selected by hdSelectStatus = storeCount === selectedCount;. In your case selectedCount is not matching the storeCount and the state of the header checkbox is not updated.
You could extend the Ext.selection.CheckboxModel and override the updateHeaderState function to fit your needs.

Related

Extjs Catch pick event (combobox)

Using ExtJS 4.2.3. I have FORM with combobox field and some values inside on choose. I need to catch event when user pick 1 of the value in combobox.
Asking for help with syntax, as example to get ALERT on picking DATA3 value.
Name of combobox field - "document_type".
Example of code on ExtJS:
documentForm_window = Ext.create("Ext.window.Window", {
title: (document_GUID == null) ? "[Create]" : "[Edit]",
width: 500,
modal: true,
layout: "fit",
items: [{
xtype: "form",
frame: true,
waitMsgTarget: true,
listeners: {
afterrender: function (form) {
if (document_GUID != null) {
form.getForm().load({
url: Ext.state.Manager.get("MVC_url") + "/Document/Get",
method: "GET",
params: { document_GUID: document_GUID },
waitMsg: "[loading]",
timeout: 300,
failure: function (form, action) {
if (action.result) Ext.Msg.alert("[Error1]!", action.result.errorMessage);
else Ext.Msg.alert("[Error2]!", "[Error3]!");
}
});
}
}
},
defaults: {
anchor: "100%",
msgTarget: "side",
labelWidth: 145,
allowBlank: false
},
items: [{
xtype: "combo",
name: "document_type",
fieldLabel: "<b>[Type]<font color='Red'>*</font></b>",
displayField: "document_type_name",
valueField: "document_type",
queryMode: "local",
triggerAction: "all",
editable: false,
store: document_store
}, {
xtype: "textfield",
name: "contract_number",
fieldLabel: "<b>[TestData]</b>"
}],
formBind: true,
buttons: [{
text: (document_GUID == null) ? "[Create]" : "[Edit]",
handler: function () {
var action = (document_GUID == null) ? "Create" : "Edit";
var form = this.up("form").getForm();
if (form.isValid()) {
form.submit({
url: Ext.state.Manager.get("MVC_url") + "/Document/" + action,
params: { document_GUID: document_GUID, treasury_GUID: tree_value },
waitMsg: "[Loading...]",
success: function (form, action) {
documentForm_window.destroy();
OrderLines_store.load({
scope: this,
callback: function (records, operation, success) {
documents_List.query('*[itemId="DATA1_grid"]')[0].selModel.select(curr_position);
}
});
},
failure: function (form, action) {
if (action.result) Ext.Msg.alert("[Error1]!", action.result.msg);
else Ext.Msg.alert("[Error2]!", "[Error3]!");
}
});
}
}
}]
}]
}).show();
}
//store//
document_store = new Ext.data.ArrayStore({
fields: ["document_type", "document_type_name"],
data: [[0, "data1"], [1, "data2"], [2, "data3"]]
});
Sorry, part of code I add as screen cause of post error "It looks like your post is mostly code".
You have to add a listener for the select event to the combobox:
editable: false,
store: document_store,
listeners: {
select: function(combo, records) {
console.log(combo);
console.log(records);
if(!Ext.isArray(records)) records = [records];
Ext.each(records, function(record) {
if(record.get(combo.valueField)==3) {
Ext.Msg.alert('Value is 3 for' + record.get(combo.displayField));
}
});
}
}

how can i get array data source, kendo-grid?

I'm getting array of properties and I want to show all of them in grid.
How to do it? Is it possible?
This is my code:
function StartBuild(ProfileProperties) {
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
$(document).ready(function () {
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
$("#grid").kendoGrid({
dataSource: datasource,
pegable: true,
sortable: {
mode: "single",
allowUnsort: false
},
columns: [{
field: "name",
title: "name",
filterable: {
cell: {
enabled:true
}
}
}, {//[Bild, nameP, email,phonework, Mobile, ManagerName]
field: "email",
title: "email"
}, {
field: "phoneWork",
title: "phoneWork"
}, {
field: "Mobile",
title: "Mobile"
}, {
field: "Manager",
title: "Manager"
}],
filterable: {
mode: "row"
},
});
});
}
Only if I write details[0] it shows the first properties otherwise it doesn't show anything.
It looks like there are a couple of problems.
http://dojo.telerik.com/#Stephen/uVOjAk
First, the transport setup is incorrect. pageSize, batch, and schema are not part of the transport configuration...you need to take them out of the transport block and just have them in the datasource block.
You want:
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
}
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
});
Instead of(what you have):
var datasource = new kendo.data.DataSource({
transport: {
type:"odata",
read: function (e) {
e.success(details);
},
pageSize: 10,
batch: false,
schema: {
model: {
fields: {
name: { editable: false },
Fname: { editable: false }
}
}
}
}
});
Second, the details needs to be an array of objects, not an array of an array of an object.
You want:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details.push({ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] });
}
Instead of:
var details = [];
for (i = 0; i < ProfileProperties.length; i++) {
details[i]=[{ name: ProfileProperties[i][0], email: ProfileProperties[i][1], phoneWork: ProfileProperties[i][2], Mobile: ProfileProperties[i][3], ManagerName: ProfileProperties[i][4] }];
}
Two other issues that are not directly causing a problem, but are incorrect are:
Your dataSource.schema configuration does not match your actual data at all. The schema really needs to match the fields of the actual data otherwise it cannot match up the configuration.
You spelled "pageable" wrong in the grid configuration.

Get Extjs grid on which context menu item is clicked

I have a Grid and on grid context menu I am calling one function as follows-
On grids context menu I have added the following item
{ text: 'Preview', handler: 'PreviewGrid', scope: cnt, };
In controller-
previewGrid: function (contextMenuItem) {
// Here I am getting the item i.e. contextmenu item.
// But I want here is grid on which there was right click
}
I tried using item.ownerCt.up('grid')
but it is not working.
Any help will be appreciated.
Sample code: https://fiddle.sencha.com/#fiddle/1i9o
Ext.application({
name: 'Fiddle',
launch: function() {
var grid = Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
width: 400,
height: 500,
title: 'itemcontextmenu',
store: {
fields: ['name', 'email', 'phone'],
data: [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "homer#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": ""
}]
},
columns: [{
text: 'Name',
dataIndex: 'name',
flex: 1
}]
});
var contextMenu = Ext.create('Ext.menu.Menu', {
width: 200,
items: [{
text: 'Preview',
handler: function() {
var record = grid ? grid.getSelection()[0] : null;
if (!record) {
return;
}
alert(record.get('name'));
}
}]
});
grid.on("itemcontextmenu", function(grid, record, item, index, e) {
e.stopEvent();
contextMenu.showAt(e.getXY());
});
}
});
This works for me.
In grid listeners:
listeners: {
itemcontextmenu: function (grid, record, item, index, e) {
var contextMenu = Ext.create('Ext.menu.Menu', {
height: 200,
width: 250,
items: [{
text:'Preview',
handler: function () {
//code...
}
}]
});
e.stopEvent();
contextMenu.showAt(e.getXY());
}
}

Kendo UI grid comboBox undefined on focus out?

I have working on Keno UI grid and I have added a comboBox as a column in the grid which also supports autocomplete feature. Apparently, comboBox is working fine but when I type half of world and focus out of the comboBox cell then it shows undefined. I have tried to handle it on combobox change event, but it is still showing undefined value? Below is my code for combobox and grid.
function productDropDownEditor(container, options) {
$('<input id="ProductDropDown" style="width:250px;" data-bind="value:' + options.field + '"/>')
.appendTo(container).kendoComboBox({
dataSource: dataSource,
autoBind: false,
dataTextField: 'ProductName',
dataValueField: 'ProductID',
filter: "contains",
suggest: true,
index: 3,
change: function (e) {
debugger;
var cmb = this;
// selectedIndex of -1 indicates custom value
if (cmb.selectedIndex < 0) {
cmb.value(0); // or set to the first item in combobox
}
},
close: function (e) {
debugger;
var cmb = this;
}
});
And here is following code for kendo grid.
$(function () {
$("#grid").kendoGrid({
columns: [
{
field: "Products", width: "250px",
editor: productDropDownEditor,
title: "Product",
template: "#=Products.ProductName#",
attributes: {
"class": "select2_single"
}
},
{ field: "PurchasePrice", width: "150px" },
{ field: "PurchaseQuantity", width: "150px" },
{ field: "SaleRate", title: "Sale Rate", width: "150px" },
{ field: "Amount", title: "Amount", width: "150px" },
{ command: "destroy", title: "Delete", width: "110px" },
],
editable: true, // enable editing
pageable: true,
navigatable: true,
sortable: true,
editable: "incell",
toolbar: ["create"], // specify toolbar commands
edit: function (e) {
//debugger;
//// var parentItem = parentGrid.dataSource.get(e.model.PurchaseID);
////e.model.set("ShipCountry", parentItem.Country);
//if (e.model.isNew()) {
// // set the value of the model property like this
// e.model.set("PropertyName", Value);
// // for setting all fields, you can loop on
// // the grid columns names and set the field
//}
},
//editable: "inline",
dataSource: {
serverPaging: true,
requestStart: function () {
kendo.ui.progress($("#loading"), true);
},
requestEnd: function () {
kendo.ui.progress($("#loading"), false);
},
serverFiltering: true,
serverSorting: true,
batch: true,
pageSize: 3,
schema: {
data: "data",
total: "Total",
model: { // define the model of the data source. Required for validation and property types.
id: "Id",
fields: {
PurchaseID: { editable: false, nullable: true },
PurchasePrice: { nullable: true },
PurchaseQuantity: { validation: { required: true, min: 1 } },
SaleRate: { validation: { required: true, min: 1 } },
Amount: { type: "number", editable: false },
Products: {
nullable: false,
validation: { required: true},
defaultValue: {ProductID:1, ProductName:"Googo" },
//from: "Products.ProductName",
parse: function (data) {
debugger;
if (data == null) {
data = { ProductID: 1};
}
return data;
},
type: "object"
}
}
}
},
batch: true, // enable batch editing - changes will be saved when the user clicks the "Save changes" button
change: function (e) {
debugger;
if (e.action === "itemchange" && e.field !== "Amount") {
var model = e.items[0],
type = model.Type,
currentValue = model.PurchasePrice * model.PurchaseQuantity;//formulas[type](model);
if (currentValue !== model.Amount) {
model.Amount = currentValue;
$("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(4)").text(currentValue);
}
//if (e.field == "Products") {
// $("#grid").find("tr[data-uid='" + model.uid + "'] td:eq(0)").text(model.Products);
//}
}
},
transport: {
read: {
url: "#Url.Action("Read", "Purchase")", //specify the URL which should return the records. This is the Read method of the HomeController.
contentType: "application/json",
type: "POST", //use HTTP POST request as by default GET is not allowed by ASP.NET MVC
},
parameterMap: function (data, operation) {
debugger;
if (operation != "read") {
// post the products so the ASP.NET DefaultModelBinder will understand them:
// data.models[0].ProductID = data.models[0].Product.ProductID;
var result = {};
// data.models[0].ProductID = $("#ProductDropDown").val();
for (var i = 0; i < data.models.length; i++) {
var purchase = data.models[i];
for (var member in purchase) {
result["purchaseDetail[" + i + "]." + member] = purchase[member];
}
}
return result;
} else {
var purchaseID = $("#hdnPurchaseId").val();
//output = '{ purchaseID: ' + purchaseID + '}';
data.purchaseID = purchaseID; // Got value from MVC view model.
return JSON.stringify(data)
}
}
}
},
}).data("kendoGrid");

How to filter ExtJs GridPanel/ExtJs Store?

I'm new to ExtJs. I have a GridPanel which is binded with a data store. I have a checkboxgroup, which containts the possible values of the GridPanel row. I want to filter the GridPanel with the checkboxgroup values.
Here is the code -
Store1 = new Ext.data.JsonStore({
url: 'CustomerProfiles/GetDetails',
root: 'rows',
fields:['Name','Id']
});
DetailedResults =
{
xtype: 'grid',
autoHeight: true,
autoWidth: true,
autoScroll: true,
border: false,
trackMouseOver: false,
frame: true,
store: Store1,
columns: [
{ header: 'Name', dataIndex: 'Name', width: 90 },
{ header: 'Id', dataIndex: 'Id', width: 50 }
]
};
Leftpanel = new Ext.Panel({
id: 'Leftpanel',
frame: true,
width: 175,
items: [
{
xtype: 'label'
},
{
xtype: 'checkboxgroup',
columns: 1,
vertical: true,
items: [{
boxLabel: 'ALL',
name: 'chkName',
inputValue: 'all'
}, {
boxLabel: 'N1',
name: 'chkName',
inputValue: 'N1'
}, {
boxLabel: 'N2',
name: 'chkName',
inputValue: 'N2'
}, {
boxLabel: 'N3',
name: 'chkName',
inputValue: 'N3'
}], listeners: {
change: {
fn: function () {
Store1.clearFilter();
var selectedValue = this.getValue();
for (var i = 0; i < selectedValue.length; i++) {
Store1.filter('Name', selectedValue[i].inputValue);
}
}
}
}
}
]});
Where I went wrong?
PS: I am using 3.4 version
The getValue() method is a little tricky, the object it returns has variable structure depending on the resultset, that caused the problem in your code. However, the getChecked() method is more straightforward, I'll use it in the solution.
Then, we use filterBy as it's more useful in this case.
Here you have the solution (comments inline):
change: {
fn: function () {
var checkedBoxes = this.getChecked(), //Array of checked checkboxes
selectedValues = []; //Array of selected values
for (var i = 0; i < checkedBoxes.length; i++) {
selectedValues.push(checkedBoxes[i].inputValue); //Add each inputValue to the array
}
var allSelected = Ext.Array.contains(selectedValues, 'all'); //Whether the 'ALL' option was selected
Store1.filterBy(function(record){
//If all was selected or if the name is included in the selectedValues, include the item in the filter
return allSelected || Ext.Array.contains(selectedValues, record.get('Name'));
});
}
}
Problem solved. Tested and working :)
UPDATE
The above code works on ExtJs >= 4. For Ext 3.4, this is the code:
change: {
fn: function () {
var selectedValues = []; //Array of selected values
this.items.each(function(checkbox){
if(checkbox.checked)
selectedValues.push(checkbox.inputValue);
});
var allSelected = selectedValues.indexOf('all') >= 0; //Whether the 'ALL' option was selected
Store1.filterBy(function(record){
//If all was selected or if the name is included in the selectedValues, include the item in the filter
return allSelected || selectedValues.indexOf(record.get('Name')) >= 0;
});
}
}
OPTIONAL (extra improvements, works only on ExtJs 4.x)
However, checking your app, I think the following improvements could be done:
Create the filter checkboxes dynamically depending on the store data
Sync the ALL checkbox with the rest (i.e. when selecting ALL, select all the other checkboxes)
This is the code with the improvements:
var Store1 = new Ext.data.JsonStore({
proxy: {
type: 'ajax',
url: 'CustomerProfiles/GetDetails',
reader: {
root: 'rows'
}
},
autoLoad: true,
fields: ['Name','Id'],
listeners: {
//Each time the store is loaded, we create the checkboxes dynamically, and add the checking logic in each one
load: function(store, records){
createCheckboxesFromStore(store);
}
}
});
var DetailedResults = {
xtype: 'grid',
autoHeight: true,
autoWidth: true,
autoScroll: true,
border: false,
trackMouseOver: false,
frame: true,
store: Store1,
columns: [
{ header: 'Name', dataIndex: 'Name', width: 90 },
{ header: 'Id', dataIndex: 'Id', width: 50 }
]
};
var Leftpanel = new Ext.Panel({
id: 'Leftpanel',
frame: true,
width: 175,
items: [
{
xtype: 'label'
},
{
xtype: 'checkboxgroup',
columns: 1,
vertical: true,
}
]});
function createCheckboxesFromStore(store){
var checkBoxGroup = Leftpanel.down('checkboxgroup');
checkBoxGroup.removeAll();
checkBoxGroup.add({
itemId: 'allCheckbox',
boxLabel: 'ALL',
name: 'chkName',
inputValue: 'all',
checked: true,
listeners: {
change: function (chbx, newValue) {
console.log("Changed ALL to ", newValue);
if(newValue){ //If ALL is selected, select every checkbox
var allCheckboxes = this.up('checkboxgroup').query("checkbox"); //Array of all checkboxes
for (var i = 0; i < allCheckboxes.length; i++) {
allCheckboxes[i].setValue(true);
}
}
}
}
});
//Create one checkbox per store item
store.each(function(record){
checkBoxGroup.add({
boxLabel: record.get('Id'),
name: 'chkName',
inputValue: record.get('Name'),
checked: true,
listeners: {
change: function (chbx, newValue) {
console.log("Changed ", chbx.inputValue, " to ", newValue);
var checkboxGroup = this.up('checkboxgroup'),
checkedBoxes = checkboxGroup.getChecked(), //Array of checked checkboxes
selectedValues = []; //Array of selected values
//If we uncheck one, also uncheck the ALL checkbox
if(!newValue) checkboxGroup.down("#allCheckbox").setValue(false);
for (var i = 0; i < checkedBoxes.length; i++) {
selectedValues.push(checkedBoxes[i].inputValue); //Add each inputValue to the array
}
Store1.filterBy(function(record){
//If all was selected or if the name is included in the selectedValues, include the item in the filter
return Ext.Array.contains(selectedValues, record.get('Name'));
});
}
}
});
});
}
This is also tested and working :). If you need it, I can pass you a jsfiddle link with the code running (just tell me).
Cheers, from La Paz, Bolivia

Categories

Resources