Multiple rows/columns timestamp, any way to make it easier? - datetime

So, I wanted to know if there is easier way to do than using (r.getRow() ==x) and do multiple lines for rows?
It's only suppose to stamp on specific rows and in original sheets there is over 50 subjects and they all have their own rows for stamp.
function onEdit(e) {
var s = SpreadsheetApp.getActiveSheet();
if (s.getName() == "spreadsheet1") {
var r = s.getActiveCell();
if (r.getRow() == 3) {//kuitattavat rivit
var nextCell = r.offset (1, 0);
if (nextCell.getValue() === "") {//tarkistaa solun onko tyhjä}
nextCell.setValue(new Date()).setNumberFormat("HH:mm");
}
}
else {
var r = s.getActiveCell();
if (r.getRow() == 5) {//kuitattavat rivit
var nextCell = r.offset (1, 0);
if (nextCell.getValue() === "") {//tarkistaa solun onko tyhjä}
nextCell.setValue(new Date()).setNumberFormat("HH:mm");
}
}
}
else {
var r = s.getActiveCell();
if (r.getRow() == 7) {//kuitattavat rivit
var nextCell = r.offset (1, 0);
if (nextCell.getValue() === "") {//tarkistaa solun onko tyhjä}
nextCell.setValue(new Date()).setNumberFormat("HH:mm");
}
}
}
}
}

Since you are trying to use an onEdit(e) trigger anyway, you can just reference the sheet name and range of e and check the row number from there using logical OR operator ||.
function onEdit(e) {
var s = e.range.getSheet();
if (s.getName() == "spreadsheet1") {
var row = e.range.getRow();
if (row == 3 || row == 5 || row == 7) {
var nextCell = e.range.offset(1, 0);
if (nextCell.getValue() === "") {
nextCell.setValue(new Date()).setNumberFormat("HH:mm");
}
}
}
}
Sample:
References:
Simple Triggers
logical OR

Related

Why can't I increment global variable

I created a variable q outside of any function. From within my function I am attempting to simply increment it with a ++. Will this increment the global q or is this simply appending the value to a local variable? As you can see in the code sample below I am attempting to use the value of the global variable (which I intend to be updated during each execution of this script) to set a variable which should trigger this function via .change. The function is initially trigger (when q = 1) however it is not trigger when a selection is made from the dropdown box with id = "selectedId2" which is leading me to believe that q has retained a value of 1 though I successfully incremented it when the function was ran prior. Any advise of how I can increment the variable "q" for each iteration of this script would be greatly appreciated.
if (q === 1) {
selectedDiv = '#selectId1';
selectedDiv2 = '#selectId2';
}
if (q === 2) {
selectedDiv = '#selectedId2';
selectedDiv2 = '#selectedId3';
}
if (q === 3) {
selectedDiv = '#selectedId3';
selectedDiv2 = '#selectedId4';
}
if (q === 4) {
selectedDiv = '#selectedId4';
selectedDiv2 = '#selectedId5';
}
if (q === 5) {
selectedDiv = '#selectedId5';
selectedDiv2 = '#selectedId6';
}
$(selectedDiv).change(function () {
if (q == 1) {
var pullDownDivs = '#2';
}
if (q == 2) {
var pullDownDivs = '#3';
}
if (q == 3) {
var pullDownDivs = '#4';
}
if (dropDownSelectJoined != null) {
var dropDownSelectJoined = dropDownSelectJoined + ", " + $(selectedDiv).val();
}
else {
var dropDownSelectJoined = $(selectedDiv).val();
}
var SelArea = $(selectedDiv).val();
if (SelArea != 0) {
var url = '#Url.Action("NetworkSubForm")';
q++;
$.post(url, { RemovedAreaId: $('#RemovedAreaId').val(), selectedNetworkId: $('#SelectedNetworkId').val(), dropDownSelectJoined: dropDownSelectJoined },
function (data) {
var productDropdown = $(selectedDiv2);
productDropdown.empty();
productDropdown.append("<option>-- Select Area --</option>");
for (var i = 0; i < data.length; i++) {
productDropdown.append($('<option></option>').val(data[i].Value).html(data[i].Text));
}
});
$(pullDownDivs).show();
$(pullDownDivs).html();
}
else {
$(pullDownDivs).hide();
$(pullDownDivs).html();
}
});
I don't know what the rest of your code looks like, but you can see this kind of behavior due to "shadowing":
var q = 0; //global "q"
function handler() {
var q = 0; //local "q" that shadows the global "q";
...
...
q++;
console.log(q);
}
Repeatedly calling handler will output 1 each time since you are redefining a local q within handler. However, the outer q remains unchanged. But if you did this:
var q = 0; //global "q"
function handler() {
var q = 0; //local "q" that shadows the global "q";
...
...
window.q++;
console.log(window.q);
}
The global q will be updated since you are explicitly referencing it by doing window.q.

