Adding multiple Variables to check value of another variable, Javascript - javascript

I am attemtping to add strings together to create the name of a variable, which I can then check its value. The code may explain this better, to understand what I mean.
I have several variables like below
var scList = ["stream", "dev", "web"];
var stream_sc = ["test0", "test1"];
var dev_sc = ["value","value"];
var web_sc = ["value", "value"];
In another function I am checking if entered text matches one of the values in scList, I then hope to add the string "_sc" to the end of the entered text, and from there be able to display the values inside the variables ending in _sc. The below is what I have so far. (With dataAr[1] being the user entered string I am checking for)
for (var i = 0; i < scList.length; i++) {
if (dataAr[1] == scList[i]) {
window.alert(scList[i]+"_sc"[0]);
}
}
While it is able to match the string to a value in the scList Array properly, the value returned by the window alert is just the user entered string, not showing the "_sc", which makes sense but how could I get this to then relate to the matching variable ending in "_sc"?
To Clarify
My hope is that if a user entered "stream" or if dataAr[1] == "stream" that the returned value would be "test0" from stream_sc[0]
Thank you for any help!

You have an extraneous [0] after "_sc" which would grab the underscore and append it to the variable name. What you want is probably scList[i] + "_sc"
You should store them in a json object, so you can reference the sc names to retrieve the values, like so:
const varMap = {
"stream_sc": [ ],
"dev_sc": [ ],
"web_sc": [ ]
};
// access the map using the entered value
varMap[scList[i] + "_sc"][j]
// where j would be the desired item index in the _sc array
I'm currently on a phone, so I hope the formatting comes out ok.
EDIT: fixed some syntax that was needed that the asker pointed out.

I assume you dataAR is an array as you make a reference to a key in the conditional dataAr[1]. You could use .includes() in that case to see if your array includes the value of scList[i]... I used a select to show how this could be achieved in a for loop and conditional. If the conditional is true, then rather that using the array scList[i] value use the value that is true... Then concatenate the _sc onto the value and define that as a new variable...
var sel = document.getElementById('sel');
var dataAr = ['gaming']; // array with a value that is not true present already
var scList = ["stream", "dev", "web"];
var stream_sc = ["test0", "test1"];
var dev_sc = ["value", "value"];
var web_sc = ["value", "value"];
function getVal(scList, sel) {
for (var i = 0; i < scList.length; i++) {
if (scList.includes(sel.value)) {
val = sel.value + '_sc';
return val;
}
}
}
let val;
sel.addEventListener("change", function(e) {
dataAr.push(sel.value);
alert(getVal(scList, sel));
// val myVar = getVal(scList, sel); <-- Do something with this var now
});
<select name="sel" id="sel">
<option>--select an option below--</option>
<option value="stream">Twitch</option>
<option value="dev">Visual Studio Code</option>
<option value="web">Mozilla</option>
</select>

Related

Google Script: Retrieving Default Values for Filter

I would like to create a filter for a column in a spreadsheet, then retrieve the list of default criteria values created for the filter. I believe that my code returns a Filter object without any values for it.
function TestFilter(){
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
sheet.getRange(1, 2, sheet.getMaxRows(), 1).createFilter();
var filter = sheet.getFilter();
var output = filter.getColumnFilterCriteria(2).getCriteriaValues();
return output;
}
You can use the following functions for this:
getHiddenValues()
Returns the values to hide.
getVisibleValues()
Returns the values to show.
In case your filter is set to hide all of the possible values, you will obtain what you desire by using the function getHiddenValues().
However, this will not be possible if your filter is only hiding a subset of your values. For that case, you could use a Google Apps Script function such as the following below to obtain the distinct values:
function getDistinctValues(range) {
var values = range.getValues();
var unique = {};
for (var i=0; i<values.length; i++) {
for (var j=0; j<values[i].length; j++) {
var key = values[i][j];
if (key !== null && key !== undefined && key !== '')
unique[key] = true;
}
}
return Object.keys(unique);
}
The usage of it would be, in case you were attempting to obtain the distinct values on your A column:
var distinctValues = getDistinctValues(sheet.getRange("A2:A"));
Note that this function will return the values as Strings. In case you want to obtain the actual numeric value instead of a String, you can parse the values simply by using the following code:
var distinctValues = getDistinctValues(sheet.getRange("A2:A")).map(parseFloat);
I believe there is a bug with 2 out of 3 of these functions, by using something like this:
var filter = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheetName").getFilter();
var criteriaValues = filter.getColumnFilterCriteria(9).getCriteriaValues();
Logger.log("criteria Values length " + criteriaValues.length);
Logger.log(criteriaValues);
var visibleValues = filter.getColumnFilterCriteria(9).getVisibleValues();
Logger.log("visible Values length " + visibleValues.length);
Logger.log(visibleValues);
var hiddenValues = filter.getColumnFilterCriteria(9).getHiddenValues();
Logger.log("hidden Values length " + hiddenValues.length);
Logger.log(hiddenValues);
and setting a filter on column I (9th from the left) regardless of how many or which values I filter by, I only ever see the values that I've hidden from the column, the criteriaValues and visibleValues arrays are always empty, while hiddenValues always shows correctly the values that are filtered out.
If someone could double check this and confirm it would be great, otherwise, maybe I'm just doing something really silly, in which case please let me know as well :).
This is created based on https://developers.google.com/apps-script/reference/spreadsheet/filter-criteria.html
Blockquote

