How to save drag/drop coordinates back to angular model? - javascript

My code allows for dragging and dropping of form fields overlaying an page image. I'm using Kendo-ui for the drag/drop but that's not critical to the answer, I don't think, and the demo is overly simplified and doesn't contain the image. I need to be able to change the angular model's coordinates to reflect the dropped location so I can save it. The meat of my question is HOW to update the model. What's the most efficient way of doing this since I can possibly have hundreds of fields? Is it possible to bind to the left/bottom CSS coordinates? Should I update the CSS manually using jQuery and then update the model?
Here's the plunker with my code
INDEX.HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common-bootstrap.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2016.2.714/styles/kendo.bootstrap.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2016.2.714/styles/kendo.bootstrap.mobile.min.css" />
<script src="https://kendo.cdn.telerik.com/2016.2.714/js/jquery.min.js"></script>
<script src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="https://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
<script id="page-template" type="text/ng-template">
<div class="page" kendo-droptarget style="{{ 'width:' + (p.width + 2) + 'px; height:' + (p.height + 2) + 'px;' }}" ng-repeat="p in model.transaction.selectedDocument.pages">
<div class="field" data-fieldname="f.fieldName" kendo-draggable k-hint="model.draggableHint" k-dragstart="model.onDragStart" k-dragend="model.onDragEnd" ng-repeat="f in p.fields" style="{{ 'left:' + f.left + 'px;bottom:' + f.bottom + 'px;width:' + f.width + 'px;height:' + f.height + 'px;' }}">
<div></div>
</div>
</div>
<pre>{{ model | json }}</pre>
</script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<page-image-component></page-image-component>
</body>
</html>
SCRIPT.JS
// Code goes here
console.clear();
function pageImageController(TransactionFactory) {
var model = this;
model.transaction = TransactionFactory;
model.draggableHint = function (e) {
return e.clone();
}
model.onDragStart = function (e) {
console.log(e);
e.currentTarget.hide();
}
model.onDragEnd = function (e) {
console.log(e);
//e.currentTarget.css("left", "0px").css("top", "0px");
var field = e.currentTarget[0];
console.log(e.currentTarget)
e.currentTarget.show();
}
}
var app = angular.module("app", ["kendo.directives"]);
app.factory('TransactionFactory', function () {
var transaction = {
selectedDocument: {
fileName: "my.pdf",
pages: [{
pageNumber: 1,
width: 400,
height: 500,
fields: [
{
fieldName: "my field 1",
width: 75,
height: 13,
left: 50,
bottom: 300,
instance: 1
},
{
fieldName: "another field 1",
width: 65,
height: 13,
left: 200,
bottom: 440,
instance: 1
},
]
}]
}
};
return transaction;
});
app.component("pageImageComponent", {
template: $("#page-template").html(),
controllerAs: "model",
controller: ["TransactionFactory", pageImageController]
});
STYLE.CSS
/* Styles go here */
.page
{
border: 1px solid black;
position: relative;
}
.field
{
background-color: #ddd;
position: absolute;
}

I think I figured it out and I think it's efficient enough for rock and roll.
Here's the Plunker
function pageImageController(TransactionFactory) {
var model = this;
model.transaction = TransactionFactory;
var tempLeft = 0;
var tempTop = 0;
model.draggableHint = function (e) {
return e.clone();
}
model.onDragStart = function (e) {
//console.log(e);
e.currentTarget.hide();
}
model.onDrop = function (e) {
tempLeft = e.draggable.hint.offset().left -9;
tempTop = e.draggable.hint.offset().top +2;
console.log(e.draggable);
}
model.onDragEnd = function (e) {
//console.log(e);
var field = e.currentTarget[0];
//console.log(field)
var fieldIndex = field.attributes['data-fieldindex'].value;
var pageIndex = field.attributes['data-pageindex'].value;
//console.log(fieldIndex);
//console.log(pageIndex);
var tempBottom = model.transaction.selectedDocument.pages[pageIndex].height - tempTop;
model.transaction.selectedDocument.pages[pageIndex].fields[fieldIndex].left = tempLeft;
model.transaction.selectedDocument.pages[pageIndex].fields[fieldIndex].bottom = tempBottom;
e.currentTarget.css("left", tempLeft + "px").css("bottom", tempBottom + "px");
e.currentTarget.show();
}
}

Related

Annotate RoughViz chart using Rough-Notation library

