Multiple level/criteria sorting using wijmo ICollectionView - sorting

Does Wijmo have functionality to add additional levels of sorting in cases where the first search criteria is a match? This secondary search would only be used in cases where the primary criteria are a match.
For example, if my two columns were State and Town, and I wanted to sort the states in ascending order, but the towns within those states in descending order. So my list might read something like
NV | Las Vegas
NV | Ely
NY | Saratoga
NY | New York City
NY | Albany

Sorting is performed at the data source level, by the CollectionView class. The CollectionView has a "sortDescriptors" property which is an array. You can add as many sorting levels as you like. For example:
// raw data
var data = [
{ state: 'NV', town: 'Las Vegas' },
{ state: 'NY', town: 'Saratoga' },
// ... more data ...
];
// CollectionView
var view = new wijmo.collections.CollectionView(data);
// sort by state, then by town
var sd = view.sortDescriptions;
sd.push(new wijmo.collections.SortDescription('state', true));
sd.push(new wijmo.collections.SortDescription('town', true));
Now you can use the "view" object as the grid's data source.
Note that if you don't use a CollectionView, the FlexGrid will create one automatically for internal use (so it can sort data etc). This internal CollectionView is exposed through the grid's "collectionView" property. So you can also do this:
// bind grid to raw data (creates internal CollectionView automatically)
grid.itemsSource = data;
// sort the grid's CollectionView
var sd = grid.collectionView.sortDescriptions;
sd.push(new wijmo.collections.SortDescriptor('state', true));
sd.push(new wijmo.collections.SortDescriptor('town', true));
I hope this helps. For more information on the CollectionView class, please check out this link:
https://wijmo.com/5/docs/topic/wijmo.collections.CollectionView.Class.html
I hope this helps.

Related

Display a dropdown menu only when a different cell contains a certain value

I'm very new to writing script for Google Sheets, and I'm attempting to create a spreadsheet that will only display a dropdown in a column ("Provisional Notes") if the value in a column ("Certified or Provisional" is "Provisional." If it is "Certified," the user is be able to enter data freely. I'm also wanting to remove the validation if the value changes from "Provisional". I also need the solution to run on the Google Sheets App, as this spreadsheet will be run on an iPad and/or a smartphone.
I've done quite a bit of searching, and only seem to find dropdowns that depend on other dropdowns, rather than leaving a cell blank if the initial dropdown is a certain value.
What I have come up with so far only runs once (even though I've attempted to have it occur on every edit?) Also, if the value changes from Provisional to Certified, the validation does not get removed.
For my practice, I've applied it to only 2 specific cells, rather than the entire 2 columns.
function onEdit2(e){
var dropdownCell = SpreadsheetApp.getActive().getRange('P2');
var certCell = SpreadsheetApp.getActive().getRange('J2');
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['Test 1', 'Test 2'], true).build();
function insertDropdown(){
if(e.certCell.getValue() === "P"){
dropdownCell.setDataValidation(rule);
}
}
}
I greatly appreciate all suggestions!
To delete a data validation you just need to use the method setDataValidation() and set its value to null to delete the data validation present on that cell.
In the following code example, depending on the value inserted I am adding or deleting the data validation. This code example has self explanatory comments:
function onEdit(e) {
// get sheet
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
// if modifications happen in A
if(e.range.getColumn()==1){
// check inserted value
if(e.range.getValue()=='Provisional'){
// create rule from a list range and set it to the same row in column B
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['A','B']).setAllowInvalid(false).build();
sheet.getRange(e.range.getRow(),2).setDataValidation(rule);
}
// if it is set to certified
if(e.range.getValue()=='Certified'){
// delete any data validation that may have been in its adjacent cell
sheet.getRange(e.range.getRow(),2).setDataValidation(null);
}
}
}

Oracle APEX Interactive Grid: Is there a way to get the corresponding column name, when clicking in a data cell in the Interactive Grid

I have a Dynamic Action which should get the data from the model, depending on the clicked column. Let 's say I have two columns in the interactive grid, column A and B. Depending on the column I clicked in, the DA should be executed and execute a query with the value from column A or B.
The DA is actived on doubleclick and I have the following source to get the value from the IG model.
var regionStaticId = $(this.triggeringElement).closest("div.js-apex-region").attr('id');
var grid = apex.region( regionStaticId ).widget().interactiveGrid("getViews", "grid");
var model = grid.model;
var record = grid.getSelectedRecords()[0];
var value;
// Code to find the the clicked column comes here
if (record) {
value = model.getValue(record, columnName);
}
Now, what I can do is add an extra css class to the particular cells, with the name of the source column. But that would be like hardcoding in my opinion. Like this.
if ($(this.triggeringElement).hasClass('columnA')) {
columnName = 'COLUMN_A';
}
else if ($(this.triggeringElement).hasClass('columnB')) {
columnName = 'COLUMN_B';
}
Is there a way to determine the clicked column, based on the triggering element?
Help is very much appreciated.

