The following piece of code works as expected:
var slctr = "What's new";
var section = document.querySelector('[aria-label="'+slctr +'"]');
var sectionAs = section.querySelectorAll('a');
$(sectionAs).click(function(e){
e.preventDefault();
var t = $(e.target).text();
var sectionTitle = section.getAttribute('aria-label');
alert('Title: ' + sectionTitle+', text: ' + t);
return false;
});
If I try to apply this to every {{section}}, the working stops:
var sections = [
"What's new",
"What's newish",
"What's not new at all"
];
for(var l = 0; l < sections.length; l++){
var slctr = sections[i];
var section = document.querySelector('[aria-label="'+slctr +'"]');
var sectionAs = section.querySelectorAll('a');
$(sectionAs).click(function(e){
e.preventDefault();
var t = $(e.target).text();
var sectionTitle = section.getAttribute('aria-label');
alert('Title: ' + sectionTitle + ', text: ' + t);
return false;
});
}
Why does it not work for the loop?
You need to use closures or IIFEs as you are setting some event handlers, which are some times asynchronous. You just need to update your code like:
var sections = [
"What's new",
"What's newish",
"What's not new at all"
];
for (var i = 0; i < sections.length; i++) {
(function (i) {
var slctr = sections[i];
var section = document.querySelector('[aria-label="' + slctr + '"]');
var sectionAs = section.querySelectorAll('a');
$(sectionAs).click(function(e) {
e.preventDefault();
var t = $(e.target).text();
var sectionTitle = section.getAttribute('aria-label');
alert('Title: ' + sectionTitle + ', text: ' + t);
return false;
});
})(i);
}
And one more thing is that you have used i for index and l for loop.
You use l as loop variable but then trying to access sections[i] and i is not defined
var slctr = sections[l];
Related
I feel like there is perhaps an obvious answer. When I'm running this code:
function searchQuery() {
var compiledParticipantsSheet = spreadSheet.getSheetByName('Participants');
var participantsSheetLr = compiledParticipantsSheet.getLastRow();
var participantsSheetLc = compiledParticipantsSheet.getLastColumn();
var querySheet = spreadSheet.getSheetByName('Query');
var querySheetLr = querySheet.getLastRow();
var querySheetLc = querySheet.getLastColumn();
var data = querySheet.getRange(3, 1, querySheetLr, querySheetLc).getValues();
for (j = 2; j <= participantsSheetLr; ++j) {
var val = compiledParticipantsSheet.getRange(j, 2, 1, 1).getValue();
console.log('Searching Query sheet for row ' + j + ' -- ' + val)
for (i = 0; i < data.length; ++i) {
if (data[i][4] == val) {
var foundData = (data[i][20]);
console.log('------ Found email in query row ' + (i + 3) + ' = ' + foundData);
compiledParticipantsSheet.getRange(j, 11, 1, 1).setValue(foundData);
}else{
compiledParticipantsSheet.getRange(j, 11, 1, 1).setValue('Participant not found');
}
}
}
}
It runs painfully slow, but if I remove the one else statement at the end it runs super fast! Is that reasonable? Am I missing something?
Thanks!
I have created an accordion with categories. I am pulling the content from a share point list with an ajax call. Each item on the share point list has its category assigned (automotive, entertainment, housing, etc). I need every item to be filtered by category.
https://jsfiddle.net/angelogianopulos/7L392emj/11/
$(document).ready(function() {
/*r container = document.createElement("div");
container.setAttribute('id', 'container');
container.classList.add('container', 'text-center', 'my-5');*/
$.ajax({
url: "http://bc-net/_api/web/lists/GetByTitle('specialDiscounts')/items",
method: "GET",
headers: {
"Accept": "application/json; odata=verbose"
},
success: function(data) {
var items = data.d.results;
console.log(items);
var createRows = function(i, items) {
//Creates 3 Rows inside container
var row = document.createElement("div");
row.setAttribute('id', 'row' + i);
row.classList.add('row', 'animated', 'fadeInUp');
//Appends Row to Container
var getContainer = document.getElementById('automotive');
getContainer.appendChild(row);
createColumns(i, items);
}; //End of creare Rows Function
//Creates columns
var createColumns = function(i, items) {
for (var j = i; j < (i + 3); j++) {
//Creates 3 Columns inside the 3 rows
var columns = document.createElement("div");
columns.setAttribute('id', 'columns' + j);
columns.classList.add('col-md-4');
//appends the 3 columns inside the rows
var getRow = document.getElementById('row' + i);
getRow.appendChild(columns);
//Create single News
var singleNews = document.createElement("div");
singleNews.setAttribute('id', 'singleNews' + j);
singleNews.classList.add("single-news", "mb-4");
var getColumns = document.getElementById('columns' + j);
getColumns.appendChild(singleNews);
//Inside Row
var insideRow = document.createElement("div");
insideRow.setAttribute('id', 'insideRow' + j);
insideRow.classList.add('row');
var getsingleNews = document.getElementById('singleNews' + j);
getsingleNews.appendChild(insideRow);
//Col-md-3
var insideCol = document.createElement("div");
insideCol.setAttribute('id', 'insideCol' + j);
insideCol.classList.add('col-md-3');
//Col-md-9
var insideColRight = document.createElement("div");
insideColRight.setAttribute('id', 'insideColRight' + j);
insideColRight.classList.add('col-md-9');
var getInsideRow = document.getElementById('insideRow' + j);
getInsideRow.appendChild(insideCol);
getInsideRow.appendChild(insideColRight);
//Rounded Image Class
var rounded = document.createElement("div");
rounded.setAttribute('id', 'rounded' + j);
rounded.classList.add('rounded', 'z-depth-1', 'mb-4');
var getinsideCol = document.getElementById('insideCol' + j);
getinsideCol.appendChild(rounded);
//Pulls the images from the list
var image = document.createElement("img");
image.setAttribute('id', 'image' + j);
image.classList.add("img-fluid");
image.src = items[j].Image.Url;
var getRounded = document.getElementById('rounded' + j);
getRounded.appendChild(image);
//Pulls header from the list
var title = document.createElement("p");
title.setAttribute('id', 'title' + j);
title.innerHTML = items[j].Title;
title.classList.add("font-weight-bold", "dark-grey-text");
insideColRight.appendChild(title);
var justifyContent = document.createElement('div');
justifyContent.setAttribute('id', 'justifyContent' + j);
justifyContent.classList.add('d-flex', 'justify-content-between', 'topSpace');
insideColRight.appendChild(justifyContent);
var textTruncate = document.createElement('div');
textTruncate.setAttribute('id', 'textTruncate' + j);
textTruncate.classList.add('col-11', 'text-truncate', 'pl-0', 'mb-3');
justifyContent.appendChild(textTruncate);
//Pulls anchor from the list
var anchor = document.createElement("a");
anchor.setAttribute('id', 'anchor' + j);
anchor.setAttribute('href', items[j].Link.Url, +j);
anchor.setAttribute('target', '_blank', +j);
anchor.classList.add("dark-grey-text");
anchor.innerHTML = items[j].Description;
textTruncate.appendChild(anchor);
var arrowAnchor = document.createElement("a");
arrowAnchor.setAttribute('id', 'arrowAnchor' + j);
arrowAnchor.setAttribute('target', '_blank' + j);
arrowAnchor.setAttribute('href', items[j].Link.Url, +j);
justifyContent.appendChild(arrowAnchor);
var iconArrow = document.createElement('i');
iconArrow.classList.add('fas', 'fa-angle-double-right');
var getarrowAnchor = document.getElementById('arrowAnchor' + j);
getarrowAnchor.appendChild(iconArrow);
//var test = document.getElementById( 'arrowAnchor' + j);
//test.onclick = function() {
// console.log('Hello');
//}
} //End of j Loop
return;
} // End of createColumns function
//Array of categories
var catGroup = [];
console.log(catGroup);
if (items.length > 0) {
for (var i = 0; i < items.length; i++) {
var categories = items[i].Category;
console.log(categories)
catGroup.push(categories);
if (catGroup[i] === "Automotive") {
var automotive = document.getElementById('automotive');
console.log(catGroup[i]);
}
if (catGroup[i] === "Entertainment") {
var entertainment = document.getElementById('entertainment');
console.log(catGroup[i]);
}
if (catGroup[i] === "Health and Beauty") {
var health = document.getElementById('health');
console.log(catGroup[i]);
}
if (catGroup[i] === "Travel") {
var travel = document.getElementById('travel');
console.log(catGroup[i]);
}
if (catGroup[i] === "Electronics") {
var electronics = document.getElementById('electronics');
console.log(catGroup[i]);
}
if (catGroup[i] === "Services") {
var services = document.getElementById('services');
console.log(catGroup[i]);
}
if (catGroup[i] === "Housing") {
var housing = document.getElementById('housing');
console.log(catGroup[i]);
} else {}
if (i % 3 == 0) {
createRows(i, items);
} //end of % if statement
} //End of for loop
} //End of if item.length statement
},
error: function(data) {
alert("Error: " + data);
}
}); //End Service Icons //End Service Icons
}); //End ready function
I expect every item to be placed by category in its own content panelenter image description here
After looking into your question, what I understood is you just want to filter your data on the basis of 'category assigned'.
I will refer you to use JavaScript Filter like so:
const result = items.filter(Category => Category === "Automotive" );
Or, if you can use Lodash, there are a lot of ways to filter and even you can group by the Category.
You can check out here for Lodash:
Documentation Lodash
If I misunderstood your question, please let me know so I can edit my answer.
I am trying to take user input in form of a lot of strings. I want to store them in an array, and the input should be seperated by line breaks.
It should be very much like this: https://www.random.org/lists/
I can not grasp where to being - can someone help? I am using JavaScript but any solutions using JS or jQuery would be great!
I have posted my JS. I want the var people from user input, instead of having to populate the array myself.
Thanks,
$(document).ready(function() {
$(".btn").on('click', function() {
var people = ["Markus Eriksson", "Leticia Hoshino", "Yemi Afolabi", "Eskil Fogelström", "Josefina Liedberg", "David Bjørn Bograd", "Tilda Dahlgren", "Damien Vignol", "Sofie Cousu", "Carolina Lindelöw", "Bilal Khan", "Louise Brandrup-Wognsen", "Emilia Lehto", "Albin Hagström",
"Victor Borg", "Anna Stella Lo-Ré", "Loucmane", "Angelica Ruth", "Victoria VL", "Johan Hellström", "Micke Skoglund", "Anna Unger", "Isaac Sennerholt", "Cyndie Léa Vintilescu", "Mahle Rakela Robin", "Louise Ek", "Ibrahim Bajwa", "Abodi Ismail",
"Alex Ashman", "Elin Grass Casalini", "Amanda Schultz", "Abenezer Abebe", "Julia Hoff", "Enny Hellsén", "Michel George", "Abdullahi Hussein", "Teodor Meurling", "Andrea Sami Mogren", "Thea Arpine Gasparyan", "Jakob Eberson"
];
var groupSize = $("input[name=checkListItem]").val();
var groups = [];
$(".group").remove();
// Randomizing function
Array.prototype.shuffle = function() {
var input = this;
for (var i = input.length - 1; i >= 0; i--) {
var randomIndex = Math.floor(Math.random() * (i + 1));
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
return input;
};
people.shuffle();
// Split people into chunks and push new arrays into var groups
while (people.length > 0) {
chunks = people.splice(0, groupSize);
var chunksSpace = chunks.join(', ');
groups.push(chunksSpace);
}
// Append the groups into the DOM
$(document).ready(function() {
for (var i = 0; i < groups.length; i++) {
$('.all-groups').append("<div class='group'><p><span class='groupheader'>Group " + (i + 1) + "</span></br> " + groups[i] + "</p></div>");
}
});
});
});
Pure Javascript
document.getElementById("element_id").value.split("\n");
OR JQuery $("#element_id").val().split("\n");
For your example give your input id='people' and should work, also avoid extra line breaks by .replace(/\n+/g,"\n").
$(document).ready(function() {
// Randomizing function
Array.prototype.shuffle = function() {
var input = this;
for (var i = input.length - 1; i >= 0; i--) {
var randomIndex = Math.floor(Math.random() * (i + 1));
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
return input;
};
$(".btn").on('click', function() {
var people = $("#people").val().replace(/\n+/g,"\n").split("\n");
var groupSize = $("input[name=checkListItem]").val();
var groups = [];
$(".group").remove();
people.shuffle();
// Split people into chunks and push new arrays into var groups
while (people.length > 0) {
chunks = people.splice(0, groupSize);
var chunksSpace = chunks.join(', ');
groups.push(chunksSpace);
}
// Append the groups into the DOM
$(document).ready(function() {
for (var i = 0; i < groups.length; i++) {
$('.all-groups').append("<div class='group'><p><span class='groupheader'>Group " + (i + 1) + "</span></br> " + groups[i] + "</p></div>");
}
});
});
});
var text = $('#total-number').text();
var eachLine = text.split('\n');
alert('Lines found: ' + eachLine.length);
for(var i = 0, l = eachLine.length; i < l; i++) {
alert('Line ' + (i+1) + ': ' + eachLine[i]);
}
Use split to split a multi line string into parts:
var textarea = document.querySelector("textarea");
textarea.addEventListener("change", function(e) {
console.log(textarea.value.split((/[\n\r]/g)));
});
<textarea></textarea>
Regex links:
\r
\n
I have a main function generatePersonDatasheet(theses) and I have a handler function submit(e) (the handler is in other function called showList()).
In the main function, I can call the handler function this way:
if (theses == 1){
Logger.log("going to showList() ");
return showList();
If I drop de return in the line return showList(); the UI of showList() opens and closes at a fraction of second, not allowing the user choose the items. If I put this return, after the handler function submit(e) is closed, the code in my main function doesn't run the next line after the if block:
if (theses == 1){
Logger.log("going to showList() ");
return showList();
}
showURL(docName, link); // Shows document name and link in UI
How could I fix that? How could I got the main function to runs its lines after the if (theses == 1) block? I didn't want to repeat the code in the handler function because it's bigger than the line showURL(docName, link); in the above sample.
This is the called functions:
var fact_list = [ ["Kennedy Inauguration", "politics", "tZwnNdFNkNklYc3pVUzZINUV4eUtWVWFSVEf"], ["Pericles’ Funeral Oration", "politics", "sdgrewaNkNklYc3pVUzZINUV4eUtW345ufaZ"], ["The Pleasure of Books", "culture", "1234rFszdgrfYc3pVUzZINUV4eU43usacd"], ["I Am The First Accused (Nelson Mandela)", "law", "34rsgadOsidjSZIswjadi95uydnfklsdks"] ];
function showList() {
Logger.log("running showList ");
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
// Store the number of items in the array (fact_list)
Logger.log("fact_list.length " + fact_list.length);
panel.add(app.createHidden('checkbox_total', fact_list.length));
// add 1 checkbox + 1 hidden field per item
for(var i = 0; i < fact_list.length; i++){
Logger.log("checkbox_isChecked_"+i + " = " + fact_list[i][0]);
Logger.log("checkbox_value_"+i + " = " + fact_list[i]);
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(fact_list[i][0]);
var hidden = app.createHidden('checkbox_value_'+i, fact_list[i]);
panel.add(checkbox).add(hidden);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
app.add(panel);
mydoc.show(app);
}
function submit(e){
Logger.log("running submit(e)");
var numberOfItems = e.parameter.checkbox_total;
var itemsSelected = [];
// for each item, if it is checked / selected, add it to itemsSelected
for(var i = 0; i < numberOfItems; i++){
if(e.parameter['checkbox_isChecked_'+i] == 'true'){
itemsSelected.push(e.parameter['checkbox_value_'+i]);
}
}
var app = UiApp.getActiveApplication();
Logger.log("itemsSelected = " + itemsSelected);
ScriptProperties.setProperties({'theses': itemsSelected}, true);
var thesesArrays = ScriptProperties.getProperty('theses');
Logger.log("thesesArrays = " + thesesArrays);// to see targetDoc's content
for (var i = 0; i < thesesArrays.lenght; i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
app.close();
return app;
}
function importTheses(targetDocId, thesesId, thesesType) { // adapted from Serge insas
Logger.log("running importTheses() ");
var targetDoc = DocumentApp.openById(targetDocId);
var targetDocParagraphs = targetDoc.getParagraphs();
var targetDocElements = targetDocParagraphs.getNumChildren();
var thesesDoc = DocumentApp.openById(thesesId);
var thesesParagraphs = thesesDoc.getParagraphs();
var thesesElements = thesesDoc.getNumChildren();
var eltargetDoc=[];
var elTheses=[];
for( var j = 0; j < targetDocElements; ++j ) {
var targetDocElement = targetDoc.getChild(j);
// Logger.log(j + " : " + type);// to see targetDoc's content
eltargetDoc[j]=targetDocElement.getText();
if(el[j]== thesesType){
for( var k = 0; k < thesesParagraphs-1; ++k ) {
var thesesElement = thesesDoc.getChild(k);
elTheses[k] = thesesDoc.getText();
targetDoc.insertParagraph(j, elTheses[k]);
}
}
}
}
Please have a look at this worflow, wouldn't it be more easy ?
(check the log to confirm the last function was called)
note : I didn't use scriptProperties as it was not necessary anymore since factList is a global variable in your example... and I simplified the importTheses function for this test since I had no docs to use ;-)
var fact_list = [["Kennedy Inauguration", "politics", "tZwnNdFNkNklYc3pVUzZINUV4eUtWVWFSVEf"], ["Pericles Funeral Oration", "politics", "sdgrewaNkNklYc3pVUzZINUV4eUtW345ufaZ"], ["The Pleasure of Books", "culture", "1234rFszdgrfYc3pVUzZINUV4eU43usacd"], ["I Am The First Accused (Nelson Mandela)", "law", "34rsgadOsidjSZIswjadi95uydnfklsdks"]];
function showList() {
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
// Store the number of items in the array (fact_list)
panel.add(app.createHidden('checkbox_total', fact_list.length));
// add 1 checkbox + 1 hidden field per item
for(var i = 0; i < fact_list.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(fact_list[i][0]);
panel.add(checkbox);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
app.add(panel);
mydoc.show(app);
}
function submit(e){
var numberOfItems = Number(e.parameter.checkbox_total);
var thesesArrays = [];
for(var i = 0; i < numberOfItems; i++){
if(e.parameter['checkbox_isChecked_'+i] == 'true'){
thesesArrays.push(fact_list[i]);
}
}
Logger.log(thesesArrays);
var target = 'target doc';
for (var i = 0; i < thesesArrays.length; i++){
var thesesId = thesesArrays[i][2];
var thesesType = thesesArrays[i][1];
importTheses(target, thesesId, thesesType);
}
// showURL(docName, link); /
return UiApp.getActiveApplication().close();
}
function importTheses(targetDocId, thesesId, thesesType) { // adapted from Serge insas
Logger.log(targetDocId+' '+thesesId+' '+thesesType);
}
Apologies here is another question regarding my javascript image replacement script.
So far with the help of stackexchangers i have this like so and it's working great. But now I need to make another little change:
var paths = ["add","clear","copy","delete"];
var fullPaths = paths.map(function(x) { return "img[src*='" + x + "']"; } );
var imgs = document.querySelectorAll(fullPaths);
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i],
iClass = img.className,
iSrc = ###THE CORRESPONDING NAME IN THE ARRAY###,
span = $('<span />', {'class': 'iconfont '+iClass+' '+iSrc,
title : img.parentNode.title
});
$(img).replaceWith(span);
}
I want iSrc to be the name of the image in the array. So that when the image with <src="edit.png" class="iconmini> is replaced, the span has the classes: .iconfont, .iconmini, and, .edit
I have tried doing the following:
iSrc = paths[i]
but that doesn't work obviously and adds the wrong classes :)
I have another question, too, regarding my script but I will ask that as a seperate question. Thanks!
EDIT:
Thanks again for everyone who has helped me here. I have now added an extra bit to my code that will also set the image title, and thought that I would post it here, it might help someone in the future.
Some of the images have titles and some dont like when they wrapped in an anchor. So I have done the following which seems to work for me:
var paths = ["add","clear","copy","delete"];
var fullPaths;
var imgs;
for(var p=0; p<paths.length; p++) {
fullPaths = "img[src*='" + paths[p] + "']";
imgs = document.querySelectorAll(fullPaths);
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
if ($(img).attr('title')) {
iTitle = img.title;
} else {
iTitle = img.parentNode.title;
}
iClass = img.className;
iSrc = paths[p];
span = $('<span />', {'class': 'iconfont '+iClass+' '+iSrc,
title : iTitle
});
$(img).replaceWith(span);
}
}
This is the same approach that #bfavaretto suggested but with the use of jQuery loops and simplified a bit:
var paths = ["add", "clear", "copy", "delete"];
$.each(paths, function (i, path) {
$("img[src*='" + path + "']").each(function () {
var $span = $('<span />', {
class: 'iconfont ' + this.className + ' ' + path,
title: this.parentNode.title
});
$(this).replaceWith($span);
});
});
You could get the images separately for each path/class, so they won't be mixed:
var paths = ["add","clear","copy","delete"];
var fullPaths;
var imgs;
for(var p=0; p<paths.length; p++) {
fullPaths = "img[src*='" + paths[p] + "']";
imgs = document.querySelectorAll(fullPaths);
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i],
iClass = img.className,
iSrc = paths[p],
span = $('<span />', {'class': 'iconfont '+iClass+' '+iSrc,
title : img.parentNode.title
});
$(img).replaceWith(span);
}
}
I like bfavaretto's answer, but if you don't want to get the images separately, you could always add this lame-ish workaround:
var paths = ["add","clear","copy","delete"];
var fullPaths = paths.map(function(x) { return "img[src*='" + x + "']"; } );
var imgs = document.querySelectorAll(fullPaths);
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i],
iClass = img.className;
//workaround start
var iSrc;
for(var j = 0; j < paths.length; j++) {
if(img.src.split('/').pop().indexOf(paths[i]) != -1) {
iSrc = paths[i];
break;
}
}
//workaround end
span = $('<span />', {'class': 'iconfont '+iClass+' '+iSrc,
title : img.parentNode.title
});
$(img).replaceWith(span);
}