I have a simple bar chart built with RoughViz.js. The key takeaway that I'd like to highlight in the chart is the difference in height between the first bar and the third bar. To do this I'd like to use the bracket annotation from Rough Notation and set the bracket to start at a y-coordiate equal to the height of the first bar and end at a y-coordinate equal to the height of the last bar. What is the best way to accomplish this?
EDIT...
this picture illustrates what I'm trying to accomplish. The large bracket is the one that the rough-notation library is drawing in my code. Note that it wraps the entire chart. I want it to instead draw the bracket like the small dark blue one that I've mocked up. The dashed lines are also just mock up so as to better convey the desired positioning.
The external libraries are:
https://github.com/jwilber/roughViz and
https://github.com/rough-stuff/rough-notation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/rough-viz#1.0.6"></script>
<script type="module" src="https://unpkg.com/rough-notation?module"></script>
<style>
body {}
;
.item1 {
grid-area: chart;
}
.item2 {
grid-area: annotation;
}
.grid-container {
margin-top: 3rem;
display: grid;
grid-template-areas:
'chart annotation';
grid-template-rows: 1fr;
grid-template-columns: 8fr, 3fr;
}
#typedtext {
font-family: 'Waiting for the Sunrise', cursive;
font-size: 25px;
margin: 10px 50px;
letter-spacing: 6px;
font-weight: bold;
color: blue;
padding-left: 3rem;
padding-top: 30%;
height: 100%;
}
</style>
</head>
<body>
<button id="annotate-button">Click me</button>
<div class="grid-container">
<div class="item1">
<div id="viz0"></div>
</div>
<div class="item2">
<div id="typedtext"></div>
</div>
</div>
</body>
</html>
<script>
// create Bar chart from csv file, using default options
new roughViz.Bar({
element: '#viz0', // container selection
data: {
labels: ['First thing', 'Second thing', 'Third thing'],
values: [100, 50, 25]
},
width: window.innerWidth * .7,
height: window.innerHeight * .7
});
</script>
<script type="module">
import { annotate } from 'https://unpkg.com/rough-notation?module';
const e = document.querySelector('#viz0');
const annotation = annotate(e, { type: 'bracket', color: 'blue', padding: [2, 10], strokeWidth: 3 });
document.getElementById("annotate-button").addEventListener('click', function(){
annotation.show();
})
</script>
<script>
//https://css-tricks.com/snippets/css/typewriter-effect/
// set up text to print, each item in array is new line
var aText = new Array(
"This is a comment"
);
var iSpeed = 10; // time delay of print out
var iIndex = 0; // start printing array at this posision
var iArrLength = aText[0].length; // the length of the text array
var iScrollAt = 20; // start scrolling up at this many lines
var iTextPos = 0; // initialise text position
var sContents = ''; // initialise contents variable
var iRow; // initialise current row
function typewriter() {
sContents = ' ';
iRow = Math.max(0, iIndex - iScrollAt);
var destination = document.getElementById("typedtext");
while (iRow < iIndex) {
sContents += aText[iRow++] + '<br />';
}
destination.innerHTML = sContents + aText[iIndex].substring(0, iTextPos) + "_";
if (iTextPos++ == iArrLength) {
iTextPos = 0;
iIndex++;
if (iIndex != aText.length) {
iArrLength = aText[iIndex].length;
setTimeout("typewriter()", 500);
}
} else {
setTimeout("typewriter()", iSpeed);
}
}
document.getElementById("annotate-button").addEventListener('click', function() {
typewriter();
})
</script>
You can also click here for a JsFiddle with the same code. The chart renders a little better on JsFiddle. https://jsfiddle.net/hughesdan/bmyda74e/1/
You can try this. You will find additional/changed code documented properly. It would be better to test the code here: https://jsfiddle.net/fo16n8tu/.
Rough annotation plugin needs HTML/SVG element to select and annotate. Therefore, I add a dummy <rect> element and use it for annotation. Let me know if this approach could work for you.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/rough-viz#1.0.6"></script>
<script type="module" src="https://unpkg.com/rough-notation?module"></script>
<style>
body {}
.item1 {
grid-area: chart;
}
.item2 {
grid-area: annotation;
}
.grid-container {
margin-top: 3rem;
display: grid;
grid-template-areas:
'chart annotation';
grid-template-rows: 1fr;
grid-template-columns: 8fr, 3fr;
}
#typedtext {
font-family: 'Waiting for the Sunrise', cursive;
font-size: 25px;
margin: 10px 50px;
letter-spacing: 6px;
font-weight: bold;
color: blue;
padding-left: 3rem;
padding-top: 30%;
height: 100%;
}
</style>
</head>
<body>
<button id="annotate-button">Click me</button>
<div class="grid-container">
<div class="item1">
<div id="viz0"></div>
</div>
<div class="item2">
<div id="typedtext"></div>
</div>
</div>
</body>
</html>
<script>
// create Bar chart from csv file, using default options
const viz = new roughViz.Bar({
element: '#viz0', // container selection
data: {
labels: ['First thing', 'Second thing', 'Third thing'],
values: [100, 50, 25]
},
width: window.innerWidth * .7,
height: window.innerHeight * .7
});
</script>
<script type="module">
import { annotate } from 'https://unpkg.com/rough-notation?module';
const e = document.querySelector('#viz0');
/* START additional code */
// Select <g id="#viz0_svg"> element
const svgGroupWrapper = e.querySelector('[id="#viz0_svg"]');
// Get each bar <g> element
const bars = svgGroupWrapper.getElementsByClassName('viz0');
// Height difference between the first (bars[0]) and the third bar (bars[2])
const diffHeight = bars[0].getBoundingClientRect().height - bars[2].getBoundingClientRect().height;
// Get the position annotation element by horizontal x-axis
const offsetX = svgGroupWrapper.getElementsByClassName('rough-xAxisviz0')[0].getBoundingClientRect().width;
// Width of annotation element (also used in annotation options!!!)
const annotationPadding = [0, 6];
// Create dummy <rect> element to annotate on it. Annotation needs an HTML element to work
const elementToAnnotate = document.createElementNS('http://www.w3.org/2000/svg','rect');
// Set "x" attribute to offsetX - annotationPadding[1] - 1 to shift <rect> to very right, but with place for annotaion and width of rect (=1)
elementToAnnotate.setAttribute('x', offsetX - annotationPadding[1] - 1);
// Just positioning "y" to 0 so that the element start from top of the SVG
elementToAnnotate.setAttribute('y', '0');
// Set "width" to 1 to be identifable in SVG for annotation plugin
elementToAnnotate.setAttribute('width', '1');
// Set "height" to the height difference value between first and third bars
elementToAnnotate.setAttribute('height', diffHeight);
// Set "fill" to transparent so that the <rect> element is not visible for users
elementToAnnotate.setAttribute('fill', 'transparent');
// Add the element in wrapper <g> element
svgGroupWrapper.appendChild(elementToAnnotate);
/* END additional code */
// CHANGED CODE: Annotate dummy <rect> element for desired effects
const annotation = annotate(elementToAnnotate, { type: 'bracket', color: 'blue', padding: annotationPadding, strokeWidth: 3 });
document.getElementById("annotate-button").addEventListener('click', function(){
annotation.show();
})
</script>
<script>
//https://css-tricks.com/snippets/css/typewriter-effect/
// set up text to print, each item in array is new line
var aText = new Array(
"This is a comment"
);
var iSpeed = 10; // time delay of print out
var iIndex = 0; // start printing array at this posision
var iArrLength = aText[0].length; // the length of the text array
var iScrollAt = 20; // start scrolling up at this many lines
var iTextPos = 0; // initialise text position
var sContents = ''; // initialise contents variable
var iRow; // initialise current row
function typewriter() {
sContents = ' ';
iRow = Math.max(0, iIndex - iScrollAt);
var destination = document.getElementById("typedtext");
while (iRow < iIndex) {
sContents += aText[iRow++] + '<br />';
}
destination.innerHTML = sContents + aText[iIndex].substring(0, iTextPos) + "_";
if (iTextPos++ == iArrLength) {
iTextPos = 0;
iIndex++;
if (iIndex != aText.length) {
iArrLength = aText[iIndex].length;
setTimeout("typewriter()", 500);
}
} else {
setTimeout("typewriter()", iSpeed);
}
}
document.getElementById("annotate-button").addEventListener('click', function() {
typewriter();
})
</script>
You could try something like in the following example:
const lbls = ['First thing', 'Second thing', 'Third thing'];
const destination = document.getElementById("typedtext");
const empty = (data) => {
switch (true) {
case (data == null || data == 'undefined' || data == false || data == ''):
return true;
case (Array.isArray(data)):
return data.length == 0;
case (typeof data == 'object'):
return (Object.keys(data).length == 0 && data.constructor == Object);
case (typeof data == 'string'):
return data.length == 0;
case (typeof data == 'number' && !isNaN(data)):
return data == 0;
default:
return false;
}
}
const typewriter = () => {
settings.sContents = ' ';
settings.iRow = Math.max(0, settings.iIndex - settings.iScrollAt);
while (settings.iRow < settings.iIndex) {
settings.sContents += settings.aText[settings.iRow++] + '<br />';
}
if(!empty(settings.aText[settings.iIndex])) {
destination.textContent = settings.sContents + settings.aText[settings.iIndex].substring(0, settings.iTextPos) + "_";
}
if (settings.iTextPos++ == settings.iArrLength) {
settings.iTextPos = 0;
settings.iIndex++;
if (!empty(settings.aText[settings.iIndex]) && settings.iIndex != settings.aText.length) {
settings.iArrLength = settings.aText[settings.iIndex].length;
setTimeout(typewriter(), 500);
}
} else {
setTimeout(typewriter(), settings.iSpeed);
}
}
new roughViz.Bar({
element: '#viz0', // container selection
data: {
labels: lbls,
values: [100, 50, 25]
},
width: window.innerWidth * 0.7,
height: window.innerHeight * 0.7
});
var settings = {};
settings.diff = [];
lbls.forEach((label) => {
let g = document.querySelector('g[attrX=\"' + label + '\"]');
g.addEventListener('click', (e) => {
let b = parseInt(e.target.parentNode.getAttribute('attrY'));
if (e.target.getAttribute('fill') == '#ff0000') {
e.target.setAttribute('fill', 'transparent');
let index = settings.diff.indexOf(b);
settings.diff = settings.diff.filter((x, i) => i !== index);
} else {
e.target.setAttribute('fill', '#ff0000');
settings.diff.push(b);
}
});
});
document.getElementById("annotate-button").addEventListener('click', (e) => {
if (settings.diff.length == 2) {
settings.aText = [(settings.diff[0] - settings.diff[1]).toString()];
} else {
settings.aText = ['Select a pair first!'];
}
settings.iSpeed = 10; // time delay of print out
settings.iIndex = 0; // start printing array at this posision
settings.iScrollAt = 20; // start scrolling up at this many lines
settings.iTextPos = 0; // initialise text position
settings.sContents = ''; // initialise contents variable
settings.iRow = 0; // initialise current row
settings.iArrLength = settings.aText[0].length; // the length of the text array
typewriter();
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/rough-viz#1.0.6"></script>
<script type="module" src="https://unpkg.com/rough-notation?module"></script>
<script type="module">
import { annotate } from 'https://unpkg.com/rough-notation?module';
const ee = document.querySelector('#viz0');
const annotation = annotate(ee, { type: 'bracket', color: 'blue', padding: [2, 10], strokeWidth: 3 });
document.getElementById("annotate-button").addEventListener('click', function(){
annotation.show();
})
</script>
<style>
body {}
;
.item1 {
grid-area: chart;
}
.item2 {
grid-area: annotation;
}
.grid-container {
margin-top: 3rem;
display: grid;
grid-template-areas:
'chart annotation';
grid-template-rows: 1fr;
grid-template-columns: 8fr, 3fr;
}
#typedtext {
font-family: 'Waiting for the Sunrise', cursive;
font-size: 25px;
margin: 10px 50px;
letter-spacing: 6px;
font-weight: bold;
color: blue;
padding-left: 3rem;
padding-top: 30%;
height: 100%;
}
</style>
</head>
<body>
<button id="annotate-button">Click me</button>
<div class="grid-container">
<div class="item1">
<div id="viz0"></div>
</div>
<div class="item2">
<div id="typedtext"></div>
</div>
</div>
</body>
</html>
OR use this JSFiddle

Iframe is not working on my website while working on local

<iframe class="metaframe rptss" src="//fileru.net/iframe.php?v=089d20963d577068d193e23819b04652" frameborder="0" scrolling="no" allow="autoplay; encrypted-media" allowfullscreen=""></iframe>
Hello people,
I really need help. So the iframe code you see above is working perfectly on my localhost server and i can watch it without problem but when i use this same embed link on my real server it doesn't work, it just shows a black screen instead of playing button. I am trying to figure it out for days but i couldn't find a solution. I got the embed link from this website(https://720p-izle.com/izle/altyazi/modo-aviao.html) and it works there perfectly as well but it doesn't work when i add it to my own website while working on localhost.
NOTE: You might see "this video is removed because of copyright(in Turkish)", when you open the embed link. It is because this embed link just opening it in certain IP(Turkish IP) as i guess. So this embed links is working for me but only problem is that i can see video when i click, when i add my localhost or when i go to the website where i took the link from but it doesn't work when i added it to my own website.
I was trying and searching so many things but i couldn't figure it out. So i also add #document as well and it gives some clue about the solution when i look but i don't have enough knowledge to understand it and fix the problem.
Another thing is that i also use some tools like(https://www.w3schools.com/tryit/tryit.asp?filename=tryhtml_default) to see if problem is just because of my hosting and video is also not working on this tool as well.
I tried small things as well such as adding https://fileru...... or similar things and change iframe code but still it doesn't work. As i say before i saw some information about video working on documentation but i don't have enough coding knowledge to understand it.
Please help me because i am searching for the solution for days and i couldn't find anything.
<!DOCTYPE html><html lang="tr"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>Video Player</title>
<meta name="referrer" content="no-referrer"> <script type="text/javascript" async="" src="https://www.google-analytics.com/analytics.js"></script><script>
function checkScreen() {
if (window.outerHeight > 1 && window.outerWidth > 1) {
if (window.outerHeight < 200 && window.outerWidth < 300) {
window.location.href = 'about:blank';
}
} else {
setTimeout(function() {
checkScreen();
}, 2);
}
}
checkScreen();
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jwplayer.com/libraries/wr6i4gal.js"></script>
</head>
<body>
<div id="Player"></div>
<div id="icon-forward-desktop" class="jw-icon jw-icon-inline jw-button-color jw-reset jw-icon-rewind" role="button" tabindex="0" aria-label="10 Saniye İleri Sar">
<svg xmlns="http://www.w3.org/2000/svg" class="jw-svg-icon jw-svg-icon-rewind" viewBox="0 0 240 240" focusable="false">
<path d="M193.14,131.08a21.57,21.57,0,0,0-17.7-10.6,21.58,21.58,0,0,0-17.7,10.6,44.77,44.77,0,0,0,0,46.3,21.63,21.63,0,0,0,17.7,10.6,21.61,21.61,0,0,0,17.7-10.6A44.77,44.77,0,0,0,193.14,131.08Zm-17.7,47.2c-7.8,0-14.4-11-14.4-24.1s6.6-24.1,14.4-24.1,14.4,11,14.4,24.1S183.34,178.28,175.44,178.28ZM132,188V137l-4.8,4.8-6.8-6.8,13-13a4.8,4.8,0,0,1,8.2,3.4v62.7ZM30.89,52.88H161V33.58c0-5.3,3.6-7.2,8-4.3l41.8,27.9a5.8,5.8,0,0,1,2.7,2.7,6,6,0,0,1-2.7,8L169,95.78c-4.4,2.9-8,1-8-4.3V72.18H45.29v96.4h48.2v19.3H30.79a4.88,4.88,0,0,1-4.8-4.8V57.78A5,5,0,0,1,30.89,52.88Z"></path>
</svg>
<div class="jw-reset-text jw-tooltip jw-tooltip-rewind" dir="auto">
<div class="jw-text">10 Saniye İleri Sar</div>
</div>
</div>
<div id="icon-forward-mobile" class="jw-display-icon-container jw-display-icon-rewind jw-reset">
<div class="jw-icon jw-icon-rewind jw-button-color jw-reset" role="button" tabindex="0" aria-label="10 Saniye İleri Sar">
<svg xmlns="http://www.w3.org/2000/svg" class="jw-svg-icon jw-svg-icon-rewind" viewBox="0 0 240 240" focusable="false">
<path d="M193.14,131.08a21.57,21.57,0,0,0-17.7-10.6,21.58,21.58,0,0,0-17.7,10.6,44.77,44.77,0,0,0,0,46.3,21.63,21.63,0,0,0,17.7,10.6,21.61,21.61,0,0,0,17.7-10.6A44.77,44.77,0,0,0,193.14,131.08Zm-17.7,47.2c-7.8,0-14.4-11-14.4-24.1s6.6-24.1,14.4-24.1,14.4,11,14.4,24.1S183.34,178.28,175.44,178.28ZM132,188V137l-4.8,4.8-6.8-6.8,13-13a4.8,4.8,0,0,1,8.2,3.4v62.7ZM30.89,52.88H161V33.58c0-5.3,3.6-7.2,8-4.3l41.8,27.9a5.8,5.8,0,0,1,2.7,2.7,6,6,0,0,1-2.7,8L169,95.78c-4.4,2.9-8,1-8-4.3V72.18H45.29v96.4h48.2v19.3H30.79a4.88,4.88,0,0,1-4.8-4.8V57.78A5,5,0,0,1,30.89,52.88Z"></path>
</svg></div>
</div>
<script type="text/javascript">
var id = '181735092eb53d9ac628d04c735abf67';
var Playlist = false;
var PlayerSettings = {
width: '100%',
primary: 'html5',
autostart: false,
cast: {},
preload: 'auto',
playlist: Playlist,
renderCaptionsNatively: true,
playbackRateControls: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
};
if (localStorage['position_' + id] > 30) {
//PlayerSettings.preload = 'none';
}
function inIframe() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
function UpdateQualityText() {
var label = jwplayer().getQualityLevels()[jwplayer().getCurrentQuality()]['label'];
if (label.length > 1) {
$('#QualityText').show().html('Aktif Kalite: <b>' + label.replace('Auto', 'Otomatik') + '</b>');
}
};
function setPlayerEvents(Player) {
var Once = true;
var Played = false;
var Watched = false;
Player.on('seek', function(a) {
Once = false;
});
Player.on('play', function() {
Played = true;
if (Once) {
UpdateQualityText();
if (localStorage['position_' + id] > 30) {
jwplayer().seek(localStorage['position_' + id] - 5);
}
Once = false;
}
});
var sendTime = 0;
Player.on('time', function() {
localStorage.setItem('position_' + id, Player.getPosition())
if (!Once) {
var timestamp = Math.floor(Date.now() / 1000);
if (timestamp > sendTime + 5) {
sendTime = timestamp;
window.parent.postMessage({
timeInfo: {
time: Player.getPosition(),
duration: Player.getDuration()
}
}, '*');
}
}
if (!Watched) {
var RemainTime = Player.getDuration() - Player.getPosition();
if (RemainTime > 1 && RemainTime < 60) {
Watched = true;
window.parent.postMessage('videoWatched', '*');
}
}
});
Player.on('complete', function() {
delete localStorage['position_' + id];
});
Player.on('displayClick', function() {
if ($('#QualityText').length == 0) {
var mo = new MutationObserver(function(m) {
if (!$('.jw-flag-user-inactive').length) {
$('#QualityText').show();
} else {
$('#QualityText').hide();
}
});
mo.observe(document.querySelector('.jwplayer'), {
attributes: true
});
$('.jw-media').prepend(
'<div id="QualityText" style="display:none; width:170px; height:30px; font: normal 16px arial; line-height:30px; text-align:right; color:#fff; background:#0000; position:absolute; top:20px; right:20px; z-index:5;"></div>'
);
}
});
Player.on('ready', function() {
$('#icon-forward-desktop').insertAfter('.jw-icon-rewind:eq(1)');
$('#icon-forward-mobile').insertAfter('.jw-display-icon-display');
$('.jw-display-icon-next').hide();
$('#icon-forward-desktop, #icon-forward-mobile').click(function() {
jwplayer().seek(jwplayer().getPosition() + 10);
});
});
Player.on('pause', function() {
if (!puShown && popURL) {initPu();} });
Player.on('levelsChanged', function(e, a) {
UpdateQualityText();
});
setInterval(function() {
if (Played && Player.getQualityLevels()[Player.getCurrentQuality()]['label'] == 'Auto') {
var label = Player.getQualityLevels()[Player.getVisualQuality().level.index]['label'];
$('#QualityText').html(
'Aktif Kalite: <b>Otomatik <span style="font-weight:normal; font-size:11px; font-weight: 700; top:-3px; margin-left:2px; padding: 3px 5px 3px 5px; border-radius: 5px; background:#35c2ff; color:#000; position:relative;">' +
label + '</span></b>');
}
}, 1000);
Player.addButton(
'https://fileru-net.cdn.ampproject.org/i/s/fileru.net/misc/download.svg?2',
'Videoyu İndir',
function() {
var url =
'/download.php?v=089d20963d577068d193e23819b04652';
var win = window.open(url, '_blank');
win.focus();
},
'download'
);
}
var Trusted = false;
if (inIframe() && !Trusted) {
document.write('Videoyu oynatmaya yetkiniz yok.');
} else {
var prefetchPoster = new Image();
prefetchPoster.src = 'https://image.tmdb.org/t/p/w1280/9OaIWmWI7Ph3jqj235zQIrh5yVd.jpg';
var Expire = false;
$.getJSON('/source.php?h=7715d59a058cef05555c295105624519a77a08c27c664c50d00001a6be526a0e032f03061c37ecd74137f5d6adb024788ef3d365950f81392ad735d723cf83cbba3b94172f8b40f6c030d0eac4bb10b434f7b53733e54a7c02b7810bcc862eca7b3df51f47f3af15e32b0ca86ecf910c6c80fb39b12c69815a85ce7faea88c0182709447c0ba8d1c208f2dc1ca8c4ad5', function(Response) {
PlayerSettings.image = prefetchPoster.src;
PlayerSettings.sources = Response.sources;
PlayerSettings.tracks = [];
Expire = Response.expire;
var Player = jwplayer('Player').setup(PlayerSettings);
setPlayerEvents(Player);
setInterval(function() {
var time = Math.floor(Date.now() / 1000);
if (Expire != false && time > Expire) {
var tmpExpire = Expire;
Expire = false;
$.getJSON('/source.php?h=7715d59a058cef05555c295105624519a77a08c27c664c50d00001a6be526a0e032f03061c37ecd74137f5d6adb024788ef3d365950f81392ad735d723cf83cbba3b94172f8b40f6c030d0eac4bb10b434f7b53733e54a7c02b7810bcc862eca7b3df51f47f3af15e32b0ca86ecf910c6c80fb39b12c69815a85ce7faea88c0182709447c0ba8d1c208f2dc1ca8c4ad5&e=' + tmpExpire, function(Response) {
var LastPosition = Player.getPosition();
var LastState = Player.getState();
Expire = Response.expire;
PlayerSettings.sources = Response.sources;
Player.load(PlayerSettings);
jwplayer().seek(LastPosition);
if (LastState == 'playing') {
Player.play();
} else {
Player.pause();
}
});
}
}, 1000);
});
}
function receiveMessage(event) {
var data = event.data;
if ('playerSeek' in data) {
jwplayer().seek(data['playerSeek']);
}
}
window.addEventListener("message", receiveMessage, false);
</script>Videoyu oynatmaya yetkiniz yok.
<script>
var popURL = "https://720p-izle.com/detay/fast-furious-presents-hobbs-shaww/"; var puShown = false;
function doOpen(url) {
if (puShown == true) {
return true;
}
win = window.open(url, 'yenipencere', 'menubar=0,resizable=1,width=1,height=1');
win.moveTo(150000, 150000);
if (win) {
win.blur();
puShown = true;
}
return win;
}
function setCookie(cname, cvalue, extime) {
var d = new Date();
d.setTime(d.getTime() + extime);
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function initPu() {
if (document.attachEvent) {
document.attachEvent('onclick', checkTarget);
} else if (document.addEventListener) {
document.addEventListener('click', checkTarget, false);
}
}
function checkTarget(e) {
if (!getCookie('popunderPause')) {
var e = e || window.event;
var win = doOpen(popURL);
setCookie('popunderPause', 1, 1 * 60 * 60 * 1000);
}
}
</script>
<script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-125574692-2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'UA-125574692-2');
</script>
<script>
</script>
<style type="text/css">
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
background: #000;
}
#Player {
position: fixed;
width: 100%;
height: 100% !important;
left: 0;
top: 0;
z-index: 10
}
.jw-rightclick {
display: none !important
}
.jw-settings-menu {
width: 135px !important;
}
.jw-breakpoint-7 .jw-settings-menu,
.jw-breakpoint-6 .jw-settings-menu,
.jw-breakpoint-5 .jw-settings-menu,
.jw-breakpoint-4 .jw-settings-menu,
.jw-breakpoint-3 .jw-settings-menu {
max-height: 220px !important;
height: 220px !important;
}
.jw-settings-content-item {
font-size: 15px
}
.jw-settings-content-item.jw-settings-item-active {
color: #35c2ff
}
.jw-text-elapsed,
.jw-text-duration {
font-size: 15px
}
.jw-slider-horizontal .jw-slider-container {
height: 10px
}
.jw-knob {
height: 16px;
width: 16px
}
</style>
<link href="https://cdn.jsdelivr.net/npm/normalize.css#8.0.1/normalize.css" rel="stylesheet" type="text/css">
<link href="misc/style.css?3" rel="stylesheet" type="text/css">
</body></html>

javascript array images link error

I'm trying to create a mini-book of images using a clip of code i found online which refreshes a set of predefined images onclick via a basic form button, however I can't figure out why the images i've specified in the array are not appearing in the div below. I've confirmed that the url addresses are correct path - but I must be doing something wrong with the linkage ? ?
<html>
<head>
<title></title>
<script>
var bookImages = new Array();
bookImages[0] = "fsheet1.jpg"
bookImages[1] = "fsheet2.jpg"
bookImages[2] = "fsheet3.jpg"
bookImages[3] = "fsheet4.jpg"
bookImages[4] = "fsheet5.jpg"
bookImages[5] = "fsheet6.jpg"
var i = 0
function updateImg() {
var i = i + 1;
var url = 'url(' + bookImages[i] + ')';
document.getElementById('bookImg').style.backgroundImage = url;
}
</script>
<style type="text/css">
#bookImg {
background-img: url();
background-repeat: no-repeat;
background-color: #CF23FA;
text-align: left;
width: 150px;
height: 200px;
margin-top: 10px;
margin-left: 15px;
}
</style>
</head>
<body>
<div id='bookImg'>
<form>
<input type="button" value=">" onClick="updateImg()">
</form>
</div>
</body>
</html>
The problem:
you are redifining i inside the function updateImg. Technically your function is equivalent to this:
function updateImg() {
var i; // redeclaring i (i is not initialised so the value is undefined)
i = i + 1; // undefined + 1
var url = 'url(' + bookImages[i] + ')'; // url(undefined)
document.getElementById('bookImg').style.backgroundImage = url;
}
The fix:
function updateImg() {
i = i + 1; // don't redeclare i just use the outer one (the one above)
var url = 'url(' + bookImages[i] + ')';
document.getElementById('bookImg').style.backgroundImage = url;
}
Note:
The above code will increment i without checking if it gone beyond the array boundaries (after 6 clicks i will be 7 and there is no image at index 7 in the array). If you want to go back to 0 when i reaches the end then replace i = i + 1; by i = (i + 1) % bookImages.length;!
Complete code:
<html>
<head>
<title></title>
<script>
// array litterals: a better way
var bookImages = [
"http://placehold.it/201x100",
"http://placehold.it/202x100",
"http://placehold.it/203x100",
"http://placehold.it/204x100",
"http://placehold.it/205x100",
"http://placehold.it/206x100"
];
var i = 0;
function updateImg() {
var url = 'url(' + bookImages[i] + ')';
document.getElementById('bookImg').style.backgroundImage = url;
i = (i + 1) % bookImages.length; // increment at the end
}
window.addEventListener("load", updateImg); // call it once the document is ready
</script>
<style type="text/css">
#bookImg {
background-repeat: no-repeat;
background-color: #CF23FA;
text-align: left;
width: 150px;
height: 200px;
margin-top: 10px;
margin-left: 15px;
}
</style>
</head>
<body>
<div id='bookImg'>
<form>
<input type="button" value=">" onClick="updateImg()">
</form>
</div>
</body>
</html>

