PDA

View Full Version : Checkbox Group Clone [HoloGrp]



bartonjd
20 Jul 2011, 8:36 AM
After struggling to make the built in checkbox group work the way I needed it too I decided to write my own clone. An example can be seen at http://beta.climate.usurf.usu.edu/demo/selectionGroup.php
The files are attached here:
27067

If anyone has any recommendations, comments, questions or improvements PLEASE POST, any help or feedback is appreciated.

The JS code for HoloGrp.js is below:


Ext.ns('wt');

Ext.data.Types.JSON = {
convert: function (v, data) {
return Ext.decode(v);
},
sortType: function (v) {
return Ext.encode(v); // When sorting, order by latitude
},
type: 'json'
};

wt.HoloGroup = Ext.extend(Ext.Panel, { //Handful of List Objects
maxLabelWidth: 14,
loadMaskMsg: 'Loading...',
grouping: false,
bodyBorder: false,
plain: false,
border: false,
defaults: { // set defaults for holoItems
bodyBorder: false,
border: false
},
initComponent: function () {
this.addEvents('beforeselect', 'select', 'toolclick', 'load', 'bufferclick' // user fired event
);
var fieldsVar = ['id', 'boxLabel', 'iconCls', 'inactiveIconCls', 'toolCls', 'group',
{
name: 'width',
type: 'int'
}, {
name: 'height',
type: 'int',
defaultValue: 22
}, {
name: 'checked',
type: 'boolean',
defaultValue: false
}, {
name: 'disabled',
type: 'boolean'
}, 'value', 'inputValue'];

if ((Ext.isDefined(this.metaFields))) { // add custom user fields to the store
fieldsVar = fieldsVar.concat(this.metaFields);
}
var holoGrp = this; // store a reference to 'this' to use later
if (Ext.isDefined(this.tbar)) {
this.tbar.style = 'padding-bottom:4px'; // ensure tbar is not flush against our content
}
this.store = new Ext.data.JsonStore({
url: (Ext.isDefined(this.url)) ? this.url : '',
root: this.root || 'data',
listeners: {
'beforeload': function () { // prepare the component for a fresh render, clear out all content so we can update from the store
if (holoGrp.rendered) {
holoGrp.removeAll(); // remove any components that have been added
holoGrp.update(); // clear all the html added by a previous call of this listener
}
if (holoGrp.showLoadMask && Ext.isDefined(holoGrp.loadMask)) {
holoGrp.loadMask.show(); // hide loadmask if it exists and is enabled
}
},
'load': function () {
if (holoGrp.showLoadMask && Ext.isDefined(holoGrp.loadMask)) {
holoGrp.loadMask.hide(); // hide loadmask if it exists and is enabled
}
var groups = holoGrp.getGroups();
this.each(function (i) {
if (groups.length > 0 && holoGrp.grouping) {
if (groups[0] === i.get('group')) {
holoGrp.add({ // add label for each group
html: {
cls: "holo-grp-text",
html: Ext.util.Format.capitalize(groups[0])
}
});
groups = groups.remove(groups[0]);
}
}
var item = new wt.HoloItem({
groupCt: holoGrp,
plain: holoGrp.plain,
maxLabelWidth: holoGrp.maxLabelWidth,
data: i.data,
record: i
});
holoGrp.add(item);
});
this.clearFilter(); //clear filter on store set in getGroups
holoGrp.doLayout();
holoGrp.fireEvent('load', holoGrp);
}
},
baseParams: (Ext.isDefined(this.baseParams)) ? this.baseParams : {},
fields: fieldsVar
});
wt.HoloGroup.superclass.initComponent.apply(this, arguments);
},
reload: function (prms) {
if (this.baseParams !== this.store.baseParams) {
this.store.baseParams = this.baseParams;
}
if (Ext.isDefined(this.loadMaskMsg) && this.showLoadMask && this.rendered) {
this.loadMask.show(); // show loading mask upon reload
}
if (Ext.isDefined(prms)) {
this.store.load({
params: prms
});
} else {
this.store.load();
}
},
getGroups: function () {
this.store.sort('group', 'ASC'); // sort into groups so that when we call the
var groups = Ext.unique(this.store.collect('group'));
return groups;
},
getGroupValue: function () {
this.store.filter('checked', true);
var vals = this.store.collect('value');
this.store.clearFilter();
return vals;
},
onRender: function () {
wt.HoloGroup.superclass.onRender.apply(this, arguments);
if (!Ext.isDefined(this.loadMask) && this.showLoadMask) {
this.loadMask = new Ext.LoadMask(this.el, {
msg: this.loadMaskMsg
});
}
if (Ext.isDefined(this.url)) {
this.store.load();
} else if (this.data) {
this.store.loadData(this.data, true);
}
},
afterRender: function () {
wt.HoloGroup.superclass.afterRender.apply(this, arguments);
this.doLayout();
}
});
Ext.reg('hologroup', wt.HoloGroup);

