Javascript not retaining div id on reload with localStorage? - javascript

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);
});

Related

JS - dynamic inserting items into array on button click

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.

Retaining Memory of Initial Properties for Dynamic Buttons

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

need to empty a div but keep only a few div's inside the div but retain there jquery click functionality

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.

How to retrieve a number of visible divs on a page and displaying a count

I have approximately 1000 divs called "itemcontainer" on the page.
I also have a number of checkboxes which allow me to filter these items.
I would like to display "# of returned results" at the top of the page. The "#" being the actual number of divs returned.
Currently I have:
var divCount = $('.item-container:visible').length;
$('.header').append(contactCount);
When clicking a filter, it displays the visible results. However, if I uncheck a filter, or check another, it shows the visible item account in additional to the previous result.
For example. There's 1000 items. I click a checkbox. It displays 604 at the top of the page. I uncheck the checkbox and it'll display 6041000.
Any help on this would be greatly appreciated.
Thanks all.
$('.header').text(contactCount);
Should do the trick. See the jQuery docs for more details.
Thats because you use the append function. It does append what you give to it to the DOM. I recommend specifying a span and than use the html function to set the content of that span.
var divCount = $('.item-container:visible').length;
$('#counter').html(divCount);

Hide all elements that don't have class matching selected element

I've got a cool interface to build.
There's a horizontal scrolling div containing "tiles" of images, and a radio button under each. A user will scroll and decide on an image, then click it. The radio button checks, and jQuery shows another horiz scrolling div below, "now select subcategory"... The user can then further refine the selection by choosing another "tile". That's the process complete.
The problem is I'm not sure how to hide all the elements in the 2nd tier of selection if they don't have a class that matches that of the first selection. Sounds confusing maybe. Here's some simplified HTML, I've posted it on jsfiddle to save space here. http://jsfiddle.net/RTGC3/
So in summary, you'll see from the HTML what needs to happen. A user will see categories, when they click a category, subcategories without the same id as the clicked parent category will be hidden. All others will remain visible ready for the containing div to "show".
I hope I've explained the problem well enough. Thanks for any help offered.
Mike.
Try with this Code:
$(document).ready(function() {
$('input[type=radio][name="type"]').live('change', function() {
var className = $(this).parent().attr("class");
var clsID = className.split('_')[2];
var subID = "in_cat_" + clsID;
$("div[class*=in_cat]").hide();
$("div." + subID).toggle("slow");
});
});
This is the JSFiddle Link:
http://jsfiddle.net/RTGC3/3/
Easiest if you name both container divs with id 1 for example to the same thing, so you would have TWO class="cat_id_1".
Then something liek this:
$('#cat-container div input').on('change', function() {
var id = $(this).parent().attr('class');
$('#des-container div.'+id).fadeToggle();
});
and in CSS you have display:none; on all divs in #des-container (for starters). This will listen for the radio button when it changes, first change it will call .fadeToggle() on div with matching class in your second row and show it, and second change will hide it again.
Was this what you wanted?
Actually I assuem you want all items in the second row to be displayed, but when checking a radio box you want to hide everything besides the one matching the id of the radiobutton? Then you could do like this:
$('#des-container div'+id).addClass('show');
$('#des-container div').not('div.show').fadeToggle();
So basically you add a class to the objects you decide to show, and hide everything that doesn't have that class. Ofcourse for this to work the other way (if you uncheck a radio-box) you would need to add a if-statement seeing the radio button that was changed was changed to checked or unchecked, if unchecked you just remove the class "show" from the element.

Categories

Resources