Flex sort Datagrid with custom compareFunction (sort numbers numerical and text alphanumerical)

I need following result.
All numbers use numeric sorting and all strings use alphanumeric sort. Further more , the numeric values should be listed before the string values:
Example:
before "i","9","89","0045","b","x"
after "9","0045","89","b","i","x"
My current code looks like this: (numeric sort works but my strings are distributed to the top and bottom?! -> "b","x","9","0045","89","i")
public function compareFunction(obj1:Object, obj2:Object):int {
var id1:String = (obj1 as WdProblem).id;
var id2:String = (obj2 as WdProblem).id;
if(id1.replace(' ', '') == "n") {
var sdld:int = 0;
}
var num1:int = Number(id1);
var num2:int = Number(id2);
if(stringIsAValidNumber(id1) && stringIsAValidNumber(id2)) {
if(num1 == num2) {
return 0;
} else {
if(num1 > num2) {
return 1;
} else {
return -1;
}
}
} else if(!stringIsAValidNumber(id1) && !stringIsAValidNumber(id2)) {
return ObjectUtil.compare(id1, id2);
//return compareString(id1, id2);
} else if(!stringIsAValidNumber(id1) && stringIsAValidNumber(id2)) {
return 1;
} else if(stringIsAValidNumber(id1) && !stringIsAValidNumber(id2)) {
return -1;
}
return -1;
}
private function stringIsAValidNumber(s:String):Boolean {
return Boolean(s.match("[0-9]+(\.[0-9][0-9]?)?"));
}
My suggestion is to break it down into it's constituent parts especially if you have a scenario like this with 1 or more priority sorts. The key is to move onto the next sort only when the first sort returns they are equal.
For your case, I would build 2 sorts, one for numeric and the other for alpha-numeric, then your main sort can prioritize these by calling the sub-sort.
For example I have something similar:
private function sort2DimensionsByIncomeVsTime(a:OLAPSummaryCategory, b:OLAPSummaryCategory, fields:Array = null):int
{
var sort:OLAPSort = new OLAPSort();
var incomeSort:int = sort.sortIncome(a, b);
var nameSort:int = sort.sortName(a, b);
var yrSort:int = sort.sortYear(a, b);
var moSort:int = sort.sortMonth(a, b);
if (incomeSort == 0)
{
if (nameSort == 0)
{
if (yrSort == 0)
{
//trace(a.name, a.year, a.month, 'vs:', b.name, b.year, b.month, 'month sort:', moSort);
return moSort;
}
else return yrSort;
}
else return nameSort;
}
else return incomeSort;
}
I use following sort function for AlphaNumeric sorting:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
creationComplete="onCC()"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.utils.ObjectUtil;
import mx.utils.StringUtil;
import spark.collections.Sort;
import spark.collections.SortField;
public function onCC():void
{
var acAlphaNumericString:ArrayCollection = new ArrayCollection();
acAlphaNumericString.addItem({ name: "NUM10071" });
acAlphaNumericString.addItem({ name: "NUM9999" });
acAlphaNumericString.addItem({ name: "9997" });
acAlphaNumericString.addItem({ name: "9998" });
acAlphaNumericString.addItem({ name: "9996" });
acAlphaNumericString.addItem({ name: "9996F" });
acAlphaNumericString.addItem({ name: "i" });
acAlphaNumericString.addItem({ name: "9" });
acAlphaNumericString.addItem({ name: "89" });
acAlphaNumericString.addItem({ name: "0045" });
acAlphaNumericString.addItem({ name: "b" });
acAlphaNumericString.addItem({ name: "x" });
var sf:SortField = new SortField("name");
sf.compareFunction = function(o1:Object, o2:Object):int
{
return compare(o1.name, o2.name);
}
var sort:Sort = new Sort();
sort.fields = [ sf ];
acAlphaNumericString.sort = sort;
acAlphaNumericString.refresh();
for each (var o:Object in acAlphaNumericString)
trace(o.name);
}
public static function compare(firstString:String, secondString:String):int
{
if (secondString == null || firstString == null)
return 0;
var lengthFirstStr:int = firstString.length;
var lengthSecondStr:int = secondString.length;
var index1:int = 0;
var index2:int = 0;
while (index1 < lengthFirstStr && index2 < lengthSecondStr)
{
var ch1:String = firstString.charAt(index1);
var ch2:String = secondString.charAt(index2);
var space1:String = "";
var space2:String = "";
do
{
space1 += ch1;
index1++;
if (index1 < lengthFirstStr)
ch1 = firstString.charAt(index1);
else
break;
} while (isDigit(ch1) == isDigit(space1.charAt(0)));
do
{
space2 += ch2;
index2++;
if (index2 < lengthSecondStr)
ch2 = secondString.charAt(index2);
else
break;
} while (isDigit(ch2) == isDigit(space2.charAt(0)));
var str1:String = new String(space1);
var str2:String = new String(space2);
var result:int;
if (isDigit(space1.charAt(0)) && isDigit(space2.charAt(0)))
{
var firstNumberToCompare:int = parseInt(StringUtil.trim(str1));
var secondNumberToCompare:int = parseInt(StringUtil.trim(str2));
result = ObjectUtil.numericCompare(firstNumberToCompare, secondNumberToCompare);
}
else
result = ObjectUtil.compare(str1, str2);
if (result != 0)
return result;
}
return lengthFirstStr - lengthSecondStr;
function isDigit(ch:String):Boolean
{
var code:int = ch.charCodeAt(0);
return code >= 48 && code <= 57;
}
}
]]>
</fx:Script>
</s:Application>

