I can't remove all the paragraphs in the page via JavaScript - dom

<!DOCTYPE html>
<meta charset="utf-8">
<title>An HTML5 Document</title>
<p>1
<p>2
<p>3
<p>4
<p>5
<p>6
<p>7
<p>8
<p>9
<p>10
<p>11
<p>12
<script>
// When the document is clicked, codes below should remove all the paragraphs in the page.
// There are 12 paragraphs in the page, but codes below can just remove 6 of them.
document.addEventListener('click', function () {
var i, allParagraphElements = document.getElementsByTagName('p');
console.log('allParagraphElements.length: ' + allParagraphElements.length);
for (i = 0; i < allParagraphElements.length; i += 1) {
console.log('i: ' + i);
allParagraphElements[i].parentNode.removeChild(allParagraphElements[i]);
}
}, false);
</script>
See codes on jsFiddle: http://jsfiddle.net/7NmRh
How can I fix this problem? Thank you.

You iterate from top to bottom:
Iteration one:
twelve paragraphs, index = 0
paragraph at index 0 is deleted and paragraph 1 is now at index 0
Second iteration:
Eleven paragraphs, index = 1
paragraph at index 1 is deleted and paragraph 2 is now at index 1
You see what's going wrong? You only delete half of the paragraphs
Iterate the other way around and all the paragraphs are deleted
JSFIDDLE

.getElementsByTagName returns a live nodelist which is automatically updated as you make changes to the underlying subtree it represents. Basically, when you remove elements the .length is changed as well and the loop will end "prematurely".
You could use .querySelectorAll to get a static nodelist instead.
http://jsfiddle.net/7NmRh/1/
allParagraphElements = document.querySelectorAll('p');
​
You can also convert the nodelist to an array, which behaves like a static nodelist as well:
allParagraphElements = [].slice.call( document.getElementsByTagName('p') );
http://jsfiddle.net/7NmRh/4/

Related

How do you prevent Word Find.Execute() from going into an endless loop?

I am writing a Word add-in using .NET and VSTO. I need to search a footer for all instances of some text. I am looping with Word's Find.Execute() as shown below. It goes into an endless loop when it matches the text in a content control in a table cell in the footer. It keeps going back to the same range.
Why would this code cause an endless loop? How can I tell Word to continue searching after this point?
using Word = Microsoft.Office.Interop.Word;
...
Word.Range range = headerFooter.Range;
Word.Find find = range.Find;
while (find.Execute(FindText: wildcard,
MatchWildcards: true,
Forward: true,
Wrap: Word.WdFindWrap.wdFindStop))
{
System.Diagnostics.Trace.TraceInformation(range.Start + ", " + range.End);
}
The code gives output like this:
192, 206
192, 206
192, 206
I tried collapsing the range to the end of the match inside the loop as follows, but it still loops forever back to the original range.
{
System.Diagnostics.Trace.TraceInformation(range.Start + ", " + range.End);
range.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
}
I am running Word version Microsoft® Word for Microsoft 365 MSO (Version 2205 Build 16.0.15225.20028) 32-bit.
In this particular instance, I was able to fix the issue by advancing the range to the beginning of the next table cell. I based this on the second post in this forum thread: https://www.msofficeforums.com/word-vba/40986-infinite-loop-when-finding-styles.html
Here is the code that fixed it in this instance. It may not fix it in every situation:
using Word = Microsoft.Office.Interop.Word;
...
Word.Range range = headerFooter.Range;
Word.Find find = range.Find;
while (find.Execute(FindText: wildcard,
MatchWildcards: true,
Forward: true,
Wrap: Word.WdFindWrap.wdFindStop))
{
results.Add(range.Duplicate);
// WARNING: In skipping the remainder of the table cell,
// we could be skipping additional matches.
if (range.Information[Word.WdInformation.wdInContentControl] && range.Information[Word.WdInformation.wdWithInTable])
{
int endOfCell = range.Cells[range.Cells.Count].Range.End;
range.End = endOfCell;
range.Start = endOfCell;
if (range.Information[Word.WdInformation.wdAtEndOfRowMarker])
{
range.End += 1;
range.Start += 1;
}
}
}

How can you access an element in a list with over 10k values for a dataset in code.org

so I am trying to recreate a wordle game inside of code.org using the wordle dataset.
//Getting Wordle Answer
var answers = getColumn("Wordle", "validWordleAnswer");
var letters = ["letter1", "letter2", "letter3", "letter4", "letter5"];
var index = (randomNumber(0, answers.length));
console.log(index);
So ofcourse the console.log outputs my index number, but out of the 10k words that are stored in the dataset, how can I access the specific one that the randomnumber generated? Foe example the index was 500, what can I write inorder to console.log the correct answer? Thanks?
The length of the array doesn't matter, 1 element or 20 billion. You still access it with bracket notation:
console.log(answers[index]);
Here's a small example (remember, indexing starts at 0):
const answers = ["chewy", "rocks", "piano", "forte", "phone"];
const index = Math.floor(Math.random() * answers.length);
console.log(index);
console.log(answers[index]);

