PDA

View Full Version : Add Custom Menu Item to a GridFilter (ListFilter)



thebadcodeguy
Nov 21, 2016, 5:02 AM
Hi,

I've got a custom menu in my code which contains menu check items. There is also another item which acts as a Select All button. This all works great.

Now, I want to add this same Select All functionality to a remote ListFilter I've got (i.e being able to click a button to check every filter in the list), and I can't figure out how to add a custom menu item.

Here is the code for the original custom menu where I add the select all button:


menu.add({
xtype: 'menucheckitem',
text: this.selectAllText,
checked: !(this.checkIndexes instanceof Array),
hideOnClick: false,
handler: function (item) {
var checked = item.checked;
item.parentMenu.items.each(function (i) {
if (item !== i && i.setChecked && !i.disabled) {
i.setChecked(checked);
}
});
}
}, '-');


And here is what I've tried:


assetClassFilter.MenuConfig = new Menu
{
Items =
{
new CheckMenuItem
{
Text = "Select All",
Checked = true,
HideOnClick = false,
Handler = @"var checked = item.checked;
item.parentMenu.items.each(function (i) {
if (item !== i && i.setChecked && !i.disabled) {
i.setChecked(checked);
}
});"
}
}
};


I've also tried adding the item to the MenuItems property, which also doesn't work.

Any help is appreciated.

fabricio.murta
Nov 22, 2016, 6:00 PM
Hello @thebadcodeguy!

I'm not sure what you mean with your two code samples. Seems you have it working on pure ExtJS and is trying to port it to Ext.NET. Is that it? So you can have it working in ExtJS and not Ext.NET?

A fully runnable code sample would be much better to have an idea of what you done so far and what's left to do.

But maybe what you mean with a custom item option can be either:

- an additional option for the ListFilter column filter in a grid panel? If so, just set the options setting manually in the listFilter config. Probably you will need a special filter treatment for the "match all" choice.
If this is the case... I don't see much reason for it. If you disable the filter then it will be the same as "select all". But maybe you want this for ease-of-use, so you'll have to intercept the filter and make it act as if the filter was deactivated when selected.

- an additional entry in the column header's context menu. We have some threads about this in the forums already, you can find some by searching the forums for "custom header menu" for example.

In this result, Daniil points the user to another thread and it was useful for him so, maybe useful for you too: How do I customize the menu in column header of gridpanel (http://forums.ext.net/showthread.php?14720).

I believe that other matches from the forums will help if not the one above. If you try (or have already tried) the search with no luck, let us know. Providing the runnable and simplified code sample will really help us help you.

thebadcodeguy
Nov 23, 2016, 12:43 AM
Thanks for the reply.

Basically, I want this option to act as a shortcut. For example, say you have a listfilter with 20 choices. You want to display every choice except for one. With the default set up, you have to go and click through manually all the choices you want, which is time consuming if there is a lot of choices. If there is a select all button, it would check every choices, so you can then deselect the ones you don't want.

I've set up an example showing this feature on a menu button in the top toolbar of a gridpanel (the gridpanel you use in the Ext.NET examples).

index.aspx


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="TestExt.NET.index" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script lang="javascript" type="text/javascript">
function configureMenu() {

var button = Ext.getCmp('button1');
var menu = button.menu;
menu.removeAll();
// add Select All item plus separator
menu.add({
xtype: 'menucheckitem',
text: "Select All",
checked: false,
hideOnClick: false,
handler: function (item) {
var checked = item.checked;
item.parentMenu.items.each(function (i) {
if (item !== i && i.setChecked && !i.disabled) {
i.setChecked(checked);
}
});
}
}, '-');

// add new items
var columns = Ext.getCmp('grid1').headerCt.items.items;

Ext.each(columns, function (column) {
if (column.text && column.dataIndex && column.dataIndex != '') {
menu.add({
xtype: 'menucheckitem',
text: column.text,
hideOnClick: false,
dataIndex: column.dataIndex
});

}
}, button);
}
</script>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:Container ID="container" runat="server" Layout="FitLayout" />
</body>
</html>



index.aspx.cs:


using Ext.Net;
using System;
using System.Web.UI;

namespace TestExt.NET
{
public partial class index : Page
{
protected void Page_Load(object sender, EventArgs e)
{

var menu = new Menu();

var button = new SplitButton
{
ID = "button1",
Text = "test",
Menu =
{
menu
}
};

var gridpanel = new GridPanel
{
ID = "grid1",
Title = "Test",
Store =
{
new Store
{
Model =
{
new Model
{
Fields =
{
new ModelField
{
Name = "company"
},
new ModelField
{
Name = "price",
Type = ModelFieldType.Float
},
new ModelField
{
Name = "change",
Type = ModelFieldType.Float
},
new ModelField
{
Name = "pctChange",
Type = ModelFieldType.Float
},
new ModelField
{
Name = "lastChange",
Type = ModelFieldType.Date,
DateFormat = "d/M hh:mmtt"
}
}
}
},
DataSource = new object[]
{
new object[] { "3m Co", 71.72, 0.02, 0.03, "9/1 12:00am" },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, "9/1 12:00am" },
new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, "9/1 12:00am" },
new object[] { "American Express Company", 52.55, 0.01, 0.02, "9/1 12:00am" },
new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, "9/1 12:00am" },
new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, "9/1 12:00am" },
new object[] { "Boeing Co.", 75.43, 0.53, 0.71, "9/1 12:00am" },
new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, "9/1 12:00am" },
new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, "9/1 12:00am" },
new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, "9/1 12:00am" },
new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, "9/1 12:00am" },
new object[] { "General Electric Company", 34.14, -0.08, -0.23, "9/1 12:00am" },
new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, "9/1 12:00am" },
new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, "9/1 12:00am" },
new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, "9/1 12:00am" },
new object[] { "Intel Corporation", 19.88, 0.31, 1.58, "9/1 12:00am" },
new object[] { "International Business Machines", 81.41, 0.44, 0.54, "9/1 12:00am" },
new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, "9/1 12:00am" },
new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, "9/1 12:00am" },
new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, "9/1 12:00am" },
new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, "9/1 12:00am" },
new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, "9/1 12:00am" },
new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, "9/1 12:00am" },
new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, "9/1 12:00am" },
new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, "9/1 12:00am" },
new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, "9/1 12:00am" },
new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, "9/1 12:00am" },
new object[] { "Verizon Communications", 35.57, 0.39, 1.11, "9/1 12:00am" },
new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, "9/1 12:00am" }
}
}
},
ColumnModel =
{
Columns =
{
new Column
{
Text = "Company",
DataIndex = "company",
Flex = 1
},
new Column
{
Text = "Price",
DataIndex = "price",
Renderer =
{
Format = RendererFormat.UsMoney
}
},
new Column
{
Text = "Change",
DataIndex = "change",
},
new Column
{
Text = "Change",
DataIndex = "pctChange",
},
new Column
{
Text = "Last Updated",
DataIndex = "lastChange",
Width = 120
},
}
},
TopBar =
{
new Toolbar
{
Items =
{
button
}
}
}
};

