Dynamically create tooltip for an element - javascript

I am trying to show a tooltip when user selects random text on the page - think of annotating text.
I was able to dynamically create v-tooltip component. I have selected element in JS, but having trouble wrapping it with v-tooltip component. I was able to wrap it, but the tooltip is positioned to the top of the page, not on the wrapped element itself. I am also not sure my approach is the best one either.
Here is a JSFiddle example: https://jsfiddle.net/6xk7zLv9/
Is there better way to dynamically generate Vue components and insert into the DOM? How can I correctly attach tooltip to the selected element.

You need to specify a side prop (top/bottom/left/right) on the tooltip.
The activator slot is also optional, instead you can use the position-x and position-y props to place it wherever you want without replacing DOM elements: https://codepen.io/kaelwd/pen/LYWLxVe?editors=1010
window.getSelection().getRangeAt(0).getBoundingClientRect() will give you the position of the current selection: https://codepen.io/kaelwd/pen/poewRaE?editors=1010
If you want to get really fancy you can call getClientRects instead and have the tooltip follow the end of the selection: https://codepen.io/kaelwd/pen/vYxZgjb?editors=1010
https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection
https://developer.mozilla.org/en-US/docs/Web/API/Selection/getRangeAt
https://developer.mozilla.org/en-US/docs/Web/API/Range/getClientRects

Related

How to attach a DOM object to a div (propertyeditor)

I am building a small property editor in Javascript. I have a list of objects with some properties (x, y, width, height) for drawing a "<div>" inside a div. Im making so that the user can drag images/divs around.
All these objecs are in a list and then I traverse the list and render the view. Next to the view I have a small editor with the properties. I can add multiple of these elements to the editor/viewer and of different kinds (text and images, and maybe other stuff in the future).
My question is this:
How do I make it so that when editing a property (like the X-coordinate) for the "first/top" box, it updates ONLY the corresponding object in the list (NOT in the view, the view is just being rendered from the list of objects). I'm adding all these in runtime and I have no round-trip to server. I'm cool with having a save button on each item.
You could follow some naming patterns when creating elements and creating property editors. Example, when new image element button is clicked, create image element with id : el_img_01 and property editor for corresponding image element as id : el_img_prop_01.
so for all images will have (el_img_, el_img_prop_), in order to know the img element for a property editor, we can read the property editor id, and remove the 'prop' text from the id to get the associated DOM element.
Several steps here:
You need a way to identify the elements, for instance, one
id.
You have to be able to select one element and be aware of
it. You can put a select containing all the ids, for example.
Now you can select the element, you just need to load/save
the values from your form.

Reset/Render again element in polymer

Their is option in polymer to reset element/ custom element to the original state. Like render the element again?
I want all the inner variables values to delete and that the element will look the same as I load the page.
Thanks
I see to ways:
First one is just to write 'reset' method which resets all vars so that bound ui gets to the initial state.
The second one is to remove the element with Polymer.dom(parent).removeChild and then create new one of same type with document.createElement and put it at old element's place with Polymer.dom(parent).appendChild/insertBefore.
I'd choose first one - seems to be more testable and confined to the lement.

Store "templates" of children

I am new to JavaScript so forgive me if the question comes around as dumb.
I know that appendChild() allows me to add a child element to an existing element. However, the problem is that I want to add an element which has an image on the left and a series of text boxes on the right and I need to add it over and over again on button click.
Adding simple elements like p, a , etc can be done by a single call to appendChild(), however for the above scenario, it will be a little messy.
Is there some way that I can define the custom element that I want to append and then just add it with a single call to appendChild()
Are you using jQuery? If it is a really complicated template, you could use .load() to ajax in an template and populate it with whatever you have to. You wouldn't need to dynamically create all of the elements using javascript, only populate it. This would would also allow you to change your template if need be very easily.
It seems you need cloneNode:
target.appendChild(template.cloneNode(true)); // If you want to clone template
// with all its descendants
target.appendChild(template.cloneNode(false)); // If you want to clone template
// without its descendants
I do this quite a bit. My code generally looks like this:
<div class="template" style="display: none;">stuff</div>
then:
$('.template').clone(true).removeClass('template').show().appendTo(someElement);
Since you're not using jQuery, have a look at the clone function here:
http://code.jquery.com/jquery-1.11.0.js
(search for "clone: function" to find it)
You can steal the relevant bits if you can't actually use jQuery itself.

How to select an element by distance when it isn't a parent or child

I'm working on editing a tooltip plugin (TooltipsY) to use a div instead of the title element for the content of the tooltip. I'm doing this for a multitude of reasons, the primary one being so I can have HTML in my tooltips without causing validation errors.
The problem I'm having is that when changed the content of the tooltip to be the div instead of the title attribute, every link with a tooltip shows the same tooltip content. That's because The div's aren't related to the links in any way so I can't use "this" to select them.
It would work if I knew some way to change $('div.showtip').html(); to this.closest($('div.showtip').html()); (that method won't work because the div isn't a parent or a child of the link) so how can I make the tooltip content the closest div to the link that's being hovered over?
Here is my example: http://jsfiddle.net/sgCCD/2/
Note: The only thing that should need to be changed is the value of the variable showtip.
Also, I don't want a suggestion for a different tooltip plugin, I'm doing this just as much for my own personal experience as I am to improve the functionality of the plugin.
Hope this is what you're looking for:
http://jsfiddle.net/sgCCD/3/
changed this line:
var showtip = $('div.showtip').html();
to this:
var showtip = $(el).next().html();

basic scripting question... dynamically modify div content?

I'm wondering what might be the simplest approach to dynamically changing the contents of a "caption" div to reflect the info corresponding to a specific thumbnail/link in an image gallery.
To be more specific, if you visit this link-- which shows off the awesome Seadragon zoom script btw-- I would like to have a small caption under the image that changes (text) content when a user clicks the different links above; perhaps pulling text from an alt or title attribute and placing in an empty div?
In my case, I'll be using thumbnails instead of text links, so upon clicking these images the user will both initiate the "switchTo" Seadragon event and fill the empty div with corresponding content.
thanks for any guidance here.
If you have the id of the div, the simplest way would be to use innerHTML:
document.getElementById(id).innerHTML = "text";
This is fine for simpler cases, like replacing all of the text in a div. If you want to do something more complicated, like having other html elements inside the div, this method is not the best choice.
If you want to add an html element to the div tag, then you should avoid innerHTML. If you have, say, a variable img that is an img tag, then use this to add it to the div:
document.getElementById(id).appendChild(img);
If you want to do anything more complicated than this, you should probably consider using a nice framework like jQuery--it might be too much for something like this, but if you plan to do anything else, then a framework would be worth using.
If you want to do this with jQuery, it can be done using some of the following functions:
var div = $("#id");// jQuery uses CSS selectors to get elements.
div.append("New content");// Puts the new content at the end.
div.empty();// Gets rid of everything inside the div.
div.append(element);// You can also append elements.
// For example, you can create and append an image to the div:
var img = $("<img>");
img.attr("src", "images/something.png");
div.append(img);

Categories