So while creating a project I've encounter a problem. I have a container, let's call it container with assigned index, so it looks like container0 etc. Inside that container I have buttons to copy ( and delete ) this particular segment with all it's data. I also have index array to make sure all id's are unique. I have a working project, but I want to solve this particular situation, when I have multiple containers, and in page source containers have indexes like [0,1,5,8,6,7,9,12,10,11]. What I am doing right now is whenever somebody clicks button inside let's say container[7] and user wants to copy that container 3 times I will have [0,1,5,8,6,7,13,14,15,9,12,10,11], and the way I've solved this problem is inside button handler I get id of container like const index = parseInt(e.target.id.match(/\d+/)[0]); and then using querySelector I select which container I want to get data from. What I would like for you to help me figure out, how may I get container Id inside which button was clicked in different, easier way instead of matching id from button ( copy and delete button also have id, which is equal to container id). Also one more thing, I use eventDelegetion to add eventListeners for newly created segments.
Related
Js student here.
I have made an example CODEPEN.
In this test case,as you can see in the above code on the right side i have 6 hardcoded html inputs,3 for first name and 3 for last name.
On the left side i have a <button> which is called ADD,and with every click of this button (with a maximum of 3 clicks) the function addInputs() generates a <li>element inside <ol id="originContainer"></ol>.
This generated <li> element contains 2 html inputs,one for the first name and one for the last name,every generated input gets a unique id using a counter variable (var inputscounter=0;).
The goal is to copy dynamically,whatever i type in the generated inputs -to the left- to the hardcoded ones -to the right-,first name to first name,last name to last name,all that by using the function changeValues() which runs with every keyup of the generated inputs.
My problem is,the function changeValues() works fine but only after i generate all 3 of the elements ( As its visualized in THIS picture ) on the left,but not with just one of them,or 2 ( like THIS )
What am i missing ?
When you try to get the value of an element that is not created yet, the function throws an error. That is, in your changeValue function where you try to get the value attribute on FnameX when it is undefined (since it can't find the element in the DOM). Same for adding the click handlers on undefined elements.
You could fix that by either checking if Fname1 etc are defined before you try to get their value.
A nicer approach would be to store in an array which elements you have generated so far. Then loop over those elements and transfer its values.
You can either store an array of ids you can use to find an element when you don't need to access them that often. In this case I would store the objects themselves.
Also you don't have to add click handlers on every element, every time you add one.
Fairly new to using JS and I have created an image that brinks up a popup modal upon clicking it. I am following an example on w3schools.com, but I wish they would explain this one aspect of their code. So the popup modal contains an "x" that upon clicking, will close out of the modal as it should. However, when they create the variable in JS for the cancel button, they have it followed by a 0 in brackets:
var closeButton = document.getElementsByClassName("close")[0];
^
^
My first question is, what do you refer to this part that contains a numeric value? Is this an array? And is this used to measure how many clicks are being recorded (i.e. upon clicking, this value will change to [1]?).
Furthermore, Is it possible for me to append another variable in place of that value? In other words if it possible for me to do the following?
var clicks = [0];
var closeButton = document.getElementsByClassName("close").clicks;
I would like to know this because I want to see that if the button is clicked, I would to use the same cancel button on other modals in the same website. By this, I mean that I would like change the click value back to [0], so it would work the same for other modals (as of now, the cancel button only works on the first modal, and it does not close out the other ones. I believe it is because I am not going back to [0]).
Apologies on not using the correct terminology; That is one of the main reasons why I am asking this. What is that value in brackets [0] referred to? Is it measuring clicks? And how can I keep changing its value so that it is back to [0] when I want to perform the same action on other modals? Any and all help would be much appreciated as I am quite new to this.
var closeButton = document.getElementsByClassName("close")[0];
"getElemetsByClassName" will return an Array. By using "[0]" at the end, it's just saying that I want to store on closeButton the first position of this array.
If there's only one ".close" on the page, the return will be ->> [element].
If there's more than one ->> [element, element...]
The function getElementsByClassName[name] returns an array of all elements having [name] as class name. Because there is only one element with this specific class name in this example (or they know they only need the first element of the array) the index [0] is appended, returning the first element of this array. Therefore it makes no sense to change the index except you create more elements using the class "close". Also, the index has nothing to do with the count of clicks or your user interaction anyways.
Hope this answers your Question ^^
The value in brackets is indicating the index of an array.
This statement:
document.getElementsByClassName("close")
returns an array of elements in your document with the class name "close". If there are multiple close buttons it would return an array of all of those elements.
Adding [0] to the end of that statement means you are selecting the element at the starting index of the array (the first element in the array).
You could change that to [1] and it would select the second element within that array, but this doesn't help you in this situation.
If you want to close multiple modals with the same close button and there is only one close button with the class name 'close' than you can always select that button with:
document.getElementsByClassName("close")[0]
I want to make a very simple mix and match system, where the user chooses items from a select drop down menu which triggers things. I have buttons that are appended to the document in a rather off the cuff manner, that is to say, whenever the user chooses something from the select some text will appear as well as a button to remove that text (and corresponding button). I'm using D3 to manipulate selections, add classes and append things. I use classes to tell the button which text to remove. All that being said, I believe this still could simply be a native javascript problem I'm running into. The problem is as follows:
After you choose some things from the select drop down menu, and then proceed to click the x buttons in the order bottom to top, the behavior is as desired. However, if you click a button at the top or in the middle, the button will not remove the right text. I believe that is because the button is simply removing whatever the latest string value of the dynamic class I'm using. That makes me doubt that the button actually retains the initial properties of its .on('click', function() {}) (hence the post title).
If that's the case, I'm not really sure how to circumvent such an issue, as the buttons are dynamic in nature.
Very short and simple example here.
No need to retain memory kind of thing just make sure your element is accessible one such scenario would be to save the id reference of element as class of another element like this
d3.select('body').append('button')
.text('X')
.attr('id','b'+(intCount+1))
.attr('class',choice+'1') //class is the id of the text element
.on('click', function(d,i) {
var t = d3.select(this).attr('id')
var c = d3.select(this).attr('class')
var thisChoice = choice;
d3.selectAll('.' + t).remove(); //remove this element
d3.selectAll('.'+ c).remove(); //remove text element
intCount -= 1;
count -= .7;
});
working FIDDLE
I have a div which I need to empty excluding a couple of divs inside it, the problem is, I have got it to work but the div's lose there jquery click functionality.
I have a stage which will have items dragged on them but I need to be able to empty these items but retain the click buttons which are also on the stage and stored in a div called keep.
I found this and it works but the things inside #keep still appear but they lose their jquery .click().
var $stage = $('#stage'), $noRemove = $stage.find('#keep');
$stage.html($noRemove);
This is because they are being removed and then re-added.
You either have to remove the children. OR Rebind the click method afterwards.
So for example:
$noRemove.click(function(...){});
See the Fiddle here : http://jsfiddle.net/r98dj/1/
Also, as a note. Make keep a class. Otherwise you'll end up with multiple divs with the same ID and this will cause you to fail W3C validation.
I am trying to have three links, which will show a div when you click on them. If you click on these links again, another type of that link will be shown. For example, if I have the link one, clicking on it will produce div one. Clicking on it again will produce div one1. This way, each element has a unique id, and can have custom styles applied to individual divs at a later time.
When the user clicks one of the a links, it creates a localStorage key for how many times that type of div was clicked. For example, if I click div one's line 5 times, the localStorage key would be 5. Then when the page is reloaded, my script duplicates the div onto the page 5 times, and sets the counter for part 1 to 5. This way, when you start clicking on the a links again, they don't start from 1, but from 5, so that they're aren't any conflicting ID's.
The problem I am running into is the delete function. Say the user duplicated 5 of div one. That means that one1, one2, one3, one4, one5 are all present on the screen. If the user reloads the page, they're all still there. Let's say the user deletes div1 from the page though. It removes div1 and all styling associated with it, and leaves the other divs in tact...
BUT, if you reload the page, the script duplicates the div's starting from 1-4 (as they're were only 4 divs saved to the localStorage key), instead of duplicating from 2-5, as #1, or div1, was deleted.
I realize that's a lot to read, and might be tough to understand, so I made a fiddle with the code in it.
http://jsfiddle.net/charlescarver/bMzME/2/
To test what I'm saying, you have to show a number of div's, say 5 of "one". You'll notice that #one1, #two1, and #three1 all have a border to them, to show what happens when you delete them. As you duplicate the divs, div1 will have the border. If you delete that div, the other div's on the page won't be affected until you reload the page. Once you reload, you'll notice that the former div2 has had it's id changed to div1, instead of keeping it at div2.
Is there anyway to fix this without having to rewrite the entire script? I feel like there might be a quicker way to fix it, and I just can't picture it.
PS, if you read all of that above, I am honestly thankful
I just couldn't get your code to work, sorry.
I did however manage to achieve roughly what you describe: http://jsfiddle.net/bMzME/11/
I believe one of the issues is that you are just keeping count of the #one, #two, #three and using that to create the div IDs dynamically.
What you need is a data structure that holds all i such that div{i} is present. Probably create a list and map it to your key which is #one, #two, #three. Then you get the list and iterate over the elements in $(".base") for-loop.
Now if you had 5 div ones and you deleted the 5th one, you will have one1, one2, one3, one4. If now I insert another div one do you want that at 5 or 6? If you want at "5" simply take the max() from your list else use a separate counter as shown below - see var: idx. Then add idx to your list - I haven't coded the list. I will try my solution but will take some time - not all to familiar with JS. But the idea should work I believe.
$(".a").click(function() {
var target = $(this).attr("href");
var id = $(target).attr("id");
var x = $("." + id).size();
var click = $(target).data("clicked") || x;
var idx = localStorage.getItem(target+"i");
$(target).data("clicked", ++click);
if (idx == null) {idx = 1;}
var name = id + idx;
alert(name);
$(target).clone().attr("id", name).attr("class", "drag " + id).appendTo("body");
localStorage.setItem(target, click);
localStorage.setItem(target+"i", ++idx);
});