Add span to page at the cursor position - javascript

I have the following JavaScript, I am trying to insert the span at where ever the cursor position is in the div.
var appendPlaceHolder = function (field) {
var e = document.getElementById("t");
e.innerHTML += (' <span class="nonEditable tags">{' + field + '} <span onclick=removePlaceholder(this) class="testing"></span>x</span> ');
}
<div id="t" contenteditable="true">
Hello
</div>
How do I go about doing it?

Here is an old script I've written.Hope it helps.
continent is the mouse entered div, tooltipOutput
function continentTooltip(continent, tooltipOutput) {
var tooltip = $('.map__tooltip');
$(continent).mouseenter(function() {
$(document).off('mousemove').bind('mousemove', function(e){
var positionX = (e.pageX + 20) + 'px';
var positionY = e.pageY + 'px';
$('.map__tooltip').css(
"transform" , 'translate(' + positionX + ', ' + positionY + ')'
);
});
tooltip.addClass('map__tooltip--show');
tooltip.text(tooltipOutput)
})
$(continent).mouseleave(function() {
tooltip.removeClass('map__tooltip--show');
});
}
//call script
continentTooltip(africa, 'Vacations in Africa');
HTML:
<div class="map__tooltip"></div>
CSS:
.map__tooltip {
display: none;
background-color: #FFF;
border-radius: $radius;
padding: 4px;
position: absolute;
top: 0;
left: 0;
}
.map__tooltip--show {
display: block;
}
#media screen and (max-width: 1300px) {
.map__tooltip--show {
display: none;
}
}

Related

How to switch between transform-origin and scrollbars