Clear Contents of Specific Ranges

I am still new to VBA. I wanted to clear all the contents of the data (Row 3 to Row 12, Row 15 to Row 24, etc) below the yellow headers, without deleting all of the headers as shown in the photos (Fig 1 becomes Fig. 2). The headers go all the way down to row 109 (increments of 12 from Row 1, so Rows 1,13,25 ...85). I have a code but its too basic and long:
Sub Clear_All()
Set Unitsheet = ThisWorkbook.Worksheets("Sheet"1)
Unitsheet.Range("A3:F12").ClearContents
Unitsheet.Range("A15:F24").ClearContents
.
.
.
.'up to
Unitsheet.Range("A111:F120").ClearContents
End Sub
I need a code that is short, since the rows may reach up to more than 1000.
Any help will be much appreciated.
|
|
V
Sub clear()
Dim i, rows As Long
rows = ActiveSheet.UsedRange.rows.Count
For i = 1 To rows
If Sheet1.Cells(i, 1).Interior.ColorIndex = -4142 Then
Sheet1.Cells(i, 1).EntireRow.ClearContents
End If
Next
End Sub
this function finds all used rows in sheet1
it iterates all rows , if color of cell in A column has no color index (-4142) it clears all contents in entire row

How to automatically generate sequent numbers when using a form

Ahab stated in 2010: the complex looking number based on the Timestamp has one important property, the number can not change when rows are deleted or inserted.
As long as the submitted data is not changed by inserting deleting rows the simple formula =ArrayFormula(ROW(A2:A) - 1) may be the easiest one to use.
For other situations there is no nice reliable solution. :(
Now we live in 2015. Maybe times have changed?
I need a reliable way to number entries using a form.
Maybe a script can do the trick? A script that can add 1 to each entry?
That certain entry has to keep that number even when rows are deleted or inserted.
I created this simple spreadsheet in which I added 1,2, and 3 manually,please have a look:
https://docs.google.com/spreadsheets/d/1H9EXns8-7m9oLbCrTyIZhLKXk6TGxzWlO9pOvQSODYs/edit?usp=sharing
The script has to find the maximum of the former entries, which is 3, and then add 1 automatically.
Who can help me with this?
Grtz, Bij
Maybe a script can do the trick? A script that can add 1 to each
entry?
Yes, that would be what you need to resort to. I took the liberty of entering this in your example ss:
function onEdit(e) {
var watchColumns = [1, 2]; //when text is entered in any of these columns, auto-numbering will be triggered
var autoColumn = 3;
var headerRows = 1;
var watchSheet = "Form";
var range = e.range;
var sheet = range.getSheet();
if (e.value !== undefined && sheet.getName() == watchSheet) {
if (watchColumns.indexOf(range.getColumn()) > -1) {
var row = range.getRow();
if (row > headerRows) {
var autoCell = sheet.getRange(row, autoColumn);
if (!autoCell.getValue()) {
var data = sheet.getDataRange().getValues();
var temp = 1;
for (var i = headerRows, length = data.length; i < length; i++)
if (data[i][autoColumn - 1] > temp)
temp = data[i][autoColumn - 1];
autoCell.setValue(temp + 1);
}
}
}
}
}
For me the best way is to create a query in a second sheet pulling everything from form responses in to second column and so on. then use the first column for numbering.
In your second sheet B1 you would use:
=QUERY(Form!1:1004)
In your second sheet A2 you would use:
=ARRAYFORMULA(if(B2:B="",,Row(B2:B)-1))
I made a second sheet in your example spreadsheet, have a look at it.

How to identify the current row in an Apex Tabular Form?

Friends,
I have written the following JavaScript to ascertain which row of an tabular form the user is currently on. i.e. they have clicked a select list on row 4. I need the row number to then get the correct value of a field on this same row which I can then perform some further processing on.
What this JavaScript does is get the id of the triggering item, e.g. f02_0004 This tells me that the select list in column 2 of row 4 has been selected. So my Javascript gets just the row information i.e. 0004 and then uses that to reference another field in this row and at the moment just output the value to show I have the correct value.
<script language="JavaScript" type="text/javascript">
function cascade(pThis){
var row = getTheCurrentRow(pThis.id);
var nameAndRow = "f03_" + row;
var costCentre = $x(nameAndRow).value;
alert("the cost centre id is " + costCentre);
}
// the triggerItem has the name fxx_yyyy where xx is the column number and
// yyyy is the row. This function just returns yyyyy
function getTheCurrentRow(triggerItem){
var theRow = triggerItem.slice(4);
return theRow;
}
Whilst this works I can't help feeling that I must be re-inventing the wheel and that
either, there are built-in's that I can use or if not there maybe a "better" way?
In case of need I'm using Apex 4.0
Thanks in advance for any you can provide.
Well, what you have described is exactly what I typically do myself!
An alternative in Apex 4.0 would be to use jQuery to navigate the DOM something like this:
var costCentre = $(pThis).parents('tr').find('input[name="f03"]')[0].value;
I have tested this and it works OK in my test form.