Unable to .empty() the appended elements - javascript

state.on('change', function(){
city.empty();
$.getJSON("pincodes.JSON", function(pincodes){
var key = state.val();
for (var j= 0; j < pincodes['address'].length; j++) {
if (pincodes['address'][j]['circlename'] == key) {
temp.push(pincodes['address'][j]['regionname']);
}
}
cities = $.unique(temp);
for (var k = 0; k < cities.length; k++) {
city.append('<option>' + cities[k] + '</option>');
}
});
});
In the above state = $('#state') , the above works fine fills the cities on select "state" . But the issue is when a new state is selected the previously filled cities are also there . Even though I tried .empty on every change() .

You don't empty your temp array. So, every time this function is called, you keep appending items to your temp array.
You simply need to add the following line in your code:
state.on('change', function() {
city.empty();
temp = []; // <---
$.getJSON("pincodes.JSON", function(pincodes) {
What about cities = $.unique(temp);, it won't work.
According to jQuery.unique() documentation, this function
Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers.
So, it is not a correct usage. If you get non-unique values from your JSON, you will need to use another way to get distinct values. There is a good SO article on this topic.

Related

How can I dynamically index through datalayer tags in GTM?

I'm using the DuracellTomi datalayer plugin to push cart data from woocommerce to a GTM model to handle some tracking.
The DuracellTomi plugin pushes content to the transactionProducts[] array in the following format:
transactionProducts: Array[1]
0 : Object
category:""
currency:"USD"
id:8
name:"Test"
price:100
quantity:"1"
sku:8
I'd like to loop through this array and unstack it into three separate arrays, pricelist, skulist, and quantitylist. Currently I anticipate doing so as some variation on
//Get Product Information
if(stack = {{transactionProducts}}){
for(i = 0; i < stack.length; i++) {
if(stack.i.sku){
skulisttemp.i = stack.i.sku;
}
if(stack.i.price){
pricelisttemp.i = stack.i.price;
}
if(stack.i.sku){
quantitylisttemp.i = stack.i.quantity;
}
}
{{skulist}} = skulisttemp;
{{pricelist}} = pricelisttemp;
{{quantitylist}} = quantitylisttemp;
}
Obviously this is not going to work because of how the tag referencing is set up, but I'm wondering if anyone has dealt with this and knows what the best way to index through these arrays might be. (For those who don't know, the square bracket array call doesn't work with GTM variables and instead the . format is used instead.)
You would need to create 3 variable type custom javascript function that picks your required value from dataLayer and returns it in an array.
Something like
function(){
var products = {{transactionProducts}};
var skuArray = [];
for(i = 0; i < products.length; i++) {
if(products[i].sku){
skuArray.push(products[i].sku)
}
}
return skuArray
}
hope this helped you :)

Javascript: Traversing through array and accessing its various elements?

Essentially what I'm trying to do right now is, given some input text, I split it up by white space and display on a
div id= "animation"
Every time a button is clicked, the array should go forward one word.
This is my current attempt.
function displayText() {
var displayText = document.getElementbyID("animation");
var list = (document.getElementbyID("input").split(/[ \tn]+/);
for (var i = 0; i < list.length; i++) {
displayText.innerHTML = list.get[i];
}
}
Is my thought process somewhat correct? For whatever reason, it doesn't seem to be working.
there are multiple issues in your method
function displayText() {
var displayTextAnimation = document.getElementbyID("animation"); //keep variable name and method name different
var list = (document.getElementbyID("input").value).split(/[ \tn]+/); //use value property and observe extra bracket
for (var i = 0; i < list.length; i++) {
displayTextAnimation.innerHTML = list.charAt(i); //observe replacing get by charAt
}
}

How to sort an array based on values of another array?

I have an array that has following values
Nata_sha_AD8_02_ABA
Jack_DD2_03_K
Alex_AD8_01_PO
Mary_CD3_03_DC
John_DD2_01_ER
Daniel_AD8_04_WS
I want to group them based on following array ['AD8','CD3','DD2','PD0']; and sort each group based on number of each value. So the output should be
Alex_AD8_01_PO
Nata_sha_AD8_02_ABA
Daniel_AD8_04_WS
Mary_CD3_03_DC
John_DD2_01_ER
Jack_DD2_03_K
So far, I wrote following code, but it does not work properly, and I am stuck here.
var temparr = [];
var order = 1000;
var pos = -1;
var temp = -1;
var filterArray= ['AD8','CD3','DD2','PD0'];
for (i =0; i< filterArray.length; i++) {
for (j =0; j < myarray.length; j++) {
if(filterArray[i].toUpperCase().search(myarray[j])>0){
temp = str.substring(myarray[j].indexOf(filterArray[i])+4, myarray[j].indexOf(filterArray[i]+6);
if(temp < order){
pos = j;
order = temp;
}
if(j == myarray.length-1){ //reached end of the loop
temparr.push(myarray[pos]);
order = 1000;
}
}
}
}
Using the first sort parameter you can pass a function to run to sort the array. This function receives 2 values of the array, and should compare them and return less than 0 if the first is lower than the second, higher than 0 if it is higher, or 0 if they are the same. In my proposition, I split the name and "token" part of the values, and then compare the tokens to order them correctly. Using the indexOf on the filterArray allows me to compare the position of the tags accordingly.
var array_to_sort = ['Natasha_AD8_02',
'Jack_DD2_03',
'Alex_AD8_01',
'Mary_CD3_03',
'John_DD2_01',
'Daniel_AD8_04'
];
var filterArray = ['AD8', 'CD3', 'DD2', 'PD0'];
array_to_sort.sort(function(a, b) {
a_token = a.substr(a.indexOf('_')+1); //Remove the name part as it is useless
b_token = b.substr(b.indexOf('_')+1);//Remove the name part as it is useless
if(a_token.substr(0,3) == b_token.substr(0,3)){//If the code is the same, order by the following numbers
if(a_token > b_token){return 1;}
if(a_token < b_token){return -1;}
return 0;
}else{ //Compare the position in the filterArray of each code.
if(filterArray.indexOf(a_token.substr(0,3)) > filterArray.indexOf(b_token.substr(0,3))){return 1;}
if(filterArray.indexOf(a_token.substr(0,3)) < filterArray.indexOf(b_token.substr(0,3))){return -1;}
return 0;
}
});
document.write(array_to_sort);
EDIT: This method will sort in a way that the filterArray can be in any order, and dictates the order wanted. After updates from OP this may not be the requirement... EDIT2: the question being modified more and more, this solution will not work.
My solution.
The only restriction this solution has has is that your sort array has to be sorted already. The XXn_nn part can be anywhere in the string, but it assumes the nn part always follows the XXn part (like DD3_17).
var result=new Array();
var p,x;
//loop the 'search' array
for(var si=0,sl=sort.length;si<sl;si++){
//create new tmp array
var tmp=new Array();
//loop the data array
for(var ai=0,al=arr.length;ai<al;ai++){
var el=arr[ai];
//test if element still exists
if(typeof el=='undefined' || el=='')continue;
//test if element has 'XXn_nn' part
if(arr[ai].indexOf(sort[si]) > -1){
//we don't now where the 'XXn_nn' part is, so we split on '_' and look for it
x=el.split('_');
p=x.indexOf(sort[si]);
//add element to tmp array on position nn
tmp[parseInt(x[p+1])]=el;
//remove element from ariginal array, making sure we don't check it again
arr.splice(ai,1);ai--;
}
}
//remove empty's from tmp array
tmp=tmp.filter(function(n){return n!=undefined});
//add to result array
result=result.concat(tmp);
}
And a working fiddle
On the basis that the filtering array is in alphabetical order, and that every string has a substring in the format _XXN_NN_ that you actually want to sort on, it should be sufficient simply to sort based on extracting that substring, without reference to filterArray:
var names = ['Nata_sha_AD8_02_ABA', 'Jack_DD2_03_K', 'Alex_AD8_01_PO', 'Mary_CD3_03_DC', 'John_DD2_01_ER', 'Daniel_AD8_04_WS'];
names.sort(function(a, b) {
var re = /_((AD8|CD3|DD2|PD0)_\d\d)_/;
a = a.match(re)[1];
b = b.match(re)[1];
return a.localeCompare(b);
});
alert(names);

Google Sites Listitem

I am working with the google sites list item.
The classes are Here and Here
I have been able to iterate through the columns and put all of the column headers in to one array with the following code.
//Global
var page = getPageByUrl(enter URL here)
var name = page.getName();
function getInfo() {
var columns = page.getColumns();
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
}
Now I want to be able to get each row of the listitem and put it in its own array.
I can add the variable
function getInfo() {
var columns = page.getColumns();
var listItems = page.getListItems();//new variable
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
}
Now that I have the variable the output is [ListItem, ListItem, ListItem, ListItem]
So I can use a .length and get a return of 4.
So now I know I have 4 rows of data so based on my wants I need 4 arrays.
Small interjection here, Not a coder by trade but code as a precursor to wants becoming needs.
A buddy of mine who is a JS coder by trade showed me this code which does work. With the logger added by me.
for (var i in listItems) {
if (listItems.hasOwnProperty(i)) {
item = listItems[i];
for (var x = 0; x < columnList.length; x++) {
attrib = item.getValueByName(columnList[x]);
Logger.log("Logging value of get list page get value by name = " + columnList[x] + " " + attrib);
}
}
}
Which brings the total code to
var name = page.getName();
var listItems = page.getListItems();
var listCount = listItems.length
var listList = [];
var columns = page.getColumns();
var name = columns[0].getName();
var item, attrib = 0;
var columnList = [];
Logger.log(listItems);
Logger.log(name + " was last updated " + page.getLastUpdated());
Logger.log(name + " was last edited " + page.getLastEdited());
var listCount = 0;
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
Logger.log(columnList);
// Get index of Due Date
var dueDateValue = columnList.indexOf("Due Date");
Logger.log("The index of due date is " + dueDateValue);
for (var i in listItems) {
if (listItems.hasOwnProperty(i)) {
item = listItems[i];
for (var x = 0; x < columnList.length; x++) {
attrib = item.getValueByName(columnList[x]);
Logger.log("Logging value of get list page get value by name = " + columnList[x] + " " + attrib);
}
}
}
}`
Forgive the above code as it has been a bit of a sketch pad trying to work this out.
I am a bit behind on understanding what is happening here
for (var i in items) { // This is for each item in the items array
if (items.hasOwnProperty(i)) {
if items is an array, how can we use has own property? Doesn't that belong to an object? Does an array become an object?
My questions are two category fold.
Category # 1
What is happening with the hasOwnProperty?
-Does the array become an object and thus can be passed to .hasOwnProperty value
Category # 2
Is this the only way to take the values from the listitem and populate an array
- If it is, is there some way to delimit so I can pass each row into it's own array
- If it isn't , why does it work with the hasOwnProperty and why doesn't it work without it in the example below
for (var i in listItems) {
for (var y = 0; y < columnList.length; y++) {
item = listItems[i];
listList = item.getValueByName(columnList[x]);
Logger.log("Logging my version of list naming " + listList);
}
In which I get a "Invalid argument: name (line 41" response. Highlighting the
listList = item.getValueByName(columnList[x]);
Not looking for a handout but I am looking to understand the hasOwnPropertyValue further.
My current understanding is that hasOwnValue has to do with prototyping ( vague understanding ) which doesn't seem to be the case in this instance
and it has to depend on a object which I described by confusion earlier.
To clarify my want:
I would like to have each row of listitems in its own array so I can compare an index value and sort by date as my current column headers are
["Project", "Start Date" , "End Date"]
Any and all help is much appreciated for this JS beginner of 2 weeks.
An array can be inside of an object as the value of a member:
{"myFirstArray":"[one,two,blue]"}
The above object has one member, a name/value pair, where the value of the member is an array.
Here is a link to a website that explains JSON.
Link To JSON.org
JSON explained by Mozilla
There are websites that will test the validity of an object:
Link to JSONLint.com
An array has elements, and elements in an array can be other arrays. So, there can be arrays inside of arrays.
.hasOwnProperty returns either true or false.
Documentation hasOwnProperty
Interestingly, I can use the hasOwnProperty method in Apps Script on an array, without an error being produced:
function testHasProp() {
var anArrayTest = [];
anArrayTest = ['one', 'two', 'blue'];
Logger.log(anArrayTest);
var whatIsTheResult = anArrayTest.hasOwnProperty('one');
Logger.log(whatIsTheResult);
Logger.log(anArrayTest);
}
The result will always be false. Using the hasOwnProperty method on an array doesn't change the array to an object, and it's an incorrect way of using Javascript which is returning false.
You could put your list values an object instead of an array. An advantage to an object is being able to reference a value by it's property name regardless of where the property is indexed. With an array, you need to know what the index number is to retrieve a specific element.
Here is a post that deals with adding properties to an object in JavaScript:
StackOverflow Link
You can either use dot notation:
objName.newProperty = 'newvalue';
or brackets
objName["newProperty"] = 'newvalue';
To add a new name/value pair (property) to an object.

Accessing nested array elements.

I'm trying to access an element located in a cell inside of an array, that's inside of another array.
I've tried several methods but everything returns undefined.
json:
[
{"assignment":"Tom" , "cell":["Tom", "2013-10-06", "Client 3", "Activity", "Scheduled" ]}
]
jquery:
$.getJSON('data/gridData1.json',function(json){
var grid = json;
filterGrid(grid, ele);
});
This code does return an array perfectly fine.
javascript:
function filterGrid(filter, ele){
var types = ['Activity','Alert','Lead','Notification'];
var newTable = [];
var cs1 = $("option:selected", ele).attr("class");
var option = $("select[name='datagrid_filter'] option:selected").text().trim();
if(cs1 == 'type'){
for(var i = 0; i < types.length; i++){
if(types[i]==option){
for(var k = 0; k < filter.length; k++){
if(**filter[0][0][0].value==option**){
newTable.push(filter[k]);
}
}
break;
}
}
}
buildGrid(newTable);
}
Doesn't return anything, including the first element.
Any ideas would be great, that.
Your array has one element, which is an object, so filter[0] gives you that object.
That object has two properties, assignment and cell, so filter[0].assignment gives you "Tom" and filter[0].cell gives you the inner array.
The inner array has filter[0].cell.length items in it, the first of which is filter[0].cell[0], the second of which is filter[0].cell[1], etc.
To iterate over the items in the inner array do this:
for(var k = 0; k < filter[0].cell.length; k++){
if(filter[0].cell[k]==option){
newTable.push(filter[0].cell[k]);
break;
}
}
...but it's kind of clunky repeating filter[0].cell everywhere, so you can add another variable that is a reference to the inner array:
var cell = filter[0].cell;
for(var k = 0; k < cell.length; k++){
if(cell[k]==option){
newTable.push(cell[k]);
break;
}
}
Your code that tried to use filter[0][0][0].value didn't work because you can't access object properties by numeric index except where the actual property name is a number, and in any case you don't want the .value bit on the end.

Categories

Resources