I have this code above who switch between CSS transform-origin and scale to CSS width and scrollbars.
I need to make this switch because I am having a pinch to zoom for a DIV wrap I'm using in my website.
I'm using CSS translateX and translateY and Scale for a smoother pinch zoom, but after the zoom take place, I need to return back to width and scrollbar so the user can move across the layout.
I have here an example of how I'm doing the switch and there is a bit margin on top that I can't really set mind my on.
what is the correct way to do so?
var isOrigin = false;
var originX = 500;
var originY = 200;
var scale = 1.5;
var deltaX = 0;
var deltaY = 0;
var from_origin_to_scroll = function () {
if (isOrigin) { from_scroll_to_origin(); return; }
var wrap = $('.containter .wrap');
//reset scroll
const el = document.scrollingElement || document.documentElement;
$('.containter')[0].scrollLeft = 0;
el.scrollTop = 0;
wrap.css({
transformOrigin: originX + "px " + originY + "px",
transform: "translate3d(" + deltaX + "px," + deltaY + "px, 0) " +
"scale3d(" + scale + "," + scale + ", 1) ",
width: 100 + '%'
});
isOrigin = true;
$('.info').html('layout set by origin and scale');
}
var from_scroll_to_origin = function () {
var wrap = $('.containter .wrap');
wrap.css({
transformOrigin: originX + "px " + originY + "px",
transform: "translate3d(" + 0 + "px," + 0 + "px, 0) " +
"scale3d(" + 1 + "," + 1 + ", 1) ",
width: (100 * scale) + '%'
});
$('.containter')[0].scrollLeft = originX * (scale - 1);
const el = document.scrollingElement || document.documentElement;
el.scrollTop = originY * (scale - 1);
isOrigin = false;
$('.info').html('layout set by width and scroll');
}
body {
margin: 0;
padding: 0;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
width:100vw;
}
.top{
position: fixed;
width: 100%;
background-color: #333;
line-height: 40pt;
text-align: center;
color: #f1f1f1;
font-size: 20pt;
left: 0;
top: 0;
z-index: 10;
}
.top .info{
}
.header_content
{
background-color: #e1e1e1;
line-height:130pt;
}
.containter {
width:100%;
box-sizing: border-box;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.containter .wrap {
display: flex;
flex-direction: column;
width: 100%;
}
.containter .wrap img {
width: 100%;
margin-top: 30pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top">
<div class="info" onclick="from_origin_to_scroll()">click to switch</div>
</div>
<div class="header_content">
this is a header content - needs to be added to overall calculation
</div>
<div class="containter">
<div class="wrap">
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/91858/594887747/stock-photo-dreams-of-travel-child-flying-on-a-suitcase-against-the-backdrop-of-sunset-594887747.jpg" />
<img src="https://thumb9.shutterstock.com/display_pic_with_logo/1020994/556702975/stock-photo-portrait-of-a-happy-and-proud-pregnant-woman-looking-at-her-belly-in-a-park-at-sunrise-with-a-warm-556702975.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/234100/599187701/stock-photo-funny-little-girl-plays-super-hero-over-blue-sky-background-superhero-concept-599187701.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/1316512/661476343/stock-photo-funny-pineapple-in-sunglasses-near-swimming-pool-661476343.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/2114402/689953639/stock-photo-adult-son-hugging-his-old-father-against-cloudy-sky-with-sunshine-689953639.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/172762/705978841/stock-photo-businessman-looking-to-the-future-for-new-business-opportunity-705978841.jpg" />
</div>
</div>
In your case the possible solution is to detect when the user is trying to zoom, and when just to scroll.
const $container = $(".container");
$container.on('touchstart', function (e) {
if (e.touches.length > 1){
//more than one finger is detected on the screen,
//change mode to transform-origin
from_scroll_to_origin()
}
});
$container.on('touchend', function (e) {
//change mode to scrollbars
from_origin_to_scroll()
});

Javascript: Create draggable elements that push each other out of the way

I would like to have a series of boxes that can be dragged around in a frame. When when they touch another box, it is pushed out of the way - repelled if you will.
I just don't even know where to start beyond making them draggable!!
To expand on my comment and show you a possible proof of concept, I have created this small bit of code:
https://jsfiddle.net/Twisty/L03rks0y/
HTML
<div id="move-frame">
<div id="obj-1" class="drag">
<span class="top">T: 2</span>
<span class="left">L: 2</span>
<span class="bottom">B:</span>
<span class="right">R:</span>
</div>
<div id="obj-2" class="no-drag">
<span class="top">T: 125</span>
<span class="left">L: 175</span>
</div>
</div>
CSS
#move-frame {
border: 1px solid #000;
margin: 20px;
padding: 2px;
width: 300px;
height: 300px;
position: relative;
}
.drag,
.no-drag {
border: 0px solid #666;
width: 75px;
height: 75px;
}
.top,
.left,
.bottom,
.right {
display: block;
font-size: 85%;
font-family: Arial;
width: 100%;
text-align: center;
}
#obj-1 {
background: #6f6;
}
#obj-2 {
background: #ccf;
position: absolute;
top: 125px;
left: 175px;
}
jQuery UI
$(function() {
var stuff = {};
$(".no-drag").each(function(k, v) {
var id = $(v).attr("id");
var top = $(v).position().top;
var left = $(v).position().left;
var bottom = top + $(v).height();
var right = left + $(v).width();
stuff[k] = {
id: id,
top: top,
left: left,
bottom: bottom,
right: right
};
});
console.log(stuff);
$("#obj-1").draggable({
containment: '#move-frame',
drag: function(e, ui) {
var objW = ui.helper.width();
var objH = ui.helper.height();
var objP = ui.position;
var buffer = 2;
objP.right = objP.left + objW;
objP.bottom = objP.top + objH;
$(this).find(".top").html("T: " + objP.top);
$(this).find(".left").html("L: " + objP.left);
$(this).find(".bottom").html("B: " + objP.bottom);
$(this).find(".right").html("R: " + objP.right);
$.each(stuff, function(k, v) {
if (objP.right == v.left - buffer) {
var $el = $("#" + v.id);
$el.css("left", v.left + buffer);
v.left += buffer;
$el.find(".top").html("T: " + $el.position().top);
$el.find(".left").html("L: " + $el.position().left);
}
if (objP.bottom == v.top - buffer) {
var $el = $("#" + v.id);
$el.css("top", v.top + buffer);
v.top += buffer;
$el.find(".top").html("T: " + $el.position().top);
$el.find(".left").html("L: " + $el.position().left);
}
});
}
});
});
There are lots of ways to improve upon this. You can see that it's very easy to drag pas the buffer, yet if moved slowly, you nudge the blue box around with the green box. You can also see some gapping issues, like if you slowly bring the green box over, but are not on the same Y plane, the blue box can still be moved.

How to show height on a div while resizing it dynamically

I want to know how the Javascript code below is working.
I tried this one on javascript but it shows me error. I got this code from : http://interactjs.io/ (Resizing).
I just want to show height on div while resizing vertically. The code is below:
interact('.resize-drag')
.draggable({
onmove: window.dragMoveListener
})
.resizable({
edges: {
left: true,
right: true,
bottom: true,
top: true
}
})
.on('resizemove', function(event) {
var target = event.target,
x = (parseFloat(target.getAttribute('data-x')) || 0),
y = (parseFloat(target.getAttribute('data-y')) || 0);
// update the element's style
target.style.width = event.rect.width + 'px';
target.style.height = event.rect.height + 'px';
// translate when resizing from top or left edges
x += event.deltaRect.left;
y += event.deltaRect.top;
target.style.webkitTransform = target.style.transform =
'translate(' + x + 'px,' + y + 'px)';
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
target.textContent = event.rect.width + '×' + event.rect.height;
});
.resize-drag {
background-color: #29e;
color: white;
font-size: 20px;
font-family: sans-serif;
border-radius: 8px;
padding: 20px;
margin: 30px 20px;
width: 120px;
/* This makes things *much* easier */
box-sizing: border-box;
}
.resize-container {
width: 100%;
height: 240px;
}
<div class="resize-container">
<div class="resize-drag">
Resize from any edge or corner
</div>
</div>
Include this on top:
<script src="http://code.interactjs.io/interact-1.2.5.min.js" type="text/javascript"></script>

