Javascript - Clone a div after user input on quantity - javascript

I'm trying to clone a div after a user puts in the amount of divs to be cloned. User will put in a number (say 3) and the function will create three group-container divs. The prompt works, but nothing happens after that. Seems pretty simple but it's evading me. Is my logic incorrect? Obviously my programming skills are very new.
I create a function that has the input (groupInput)
Create a for loop to reiterate the following instruction
The for loop will clone group-container as many times as i<groupInput
function addGroup() {
var groupInput = prompt("How many groups? 1-100");
for(i=0; i<groupInput; i++){
var group = document.getElementById("group-container");
var clone = group.cloneNode(true);
group.parentNode.appendChild(clone);
}
}
Any suggestions would be much appreciated.
Updated
Thanks for the suggestions, I get I should use class for this now.
I did get it to work with the ID in jsfiddle (not sure why it's not in my html), but now with the class it's not: https://jsfiddle.net/waynebunch/c5sw5dxu/. getElementsByClassName is valid right?

You should put the group declaration outside of the for loop so the clone remains the same throughout the loop.
Fiddle
function addGroup() {
var groupInput = prompt("How many groups? 1-100");
var group = document.getElementById("group-container");
for(i=0; i<groupInput; i++){
var clone = group.cloneNode(true);
group.parentNode.appendChild(clone);
}
}

The prompt() method probably returns the correct number, but with type set to String. Instead try
parseInt(groupInput)
To convert the value to a number, which should allow the for loop to execute properly.

Something like the below might work once you get your quantity in from a prompt or text input.
var doc = document;
var input = prompt("Please enter your qty", "0");
if (input != null) {
for (i = 0; i < input; i++) {
var elem = doc.createElement('div');
elem.className = 'group-container';
}
}

Related

Change string (text-element) in svg-element

I'm just playing around with some svg-drawings.
Actually I have a svg-drawing, that contains some grouped Elements.
I like to copy one of These Elements and give it e new value in its Text-field.
First I copy the Element:
var selectedSymbol = document.getElementsByClassName('selected');
if(selectedSymbol.length >>0)
{
var newSymbol = selectedSymbol[0].cloneNode(true);
//now Change Information of <text id='BMK'>emptyBMK</text>
}
Of course every grouped Symbol has this text-field, with same id, so I think I Need to Change it only in selected Symbol but newSymbol.getElementsById('BMK') does not work :(
Ok, I did it, but I am not sure if this is a good practice:
for (var x = 0; x < newSymbol.childElementCount; x++)
{
if(newSymbol.Children[x].id == "BMK")
newSymbol.children[x].innerHTML = "newBMK";
}
Can someone tell me if this is ok?
I mean it works but seems a bit strange to me.

how to remove HTML tags from a string in JavaScript without using regexp?

I am new to programming and I was solving this exercise.
I have tried 3 loops with string.slice() but for some reason it prints an empty string.
Would you please explain what happens inside my code and why it prints the wrong output and how I can correct, rather than giving me your version of the correct answer, so that I can learn from my mistakes.
the test input is
<p><strong><em>PHP Exercises</em></strong></p>
and output should be PHP Exercises
p.s this is not a PHP exercise, I'm not confused
here is my code :
function remove(answer){
var sen = answer.split("");
var arr = [];
for (var i = 0; i<answer.length; i++){
if (answer[i] == "<"){
for (var j = i; j<answer.length; j++){
if (answer[j] == ">"){
for (var k = j; k<answer.length; k++){
if (answer[k] == "<"){
return answer.slice(j+1, k);
}
}
}
}
}
}
}
Try this:
function stripTags(data)
{
var tmpElement = document.createElement("div");
tmpElement.innerHTML = data;
return tmpElement.textContent || tmpElement.innerText || "";
}
var something = '<p><strong><em>PHP Exercises</em></strong></p>';
alert(stripTags(something));
or You can use string.js (string.js link):
var S = window.S;
var something = '<p><strong><em>PHP Exercises</em></strong></p>';
something = S(something).stripTags().s;
alert(something);
<script src="https://raw.githubusercontent.com/jprichardson/string.js/master/dist/string.min.js"></script>
if You're trying nodejs so:
var S = require('string');
var something = '<p><strong><em>PHP Exercises</em></strong></p>';
something = S(something).stripTags().s;
console.log(something);
As to why the provided code isn't working, the code returns when j = 2 and k = 3. I discovered this by writing console.log(j, k); immediately before the return. This insight made it clear that the code is identifying the first set of open tags, when actually you seem to want to identify the open and closed "em" tags. The answers provided by others are more robust, but a quick fix to your code is:
change
if (answer[i] == "<"){
to
if (answer.slice(i, i+3) == "<em"){
Hope this helps!
Your code does not account for ... nothing. It simply stops at the first encounter of what's between ">" and "<", which is, in the first case, is nothing! You should check if a character is present, and move on if not.
Honestly, this is one of those useless exercises that text books use to try to get you to think outside the box. But you will never want to loop through a string to find text between tags. There are so many methods built in to JavaScript, it's literally reinventing the wheel to do this... that is if a wheel were really a for-loop.
If you really want to avoid Regex and other built in functions so that you can learn to problem solve the long way, well try slicing by brackets first!

How to delete all items from an FormApp object?

I recently asked a question about how to add items to a Google Form from a Google Spreadsheet. And it works great. Instead of using FormApp.create(), though, I'll have to use .openByUrl() because the ID has to stay the same. The problem is that if I run my script again, it'll open the existing form (great) and then append more items to the existing form.
This behaviour makes perfect sense but is not quite what I want. So I thought I'd just remove all existing items before I add new ones from my spreadsheet. I consulted the Google dev site for Form Services and feel like I should have all the pieces. I can't quite put them together, though.
I am now doing this following:
var form = FormApp.openByUrl('https://docs.google.com/forms/d/.../edit');
var items = form.getItems();
for (var i in items) {
form.deleteItem(i);
}
However, that'll give me an out of range error. Can someone point me in the right direction?
The problem is with how you're iterating over the array.
Try this:
var form = FormApp.openByUrl('https://docs.google.com/forms/d/.../edit');
var items = form.getItems();
for (var i=0; i<items.length; i++) {
form.deleteItem(i);
}
function clearForm(){
var items = form.getItems();
while(items.length > 0){
form.deleteItem(items.pop());
}
}
This worked for me when I ran into the same issue:
for (var i=0; i<items.length; i++) {
if (items[i] != null){
form.deleteItem(i);
}
}
Start by deleting the last item and repeat it until all items are deleted. This could be done by a reverse for loop:
function deleteAllItems(){
var form = FormApp.openById(/*put here your form id*/);
var items = form.getItems();
var end = items.length - 1;
for(var i = end ; i >= 0; i--){
form.deleteItem(i);
}
}
Another alternative is avoid of a variable index by using 0, so the first item will be deleted, no matter if a regular or a reverse loop is used. Note: This was already mentioned in a comment to another answer.
I also ran into the same problem. This one worked for me:
function deleteItems(){
var form = FormApp.openById('ID');
var items = form.getItems();
items.forEach(function(e){form.deleteItem(e)})
}
var form = FormApp.openByUrl('https://docs.google.com/forms/.../edit');
var items = form.getItems();
while(items.length > 0)
{
form.deleteItem(items.pop());
}
This works for me.
When you are checking the length of a variable=form.getItems() in a loop, its going to through some error because the length of that is not changing and the loops end up being infinite and throughing error.
So, heres my solution to the problem:
for(;form.getItems().length>0;)
{
form.deleteItem(0);
}
I ran into the same problem. However, I have fixed it by iterating in the reverse order.
var form=FormApp.openByUrl('form url here');
var Items=form.getItems();
var len=Items.length;
for (var i=Items.length-1;i>2;i--){ //Delete every item except first three items
form.deleteItem(i)
}
There are many options for looping over all form items and removing each, the most succinct being:
With Chrome V8 runtime
form.getItems().forEach(form.deleteItem)
Without Chrome V8 runtime
for each (var item in form.getItems()) {
form.deleteItem(item);
}

Get array values and put them into different divs with a for loop?

I'm trying hard to learn javascrip+jquery on my own, and also trying to learn it right. Thus trying to enforce the DRY rule.
I find myself stuck with a problem where I have an array,
var animals = [4];
a function,
var legs = function(amount){
this.amount = amount;
this.body = Math.floor(Math.random()*amount)+1;
}
and an evil for loop. I also have 5 div's called printAnimal1, printAnimal2 and so on.. In which I wish to print out each value in the array into.
for(i = 0; i < animals.length; i++){
animals[i] = new legs(6);
$(".printAnimal"+i).append("animals[i]");
}
I feel as if I'm close to the right thing, but I cant seem to figure it out. I also tried something like this:
for(i = 0; i < animals.length; i++){
animals[i] = new legs(6);
$this = $(".printAnimal");
$(this+i).append("animals[i]");
}
But one of the problems seem to be the "+i" and I cant make heads or tails out of it.
I also know that I can simply do:
$(".printAnimal1").append("animals[i]");
$(".printAnimal2").append("animals[i]");
$(".printAnimal3").append("animals[i]");
...
But that would break the DRY rule. Is it all wrong trying to do this with a for loop, or can it be done? Or is there simply a better way to do it! Could anyone clarify?
Your first attempt should be fine, as long as you take "animals[i]" out of quotes in your append() call ($(".printAnimal"+i).append(animals[i]))
Also, I assume you declared var i; outside your for loop? If not, you'll want to declare it in your for loop (for(var i=0....)
EDIT: problems with your fiddle
you never call startGame()
you didn't include jQuery
you can't (as far as I know) append anything that isn't html-- in your case, you're trying to append a js object. What do you want the end result to look like?
http://jsfiddle.net/SjHgh/1/ is a working fiddle showing that append() works as you think it should.
edit: forgot to update the fiddle. Correct link now.
EDIT: reread your response to the other answer about what you want. http://jsfiddle.net/SjHgh/3/ is a working fiddle with what you want. More notes:
You didn't declare new when you called DICE
you have to reference the field you want, (hence dices[i].roll), not just the object
Just a few comments:
This is declaring an array with only one item and that item is the number 4
var animals = [4];
In case you still need that array, you should be doing something like:
var animals = []; // A shiny new and empty array
and then add items to it inside a for loop like this:
animals.push(new legs(6)); //This will add a new legs object to the end of the array
Also, what is the content that you are expecting to appear after adding it to the div?
If you want the number of legs, you should append that to the element (and not the legs object directly).
for(i = 0; i < animals.length; i++){
animals.push(new legs(6));
$(".printAnimal"+i).append(animals[i].body);
}
Adding another answer as per your comment
var i, dicesThrown = [];
function throwDice(){
return Math.ceil(Math.random() * 6);
}
//Throw 5 dices
for (i=0 ; i<5 ; i++){
dicesThrown.push( throwDice() );
}
//Show the results
for (i=0 ; i<5 ; i++){
$("body").append("<div>Dice " + (i+1) + ": " + dicesThrown[i] +"</div>");
}

How should I store and retrieve dictionary words

I have a JavaScript variable that holds an array of dictionary words like
var words = ['and','cat', n1, n2, n3 and so on ]
This array holds about 58020 words.
What i have done is created an auto complete jQuery plugin that displays the words from the dictionary array in a drop down list when the user starts typing text into the text box. But the browser crashes at some point because I think the looping through each word is making the process slow.
How can i overcome this?
Here is the function that checks the word array and outputs the words if found
$(textInput).keyup(function(e) {
var text = $(this).val();
var foundTag = false;
for (var i = 0; i < settings.tags.length; i++) {
var tagName = settings.tags[i].toLowerCase();
if (tagName.startsWith(text)) {
if (text != '') {
foundTag = true;
$(settings.tagContainer).append(GetDivDropDownItem(settings.tags[i]));
}
else {
}
}
}
});
Edit
$(textInput).keyup(function(e) {
var text = $(this).val();
var foundTag = false;
for (var i = 0; i < settings.words.length; i++) {
var tagName = settings.words[i].toLowerCase();
if (tagName.startsWith(text)) {
if (text != '') {
foundTag = true;
$(settings.tagContainer).append(GetDivDropDownItem(settings.words[i]));
}
else {
}
}
}
});
var GetDivDropDownItem = function(text) {
var cWidth = $(container).css("width");
cWidth = cWidth.split("px")[0];
var tag = $("<div/>");
$(tag).css("paddingLeft", "5px");
$(tag).css("paddingRight", "5px");
$(tag).css("paddingBottom", "5px");
$(tag).css("paddingTop", "5px");
$(tag).css("width", cWidth - 10);
$(tag).css("float", "left");
$(tag).css("fontFamily", "Arial");
$(tag).css("fontSize", "12px");
$(tag).css("color", "#6A6B6C");
$(tag).text(text);
return $(tag);
};
You need to use better datastructures and algorithms. In general, I would suggest doing some research on pre-existing work before trying to tackle any problem.
This is an article that may be of help: http://orion.lcg.ufrj.br/Dr.Dobbs/books/book5/chap08.htm
See this benchmarks and comparisons done by jQuery creator John Resig:
http://ejohn.org/blog/revised-javascript-dictionary-search/
Basically the answer is a simple trie structure, if you really want to do it pure-JS.
By not putting 58.000 words in a Javascript array.
Use a webservice that holds all the dictionary words in a database, and query that.
edit: If you really insist on storing this in a javascript array, group the words by their first two characters. Easy to implement and around 600 times faster already.
A trie data structure would be good for a dictionnary.
Assuming settings.tags is the array of dictionary words, this code is going to be very cumbersome, since you're looping through the entire array with each keyup event.
I would suggest that you organize the dictionary words in a structure that allows you to go to the words very quickly. Perhaps a binary tree or just an associative array.

Categories