HTML5 ondragstart not firing when attirubtes added through C# - javascript

I am trying to implement HTML5 drag & drop but the ondragstart event doesn't fire.
I am loading tabs for my page programmaticly and apply the attributes like so:
TabCell.Attributes.Add("draggable", "true");
TabCell.Attributes.Add("ondragstart", "onDragStart(event)");
My javaScript function which will not fire:
function onDragStart(e) {
alert("TESTING");
}
Has anyone tried to add the attributes in the code behind before as I am unsure if this is the issue here?

You need to set the attributes with setAttribute:
TabCell.setAttribute("draggable", "true");
TabCell.setAttribute("ondragstart", "onDragStart(event)");
Working code example below. If you start dragging the first tab onDragStart fires and shows the message 'Drag has started'.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
}
.tab button:hover {
background-color: #ddd;
}
</style>
</head>
<body>
<div class="tab">
<button id="TabCell1">Tab1 Header</button>
<button id="TabCell2">Tab2 Header</button>
</div>
<div id="content"></div>
<script>
window.onload = () => {
var TabCell = document.getElementById('TabCell1');
TabCell.setAttribute("draggable", "true");
TabCell.setAttribute("ondragstart", "onDragStart(event)");
var TabCell2 = document.getElementById('TabCell2');
TabCell2.setAttribute("draggable", "true");
};
function onDragStart(ev) {
var el = document.getElementById('content');
el.innerHTML = "Drag has started";
}
</script>
</body>
</html>

Related

clearTimeout() doesn't work when called from an event

