Select from createListBox with ScriptDb - google-apps-script

I have this code in input:
utentiGrid.setWidget(1, 2, app.createLabel('Stato:'));
utentiGrid.setWidget(1, 3,
app.createListBox().setName('tipologia').addItem("Alpha").addItem("Beta"));
I select "Beta" and write ScriptDb
Then I take the record and visualize the result by modifying with this code:
utentiGrid.setWidget(1, 2, app.createLabel('Stato:'));
utentiGrid.setWidget(1, 3,
app.createListBox().setName('tipologia').addItem("Alpha").addItem("Beta"));
The problem
I want see my first selection ("Beta") and not "Alpha".
how can I do?
thank you
raffaele
p.s. are not a programmer but scriptDb is fantastic!

Just use the method setSelectedItem as bellow:
function doGet() {
var app = UiApp.createApplication();
var utentiGrid = app.createGrid(3, 4);
utentiGrid.setWidget(1, 2, app.createLabel('Stato:'));
var listBox = app.createListBox().setName('tipologia').addItem("Alpha").addItem("Beta");
//To select Beta use 1 as argument
listBox.setItemSelected(1, true);
utentiGrid.setWidget(1, 3, listBox);
app.add(utentiGrid);
return app;
}
If you change the argument to 0 the item selected will be alpha. If you have a third element, their index will be 2 and so one.

Related

Formatting text (from array) on prompt window

I have a very simple prompt that outputs elements from an array:
const arr = [1, 2, 3, 4, 5, 6];
function alertMessage() {
SpreadsheetApp.getUi().alert(`List of numbers: ${arr}`);
}
alertMessage();
The message currently reads like this:
List of numbers: 1,2,3,4,5,6
However, I would like it to create a new line after each element (with no commas), so it would look like the below example. What would be the best way to do this?
List of numbers:
1
2
3
4
5
6
It seems that in your script, arr is an array. So, how about the following modification?
From:
SpreadsheetApp.getUi().alert(`List of numbers: ${arr}`);
To:
SpreadsheetApp.getUi().alert(`List of numbers: \n${arr.join("\n")}`);
If you want the double line breaks, please modify to SpreadsheetApp.getUi().alert(List of numbers: \n${arr.join("\n\n")});
Reference:
join()

Selective rearrangement of columns in XMLListCollection not working

I am trying to selectively rearrange columns in my XMLListCollection but for some reasons it is not working.
As an example, say my array is - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. I am trying to shift 9th column to 2nd column. So my output shall be like this [1, 9, 2, 3, 4, 5, 6, 7, 8, 10].
I have tried the below code to achieve my result.
model.columns = new XMLListCollection(event.payload.Columns.Column);
// Selective re-arrangment
// Storing 9 col in backup variable
Var backUp:XMLListCollection = model.columns[9];
// Removing item from column 9
model.columns.removeItemAt(9);
// Inserting backup variable at desired index
model.columns.addItemAt(backUp,2)
// Code for rendering each column
for each( var col:XML in model.columns){
if(col.#visible == "Y"){
var dataGridColumn:FlexDataGridColumn = new FlexDataGridColumn();
dataGridColumn.headerText = col.#display_nm;
dataGridColumn.dataField = '#'+col.#variable;
view.adjustmentModuleColumns.addColumn( dataGridColumn);
view.adjustmentsDataGrid.reDraw();
}
}
For some reasons above code is not working as expected. Please suggest.

How to get only unique values of a 2d array

I need to get the following 2d array from:
[[Option 10, 2.0], [Option 10, 2.0], [Option 9, 1.0], [Option 7, 1.0]]
to
[[Option 10, 2.0], [Option 9, 1.0], [Option 7, 1.0]]
I found this post (Splitting a 2D array using some() , by date, avoiding duplicates. Just want 1 unique email, not row. Where am i wrong here?) that has a very efficient way of getting unique values, but I cannot figure out how to apply it to my situation.
Your use case is simpler than the one you refer to.
try this for example :
function myFunction() {
var source = [['Option 10', 2], ['Option 10', 2], ['Option 9', 1], ['Option 7', 1]];
var dest = [];
dest.push(source[0]);
for(var n = 1 ; n< source.length ; n++){
if(dest.join().indexOf(source[n].join()) == -1){dest.push(source[n])};
}
Logger.log(dest);
}
Because 'unique' is not always simple to describe, I often use a pattern which is is, in effect, a variation of Serge's correct answer using ES5 array map/filter functions.
An edited version:
function hash(arr) {
// in this case the hash method is the same as Serge's Array.join() method,
but could be customised to suit whatever condition you need to generate
bespoke comparators such as where `1 + 3` should match `2 + 2`, or where
particular columns in the array can be omitted
return arr.join();
}
function myFunction() {
var source = [['Option 10', 2], ['Option 10', 2], ['Option 9', 1], ['Option 7', 1]];
var hash = source.map(
function (row) {
return hash(row);
}
);
source = source.filter(
function (filterRow, i) {
return hash.slice(0, i).indexOf(hash(filterRow)) < 0;
}
);
Logger.log(source);
}
I only include this as there are times when your comparison may need to flex a little. In your example this isn't important which is why Serge's is correct, but I share to show a potential expansion food for thought for when unique needs to be 'tweaked'