mathjax with jquery fadein

In a html page with mathematical formulas using MathJax, I'm trying a smooth transition in the change from one formula to the another.
Here is the current code, that you can test here
<!DOCTYPE html>
<html>
<head>
<!-- https://jsfiddle.net/LnfL020r/2 -->
<title>math guided training</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
TeX: {
Macros: {
mgtMult: "",
mgtSelect: [ "\\bbox[10px,border:1px solid red]{#1}", 1],
}
}
});
</script>
<script type="text/javascript"
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<style>
.results {
display: flex;
height: 4cm;
position: relative;
}
#fadeBox,
#visibleBox {
width: 100%;
height: 100%;
position: absolute;
top: 0%;
left: 0;
}
</style>
</head>
<body>
<script>
var QUEUE = MathJax.Hub.queue; // shorthand for the queue
var math = null; // the jax element
var box = null; // the box math is in
var formula = "1+2x^3";
var SHOWBOX = function () {
var a = $('#box').html();
var dstDiv = $('#visibleBox');
dstDiv.html(a);
}
var SHOWBOX_FADE = function () {
var a = $('#box').html();
var dstDiv = $('#visibleBox');
var fadeDiv = $('#fadeBox');
fadeDiv.html(a);
fadeDiv.fadeIn(2000,function() {
dstDiv.html(a);
fadeDiv.hide();
});
}
var REFRESH = function () {
QUEUE.Push(
["Text",math,formula], // == math.Text(formula), [ method, object, args... ]
SHOWBOX
);
}
var REFRESH_FADE = function () {
QUEUE.Push(
["Text",math,formula], // [ method, object, args... ]
SHOWBOX_FADE
);
}
// Get the element jax when MathJax has produced it.
QUEUE.Push(
function () {
math = MathJax.Hub.getAllJax("box")[0]; // returns a MathJax.ElementJax
math.Text(formula);
SHOWBOX();
}
);
setTimeout(function(){
SHOWBOX();
}, 2000);
window.changeIt = function() {
formula = "1 + 2 { \\left( y + 4 \\right) } ^ 3 ";
REFRESH_FADE();
}
</script>
</head>
<body>
<div id="box" style="visibility:hidden; font-size: 500%; height:1px;">
\( \)
</div>
<div class="results">
<div id="visibleBox" style="font-size: 500%;">
Loading ...
</div>
<div id="fadeBox" style="font-size: 500%; display:none;">
</div>
</div>
<button onclick='changeIt()'/>click me</button>
</body>
</html>
The problem is:
The second formula has different height than the first one, due to the parenthesis. For this reason, the common part "1 + " of the second one is printed slightly down respect to its print in the first formula.
That produces an effect of borrow during the transition. I want that the "1 + " part, common to both formulas, doesn't moves when changing from first to second.
Any hint?
maybe this will work :
var SHOWBOX = function () {
var a = $('#box').html();
var dstDiv = $('#visibleBox');
// apply margin for the first equation
dstDiv.css({"margin-top":"2px"});
dstDiv.html(a);
}
var SHOWBOX_FADE = function () {
var a = $('#box').html();
var dstDiv = $('#visibleBox');
var fadeDiv = $('#fadeBox');
fadeDiv.html(a).fadeOut();
fadeDiv.fadeIn(500,function() {
dstDiv.html(a);
// remove the margin for the second equation
dstDiv.css({"margin-top":"0"});
fadeDiv.hide();
});
}
just applying a margin to counter the slight variance in top margin
Made little change in fadeIn and fadeOut
fadeDiv.html(a);
dstDiv.fadeOut(1000,function() {
dstDiv.html(a);
fadeDiv.fadeIn(1000);
});
}
Forked fiddle
Please comment if transition is not up to expection
EDIT
Updated With requirement
Fiddle link
window.onload=function(){
var QUEUE = MathJax.Hub.queue; // shorthand for the queue
var math = null; // the jax element
var mathdef = null; // the jax element
var box = null; // the box math is in
var defaultformula = "1+";
var formula = "2x^2";
var SHOWBOX = function () {
var a = $('#box').html();
var def = $('#defbox').html();
var fixedDiv = $('#fixed');
fixedDiv.html(def);
var dstDiv = $('#visibleBox');
dstDiv.html(a);
}
var SHOWBOX_FADE = function () {
var a = $('#box').html();
var dstDiv = $('#visibleBox');
var fadeDiv = $('#fadeBox');
fadeDiv.html(a);
dstDiv.fadeOut(1000,function() {
dstDiv.html(a);
fadeDiv.fadeIn(1000);
});
}
var REFRESH = function () {
QUEUE.Push(
["Text",math,formula], // == math.Text(formula), [ method, object, args... ]
SHOWBOX
);
QUEUE.Push(
["Text",mathdef,defaultformula], // == math.Text(formula), [ method, object, args... ]
SHOWBOX
);
}
var REFRESH_FADE = function () {
QUEUE.Push(
["Text",math,formula], // [ method, object, args... ]
SHOWBOX_FADE
);
}
// Get the element jax when MathJax has produced it.
QUEUE.Push(
function () {
math = MathJax.Hub.getAllJax("box")[0]; // returns a MathJax.ElementJax
mathdef = MathJax.Hub.getAllJax("defbox")[0]; // returns a MathJax.ElementJax
mathdef.Text(defaultformula);
math.Text(formula);
SHOWBOX();
}
);
setTimeout(function(){
SHOWBOX();
}, 2000);
window.changeIt = function() {
formula = "2 { \\left( y + 4 \\right) } ^ 2";
REFRESH_FADE();
}
}//]]>
.results {
display: flex;
height: 4cm;
position: relative;
}
#fadeBox,
#visibleBox {
width: 100%;
height: 100%;
position: absolute;
top: 0%;
left: 0;
}
<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
TeX: {
Macros: {
mgtMult: "",
mgtSelect: [ "\\bbox[10px,border:1px solid red]{#1}", 1],
},
Macros: {
mgtMult: "",
mgtSelect: [ "\\bdefbox[10px,border:1px solid red]{#1}", 1],
}
}
});
</script>
<script type="text/javascript"
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<div id="defbox" style="visibility:hidden; font-size: 500%; height:1px;padding-top:10px">
\( \)
</div>
<div id="box" style="visibility:hidden; font-size: 500%; height:1px;padding-left:200px">
\( \)
</div>
<div class="results">
<div id="fixed" style="font-size: 500%;margin-top:50x">
Loading ...
</div>
<div id="visibleBox" style="font-size: 500%;padding-left:100px">
</div>
<div id="fadeBox" style="font-size: 500%; display:none;padding-left:100px">
</div>
</div>
<button onclick='changeIt()'>click me</button>
</body>
</html>