Using cell contents to modify drop-down menu list

I have a Google Sheets where I am saving information about universities and I have a column for regions and countries (regions or continents, however you want to see it) and what I'd like to do is have the regions column contain a drop-down menu (data validation) of all the continents and depending on what continent you select, the countries column will have the corresponding countries.
I have another sheet containing the required data with the first row being the continent names and the remaining rows being the countries in that continent.
I've tried custom formulas but ended up having something too complex that didn't work so I deleted it.
If anyone knows how I could do this with either the script editor or directly in data validation, that'd be great!
Continent and Country Dropdowns
I apologize but this is a little involved. Let's start with where I got the data. This is the website: https://datahub.io/JohnSnowLabs/country-and-continent-codes-list
I actually just copied and paste it into a Sheet named "C&C". I sorted it by continents and then by countries and I depend upon it remaining like that since it reduces the amount of effort to get the countries.
And here is the Google Script Code:
function onEdit(e) {
var dlm=" - ";
var msg="Start" + dlm;
var sh=e.range.getSheet();
if(sh.getName()!='DropDown')return;
if(e.range.getA1Notation()=='A2' && e.value) {
var dsh=e.source.getSheetByName('C&C');
var drg=dsh.getRange(1,1,dsh.getLastRow(),1);
var dvA=drg.getValues();
var cA=[];
var cStart=0;
var cEnd=0;
for(var i=0;i<dvA.length;i++) {
if(!cEnd && !cStart && dvA[i][0]==e.value) {
cStart=i+1;
msg+="cStart: " + cStart + dlm;
//e.source.toast(msg);
}
if(!cEnd && cStart && dvA[i][0]!=e.value || i==dvA.length-1) {
cEnd=i+1;
msg+="cEnd: " + cEnd + dlm;
//e.source.toast(msg);
break;
}
}
var crg=dsh.getRange(cStart,3,cEnd-cStart+1,1);
var cvA=crg.getValues();
e.source.getRangeByName('Countries').clearContent();
sh.getRange('B2').clearContent();
e.source.getSheetByName('NamedRanges').getRange(2,2,cvA.length,1).setValues(cvA);
}
msg+="Exit" + dlm;
e.source.toast(msg);
}
I left the debug toasts in there in case you want them.
Here's what the C&C page looks like:
And here's the page where I placed the NamedRanges. I named that page NamedRanges:
And here's the page with the two dropdowns:
It's displaying the South America continent selection.
Here's the NamedRanges setups:
And here's the Data Validation Setups:

Dynamic data validation based on other cell values, and copying/filling validation criteria relatively down each row (Google Sheets)

I am trying to achieve the following situation using Data Validation in Google Sheets. I've provided a truncated version of situation in the image below.
I would like to set up data validation in Column B that automatically checks the options in column C (or multiple columns in the same row) to populate the dropdown menu for that row.
I did notice that Google Sheets has an option for formulas in the data validation screen and I tried writing an array formula in this area but I have not been having any luck getting any sort of output.
If it can't be done through this menu I would appreciate any idea how to achieve this through scripts.
One way to achieve this is to select list from a range in the "Criteria" section of the Data Validation editor. Then, select the cells whose values you want to appear in your dropdown.
The only issue is that when you try to fill this down across the column, Google Sheets will not update the criteria range. Say you do the following:
In cell B2, use data validation based on list from a range and select D2:F2 as the criteria range. Now the dropdown in B2 will have the options John's Mom, John's Dad, John's Grandma
Then, fill down or copy this cell down across the whole column
When you open the dropdown for cell B3, it will still have the options John's Mom, John's Dad, John's Grandma
Unfortunately Google Sheets does not currently have a built-in solution for copying/filling data validation references or formulas relatively, as far as I know. But it looks like somebody already wrote a nice script in this Google Docs forum post. To avoid just a link as an answer, I'm going to copy in the script and instructions here. Credit to AD:AM from Google Docs forum.
How to use their script:
Select a range of cells across which you want to copy a data validation rule, relatively
From the Validation+ custom menu, select the appropriate option (all references relative, columns absolute, or rows absolute)
The validation of the upper-left cell will be copied to the rest of the range
Link to original solution's example Google Sheets with script already included - you can save your own copy and then start using.
Or to recreate from scratch, here is the script.
function onOpen()
{
SpreadsheetApp.getActiveSpreadsheet().addMenu
(
"Validation+",
[
{name: "Copy validation (all relative references)", functionName: "copyValidation"},
{name: "Copy validation (relative rows, absolute columns)", functionName: "copyValidationColumnsAbsolute"},
{name: "Copy validation (absolute rows, relative columns)", functionName: "copyValidationRowsAbsolute"}
]
);
}
function copyValidation(rowsAbsolute, columnsAbsolute)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var r = ss.getActiveRange();
var dv = r.getDataValidations();
var dvt = dv[0][0].getCriteriaType();
if (dvt != SpreadsheetApp.DataValidationCriteria.VALUE_IN_RANGE) return;
var dvv = dv[0][0].getCriteriaValues();
Logger.log(dvv);
for (var i = 0; i < dv.length; i++)
{
for (var j = i ? 0 : 1; j < dv[0].length; j++)
{
dv[i][j] = dv[0][0].copy().withCriteria(dvt, [dvv[0].offset(rowsAbsolute ? 0 : i, columnsAbsolute ? 0 : j), dvv[1]]).build();
}
}
r.setDataValidations(dv);
}
function copyValidationRowsAbsolute()
{
copyValidation(true, false);
}
function copyValidationColumnsAbsolute()
{
copyValidation(false, true);
}

