Could be a naive beginner's question, but I trust you all to be nice
We'd like to be able to load our WAB app with a group filter enabled based on a url parameter. For example, http://somelocalgovernmentdomain.gov/OurAwesomeWABApp/?filter=ByStatus&filterValue=Active would load the app with the group filter "By Status" applied with the value of "Status."
I know that this is currently not a supported OOB url paramater, but any guidance on whether or not this is possible through customization would be greatly appreciated.
Shaun
Solved! Go to Solution.
I have made a couple of code changes to the GroupFilter Widget.js to add your desired url parameter support. These changes were only tested in a very limited manner.
createNewRow: function(pValue) {
var table = dom.byId("tblPredicates");
var prevRowConjunTable;
var prevRowConjunCell;
if(pValue.state === "new") {
if(table.rows.length > 1) {
prevRowConjunTable = table.rows[(table.rows.length - 1)].cells[0].firstChild;
prevRowConjunCell = prevRowConjunTable.rows[2].cells[0];
this.createConditionSelection(prevRowConjunCell, pValue);
} else {
if(table.rows.length === 1) {
prevRowConjunTable = table.rows[(table.rows.length - 1)].cells[0].firstChild;
prevRowConjunCell = prevRowConjunTable.rows[2].cells[0];
this.createConditionSelection(prevRowConjunCell, pValue);
}
}
}
var row = table.insertRow(-1);
var subTableNode = row.insertCell(0);
var deleteNode = row.insertCell(1);
domClass.add(subTableNode, "criteriaCellSize");
domClass.add(deleteNode, "deleteCellSize");
var subTable = domConstruct.create("table", {border: "0", width: "100%"}, subTableNode);
var rowOperator = subTable.insertRow(-1);
var cell_operator = rowOperator.insertCell(0);
var rowValue = subTable.insertRow(-1);
var cell_value = rowValue.insertCell(0);
var rowConjunc = subTable.insertRow(-1);
var cell_conjunc = rowConjunc.insertCell(0);
domStyle.set(cell_conjunc, {paddingLeft: "3px", paddingRight: "3px"});
domClass.add(rowOperator, "operator-class");
this.colorRows();
this.createOperatorSelection(cell_operator, pValue);
this.removeTableRow(deleteNode, row, table.rows.length);
this.createInputFilter(cell_value, pValue);
this.resize();
//check simple mode
if(this.config.simpleMode) {
domClass.add(this.btnCriteria, "hide-items");
domClass.add(rowOperator, "hide-items");
query(".container").style("borderTop", "0px");
domStyle.set(cell_value, {paddingLeft: "0px", paddingRight: "0px"});
}
if(pValue.state === "reload") {
if(pValue.conjunc !== "") {
prevRowConjunTable = table.rows[(table.rows.length - 1)].cells[0].firstChild;
prevRowConjunCell = prevRowConjunTable.rows[2].cells[0];
this.createConditionSelection(prevRowConjunCell, pValue);
}
} else {
if(this.runInitial) {
this.runInitial = false;
setTimeout(lang.hitch(this, this.setFilterLayerDef), 1000);
}
}
var urlParams = utils.urlToObject(window.location.href).query;
if(urlParams.filter){
this.grpSelect.set("value", urlParams.filter);
setTimeout(lang.hitch(this, this.setFilterLayerDef), 2000);
}
},
....
checkDefaultValue: function(pGroup) {
var defaultVal = "";
if(pGroup.defaultVal !== "") {
defaultVal = pGroup.defaultVal;
}
//Check the url for a filterValue
var urlParams = utils.urlToObject(window.location.href).query;
if(urlParams.filterValue){
defaultVal = urlParams.filterValue;
}
return defaultVal;
},
....
Curious why you want to do it this way. The existing widget can be configured to be open by default when the app loads and apply the filter as well. I set my config like below and it applies the filter when the app loads.
Hope this helps.
Solomon Pulapkura
Appreciate the feedback. I think your argument could be made for many of the url parameters. For example, the search box is open by default, yet the ?find= url parameter is extremely valuable. I think, like with most of the url parameters, the need is to limit the steps required by the end user to achieve the desired result, especially if they are beginning from a location that has already narrowed their focus. For example, our need for this is stemming from non-gis/non-technical users accessing the map via another non-gis application. Specifically they are starting their journey on an app they use to manage projects. They navigate to a specific project, open the record, then click on a "view in map" icon that launches this app (either embedded or in a new frame). Instead of requiring them to recreate the steps they've already gone through in the project tracking app (finding their desired project etc) , our goal is to minimize the steps required on the user side (especially given they are not all GIS folks.) We are currently using the ?find= url parameter, which is a great starting point and is most likely enough of a solution. But, we wanted to pursue the option to filter results via url parameter.
Another proposed use is to have default map states based on the department of the user. For example, users in the project tracking app belong to groups. If a user is a member of the public works group, then we can simply append the url parameter values to filter on map items by the public works group. Again, we are just assessing what is available in order to respond to user requests.
I have made a couple of code changes to the GroupFilter Widget.js to add your desired url parameter support. These changes were only tested in a very limited manner.
createNewRow: function(pValue) {
var table = dom.byId("tblPredicates");
var prevRowConjunTable;
var prevRowConjunCell;
if(pValue.state === "new") {
if(table.rows.length > 1) {
prevRowConjunTable = table.rows[(table.rows.length - 1)].cells[0].firstChild;
prevRowConjunCell = prevRowConjunTable.rows[2].cells[0];
this.createConditionSelection(prevRowConjunCell, pValue);
} else {
if(table.rows.length === 1) {
prevRowConjunTable = table.rows[(table.rows.length - 1)].cells[0].firstChild;
prevRowConjunCell = prevRowConjunTable.rows[2].cells[0];
this.createConditionSelection(prevRowConjunCell, pValue);
}
}
}
var row = table.insertRow(-1);
var subTableNode = row.insertCell(0);
var deleteNode = row.insertCell(1);
domClass.add(subTableNode, "criteriaCellSize");
domClass.add(deleteNode, "deleteCellSize");
var subTable = domConstruct.create("table", {border: "0", width: "100%"}, subTableNode);
var rowOperator = subTable.insertRow(-1);
var cell_operator = rowOperator.insertCell(0);
var rowValue = subTable.insertRow(-1);
var cell_value = rowValue.insertCell(0);
var rowConjunc = subTable.insertRow(-1);
var cell_conjunc = rowConjunc.insertCell(0);
domStyle.set(cell_conjunc, {paddingLeft: "3px", paddingRight: "3px"});
domClass.add(rowOperator, "operator-class");
this.colorRows();
this.createOperatorSelection(cell_operator, pValue);
this.removeTableRow(deleteNode, row, table.rows.length);
this.createInputFilter(cell_value, pValue);
this.resize();
//check simple mode
if(this.config.simpleMode) {
domClass.add(this.btnCriteria, "hide-items");
domClass.add(rowOperator, "hide-items");
query(".container").style("borderTop", "0px");
domStyle.set(cell_value, {paddingLeft: "0px", paddingRight: "0px"});
}
if(pValue.state === "reload") {
if(pValue.conjunc !== "") {
prevRowConjunTable = table.rows[(table.rows.length - 1)].cells[0].firstChild;
prevRowConjunCell = prevRowConjunTable.rows[2].cells[0];
this.createConditionSelection(prevRowConjunCell, pValue);
}
} else {
if(this.runInitial) {
this.runInitial = false;
setTimeout(lang.hitch(this, this.setFilterLayerDef), 1000);
}
}
var urlParams = utils.urlToObject(window.location.href).query;
if(urlParams.filter){
this.grpSelect.set("value", urlParams.filter);
setTimeout(lang.hitch(this, this.setFilterLayerDef), 2000);
}
},
....
checkDefaultValue: function(pGroup) {
var defaultVal = "";
if(pGroup.defaultVal !== "") {
defaultVal = pGroup.defaultVal;
}
//Check the url for a filterValue
var urlParams = utils.urlToObject(window.location.href).query;
if(urlParams.filterValue){
defaultVal = urlParams.filterValue;
}
return defaultVal;
},
....
Thanks Robert! This works great so far and is exactly what we were hoping to see.
UPDATE:
Ran into an issue where if a user manually selected another group filter from the list, the added code to use url parameters was overriding user selection, essentially only allowing the group filter defined in the url to be used. Added a variable to track initial load and only fire urlParamater check on that initial load.
if(this.loadCount == 0){
if(urlParams.filter){
this.loadCount++;
this.grpSelect.set("value", urlParams.filter);
setTimeout(lang.hitch(this, this.setFilterLayerDef), 2000);
}
}