jquery autocomplete not working on dynamically added input boxes

Here is something i am trying to do. I want to add jquery autocomplete to all the input boxes. Initially i have only 2 boxes, user can dynamically add multiple boxes. Autocomplete works in first two boxes but fails in the dynamically added buttons.
hers the fiddle for the code : http://jsfiddle.net/HG2hP/
code:
HTML:
<!doctype html>
<html>
<head>
<title>TakeMeHome</title>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> -->
<!--<script type="text/javascript" src="js/jquery-1.9.0.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.0.custom.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.0.custom.min.js"></script>-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<link type="text/css" rel="stylesheet" href="css/design.css"/>
</head>
<body>
<center>
Your Place:<input class="address" id="source" type="text"/><br/>
<div id= "div1">Friend1:<input class="address" id="friend1" type="text"/></div><br/>
<pre>
<div id="button">Add!</div> <div id="button2">Remove</div></br>
</pre>
<div id="sumbit_button">GO!</div>
<div id="map" style = "width: 500px; height: 500px"></div>
</center>
</body>
</html>
JS
$(document).ready(function() {
var geocoder;
var map;
var marker;
var friends_cnt = 1;
var friends = [];
var distance = [];
$('#button').click(function() {
if (friends_cnt < 11) {
$('<div id = div' + (friends_cnt + 1) + '>Friend' + (friends_cnt + 1) + ':<input type="text" class="address" id="friend' + (friends_cnt + 1) + '"/></div>').insertAfter('#div' + friends_cnt);
friends_cnt++;
} else {
console.log("Limit reached");
}
});
$('#button2').click(function() {
if (friends_cnt > 1) {
$('#friend' + friends_cnt).remove();
$('#div' + friends_cnt).remove();
friends_cnt--;
}
});
geocoder = new google.maps.Geocoder();
$(function() {
$(".address").autocomplete({
source : function(request, response) {
geocoder.geocode({
'address' : request.term
}, function(results, status) {
response($.map(results, function(item) {
return {
label : item.formatted_address,
value : item.formatted_address,
latitude : item.geometry.location.lat(),
longitude : item.geometry.location.lng()
}
}));
})
},
});
});
$('#sumbit_button').on("click", function() {
console.log("button clicked");
var a = [];
a.push($("#source").val());
for ( i = 1; i <= friends_cnt; i++) {
a.push($("#friend" + i).val());
}
console.log("a :");
console.log(a);
var gurl = "http://maps.googleapis.com/maps/api/distancematrix/json";
console.log("gurl :" + gurl);
$.ajax({
url : gurl,
data : {
origins : a.join('|').replace(/ /g, '+'),
destinations : a.join('|').replace(/ /g, '+'),
sensor : false
},
success : function(response) {
console.log("response type :");
console.log( typeof response);
if ( typeof response == "string") {
response = JSON.parse(response);
}
var rows = response.rows;
for (var i = 0; i < rows.length; i++) {
distance[i] = [];
for (var j = 0; j < rows[i].elements.length; j++) {
distance[i][j] = rows[i].elements[j].distance.value;
}
}
}
});
console.log("No.of friends is " + friends_cnt);
console.log(distance);
});
});
CSS
input {
margin: 10px 4px;
}
#button, #button2 {
width: 70%;
margin: 0 auto;
}
.ui-autocomplete {
background-color: white;
width: 300px;
border: 1px solid #cfcfcf;
list-style-type: none;
padding-left: 0px;
}
.ui-helper-hidden-accessible {
display: none;
}
As I am using classes concept to add auto-complete, I should get the results.
Can you please let me know where I am wrong?
In your click event:
$('#button').click(function ()...
You should set your autocomplete on newly added input field, something like:
$('#button').click(function () {
if (friends_cnt < 11) {
$('<div id = div'+(friends_cnt+1)+'>Friend' + (friends_cnt+1) + ':<input type="text" class="address" id="friend' + (friends_cnt+1) + '"/></div>').insertAfter('#div'+friends_cnt);
$('div#div'+(friends_cnt+1)).autocomplete(...);
friends_cnt++;
}
else {
console.log("Limit reached");
}
});
As your autocomplete attachs to current DOM only, not the dynamically added one.
you must either re apply the auto complete to each element like Kapo suggested
$('div#div'+(friends_cnt+1)).autocomplete(...);
or use liveuery (see this thread for more details on that)
On pageload your autocomplete attaches to fields with class .address, however on page load you do not have any .address field, so nothing gets attached.
You need to run
$(".address").autocomplete({
Right after you add your new field to the dom, or better still, make the input an object, and you can attach events straight to it like:
$input = $('input')
.attr('type', 'text')
.attr('class', 'address')
.attr('id', 'friend')
.autocomplete({ etc
As i got the answers, this change in the code worked for me :
Adding this in the $('#button').click(function () { function
$(function() {
$("#friend"+(friends_cnt+1)).autocomplete({
source: function(request, response) { . .. . .
This will add autocomplete to all the boxes whenever made.

Categories