wt.HoloItem = Ext.extend(Ext.Container, {
maxLabelWidth: 13,
defaults: {
bodyBorder: false,
border: false
},
initComponent: function () {
this.autoEl = {};
var bgClass = (this.plain) ? 'holo-nobg holo-bg' : 'holo-bg';
this.tpl = new Ext.XTemplate('<div class="{[(values.checked) ? "holo-bg-active ' + bgClass + '" : "' + bgClass + '"]}"> ', '<ul>', '<li id="check-{id}" class="holo-check" ><img src="' + Ext.BLANK_IMAGE_URL + '" id="chkImg-{[xindex-1]}" class="{[(values.checked) ? "holo-active-check" : "holo-inactive-check"]}" width="12" height="12"></li>', '<li id="icon-{id}" class="holo-icon"><img src="' + Ext.BLANK_IMAGE_URL + '" class="{[(values.checked) ? values.iconCls :"holo-inactive-icon " + values.inactiveIconCls]}" width="16" height="18"></li>', '<li id="label-{id}" class="holo-lbl" ext:qtip="{[(values.boxLabel.length >= 13) ? values.boxLabel : ""]}">{[fm.ellipsis(values.boxLabel, ' + this.maxLabelWidth + ')]}</li>', '<li id="tool-icon-{id}" class="holo-tool"><img src="' + Ext.BLANK_IMAGE_URL + '" id="toolImg-{[xindex-1]}" class="{toolCls} holo-tool-img" width="16" height="18"></li>', '</ul></div>', '<div class="holo-xclear"></div>', {
maxLabelWidth: this.maxLabelWidth
});
wt.HoloItem.superclass.initComponent.apply(this, arguments);
},
handleClick:function(e,t){
if (Ext.DomQuery.is(t,'img.holo-tool-img')){
this.selectTool(e,t);
}else{
this.selectChk(e,t);
}
},
selectChk: function (e,t) {
if (!this.disabled) { // only allow this event to fire if the component is not disabled
//Ensure the event fires for the whole bar -- EXCEPT the tool icon
chkState = this.record.get('checked');
if (this.groupCt.fireEvent('beforeselect', e, this, this.record, this.record.get('checked')) !== false) { // if the beforeselect listener returns false then the select event will not fire and the event stops
this.record.set('checked', !chkState);
this.update(this.record.data);
this.groupCt.fireEvent('select', e, this, this.record, this.record.get('checked'));
}
}
},
selectTool: function (e) {
if (!this.disabled) { // only allow this event to fire if the component is not disabled
this.groupCt.fireEvent('toolclick', e, this, this.record);
}
},
toggleIcon: function (state) { //true to swap out the inactive icon, false to add it back in
state = state || !this.record.get('checked');
var inactiveClass = ['holo-inactive-icon', this.record.get('inactiveIconCls')];
addVar = (state) ? this.record.get('iconCls') : ['holo-inactive-icon', this.record.get('inactiveIconCls')];
removeVar = (state) ? ['holo-inactive-icon', this.record.get('inactiveIconCls')] : this.record.get('iconCls');

this.el.child('li.holo-icon img').addClass(addVar);
this.el.child('li.holo-icon img').removeClass(removeVar);
},
afterLayout: function () {
if (this.record.get('disabled')) {
this.disable();
}
},
afterRender: function () {
wt.HoloItem.superclass.afterRender.apply(this, arguments);
this.doLayout();
if (!Ext.isDefined(this._listenersDefined)) { //ensure listeners are only applied once
this.el.addListener('click', this.handleClick, this);
this.addListener('afterlayout', this.afterLayout);
this._listenersDefined = true;
}
}
});


The items for this component can be added locally or from a server side response, the items are configured in the same way as an array of checkboxes with a few minor exceptions. Here is the response used to generate the screenshot shown below:


{
"has_error": 0,
"error_desc": "",
"payload": "",
"success": "true",
"total": 7,
"data": [{
"boxLabel": "COOP",
"inputValue": "coop",
"value": "coop",
"id": "COOP_Stations",
"disabled": false,
"reports": "[{\"report_name\":\"Climate Indices\",\"file\":\"indices.php\"},{\"report_name\":\"Monthly\",\"file\":\"e15daily.php\"},{\"report_name\":\"Period of Record\",\"file\":\"monthly_data_summary.php\"},{\"report_name\":\"Precipitation\",\"file\":\"por_pcpn.php\"},{\"report_name\":\"Mean Temperature\",\"file\":\"por_tmean.php\"},{\"report_name\":\"Evapotranspiration\",\"file\":\"por_et0.php\"},{\"report_name\":\"Snowfall\",\"file\":\"por_snow.php\"}]",
"iconCls": "neticon-coop",
"inactiveIconCls": "neticon-coop_gray",
"toolCls": "icon-info",
"group": "daily",
"checked": 1,
"aggregator": "DIRECT",
"info": "The Cooperative Data Network (COOP) or the National Weather Service (NWS) Cooperative Observer Program is administered through National Climatic Data Center (NCDC). More than 11,000 volunteers take observations of daily maximum and minimum temperatures, snowfall, and 24-hour precipitation totals in all areas of the nation.",
"link": "http:\/\/www.ncdc.noaa.gov\/oa\/hofn\/coop\/coop-home.html"
}, {
"boxLabel": "CRN",
"inputValue": "crn",
"value": "crn",
"id": "CRN_Stations",
"disabled": false,
"reports": false,
"iconCls": "neticon-crn",
"inactiveIconCls": "neticon-crn_gray",
"toolCls": "icon-info",
"group": "daily",
"checked": 0,
"aggregator": "DIRECT",
"info": "The U.S. Climate Reference Network (USCRN) is a network of climate stations developed by the National Oceanic and Atmospheric Administration (NOAA). Their primary goal is to provide future long-term homogeneous temperature and precipitation observations that can be coupled to long-term historical observations for the detection and attribution of present and future climate change. ",
"link": "http:\/\/www.ncdc.noaa.gov\/crn\/"
}, {
"boxLabel": "AWOS",
"inputValue": "awos",
"value": "awos",
"id": "AWOS_Stations",
"disabled": false,
"reports": "[{\"report_name\":\"Current Conditions Graph\",\"file\":\"cur_conditions.php\"}]",
"iconCls": "neticon-awos",
"inactiveIconCls": "neticon-awos_gray",
"toolCls": "icon-info",
"group": "hourly",
"checked": 0,
"aggregator": "DIRECT",
"info": "The Automated Surface Observing Systems (ASOS - formerly AWOS) program is a joint effort of the National Weather Service (NWS), the Federal Aviation Administration (FAA), and the Department of Defense (DOD). The ASOS systems serves as the nations primary surface weather observing network. ASOS is designed to support weather forecast activities and aviation operations and, at the same time, climatological research.",
"link": "http:\/\/www.nws.noaa.gov\/asos\/index.html"
}, {
"boxLabel": "GSOD",
"inputValue": "gsod",
"value": "gsod",
"id": "GSOD_Stations",
"disabled": false,
"reports": false,
"iconCls": "neticon-gsod",
"inactiveIconCls": "neticon-gsod_gray",
"toolCls": "icon-info",
"group": "daily",
"checked": 0,
"aggregator": "DIRECT",
"info": "Global Surface Summary of the Day (GSOD) is produced by the National Climatic Data Center (NCDC). The input data used in building these daily summaries are the Integrated Surface Data (ISD), which includes global data obtained from the USAF Climatology Center. The data files begin with 1929 and are up to date normally 1-2 days after the observations.",
"link": "http:\/\/www.ncdc.noaa.gov\/cgi-bin\/res40.pl?page=gsod.html"
}, {
"boxLabel": "SCAN",
"inputValue": "scan",
"value": "scan",
"id": "Direct_Station_Networks.Direct_SCAN_Stations",
"disabled": false,
"iconCls": "neticon-scan",
"inactiveIconCls": "neticon-scan_gray",
"toolCls": "icon-info",
"group": "hourly",
"checked": 0,
"reports": "[{\"report_name\":\"Current Conditions Graph\",\"file\":\"cur_conditions.php\"}]",
"aggregator": "Direct",
"info": "The Soil Climate Analysis Network (SCAN) is a nationwide soil moisture and climate information system. Administered by the United States Department of Agriculture Natural Resources Conservation Service (NRCS) through the National Water and Climate Center (NWCC), in cooperation with the NRCS National Soil Survey Center, the system focuses on agricultural areas of the U.S.",
"link": "http:\/\/www.wcc.nrcs.usda.gov\/scan\/"
}, {
"boxLabel": "FGNet",
"inputValue": "fgnet",
"value": "fgnet",
"id": "Direct_Station_Networks.FGNet_Stations",
"disabled": false,
"iconCls": "neticon-fgnet",
"inactiveIconCls": "neticon-fgnet_gray",
"toolCls": "icon-info",
"group": "hourly",
"checked": 0,
"reports": false,
"aggregator": "Direct",
"info": null,
"link": null
}, {
"boxLabel": "ISD-LITE",
"inputValue": "isd-lite",
"value": "isd-lite",
"id": "Direct_Station_Networks.ISD-LITE_Stations",
"disabled": false,
"iconCls": "neticon-isd-lite",
"inactiveIconCls": "neticon-isd-lite_gray",
"toolCls": "icon-info",
"group": "hourly",
"checked": 0,
"reports": false,
"aggregator": "Direct",
"info": "The ISD-Lite data source is a subset derived from the full Integrated Surface Data (ISD) product provided by National Climatic Data Center (NCDC). ISD consists of global hourly and synoptic observations compiled from numerous sources and comprises over 20,000 stations worldwide with some having data as far back as 1901. ",
"link": "http:\/\/www.ncdc.noaa.gov\/oa\/climate\/isd\/index.php?name=isd-lite"
}]
}


The built in store has the ability to add in custom fields from the user without being redefined, you simply add a data store field configuration to the metaFields property of the holoGroup:


metaFields:[{
name:'reports',
type:'json' //type defined in holoGrp.js
},'aggregator','info','link'],