Limiting the results of drop-down in Google Sheets

I work as an operations manager at at small business and I'm trying to set up an order sheet that is easy for the salesman to use. In the order sheet, I've used the OFFSET function to refer to a master list containing customers and prices. Under Customer, I type the customer and it draws it from the master list via an auto-complete drop-down. The same happens with the product.
Here is the order sheet:
Order Sheet Example
My issue is I'll begin typing in the product e.g. 'prawn'. We have over a dozen prawn lines, but a particular customer will only take one. All of the other prawn results have no prices for that customer. However, the auto-complete function will offer up all the 'prawn' results.
In the Master list, I've entered prices for only the products that the particular customer uses. Take a look at what the Master List looks like:
Master List look
Without an excellent memory of what customer wants what, it's an exercise in trial and error. In the above example, I could type 'topside' and if I select the wrong one, no price comes up.
This is frustrating.
I was hoping for a way to limit the auto-complete so that when I type 'prawn' or 'topside' for that customer, it only comes up with auto-complete fields that have the price in it. Can anyone help? Or does anyone know of any work-arounds? I'd be really thankful, the current order system is quite difficult.
I believe this will do what you want. It is a little difficult to tell from your sample data. It uses google apps script and sheet names and/or columms may need to be changed in the script for your data. I am attaching a sample spreadsheet you can copy then try. You will have to approve the script in the copy you make.
function onEdit(e) {
var cust=e.value //The value of the edited cell
var sh=e.source.getActiveSheet().getSheetName()//Name of the active sheet.
var col=e.range.getColumn()//The edited column
var r=e.range.getRow()//The edited row
var row=e.range.offset(0,1).getA1Notation()//Cell A1 notation of cell in same row one column to the right.
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s=ss.getActiveSheet().getSheetName()//Name of active sheet
var s1=ss.getSheetByName("Sheet1")//Variables for sheets
var s2=ss.getSheetByName("Sheet2")
var s3=ss.getSheetByName("TEMP")
var rng=s2.getDataRange().getValues()//Customer/Products
if(sh=="Sheet1" && col==1){//If sheet1 is active sheet and Customer (column A) is edited.
var array=[]//Array to hold customers products
for (var i=0;i<rng.length;i++){
if(rng[i][0]==cust ){
for(var j=1;j<rng[0].length-1;j++){
if(rng[i][j]!="" ){//If customers product has $ entry add to Array.
array.push([rng[0][j]])
}}}}
s3.clearContents()//Clear old product list from TEMP.
s1.getRange(row).clearContent()//Clear product dropdown
s3.getRange(1,1,array.length,1).setValues(array)//Set new customer product list in TEMP.
drop(row,cust)// Call drop function to build new dropdown.
}
if(sh=="Sheet1" && col==2){//If sheet1 is active sheet and Product (column B) is edited.
var cust1=e.range.offset(0,-1).getValue()//Get customer in A
var prod=e.range.getValue()//Get selected product
for (var i=0;i<rng.length;i++){//Get the customer/product price
if(rng[i][0]==cust1 ){
for(var j=1;j<rng[0].length-1;j++){
if(rng[0][j]==prod){
price=rng[i][j]
s1.getRange(r,5).setValue(price)//Set the price in column E
s1.getRange(r,2).clearDataValidations() //Remove the data validation dropdown in column B
}
}}
}}}
function drop(row,cust){
var ss=SpreadsheetApp.getActiveSpreadsheet()
var s3=ss.getSheetByName("TEMP")
var s1=ss.getSheetByName("Sheet1")
var cell = s1.getRange(row);//set validation in B
var ocell=s1.getRange(row).offset(0, -1).getValue()//evaluate value in A
var cellVal=cell.getValue()
if(ocell==cust){
var lr= ss.getSheetByName("TEMP").getLastRow()
var range = ss.getSheetByName("TEMP").getRange(1, 1, lr, 1)
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();//Build the dropdown
cell.setDataValidation(rule)}//Set the validation rules (Customers
products)
}
Test spreadsheet:
https://docs.google.com/spreadsheets/d/1u86sdf1_mO-Mv7hQM_hRZl3Gma-Y2lsu9ZvxSW4jA1U/edit?usp=sharing

Resources