Retaining Memory of Initial Properties for Dynamic Buttons - javascript

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

Related

How to fill in Google Form's drop down and text inputs with Tampermonkey?

I am trying to automate an attendance form hosted by Google Forms, but the inputs aren't HTML <input> or <select> elements, so I am not sure how to change them other than manipulating the mouse and keyboard (an approach I used with Selenium).
Based off a fast peak; you could
let Form = document.querySelector('.freebirdFormviewerViewItemList');
let itemContainer = Form.querySelectorAll('.freebirdFormviewerViewNumberedItemContainer');
itemContainer.forEach((element)=>{
// Your code here, you should in theory be doing deeper loops depending on how advanced you want this.
});
Inside the loop we'd need to just find all the active inputs we want with a
itemContainer.forEach((element)=>{
if(element.querySelector('.exportOuterCircle')) {
console.log('we found ourselves a radio button but just one, we could go deeper with querySelector (and help of loops/etc)')
}
});
This is a bit of a large-task but not so bad, just make sure the freebirdFormviewerViewNumberedItemContainer class is correct every-form to or y ou find the pattern per-page that selects the questions for a fast loop through.
On loop, you're to query select one or more(if so apply another loop) to find the options you want. In this demo above radio button search, if the pages stay static you should with my example be able to grab/see a console pop-up no errors;
For setting these values, it's as easy in some cases setAttribute/value/ and other modifiers once selection is made. So you know click already and so the radio buttons be a good example. Any issues try navigating your elements in developer menu and sort if selections are going down correctly.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

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.

Paper.js - Get first ''selected item'' from selectedItems

I'm trying my way around building a graphics editor with Paper.js
I would like to select the first(1st) element that was picked using a selection tool(either Shift+Click, or dragging a selection box). Direct-click detection is done via hit-testing and selection box via getIntersection
If it's Shift+Click its the first selected element. Which element was clicked is found with HitResult
If its selectionBox, the first intersection? result of the selection box.
Is it possible to get this?
I do a FOR loop to get all the elements in the Paper.js selectedItems array which returns all the selected items on the canvas.
I've tried this:
var selected = paper.project.selectedItems;
var firstSelected = selected[0];
but this doesn't return what i need.
The above code snippet fetches an array that is agnostic to which element was selected first. It simply orders the selectedItems in the array starting from the ''oldest drawn path''.
What i need is a way to find out which is the 1st element that was selected.
Either the 1st that get's ''touched(intersected)'' with the selection
rectangle
Or the first that was clicked while in Shift+Click
functionality(Select more than one element with click).
The reason for this is that i would like to add to my editor, align-relative-to functionality.
In order to have a correct UX, the user must have the ability to align an element relative to another that he sets as the ''reference item''. Therefore i need to know the 1st element selected relative to others in order to use it as the ''reference item''.
Any ideas ?
Here is a working example of what I understood you want to achieve for the selection (without the align-relative-to functionality).
And here is the code (under SelectPaperJS) https://c9.io/arthursw/oiio/
It should not be too hard to make something similar on Stylii (since you're using it).
You can have an array to keep track of the order of selection of your items. For example in the mousedown function of the direct select tool (from line 789 of editor.js) you can add the newly selected element to this array (line 800). Same thing when you select with the rectangular selection tool.

Javascript not retaining div id on reload with localStorage?

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

Show a button next to an element inside TinyMCE

I want to show a button (for example, span.mybutton) next to every instance of a specified element (for example, a table) in TinyMCE—and then, when that button is clicked, grab that specific element's html, process it, and update it in the editor.
I can handle the processing, but I can't figure out how to display the button and pass in grab the specific element's html. If I do this, for example, it adds the html of span.mybutton to TinyMCE as if it were regular content, which I don't want:
jQuery('iframe#content').contents().find('table').append('<span class="mybutton">My button</span>');
Here's what I'm trying to do:
function processElement( element, values ) {
// do stuff to the table html (I don't need help with this part)
return element;
}
function appendButtonToTinyMCEElement ( button, element ) {
// put button next to all instances of the specified element in TinyMCE
// (in this case, put span.mybutton at the corner of all tables)
}
$('.myhelperbutton').click(function(){
var element = ??? // get content of the element whose button was clicked
var element = processElement( element );
// send element back to TinyMCE (not sure how)
});
So, my two questions are:
How can I display the button in the right place without affecting the html that gets saved in TinyMCE? And, when the button is clicked, how do I get/set just that element from TinyMCE?
If I understand correctly you wish to grab all table DOM elements, and place a button next to it which does some stuff.
Below is my first thought. I am going to make convenient assumptions to make it easier, but let me know if I made some wrong assumptions somewhere. I also don't know how much javascript/jquery you already know, so let me know if I didn't explain something clearly.
jQuery('iframe#content').contents().find('table').each(function(index, element) {
// create a new button.
var $btn = $('<input type="button" class="mybutton"></input>');
function action() {
// This is using the `processElement` function you defined in your question,
// I am applying it to the specific table just grabbed.
processElement(element);
}
$btn.click(action);
// This should append the button. See http://api.jquery.com/after/
$(element).after($btn[0]);
});
Let me know if this works for you or not.

Categories

Resources