This is a summarized example of another larger project I have. In this example I set a new style for my node when I click on it, once the new style is set I fire a setTimeout() to allow the style for a few seconds until it desappear. on the other hand, I have a keydown event that is supposed to cancel the Timeout when I press any key. So if the timeout is canceled with clearTimeout(), the box is supposed to stay styled, but it is not working. The clearTimeout() doesn't cancel the timeout, and doesn't prevent the style to be deleted.
Any idea about what is wrong with the clearTimeout()?
const box = document.querySelector("div")
let timeout
box.onclick = () =>{
box.classList.add("black")
}
box.ontransitionend = () =>{
timeout = setTimeout(() =>{
box.classList.remove("black")
}, 3000)
}
window.onkeydown = () =>{
clearTimeout(timeout)
}
*{
margin: 0px;
padding: 0px;
}
.box{
width: 200px;
height: 200px;
margin: auto;
border: #333 1px solid;
transition: all 1s ease-in-out 0s;
}
.black{
background-color: black;
border: #ccc 1px solid;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div class="box">
</div>
<script src="./main.js"></script>
</body>
</html>
The ontransitionend event gets called for each transitioned style, in your case, that's your background-color, as well as border-top-color, border-right-color, border-bottom-color and border-left-color for the border style change due to the all in your transitional: all ... style. You could apply a check in your event handler to only apply your timeout when the transition is for CSS style background-color by using event.propertyName. This way you won't end up creating multiple timeouts and will be able to cancel it.:
const box = document.querySelector("div");
let timeout;
box.onclick = () => {
box.classList.add("black")
}
box.ontransitionend = (event) => {
if (event.propertyName === "background-color") {
timeout = setTimeout(() => {
box.classList.remove("black")
}, 3000);
}
}
window.onkeydown = () => {
clearTimeout(timeout);
}
* {
margin: 0px;
padding: 0px;
}
.box {
width: 200px;
height: 200px;
margin: auto;
border: #333 1px solid;
transition: all 1s ease-in-out 0s;
}
.black {
background-color: black;
border: #ccc 1px solid;
}
<div class="box"></div>
I've noticed that the event ontransitionend fires once for each style in the class i've set, so i'm creating more than one Timeout.

How to get reference to Codemirror inside an iframe from parent page?

I have a parent.html page which I have embedded an Iframe inside a div element and the src of iframe refer to a codemirror.html page which displays Code-mirror.
<div id="cmModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<iframe id="cmIframeId" name="cmiframe" src="../html/codemirror.html"></iframe>
</div></div>
when I click a button I display a div which contains iframe as a modal block.
At this time I would like initialize Code-mirror by calling Code-mirror instance.
How can I initialize CodeMirror content from parent.html?
What I have done and still couldn't initialize codemirror:
Declared a global instants of codemirror and a global function on codemirror.html page.
var codeMirrorEditor;
window.setCode = function(content) {
codeMirrorEditor.setValue(content);;
}
Calling those global instants and function from parent.html
function openCodeMirror(){
// Get the modal
var modal = document.getElementById("cmModal");
modal.style.display = "block";
var iframe = document.getElementById("cmIframeId");
iframe.contentWindow.setCode('My initial value');
iframe.contentWindow.codeMirrorEditor.setValue('My initial value')
}
codemirror.html
<!doctype html>
<html lang="en">
<head>
<title>CodeMirror: HTML EDITOR</title>
// all codmirror addons and script comes here ...
</head>
<body>
<div id="code" ></div>
<script>
var codeMirrorEditor;
window.setCode = function(content) {
codeMirrorEditor.setValue(content);;
}
window.onload = function () {
codeMirrorEditor = CodeMirror(document.getElementById("code"), {
mode: "text/html",
styleActiveLine: true,
lineNumbers: true,
lineWrapping: true,
autoCloseTags: true,
theme: "night",
value: getOwnSource(),
});
};
function setContent(content) {
codeMirrorEditor.setValue(content);
}
function getContent() {
return codeMirrorEditor.getValue();
}
function getOwnSource() {
return document.documentElement.innerHTML;
}
</script>
</body>
</html>
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="../css/modal.css">
</head>
<body>
<textarea id="source" style="width:100%; height:400px"> initial text comes from here </textarea><br>
<input type="button" value="open codemirror" onclick="openCodeMirror()"> </input>
<!-- The Codemirror Modal window-->
<div id="cmModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<iframe id="cmIframeId" name="cmiframe" src="../html/codemirror.html" style="width:100%; height:300px"></iframe>
</div>
</div>
<script>
function openCodeMirror(){
var modal = document.getElementById("cmModal");
modal.style.display = "block";
var iframe = document.getElementById("cmIframeId");
let textarea = document.getElementById("source");
iframe.contentWindow.codeMirrorEditor.setValue(textarea.value);
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
}
</script>
</body>
</html>
modal.css for parent.html
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 0px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
/* background-color: #ff8000; */
background-color:#fefefe ;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
margin-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
/* padding: 10px; */
border: 1px solid #888;
width: 100%;
height:100%;
}
/* The Close Button */
.close {
color: #aaaaaa;
float: right;
font-size: 32px;
font-weight: bold;
margin-right: 10px;
/* border: 1px solid #ff0000; */
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
Guys it works like charm, it was just my mistake mixing code. After cleaning the code it works as it should. Thanks to everyone, may it help someone else to solve other issues.

Custom textarea/contenteditable with divs inside it

I’ currently working on a website, where a user should be able to write and insert new songs with belonging chords into a database.
To sum things up, and get to the point pretty quick, here is my problem:
I have a div with the id “#textarea”, and the attribute contenteditable=“true”. On each enter/linebreak, I would like to create a new div with the class “.chords” and the attribute contenteditable=“false”. This ".chords" div should be placed right before the new line, like the image shows here:
The red color is the #textarea div, and the blue color the .chords divs
So my question is: how do I do this?
I’ve posted the code I've tried in the end of this post, but as you see if you run it, the .chords divs are positioned below the new line, so I’m now a bit stuck.. If any of you guys have an idea on how to do this, please let me hear from you!
$(function(e) {
$('#textarea').keydown(function(e) {
var i = 0;
// Check if the returnkey is being pressed
if (e.keyCode === 13) {
$("#textarea div:last-of-type").after("<div class=\"chords\" id=\"" + (i + 1) + "\" contenteditable=\"false\"></div>");
i = i + 1;
}
});
})
#textarea {
border: 1px solid black;
line-height: 50px;
font-size: 20px;
}
.chords {
height: 30px;
border: 1px solid black;
position: relative;
}
#textarea div:not(.chords) {
margin-top: 20px;
min-height: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="textarea" contenteditable="true">
<div class="chords" id="1" contenteditable="false"></div>
<div></div>
<!--End of #textarea-->
</div>
Similar Something like that
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#textarea {
border: 1px solid red;
line-height: 50px;
font-size: 20px;
min-height: 40px;
}
.chords {
height: 30px;
border: 1px solid black;
position: relative;
margin-top:5px;
}
#textarea div:not(.chords) {
margin-top: 20px;
min-height: 40px;
}
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(e) {
$('#textarea').keydown(function(e) {
var i = 0;
// Check if the returnkey is being pressed
if (e.keyCode === 13) {
$(this).after('<div class="chords" id="'+ (i + 1) +'" contenteditable="false"></div><div>'+$(this).html()+'</div>');
$(this).html("");
i = i + 1;
}
});
})
</script>
<div id="textarea" contenteditable="true">
</div>
<div class="chords" id="1" contenteditable="false"></div>
<div></div>
<!--End of #textarea-->
</body>
</html>
Check it out
https://jsfiddle.net/emarufhasan/66L2ohnp/?utm_source=website&utm_medium=embed&utm_campaign=66L2ohnp

Imperfect Jquery animations timings