container.Add(gridpanel);

X.Js.Call("configureMenu");
}
}
}


I suppose what I want to do is add this 'select all' item (the ext.net version in the OP) as an additional item to the list, but I can't figure out how to add it. The Options setting only accepts strings, can I add the item as js or something else?

fabricio.murta
Nov 23, 2016, 4:18 PM
Hello @thebadcodeguy!

The example you provided has a split button with the options working (if I check first, all below are checked, and the other way around), but I see no filtering at all. It does not add up.

You made a split button with column names in it and a grid with no filtering at all? By the way it looks, it suggests you want to make a filter to show and hide columns, but it does not match your description at all... I'm confused on how to help you... The grid you provided also has very different data, the columns don't seem to suggest being usable with a listfilter at all...

thebadcodeguy
Nov 23, 2016, 7:22 PM
The code is just a throwaway example to show you the functionality of having an option which selects all other options. What I want to know is if it's possible to add that option to the list filter.

fabricio.murta
Nov 29, 2016, 3:00 AM
Hello @thebadcodeguy!

I am afraid the ListFilter feature of the GridFilters plugin will have to be overridden or extended in order to support such a custom behavior. But I'm not even sure which filtering mechanism are you trying to use on your case.

I am thinking you are trying with the filter combination above, as can be seen on this example, column Size: GridPanel with Local Filtering, Sorting and Paging (http://examples4.ext.net/#/GridPanel/Plugins/GridFilters_Local/).

While this one would be harder to customize, I believe you can do fine if you can allow your grid to use the FilterHeader plug in and add a (maybe manually defined) combo box which will apply a custom filter like showcased in this example: Custom Behaviour for FilterHeader (http://examples4.ext.net/#/GridPanel/FilterHeader/Custom_Behaviour/).

Additionally, this example shows a combo box as the filter selection component in the grid: Custom Field for FilterHeader (http://examples4.ext.net/#/GridPanel/FilterHeader/Custom_Field/).

Hope this helps!

thebadcodeguy
Dec 22, 2016, 10:16 PM
Hi.

I ended up being able to do this and it worked quite well. I didn't have to override or extend anything.

What I ended up doing is putting a handler on the grid panel for when it loaded, with the parameters being a string list of all the filters I wanted to apply the select all button to (the timeout is to give the gridpanel a little time to load fully):



gridPanel.Store.First().Listeners.Load.Handler =
@"setTimeout(function() {
Ext.net.DirectMethod.request({
url: '/FakeController/AddSelectAllOption',
params: { filters : " + JSON.Serialize(options) + @"}
});
}, 1000);";


Then, in the controller method it called, I then publish a message bus for each filter. I also remove the handler before, so this chain of events can only be called once:


public ActionResult AddSelectAllOption(string filters)
{
var list = JSON.Deserialize<List<string>>(filters);

foreach (var item in list)
{
MessageBus.Default.Publish("App.TestGridPanel.onLoad", item);
}

var store = this.GetCmp<Store>("TestGridPanelStore");
store.Listeners.Load.Clear();

return this.Direct();
}


Lastly, in the message bus listener, I simply get the filter from the grid through the parameter that's been passed, and insert a new menu item into the filters menu.


MessageBusListeners.Add(new MessageBusListener
{
Name = "App.TestGridPanel.onLoad",
Handler = @"
var filter = Ext.getCmp('TestGridPanel').filters.getFilter(data );
if (filter.menu.items.items[0].text !== 'Select All') {
filter.menu.insert(0, {
xtype: 'menucheckitem',
text: 'Select All',
checked: false,
hideOnClick: false,
handler: function (item) {
var checked = item.checked;
item.parentMenu.items.each(function (i) {
if (item !== i && i.setChecked && !i.disabled) {
i.setChecked(checked);
}
});
}
});
}"
});

fabricio.murta
Dec 23, 2016, 5:41 PM
Hello!

Interesting solution! Glad you could find a way that fit your needs! And also thanks for sharing the outcome of your set up!