Add values from one array to object with specified key & index

Im using the following code,
jQuery.each(aDataSel, function(index, oData) {
oPushedObject = {};
aSelectedDataSet.push(fnCreateEnt(aProp, oData, oPushedObject));
});
This is aSelectedDataSet values
and this is the values of OData
What I need is that before I do the push is to fill the listTypeGroup & listTypeGroupDescription (with the red arrow ) with values that Are inside the oData -> ListTypeGroupAssigment -> result (listTypeGroup & listTypeGroupDescription) , The index is relevant since I want to add just the value of the index in each iteration (since this code is called inside outer loop and the index determine the current step of the loop) ,How it can be done nicely?
The result contain 100 entries (always) and the a selected data will have 100 entries at the end...
Update :)
Just to be clear In the pic I show the values which is hardcoded for this run but the values can be any values, we just need to find the match between the both objects values...
I mean to find a match between to_ListTypeGroupAssigment in both object (which in this case exist ) and if in oData there is result bigger then one entry start with the matching ...
UPDATE2 - when I try Dave code the following happen for each entry,
This happen in the Jquery.extend line...any idea how to overcome this?
The following hard-coded of Dave:-) work perfect but I need generic code which doesnt refer to specific field name
jQuery.each(aDataSet, function(index, oData) {
oPushedObject = {};
fnCreatePushedEntry(aProperties, oData, oPushedObject);
var result = oData.to_ListTypeGroupAssignment.results[index];
oPushedObject.to_ListTypeGroupAssignment = {
ListTypeGroup: result.ListTypeGroup,
ListTypeGroupDescription: result.ListTypeGroupDescription
};
aSelectedDataSet.push(oPushedObject);
});
Im stuck :(any idea how to proceed here ?what can be wrong with the extend ?
should I use something else ? Im new to jQuery...:)
I think that this happen(in Dave answer) because the oData[key] is contain the results and not the specified key (the keyValue = to_ListTypeGroupAssignment ) which is correct but we need the value inside the object result per index...
var needValuesForMatch = {
ListTypeGroup: 'undefined',
ListTypeGroupDescription: 'undefined',
}
//Just to show that oPushedObject can contain additional values just for simulation
var temp = {
test: 1
};
//------------------This object to_ListTypeGroupAssigment should be filled (in generic way :) ------
var oPushedObject = {
temp: temp,
to_ListTypeGroupAssignment: needValuesForMatch
};
oPushedObject is one instance in aSelectedDataSet
and after the matching I need to do the follwing:
aSelectedDataSet.push(oPushedObject);
Is this what you're after:
OPTION ONE - DEEP CLONE FROM oData TO aSelectedDataSet
aSelectedDataSet.forEach(function(currentObject,index){
for (var childObject in currentObject) {
if (! currentObject.hasOwnProperty(childObject))
continue;
var objectToClone = oData[childObject]['results'][index];
if(objectToClone)
$.extend(true,currentObject[childObject],objectToClone);
}
});
Here is your data in a fiddle with the function applied: https://jsfiddle.net/hyz0s5fe/
OPTION TWO - DEEP CLONE FROM oData ONLY WHERE PROPERTY EXISTS IN aSelectedDataSet
aSelectedDataSet.forEach(function(currentObject,index){
for (var childObject in currentObject) {
if (! currentObject.hasOwnProperty(childObject))
continue;
if(typeof currentObject[childObject] !== 'object')
continue;
for(var grandChildObject in currentObject[childObject]) {
var objectToClone = oData[childObject]['results'][index][grandChildObject];
if(typeof objectToClone === 'object') {
$.extend(true,currentObject[childObject][grandChildObject],objectToClone);
} else {
currentObject[childObject][grandChildObject] = objectToClone;
}
}
}
Fiddle for option 2: https://jsfiddle.net/4rh6tt25/
If I am understanding you correctly this should just be a small change:
jQuery.each(aDataSel, function(index, oData) {
oPushedObject = {};
fnCreateEnt(aProp, oData, oPushObj);
//get all the properties of oData and clone into matching properties of oPushObj
Object.getOwnPropertyNames(oData).forEach(function(key) {
if (oPushObj.hasOwnProperty(key)) {
//oPushObj has a matching property, start creating destination object
oPushObj[key] = {};
var source = oData[key];
var destination = oPushObj[key];
//can safely assume we are copying an object. iterate through source properties
Object.getOwnPropertyNames(source).forEach(function(sourceKey) {
var sourceItem = source[sourceKey];
//handle property differently for arrays
if (Array.isArray(sourceItem)) {
//just copy the array item from the appropriate index
destination[sourceKey] = sourceItem.slice(index, index + 1);
} else {
//use jQuery to make a full clone of sourceItem
destination[sourceKey] = $.extend(true, {}, sourceItem);
}
});
}
});
aSelectedDataSet.push(oPushedObject);
});
It is unclear what exactly your fnCreateEnt() function returns though. I am assuming it is the populated oPushObj but it's not entirely clear from your question.

Angular - Select box - set selected entry from controller

I have a select box, defined as follows:
<select ng-model="selectedSupplier" ng-options="supplier.name for supplier in suppliers">
</select>
IN my controller, I have the a button which, although not doing anything useful, serves to explain a problem I'm having changing the selected value in the controller:
When this function is executed, the options in the select box are set, and the selected option is set:
$scope.foo = function() {
var foos = [{"id":1,"name":"No 1"},{"id":2,"name":"No 2"},{"id":3,"name":"No 3"},{"id":4,"name":"No 4"}];
$scope.suppliers = foos;
$scope.selectedSupplier = foos[2];
}
But I changed the function to be like this, it still sets the options, but the selected option is a new blank option, none of my defined ones:
$scope.foo = function() {
var foos = [{"id":1,"name":"No 1"},{"id":2,"name":"No 2"},{"id":3,"name":"No 3"},{"id":4,"name":"No 4"}];
$scope.suppliers = foos;
$scope.selectedSupplier = {"id":3,"name":"No 3"};
}
What's going on here? How can I set the selected option using an object other than the original?
This is an equality/identity issue. The literal
$scope.selectedSupplier = {"id":3,"name":"No 3"};
Is not the same as the object in your foos array. Although they contain the same data, they are 2 different references.
$scope.selectedSupplier === foos[2] // false
You correctly reference the object in your array in your first example.
$scope.selectedSupplier = foos[2];
ngOptions directive handles arrays and objects differently: https://docs.angularjs.org/api/ng/directive/ngOptions
In this line:
$scope.selectedSupplier = {"id":3,"name":"No 3"};
You are assigning an independant object into $scope.selectedSupplier, which is not part of the options list. There is no deep comparison behind the scenes - in case of complex objects, you must assign the actual object itself.
If you want for example to assign selected value based on the id property, have such code:
var idToAssign = 2;
for (var i = 0; i < $scope.suppliers.length; i++) {
var curSupplier = $scope.suppliers[i];
if (curSupplier.id == idToAssign) {
$scope.selectedSupplier = curSupplier;
break;
}
}
I tried it with removing " around object keys (id not "id") as it is not required in javascript and it worked.
$scope.foo = function() {
var foos = [{id:1,name:"No 1"},{id:2,name:"No 2"},{id:3,name:"No 3"},{id:4,name:"No 4"}];
$scope.suppliers = foos;
$scope.selectedSupplier = {id:3,name:"No 3"};
};
if you have no issue removing quotes then it can be a solution

Get all items in NotesXSPDocument

In my Notes Database, I perform an audit when the document is saved. Pretty easy in LotusScript. I grab the original document (oDoc) from the server, then in the document I modified (mDoc), I do a Forall loop that gets the names of each item; forall item in mDoc.items. Grab the same item from oDoc, execute a function with the new item as an argument that will run down a case statement that will see if its a field we care about. if so, I update a set of list values in the document with "When", "Who", "What field", and the "New Value".
I'm doing this in a server side script. In trying this, I discovered a couple of interesting things;
currentDocument is the NotesXSPDocument that contains everything that was just changed.
currentDocument.getDocument() contains the pre-change values. It also returns a NotesDocument which has the "items" field that I can run through.
Thing is, I need something similar in the NotesXSPDocument. Is there a way in an iterative loop to grab the names and values of all items from there?
Here's the broken code. (Currently it's walking through the NotesDocument items, but those are the old values. I'd rather walk down the XSP document items)
function FInvoice_beginAudit() {
var original_doc:NotesDocument = currentDocument.getDocument();
var oItem:NotesItem;
var oItems:java.util.Vector = original_doc.getItems();
var iterator = oItems.iterator();
while (iterator.hasNext()) {
var oItem:NotesItem = iterator.next();
item = currentDocument.getItemValue(oItem.getName());
if (oItem == undefined) {
var MasterItem = ScreenAudit(doc,item,True)
if (MasterItem) { return true }
} else {
if (item.getValueString() != oItem.getValueString()) {
var MasterItem = ScreenAudit(doc,Item,True);
if (MasterItem) { return true }
}
}
}
}
You can get both versions of a document after submit - the original and the one with changed/new values:
original: var original_doc:NotesDocument = currentDocument.getDocument();
changed: var changed_doc:NotesDocument = currentDocument.getDocument(true);
This way you can compare the items for changes.
But, there is a pitfall: after assigning "changed_doc" to currentDocument.getDocument(true) the "original_doc" has the changed values too because both variables point to the same document. That's why we have to copy all items from currentDocument.getDocument() to a new temporary document first and only after get the changed values with currentDocument.getDocument(true). As an alternative you could read the original document from server like you do in LotusScript.
This is a code for detecting changed items as a starting point:
var original_doc:NotesDocument = database.createDocument();
currentDocument.getDocument().copyAllItems(original_doc, true);
var changed_doc:NotesDocument = currentDocument.getDocument(true);
var oItems:java.util.Vector = original_doc.getItems();
var iterator = oItems.iterator();
while (iterator.hasNext()) {
var oItem:NotesItem = iterator.next();
var itemName = oItem.getName();
var cItem:NotesItem = changed_doc.getFirstItem(itemName);
if (cItem.getText() !== oItem.getText()) {
print("changed: " + itemName);
}
oItem.recycle();
cItem.recycle();
}
original_doc.remove(true);
original_doc.recycle();

iterating over JSON in javascript to put into select options

I keep having issues iterating over some JSON to put in select options
(btw, ignore the actual values for "label", those are garbage atm).
Here is an example that my php is passing into this:
[{"value":"1","label":"04-22-12"},{"value":"4","label":"04\/04\/12"}]
I am currently trying this loop:
*note, dateSelect is defined somewhere else
for (res in JSON.parse(request.responseText)) {
var date = document.createElement("option");
date.value = res.value;
date.text = res.label;
dateSelect.add(date, null);
}
However, it is adding "undefined" into my options...
How do I get it so each value and corresponding label is put in there correctly?
You have an Array, so don't for-in.
In your code, res is the property name (the index of the Array in this case) in the form of a string, so the properties you're looking for aren't going to be defined on the string.
Do it like this...
for (var i = 0, parsed = JSON.parse(request.responseText); i < parsed.length; i++) {
var res = parsed[i];
var date = document.createElement("option");
date.value = res.value;
date.text = res.label;
dateSelect.add(date, null);
}

Categories