var count = 0;
$(document).ready(function() {
$("div").on("click", function() {
$("#test").fadeOut(500);
count++;
$("#test").fadeIn(500);
document.getElementById("test").innerHTML = count;
});
});
div {
background-color: gold;
border: 2px solid goldenrod;
border-radius: 7px;
text-align: center;
vertical-align: middle;
font-family: Arial;
font-size: 35px;
width: 100px;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div><span id="test">0</span></div>
</body>
</html>
I am new to Jquery. In the above code, the number inside the div increments on clicking and fades out and in. I want it to work such that the existing number disappears first and then the next number appears while, here, the number first changes and then fades out and in, which is not how I want it to work. Please run the snippet to see the problem. What is wrong or missing in my code? Any help would be appreciated.
It's because it takes the fadeOut 500 ms but the increment of count and the assignment happens right away. You can use the callback complete of fadeOut to achieve what you need:
$("#test").fadeOut(500, function() { // the function will be called when the fadeOut is completed
count++; // increment count
this.textContent = count; // assign it to this element (#test) textContent
}).fadeIn(500); // then fadeIn
var count = 0;
$(document).ready(function() {
$("div").on("click", function() {
$("#test").fadeOut(500, function() {
count++;
this.textContent = count;
}).fadeIn(500);
});
});
div {
background-color: gold;
border: 2px solid goldenrod;
border-radius: 7px;
text-align: center;
vertical-align: middle;
font-family: Arial;
font-size: 35px;
width: 100px;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div><span id="test">0</span></div>
</body>
</html>
Try this
you need to increment in callback of fading out, meaning increment when animation is complete
var count = 0;
$(document).ready(function() {
$("div").on("click", function() {
$("#test").fadeOut(500, function(){
count++;
document.getElementById("test").innerHTML = count;
}
);
$("#test").fadeIn(500);
});
});
div {
background-color: gold;
border: 2px solid goldenrod;
border-radius: 7px;
text-align: center;
vertical-align: middle;
font-family: Arial;
font-size: 35px;
width: 100px;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div><span id="test">0</span></div>
</body>
</html>
var count = 0;
$(document).ready(function() {
$("div").on("click", function() {
count++;
$("#test").fadeOut(500).$("test").text(count).fadeIn(500);
});
});
"JQuery Chaining"
https://www.w3schools.com/jquery/jquery_chaining.asp

Clicking in the top corners of my webpage causes the flex boxes to misbehave

I have been making a simple page using flexboxes that should expand one flex box to the majority of the page on a click. However, the page will occasionally make the sizes of all of the flexboxes equal (see the below picture). I've only notices it when I click in the corners of the page on the yellow or blue sections. Does anyone have an idea of what is going on?
Edit: Added relevant code and removed JS Bin links
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<title>Home Page</title>
<link href="/stylesheets/flex.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="yel" class="page selected">
<h2>Home
</h2>
</div>
<div id="green" class="page">
<h2>About Me
</h2>
</div>
<div id="red" class="page">
<h2>Portfolio
</h2>
</div>
<div id="blue" class="page">
<h2>Playground
</h2>
</div>
</body>
</html>
CSS
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
width: 100%;
height: 100%;
display: -webkit-flex;
-webkit-flex-flow: row;
}
.selected {
min-width: 90%;
}
#red {
background-color: #f00;
}
#yel {
background-color: #ff0;
}
#green {
background-color: #008000;
}
#blue {
background-color: #00f;
}
.page {
flex: 1;
min-width: auto;
min-height: 100%;
-webkit-transition-duration: 750ms;
}
.page h2 {
font: 20px Helvetica, Tahoma, sans-serif bold;
color: #ccc;
-webkit-transform: rotate(90deg);
margin: 5px;
}
.content {
margin: 10% auto auto auto;
padding: 10px;
width: 90%;
height: 50%;
border: 1px solid #000;
}
JS
var $ = function(sel, e) {return (e || document).querySelector(sel)};
var $$ = function(sel, e) {return (e || document).querySelectorAll(sel)};
var boxes = $$('.page');
var links = $$('.nav');
var flexTransitionTo = function flexTransitionTo(el) {
if(!el.classList.contains('selected')) {
$('.selected').classList.remove('selected');
el.classList.add('selected');
}
};
for(var i = 0; i < boxes.length; i++) {
var el;
boxes[i].addEventListener('click', function(event) {
el = event.target;
flexTransitionTo(el);
});
}
for(var i = 0; i < links.length; i++) {
var el;
var pageEl;
links[i].addEventListener('click', function(event) {
el = event.target;
pageEl = $(el.dataset.page); //should get the page I want
flexTransitionTo(pageEl);
});
}
I can tell you the why, but I can't give you the fix (my JavaScript-fu is weak). The problem is that when you click on the h2 element (or probably any other descendant of the page element), it is intercepting the click event and it has the selected class applied to it. Because the selected class is removed from all page elements, none of them are set to selected.

Categories