How do i get values from a combo box?

import fl.events.*;
const PointsStart:int=0;
var Points:int=PointsStart;
youChose.text=String(Points)+" points";
comboBox.prompt='Contestants'
comboBox.addItem({label:"John Smith",Points:10});
comboBox.addItem({label:"Chris Tucker",Points:12});
comboBox.addItem({label:"Paul Allen",Points:14});
comboBox.addEventListener(Event.CHANGE, listevalg);
function listevalg (evt:Event)
{
Points=comboBox.selectedItem.Points;
youChose.text=String(Value)+" points";
}
I'd like to have a textbox that says what the current standings are. Say I choose Chris Tucker in the combo box, I want the textbox to say something like 'He's in second place'
First you need to know which rank each person is in. To do that you can copy the list of people and sort it by Points, then register their rank as their position in that list.
import fl.events.*;
const PointsStart:int=0;
var Points:int=PointsStart;
youChose.text=String(Points)+" points";
comboBox.prompt='Contestants'
var people:Array = [{label:"John Smith",Points:10},
{label:"Chris Tucker",Points:12},
{label:"Paul Allen",Points:14}];
// Copy of "people", sorted by Points, descending.
var sortedPeople:Array = people.concat().sortOn("Points", Array.DESCENDING | Array.NUMERIC);
for each (var person:Object in people) {
// Register this person's ranking as its position in the sorted array + 1
// (because indexes start at 0)
person.Rank = sortedPeople.indexOf(person) + 1;
comboBox.addItem(person);
}
comboBox.addEventListener(Event.CHANGE, listevalg);
function listevalg (evt:Event)
{
Points=comboBox.selectedItem.Points;
// The ranking is now available as "item.Rank".
youChose.text=String(Points)+" points, rank "+String(comboBox.selectedItem.Rank);
}
If you don't actually need to keep the current order in the combobox, you don't even need to make a copy of the array before sorting.

AS3 sortOn woes

I have an Array called alarmQueue. I'm pushing a new arrays in to it with the contents [hours:int, minutes:int, seconds:int] and I'd like to use alarmQueue.sortOn() to sort the queue of alarms Ascending but I'm having problems getting my head around the logic.
// the function to push the alarm in to a queue
public function setAlarm(_hours:int = 0, _minutes:int = 0, _seconds:int = 0):void
{
var alarmAsArray:Array = new Array(_hours, _minutes, _seconds);
alarmQueue.push(alarmAsArray);
alarmQueue.sortOn([0, [1, 2]], Array.NUMERIC | Array.DESCENDING);
trace(alarmQueue);
}
I'm setting these alarms:
clock.setAlarm(1, 0, 31); // alarm 1
clock.setAlarm(12, 1, 21); // alarm 2
clock.setAlarm(12, 1, 19); // alarm 3
and getting the following traces:
1,0,31
12,1,21,1,0,31
12,1,21,12,1,19,1,0,31
I seem to be ordering them as: alarm 2, alarm 3, alarm 1
but I want to be ordering them by hour, then minute and seconds.
Can anyone shed any light on my sorting woes?
Cheers!
thanks for the feedback.
I've tested:
alarmQueue.push(
{
hours: _hours,
minutes: _minutes,
seconds: _seconds
});
alarmQueue.sortOn(
['hours', 'minutes', 'seconds'],
[Array.NUMERIC | Array.ASCENDING, Array.NUMERIC | Array.ASCENDING, Array.NUMERIC | Array.ASCENDING]
);
if(alarmQueue.length == 3)
{
for(var i:int = 0; i SMALLERTHAN alarmQueue.length; i++)
{
trace(alarmQueue[i].hours,alarmQueue[i].minutes, alarmQueue[i].seconds);
}
}
I had to change the trace slightly due to the array items being objects now and used SMALLERTHAN as the < symbol seems to break to code tags here, but the app wouldn't compile as Flex Builder was telling me Array.ASCENDING not being a sort method, so I checked livedocs and found no mention of it there too. Any other guesses?
This should work, but I have not tested it.
public function setAlarm(_hours:int = 0, _minutes:int = 0, _seconds:int = 0):void
{
alarmQueue.push(
{
hours: _hours,
minutes: _minutes,
seconds: _seconds
});
alarmQueue.sortOn(['hours', 'minutes', 'seconds'], Array.NUMERIC);
}
Found the answer after some tinkering. The default method of sorting is ascending but there's no option to set Ascending as a secondry sorting method. So by performing two sorts, the first descending on the minutes and seconds, the second is a sortOn the hours with no parameter applied so it sorts ascending!
var alarmAsArray:Array = new Array(_hours, _minutes, _seconds);
alarmQueue.push(alarmAsArray);
alarmQueue.sortOn([1, 2]);
alarmQueue.sortOn([0], Array.DESCENDING);
if(alarmQueue.length == 3)
{
trace(alarmQueue);
}
this gives the correct output of: 12,1,19 12,1,21 1,0,31
Many thanks all!
ant