j script runtime error: object requiered

I am working on the platform confirmit, which creates online surveys. This is a script node that results in the runtime error "object required", I would be grateful if you could help me fix it.. It is supposed to check whether certain codes hold 1 or 2 in the questions q2b and q3a (questions are referenced with the function f() - f(question id)[code]) - the
'//skip ?' part. Then it recodes a maximum of four of the codes into another question (h_q4) for further use.
var flag1 : boolean = false;
var flag2 : boolean = false;
//null
for(var i: int=0; i <9; i++)
{
var code = i+1;
f("h_q4")[code].set(null);
}
f("h_q4")['95'].set(null);
//skip ?
for(var k: int=1; k <16; k+=2)
{
var code = k;
if(f("q2b")[code].none("1", "2"))
flag1;
else
{
flag1 = 0;
break;
}
}
if(f("q3a")['1'].none("1", "2"))
flag2;
if(flag1 && flag2)
f("h_q4")['95'].set("1");
//recode
else
{
var fromForm = f("q2b");
var toForm = f("h_q4");
const numberOfItems : int = 4;
var available = new Set();
if(!flag1)
{
for( i = 1; i < 16; i+=2)
{
var code = i;
if(f("q2b")[i].any("1", "2"))
available.add(i);
}
}
if(!flag2)
{
available.add("9");
}
var selected = new Set();
if(available.size() <= numberOfItems)
{
selected = available;
}
else
{
while(selected.size() < numberOfItems)
{
var codes = available.members();
var randomNumber : float = Math.random()*codes.length;
var randomIndex : int = Math.floor(randomNumber);
var selectedCode = codes[randomIndex];
available.remove(selectedCode);
selected.add(selectedCode);
}
}
var codes = fromForm.domainValues();
for(var i = 0;i<codes.length;i++)
{
var code = codes[i];
if(selected.inc(code))
{
toForm[code].set("1");
}
else
{
toForm[code].set("0");
}
}
}
the first part of the code (//null) empties the 'recepient' question to ease testing
.set(), .get(), .any(), .none() are all valid

Flex Datagrid + Tab Navigator

I have a several datagrids (with data being retrieved from some map service).
I want to place these data grids within seperate tabs of a tab navigator. All works fine apart from the first tab which always ends up without any datagrid in it.
I have tried creation policy="all" and stuff but the first tab always is empty. Does anybody have any ideas as to why the first tab is always empty.
Any workarounds.
Thanks
var box:HBox=new HBox();
var dg:DataGrid = new DataGrid();
dg.dataProvider = newAC;
box.label=title.text;
box.addChild(dg);
tabNaviId.addChild(box);
tabNaviId.selectedIndex=2;
resultsArea.addChild(tabNaviId);
dg is datagrid that is being filled up. The above code is in a loop, in each loop i am creating an Hbox+datagrid. then i am adding the Hbox to the navigator and final adding the navigator to resultsArea (which is a canvas).
The above code works great apart from first time.
The end result i get is, having a tab navigator with first tab without any datagrid but the remaining tabs all have the datagrids. Any ideas as to why this is happening.
Call to a function called createDatagrid is made:
dgCollection.addItem(parentApplication.resultsPanel.createDatagrid( token.name.toString() + " (" + recAC.length + " selected)", recAC, false, callsToMake ));
In another Mxml component this function exists
public function createDatagrid(titleText:String, recACAll:ArrayCollection, showContent:Boolean, callsToMake:Number):DataGrid
{
var dg:DataGrid = new DataGrid();
var newAC:ArrayCollection = new ArrayCollection();
var newDGCols:Array = new Array();
for( var i:Number = 0; i < recACAll.length; i ++)
{
var contentStr:String = recACAll[i][CONTENT_FIELD];
var featureGeo:Geometry = recACAll[i][GEOMETRY_FIELD];
var iconPath:String = recACAll[i][ICON_FIELD];
var linkStr:String = recACAll[i][LINK_FIELD];
var linkNameStr:String = recACAll[i][LINK_NAME_FIELD];
var featurePoint:MapPoint = recACAll[i][POINT_FIELD];
var titleStr:String = recACAll[i][TITLE_FIELD];
if( contentStr.length > 0)
{
var rows:Array = contentStr.split("\n");
var tmpObj:Object = new Object();
if(!showContent)
{
for( var j:Number = 0; j < rows.length; j++)
{
var tmpStr:String = rows[j] as String;
var header:String = tmpStr.substring(0,tmpStr.indexOf(":"));
var val:String = tmpStr.substring(tmpStr.indexOf(":") + 2);
if(header.length > 0)
{
tmpObj[header] = val;
if(newDGCols.length < rows.length - 1)
{
newDGCols.push( new DataGridColumn(header));
}
}
}
}
else
{
if(newDGCols.length == 0)
{
newDGCols.push(new DataGridColumn(CONTENT_FIELD));
newDGCols.push(new DataGridColumn(GEOMETRY_FIELD));
newDGCols.push(new DataGridColumn(ICON_FIELD));
newDGCols.push(new DataGridColumn(LINK_FIELD));
newDGCols.push(new DataGridColumn(LINK_NAME_FIELD));
newDGCols.push(new DataGridColumn(POINT_FIELD));
newDGCols.push(new DataGridColumn(TITLE_FIELD));
}
}
tmpObj[CONTENT_FIELD] = contentStr;
tmpObj[GEOMETRY_FIELD] = featureGeo;
tmpObj[ICON_FIELD] = iconPath;
tmpObj[LINK_FIELD] = linkStr;
tmpObj[LINK_NAME_FIELD] = linkNameStr;
tmpObj[POINT_FIELD] = featurePoint;
tmpObj[TITLE_FIELD] = titleStr;
newAC.addItem(tmpObj);
}
if( showHidePic.source == minSourceI )
{
showHidePic.source = minSource;
}
else if( showHidePic.source == maxSourceI )
{
showHidePic.source = maxSource;
}
curResults = curResults + recACAll.length;
if (curResults == 1)
{
showInfoWindow(tmpObj);
if(showContent)
{
parentApplication.maps.map.extent = featureGeo.extent;
}
}
else
{
showInfoWindow(null);
// Added to avoid the overview button problem (needs checking)
this.removeEventListener(MouseEvent.MOUSE_OVER, handleMouseOver, false);
this.removeEventListener(MouseEvent.MOUSE_MOVE,handleMouseOver,false);
this.removeEventListener(MouseEvent.MOUSE_OUT,handleMouseOut,false);
this.removeEventListener(MouseEvent.MOUSE_DOWN,handleMouseDrag,false);
this.removeEventListener(MouseEvent.MOUSE_UP,handleMouseDragStop,false);
this.parent.removeEventListener(MouseEvent.MOUSE_MOVE,handleParentMove,false);
this.parent.removeEventListener(MouseEvent.MOUSE_UP,handleMouseDragStop2,false);
maximizePanel();
}
}
dg.dataProvider = newAC;
dg.columns = newDGCols;
dg.rowCount = newAC.length;
var totalDGCWidth:Number = 0;
for( var m:Number = 0; m < dg.columns.length; m++)
{
var dgc2:DataGridColumn = dg.columns[m];
/*if(dgc2.headerText.toUpperCase()==LINK_FIELD.toUpperCase()){
//dgc.itemRenderer=new ClassFactory(CustomRenderer);
dgc2.itemRenderer=new ClassFactory(CustomRenderer);
}*/
var dgcWidth2:Number = dgc2.headerText.length * CHAR_LENGTH;
for( var l:Number = 0; l < newAC.length; l++)
{
var row2:Object = newAC.getItemAt(l) as Object;
var rowVal2:String = row2[dgc2.headerText];
if( rowVal2 != null)
{
var tmpLength2:Number = rowVal2.length * CHAR_LENGTH;
if(tmpLength2 < CHAR_MAX_LENGTH)
{
if(tmpLength2 > dgcWidth2)
{
dgcWidth2 = tmpLength2;
}
}
else
{
dgcWidth2 = CHAR_MAX_LENGTH
break;
}
}
}
// Added by FT:to change the item renderer for link field
if( dgc2.headerText == GEOMETRY_FIELD || dgc2.headerText == CONTENT_FIELD ||
dgc2.headerText == ICON_FIELD || dgc2.headerText == LINK_FIELD ||
dgc2.headerText == POINT_FIELD || dgc2.headerText == TITLE_FIELD ||
dgc2.headerText == LINK_NAME_FIELD)
{
if(dgc2.headerText == CONTENT_FIELD && showContent)
{
//something
}
else
{
dgcWidth2 = 0;
}
}
totalDGCWidth += dgcWidth2;
}
dg.width = totalDGCWidth;
for( var k:Number = 0; k < dg.columns.length; k++)
{
var dgc:DataGridColumn = dg.columns[k];
var dgcWidth:Number = dgc.headerText.length * CHAR_LENGTH;
for( var n:Number = 0; n < newAC.length; n++)
{
var row:Object = newAC.getItemAt(n) as Object;
var rowVal:String = row[dgc.headerText];
if(rowVal != null)
{
var tmpLength:Number = rowVal.length * CHAR_LENGTH;
if(tmpLength < CHAR_MAX_LENGTH)
{
if(tmpLength > dgcWidth)
{
dgcWidth = tmpLength;
}
}
else
{
dgcWidth = CHAR_MAX_LENGTH
break;
}
}
}
if( dgc.headerText == GEOMETRY_FIELD || dgc.headerText == CONTENT_FIELD ||
dgc.headerText == ICON_FIELD || dgc.headerText == LINK_FIELD ||
dgc.headerText == POINT_FIELD || dgc.headerText == TITLE_FIELD ||
dgc.headerText == LINK_NAME_FIELD)
{
if(dgc.headerText == CONTENT_FIELD && showContent)
{
dgc.visible = true;
}
else
{
dgc.visible = false;
dgcWidth = 0;
}
}
if( dgc.headerText == LINK_COL_NAME)
{
dgcWidth = LINK_COL_WIDTH;
}
dgc.width = dgcWidth;
}
dg.addEventListener(ListEvent.ITEM_CLICK,rowClicked);
dg.addEventListener(ListEvent.ITEM_ROLL_OVER,mouseOverRow);
dg.addEventListener(ListEvent.ITEM_ROLL_OUT,mouseOutRow);
var title:Text = new Text();
title.text = titleText;
title.setStyle("fontWeight","bold");
//resultsArea.addChild(title);
return dg;
//tabNaviId.selectedIndex=2;
}
public function populateGrid(dgCollection:ArrayCollection):void{
for( var k:Number = 0; k < dgCollection.length; k++)
{
var box:HBox=new HBox();
var dg2:DataGrid=dgCollection.getItemAt(k) as DataGrid;
box.label="some";
box.addChild(dg2);
tabNaviId.addChild(box);
}
resultsArea.addChild(tabNaviId);
}
and the tab navigator declared as
<mx:Image id="showHidePic" click="toggleResults()"/>
<mx:VBox y="20" styleName="ResultsArea" width="100%" height="100%">
<mx:HBox>
<mx:Button label="Export to Excel" click="downloadExcel()"/>
<mx:Button label="Clear" click="clear()" />
</mx:HBox>
<mx:VBox id="resultsArea" styleName="ResultsContent" paddingTop="10" paddingLeft="10" paddingRight="10" verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:TabNavigator id="tabNaviId" width="622" height="274" creationPolicy="all">
</mx:TabNavigator>
</mx:VBox>
</mx:VBox>
Abstract, can we get the full code including the loop you mention, as well as the code where you create the TabNavigator?
It's possible that the TabNavigator already has an initial child, and all the children you're creating are being added after that.

Style formatting contd

I need to write text in green or red based on:
if(str > 0)
{
document.getElementById('change').style.color = "Green";
document.getElementById('change').innerHTML = html[1];
}
else
{
document.getElementById('change').style.color = "Red";
document.getElementById('change').innerHTML = html[1];
}
str = html[2];
str = str.replace("+","");
str = str.replace("-","");
if(str > 0)
{
document.getElementById('changePercent').style.color = "Green";
document.getElementById('changePercent').innerHTML = html[2];
}
else
{
document.getElementById('changePercent').style.color = "Red";
document.getElementById('changePercent').innerHTML = html[2];
}
But for values -17.91, -5.61, i get both values in the green. Where is the error?
var value = $('p').text();
if (value > 0){
$('p').css('color','green');
}
else {
$('p').css('color','red');
}
Simple jQuery
It could be something bizarre about your variable type. I'm only suspicious because your variable is called str.

Resources