Select to view content in your preferred language

Change the color of a header in AT

1786
15
Jump to solution
03-11-2019 12:10 PM
LefterisKoumis
Frequent Contributor

I am looking to change the color of the header by directly click on the header and

also if  column is selected through a click on a list of fields..

For the first task I tried css:

.jimu-widget-attributetable .dgrid-header .dgrid-selected {
  background-color: rgb(34, 228, 34)
}‍‍‍‍‍‍‍

but it doesn't seem to be working.

0 Kudos
15 Replies
LefterisKoumis
Frequent Contributor

So there is no way you can stop event propagation. What is puzzling is that by just clicking the select box the second time for another field, it triggers refresh, even though no filtering is done. I changed my script so no filtering is performed after you click on the select, for the second field, and it still refreshes the map. Why?I just try to understand the mechanics of it.Does it has to do that the select is inside the toolbar? THanks.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

That must be some side effect from how you have your dropdown event wired up. Here is how mine is setup:

    createToolbar: function() {
      var toolbar = new Toolbar({}, html.create("div"))
....
      this.refreshButton = new Button({
        label: this.nls.refresh,
        showLabel: true,
        iconClass: "esriAttributeTableRefreshImage",
        onClick: lang.hitch(this, this.refresh)
      });
      toolbar.addChild(this.refreshButton);

//Add filter functionality
      this.filterFieldDD = new Select({
        value: "",
        onChange: lang.hitch(this, this.filterFieldChanged),
        intermediateChanges: true
      });
      html.addClass(this.filterFieldDD.domNode, 'filter-field-select');
      toolbar.addChild(this.filterFieldDD);

      this.thetextbox = new TextBox({
        value: "",
        placeHolder: "type in your filter value",
        onChange: lang.hitch(this, this.filterTextChanged),
        intermediateChanges: true
      });
      html.addClass(this.thetextbox.domNode, 'filter-textbox');
      toolbar.addChild(this.thetextbox);
//End add filter functionallity
....
    filterFieldChanged: function(field) {
      query('.dgrid-header th').forEach(function(th){
        if(html.hasClass(th, 'field-' + field)){
          html.addClass(th, 'th-selected');
        }else{
          html.removeClass(th, 'th-selected');
        }
      });
      filter_name = field;
    },

    filterTextChanged: function(value) {
      if (value.length >= 3 && filter_name) {
        var partsObj = {
          "expr": "UPPER(" + filter_name + ") LIKE '%" + value.toUpperCase() + "%'",
          "parts": []
        };
        this.setFilterObj(partsObj);
        this.clearSelection(false);
        this.startQuery();

        this.emit('apply-filter', {
          layerInfoId: this.layerInfo.id,
          expr: partsObj.expr
        });
      }
      if(value === ""){
        this.setFilterObj(null);
        this.clearSelection(false);
        this.startQuery();

        this.emit('apply-filter', {
          layerInfoId: this.layerInfo.id,
          expr: null
        });
      }
    },
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Oh. Here is how I populate the dropdown.

    queryExecute: function(oFields, recordCounts, exceededLimit, results, nExtent) {
      var data = [];
      var store = null;
      var columns = {};
      if (!this.domNode) {
        return;
      }
      // mixin porperty of field to result.fields
      this.filterFieldDD.innerHTML = '';
      results.fields = this._processExecuteFields(this.layer.fields, oFields);
      results.fields.map(lang.hitch(this, function(fld, indx){
        if(fld.type !== 'esriFieldTypeOID'){
          this.filterFieldDD.options[this.filterFieldDD.options.length] = new Option(fld.alias, fld.name);
        }
      }));
....
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

So like I said in my previous post, I am not sure about the soundness of your workflow, but here is how to maintain the css rule on the header after a filter refresh. Add lines 2 -10 to the changeToolbarStatus function.

    changeToolbarStatus: function() {
      if(filter_name && filter_name !== ""){
        query('.dgrid-header th').forEach(function(th){
          if(html.hasClass(th, 'field-' + filter_name)){
            html.addClass(th, 'th-selected');
          }else{
            html.removeClass(th, 'th-selected');
          }
        });
      }
      //selected/all option
....
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lefteris,

   This is what I am liking now (cleaner UI/UX feel). Filter icon does not get applied till the table is actually filtered and it persists when the table is refreshed.

define([
...
  'dijit/form/TextBox',
  "dijit/form/Select",
  'dijit/ToolbarSeparator'
], function(
...
  TextBox,
  Select,
  ToolbarSeparator
) {
    createToolbar: function() {
      var toolbar = new Toolbar({}, html.create("div"));

....

      this.refreshButton = new Button({
        label: this.nls.refresh,
        showLabel: true,
        iconClass: "esriAttributeTableRefreshImage",
        onClick: lang.hitch(this, this.refresh)
      });
      toolbar.addChild(this.refreshButton);

//my quick filter additions
      var sep = new ToolbarSeparator();
      toolbar.addChild(sep);
      html.place("<div class='quickFilterLabel'>Quick Filter: </div>", sep.domNode, "after");

      this.filterFieldDD = new Select({
        value: "",
        onChange: lang.hitch(this, this.filterFieldChanged),
        intermediateChanges: true
      });
      html.addClass(this.filterFieldDD.domNode, 'filter-field-select');
      toolbar.addChild(this.filterFieldDD);

      this.thetextbox = new TextBox({
        value: "",
        placeHolder: "type in your filter value",
        onChange: lang.hitch(this, this.filterTextChanged),
        intermediateChanges: true
      });
      html.addClass(this.thetextbox.domNode, 'filter-textbox');
      toolbar.addChild(this.thetextbox);

      this.clearFilterButton = new Button({
        label: "Clear Filter",
        showLabel: true,
        iconClass: "esriAttributeTableFilterImage",
        onClick: lang.hitch(this, this.clearFilter)
      });
      toolbar.addChild(this.clearFilterButton);
//end my quick filter additions‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
....
    changeToolbarStatus: function() {
//my quick filter additions
      query('.esriAttributeTableFilterFieldImage').forEach(function(node){
        html.destroy(node);
      });
      if (this.thetextbox.value.length >= 3 && this.filter_name) {
        var header = query('.dgrid-header th.field-' + this.filter_name + '>div')[0];
        var tip = "Filter SQL: " + this._filterObj.expr;
        html.place('<div class="esriAttributeTableFilterFieldImage" role="presentation" title="' + tip + '"></div>',header, "first");
      }
//end my quick filter additons
      //selected/all option

      if (!this.tableCreated) {
        //dgrid not created, set initial state
        if (this._relatedQuery) {
          //if RELATIONSHIPTABLE mode, show "Show All Records"
          this.showSelectedRecordsMenuItem.set('disabled', false);
          this.showSelectedRecordsMenuItem.set('label', this.nls.showAllRecords);
        } else {
          this.showSelectedRecordsMenuItem.set('disabled', true);
        }

        this.showRelatedRecordsMenuItem.set('disabled', true);
        this.matchingCheckBox.set('disabled', true);
        this.filterMenuItem.set('disabled', true);
        this.toggleColumnsMenuItem.set('disabled', true);
        if (!this.hideExportButton) {
          this.exportCSVMenuItem.set('disabled', true);
        }
        this.zoomButton.set('disabled', true);
        return;
      }

      //now dgid is created
      var selectionRows = this.getSelectedRows();
      if (this.showSelected) {
        //if this.showSelected is true, means we are in selected mode
        //now we need to show "Show All Records"
        this.showSelectedRecordsMenuItem.set('label', this.nls.showAllRecords);
      } else {
        this.showSelectedRecordsMenuItem.set('label', this.nls.showSelectedRecords);
      }
      if (this.tableCreated && selectionRows && selectionRows.length > 0 &&
        this.layer && this.layer.objectIdField) {
        this.showSelectedRecordsMenuItem.set('disabled', false);
        this.clearSelectionButton.set('disabled', false);
      } else {
        this.showSelectedRecordsMenuItem.set('disabled', true);
        this.clearSelectionButton.set('disabled', true);
      }
//my quick filter additons
      if(this.tableCreated && this._filterObj){
        this.clearFilterButton.set('disabled', false);
      }else{
        this.clearFilterButton.set('disabled', true);
      }
//end my quick filter additons
...‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
//my quick filter additons
    filterFieldChanged: function(field) {
      this.filter_name = field;
    },

    filterTextChanged: function(value) {
      if (value.length >= 3 && this.filter_name) {
        var partsObj = {
          "expr": "UPPER(" + this.filter_name + ") LIKE '%" + value.toUpperCase() + "%'",
          "parts": []
        };
        this.setFilterObj(partsObj);
        this.clearSelection(false);
        this.startQuery();

        this.emit('apply-filter', {
          layerInfoId: this.layerInfo.id,
          expr: partsObj.expr
        });
      }
    },

    clearFilter: function() {
      this.thetextbox.set("value", '');
      this.setFilterObj(null);
      this.clearSelection(false);
      this.startQuery();

      this.emit('apply-filter', {
        layerInfoId: this.layerInfo.id,
        expr: null
      });
    },
//end my quick filter additons
    queryExecute: function(oFields, recordCounts, exceededLimit, results, nExtent) {
      var data = [];
      var store = null;
      var columns = {};
      if (!this.domNode) {
        return;
      }
      // mixin porperty of field to result.fields
      results.fields = this._processExecuteFields(this.layer.fields, oFields);
//my quick filter additons
      this.filterFieldDD.innerHTML = '';
      results.fields.map(lang.hitch(this, function(fld, indx){
        if(fld.type !== 'esriFieldTypeOID'){
          this.filterFieldDD.options[this.filterFieldDD.options.length] = new Option(fld.alias, fld.name);
        }
      }));
//end my quick filter additons
...
.jimu-widget-attributetable .filter-textbox {
  height: 24px;
  line-height: 24px;
  margin: 0 0.3em;
}

.claro .dijitInputContainer {
  line-height: 20px;
}

.claro .dijitTextBox .dijitInputInner {
  height: 20px;
  line-height: 20px !important;
}

.claro .dijitTextBox .dijitPlaceHolder {
  font-size: 12px;
  height: 22px;
}

.jimu-widget-attributetable .filter-field-select {
  height: 24px;
  line-height: 24px;
  margin: 0 0.3em;
  min-width: 120px;
}

.esriAttributeTableFilterFieldImage{
  background-image: url("../images/filter.png");
  width: 13px;
  height: 13px;
  float: left;
  margin: 1px 9px 0 5px;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

.quickFilterLabel {
  display:inline-block;
  margin: 0 2px 0 5px;
  line-height: 22px;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
LefterisKoumis
Frequent Contributor

Robert, I'd like to thank you for your time and effort to assist me with this effort.

I finally realized why the map kept refreshing when I was clicking on the column header at first, then at the select drop down. Because of  stupidity, I didn't realized that by initializing the textbox,  every time I was selecting another field, I was re-initiating the query of the fields.

this.thetextbox.set("value", "")

What I should have done is that I could keep this line but also use

if(filter_name && filter_name !== ""){
...............................

Anyway, your code is very helpful to understand, among other things, of how to change the default stylesheetsof WAB widgets for a target element.

0 Kudos