How to create DOM element on event, and then prevent event handler from triggering until DOM element exists?

So basically I'm creating a tooltip function.
And tooltip will appear as a new DOM element over the element you clicked.
Here is the fiddle:
$(document).ready(function () {
$('.tooltipTarget').click(function () {
var title = $(this).data('tooltip');
$('<p class="tooltip active"></p>')
.text(title)
.appendTo('body')
.fadeIn(250);
var coords = $(this).offset();
var tooltipHeight = $('.tooltip').height() + $(this).height() + 20;
var tooltipWidth = $('.tooltip').width() / 2;
coords.top = coords.top - tooltipHeight;
coords.left = coords.left - tooltipWidth;
$('.tooltip').css({
top: coords.top,
left: coords.left
});
});
});
.tooltip {
display: none;
position: absolute;
border-radius: 1px;
color: #767676;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
background: #f7f7f7;
padding: 10px;
font-size: 12px;
text-align: left;
z-index: 10;
max-width: 250px;
}
<button style="margin: 50px;" data-tooltip="This is a tooltip" class="tooltipTarget">Click me!</button>
But the problem I have is that new DOM elements will keep appearing as long as you trigger the event.
I wont to prevent it. I want it to be like this:
1)You click a button
2)Tooltip appears
3)You click again on the button - tooltip disappears.
How can I do it?
Working fiddle: https://jsfiddle.net/4d8xhLqj/2/
I would second what #JamesSutherland has put. The tooltip should pre-exist so you only have to play with its positioning and opacity later on.
Having said that though, if you really need to follow the approach that you already have, you could do this:
Snippet:
$(document).ready(function() {
$('.tooltipTarget').click(function() {
var title = $(this).data('tooltip');
if (!$('p.tooltip').hasClass('active')) {
$('<p class="tooltip active"></p>')
.text(title)
.appendTo('body')
.fadeIn(250);
var coords = $(this).offset();
var tooltipHeight = $('.tooltip').height() + $(this).height() + 20;
var tooltipWidth = $('.tooltip').width() / 2;
coords.top = coords.top - tooltipHeight;
coords.left = coords.left - tooltipWidth;
$('.tooltip').css({
top: coords.top,
left: coords.left
});
} else {
$('p.tooltip.active').fadeOut(250, function() {
$(this).remove();
});
}
});
});
.tooltip {
display: none;
position: absolute;
border-radius: 1px;
color: #767676;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
background: #f7f7f7;
padding: 10px;
font-size: 12px;
text-align: left;
z-index: 10;
max-width: 250px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button style="margin: 200px;" data-tooltip="This is a tooltip" class="tooltipTarget">Click me!</button>
Here is the resulting fiddle. Hope this helps.
You should check if the tooltip is already shown:
$(document).ready(function () {
$('.tooltipTarget').click(function () {
var title = $(this).data('tooltip');
if ($('.tooltip[data-title=' + title + ']').length > 0) {
$('.tooltip[data-title=' + title + ']').remove();
return;
}
$('<p class="tooltip active" data-title=" ' + title + ' "></p>')
.text(title)
.appendTo('body')
.fadeIn(250);
var coords = $(this).offset();
var tooltipHeight = $('.tooltip').height() + $(this).height() + 20;
var tooltipWidth = $('.tooltip').width() / 2;
coords.top = coords.top - tooltipHeight;
coords.left = coords.left - tooltipWidth;
$('.tooltip').css({
top: coords.top,
left: coords.left
});
});
});
I've added a data attribute to the newly created tooltip in order to check afterwards if there is a tooltip for that element present, and if yes, remove it and return.
just check whether or not the tooltip exists as part of your click function. Remove the tooltip when it does exist and create a tooltip when it doesn't.
if($('.tooltip').length) {
$('.tooltip').remove();
}
else {
//create the tooltip as usual here
}
here is a working fiddle
https://jsfiddle.net/4d8xhLqj/3/

JQuery/JavaScript calender slider

I´m currently programming an Calender and had the idea to design it like a slider.
Something like: http://wisestartupblog.com/wp-content/uploads/2008/02/itunes-cover-flow1.png
The selected day should be centered on the viewport and should show below later on different events.
I´ve created a flex-box and created for each day a rounded div-container and set the parent container to overflow for hiding the non relevant days.
HTML with JavaScript:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="/javascripts/jquery-1.11.3.min.js"></script>
</head>
<body>
<section id="top_container">
<div id="date_rotation">
</div>
</section>
<nav id="menu_bar">
</nav>
<section id="event_container">
jj
</section>
<script>
// Variables
var date = new Date();
var daynames = ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"]
var monthnames = ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober",
"November","Dezember"];
var calStart = new Date(2015, 4, 28);
var selectedYear = calStart.getFullYear();
var selectedMonth = calStart.getMonth();
var selectedDay = calStart.getDate();
var calLength = 2000;
//Functions
function daysofMonths(myyear,mymonth) {
var monthStart = new Date(myyear, mymonth, 1);
var monthEnd = new Date(myyear, mymonth + 1, 1);
var monthLength = (monthEnd - monthStart) / (1000 * 60 * 60 * 24);
return monthLength;
}
// Creating Calender
for (var i=0; i <= calLength; i++) {
currentDate = new Date(selectedYear, selectedMonth, selectedDay);
if (selectedDay > daysofMonths(selectedYear,selectedMonth)) {
selectedDay = 1;
selectedMonth ++;
if (selectedMonth > 11) {
selectedMonth = 0;
selectedYear ++;
}
$("#date_rotation").append('<div class="date_picker" id="' + selectedDay + selectedMonth + selectedYear + '"><p>' + selectedDay + monthnames[selectedMonth] + '<br>' + daynames[currentDate.getDay()] + ' ' + selectedYear + '</p></div>');
console.log("First");
} else {
$("#date_rotation").append('<div class="date_picker" id="' + selectedDay + selectedMonth + selectedYear + '"><p>' + selectedDay + monthnames[selectedMonth] + '<br>' + daynames[currentDate.getDay()] + ' ' + selectedYear + '</p></div>');
selectedDay ++;
console.log("Secound");
}
}
// Rotate Calender
// Get Position relative to Container
$(".date_picker").click(function( event ) {
var thisPos = $(this).position();
var parentPos = $(this).parent().position();
var x = thisPos.left - parentPos.left;
var y = thisPos.top - parentPos.top;
var width = $("#date_rotation").width();
$("#menu_bar").text(x + "px, " + y + "px," + width + "px");
</script>
</body>
</html>
SCSS
#top_container {
position: fixed;
z-index: 100;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 300px;
background-color: rgba(0, 0, 0, 0.75);
border-bottom: 2px solid black;
}
#event_container {
margin: 0 auto 0;
height: 100%;
width: 70%;
background-color: rgba(0, 0, 0, 0.5);
}
#menu_bar {
width: 70%;
margin: 302px auto 0;
height: 50px;
background-color: rgba(0, 0, 0, 0.75);
color: white;
}
#date_rotation {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
position: fixed;
top: 75px;
z-index: 101;
}
#date_rotation .date_picker {
display: inline-block;
position: relative;
overflow: hidden;
margin: 0 25px;
width: 150px;
height: 150px;
background-color: white;
border-radius: 50%;
text-align: center;
font-size: 1em;
}
#date_rotation .date_picker p {
line-height: 50px;
}
#date_rotation .date_picker:hover {
cursor: pointer;
transform: scale(1.5);
background-color: rgba(0, 0, 0, 0.5);
color: white;
}
What I´m trying to archieve is to center the clicked div with the class date_picker and therefore moving the complete parent overflowed container.
I´m totally stuck and dont know how to exactly move the parent-container till the selected child-item is centered perfectly =/ Id love to have an animated solution or hints how I can archieve my goal.
Would really appreciate some hints/answers =)
Solution:
$(".date_picker").click(function( event ) {
var thisPos = $(this).position();
var parentPos = $(this).parent().position();
var x = thisPos.left - parentPos.left;
var y = thisPos.top - parentPos.top;
var width = $("#date_rotation").width();
$("#menu_bar").text(x + "px, " + y + "px," + width + "px");
//Center Selected child-items
var selectedDate = $(document).width() / 2;
var selectedLeft = $(this).position().left
console.log(selectedLeft);
var dateCentering = selectedLeft - selectedDate;
dateCentering += 150;
$("#date_rotation").animate({
'left' : -dateCentering
});
});
Best regards Cab
What I can think of is to calculate the left offset of your centered element (l-cen), the left offset of your current one (l-curr) and calculate the difference = l-cen - l-curr; (centered element minus the one you want to go to...so, if it's left you get a positive value, if it's right you get a negative value). Apply difference to a transition on #date_rotation (if it's right, thus a negative value, your div will move left). That should work. You could technically apply the transition on the first datepicker element as well.
Getting the rotation of the elemnts like in the image you offered will be trickier, but based on the same principle.

Categories

Resources