I want to implement some draggable elements on the page, which should not break the currently focused control on the page. That is what I tried:
$('input').focus();
$('div').on('mousedown', function(event) {
// event.preventDefault(); // drag does not work anymore
// $('input').focus(); // focus still lost
});
div {
display: inline-block;
border: 1px solid green;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div draggable="true">Hello World</div><br />
The input field should not loose focus, when dragging "Hello World".<br />
<input type="text" />
If I activate event.preventDefault(), the focus is not lost on mousedown, but the drag operation cannot start anymore. Does anyone know how to solve this problem?
I guess, setTimeout will solve your problem
$('input').focus();
$('div').on('mousedown', function(event) {
window.setTimeout(
function() {
$('input').focus();
}, 1);
});
div {
display: inline-block;
border: 1px solid green;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div draggable="true">Hello World</div><br />
The input field should not loose focus, when dragging "Hello World".<br />
<input type="text" />
Result;
jsfiddle
Hope helps,
$(document).ready(function(){
$("div").on("mousedown",function(event){
event.preventDefault();
$("div").draggable();
$("input").droppable({
drop: function(event, ui) {
$("input").css('background', 'rgb(0,200,0)');
}
});
});
});
div {
display: inline-block;
border: 1px solid green;
padding: 10px;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div draggable="true">Hello World</div><br />
The input field should not loose focus, when dragging "Hello World".<br />
<input type="text" />
Related
How to prevent a user from removing <section> inside <div contenteditable> editor during editing (at least by pressing "Delete"/"Backspace" keys)?
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<style>
#editor {
width: 100%;
height: 300px;
border: 1px black solid;
}
#dont-remove-me-please{
width: 100%;
height: 100px;
border: 1px red dashed;
font-weight: bold;
user-select: none;
}
</style>
</head>
<body>
<div id="app"></div>
<div contenteditable="true" id="editor">
<div>hey guys!</div>
<div><strong>more text...</strong></div>
<section id="dont-remove-me-please" contenteditable="false">DONT' REMOVE ME!!!</section>
<div><br></div>
</div>
<script>
document.getElementById('editor').focus()
</script>
</body>
</html>
Thank You.
You can set contenteditable=false to children to prevent them from being editable.
However if you still want the children to be editable but the child dom elements shouldn't be removable I think you need to listen to backspace/delete events and see how these effect the dom and undo the changes if they remove dom nodes. Trying to figure this out myself
Edit: this is what I did
function onpaste(e: ClipboardEvent) {
e.preventDefault();
const selection = window.getSelection();
// Don't allow deleting nodes
if (selection.anchorNode.isSameNode(selection.focusNode)) {
// get text representation of clipboard
const text = e.clipboardData.getData("text/plain");
// insert text manually, but without new line characters as can't support <br/>s yet
document.execCommand("insertHTML", false, text.replace(/\n/g, ""));
}
}
function onkeydownInEditable(e: KeyboardEvent) {
if (e.key === "Enter") {
e.preventDefault();
}
if (e.key === "Backspace" || e.key === "Delete" || e.key === "Paste") {
const selection = window.getSelection();
// Don't allow deleting nodes
if (!selection.anchorNode.isSameNode(selection.focusNode))
e.preventDefault();
}
}
elementEditing.addEventListener("keydown", onkeydownInEditable);
elementEditing.addEventListener("paste", onpaste);
To achieve expected result, use below click event listener and add contenteditable attribute based on id
<script>
document.getElementById('editor').addEventListener('click', function(e) {
if(e.target.id !=="dont-remove-me-please"){
e.target.setAttribute("contentEditable", true);
}
}, false);
</script>
code sample - https://codesandbox.io/s/rypy7wkn5m
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<style>
#editor {
width: 100%;
height: 300px;
border: 1px black solid;
}
#dont-remove-me-please{
width: 100%;
height: 100px;
border: 1px red dashed;
font-weight: bold;
user-select: none;
}
</style>
</head>
<body>
<div id="app"></div>
<div id="editor">
<div>hey guys!</div>
<div><strong>more text...</strong></div>
<section id="dont-remove-me-please" contenteditable="false">DONT' REMOVE ME!!!</section>
<div><br></div>
</div>
<script>
document.getElementById('editor').focus()
</script>
<script>
document.getElementById('editor').addEventListener('click', function(e) {
if(e.target.id !=="dont-remove-me-please"){
e.target.setAttribute("contentEditable", true);
}
}, false);
</script>
</body>
</html>
I have an HTML element (form element - textbox) inside another series of divs.
I created listener for mouseup event on the outer div, but it fires when I click on the textbox.
I thought it would only fire when mouseup on the outer div since I attached the listener to that element - not to the textbox
Is there a way to prevent it from firing when 'mouseup' fires on the textbox?
require([
"dijit/form/TextBox",
"dojo/on",
"dojo/dom"
], function (
TextBox,
on,
dom) {
var box = new TextBox({
name: "any",
value: "",
placeholder: "Type anything here"
}, "textBox");
var canvas = dom.byId("outerDiv");
on(canvas, "mouseup", function (e) {
alert();
});
});
dojo.require("dijit.form.anyText");
var textBox = dijit.byId("textBox");
console.log( "--- >> "+textBox.get("value"));
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js"></script>
<Div id="outerDiv" style="width: 3in; height: 3in; border: 1px solid;border-color:black; cursor: pointer;">
<Div id="innerDiv" style="height: auto; border: 1px solid;border-color:blue;">
<div id="textBox" readonly></div>
</Div>
</Div>
When you click the text box, the event "bubbles up" to the outer elements.
JavaScript's Event.stopPropagation() "prevents further propagation of the current event in the capturing and bubbling phases".
Below is an example in pure JavaScript, but see also dojo.stopEvent.
var outerDiv = document.getElementById('outerDiv');
var textBox = document.getElementById('textBox');
outerDiv.addEventListener('mouseup', function(event) {
console.log('mouse up on outer div');
});
textBox.addEventListener('mouseup', function(event) {
event.stopPropagation();
console.log('mouse up on text box');
});
#outerDiv {
width: 3in;
height: 3in;
border: 1px solid;
border-color: black;
cursor: pointer;
}
#innerDiv {
height: auto;
border: 1px solid;
border-color: blue;
}
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js"></script>
<Div id="outerDiv">
<Div id="innerDiv">
<div id="textBox" readonly>textbox</div>
</Div>
</Div>
Edit
Here's a Dojo example:
require([
"dijit/form/TextBox",
"dojo/on",
"dojo/dom"
], function(
TextBox,
on,
dom) {
var box = new TextBox({
name: "any",
value: "",
placeholder: "Type anything here"
}, "textBox");
var canvas = dom.byId("outerDiv");
on(box, "mouseup", function(e) {
console.log('mouse up on text box');
dojo.stopEvent(e);
});
on(canvas, "mouseup", function(e) {
console.log('mouse up on outer div');
});
});
#outerDiv {
width: 3in;
height: 3in;
border: 1px solid;
border-color: black;
cursor: pointer;
}
#innerDiv {
height: auto;
border: 1px solid;
border-color: blue;
}
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<Div id="outerDiv">
<Div id="innerDiv">
<div id="textBox" readonly>textbox</div>
</Div>
</Div>
You can check the id before creating the alert
on(canvas, "mouseup", function (e) {
if (e.target.id == "outerDiv") {
alert();
}
});
JS Fiddle
Following is my code in question
(function($) {
'use strict';
var button = $('#open_button');
var box = $('#dropdown');
function init() {
eventsInit();
}
function eventsInit() {
box.hide();
button.on('click', open);
}
function open(event) {
if (event.target !== button[0]) {
box.hide();
} else {
box.show();
}
}
init();
})(jQuery);
body,
html {
padding: 0;
margin: 0;
}
#container {
height: 100px;
width: 800px;
margin: 0 auto;
}
h1 {
color: white;
}
#dropdown {
height: 600px;
width: 800px;
background-color: black;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<form action="" id="open_button">
<input type="text" placeholder="Enter the text" />
</form>
</div>
<div id="dropdown"></div>
I need to dropdown when I click on the input form input element and close it when I click outside.
My code I believe it says, if the click target is not the button, close the dropdown, else show.
Could someone explain, why doesnt it work ?
(event.target !== button[0]) is always true.
event.target is the <input> field.
button[0] is the <form> element.
You could move the #open_button id to the input field, that would cause the box to appear when the user clicks the input field -- but then the box would never disappear (because your if condition would never return true.)
What you really want are focus and blur handlers on the input field, to show and hide the box respectively:
$('#open_button input').on('focus', function() {
$('#dropdown').show()
}).on('blur', function() {
$('#dropdown').hide()
});
// added to answer per comment below:
$('#dropdown').on('mousedown',function(e) {
e.preventDefault() // prevent input field from losing focus when user clicks inside the box
});
$('#dropdown').hide();
#dropdown {
height: 600px;
width: 800px;
background-color: black;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<form action="" id="open_button">
<input type="text" placeholder="Enter the text" />
</form>
</div>
<div id="dropdown"></div>
I am trying to make a simple widget that allows the user to select either the check box OR the whole div to change its value. I have the following code:
$(document).ready(function() {
$(document).on("click", ".inputCheck", function(event) {
event.stopImmediatePropagation();
event.preventDefault();
$(this).closest(".outter").trigger("click");
});
$(document).on("click", ".outter", function(event) {
console.log("inside");
event.stopImmediatePropagation();
event.preventDefault();
var $checkBox = $(this).find("input");
$(this).removeClass("selected");
$checkBox.prop("checked", !$checkBox.prop("checked"));
if ($checkBox.prop("checked"))
$(this).addClass("selected");
});
});
.outter {
width: 100px;
height: 100px;
border-style: solid;
border-width: 1px;
}
.outter:hover,
.inputCheck:hover {
cursor: pointer;
}
<!DOCTYPE HTML>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<div class="outter">
<input class="inputCheck" type="checkbox">
<div>This is a test</div>
</div>
</body>
</html>
It works as normal when the div is selected I.e. Checkbox changing values and a new class 'selected' being added to the .outter class. When the checkbox is selected I try to stop all defaults and propagation and then trigger the same code as selecting the div to change the class value. However the check box stays the same. Can someone please tell me why this isn't working and how to fix it?
Thanks
You don't need to stop propagation or anything. You can just check if the click was on the input or not, then change the input checked status like following. The click on the input will automatically be propagated to the parent div. You can check the click origin using event.target and make necessary actions.
$(document).ready(function() {
$(".outter").click(function(event) {
console.log('clicked');
var $checkBox = $(this).find("input");
$(this).removeClass("selected");
if (!$(event.target).is($checkBox)) {
$checkBox.prop("checked", !$checkBox.prop("checked"));
}
if ($checkBox.prop("checked"))
$(this).addClass("selected");
event.stopPropagation();
});
});
.outter {
width: 100px;
height: 100px;
border-style: solid;
border-width: 1px;
}
.outter:hover,
.inputCheck:hover {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="outter">
<input class="inputCheck" type="checkbox" />
<div id="testIt">This is a test</div>
</div>
$(document).ready(function() {
$(document).on("click", ".inputCheck", function(event) {
event.stopImmediatePropagation();
$(this).closest(".outter").trigger("click");
});
$(document).on("click", ".outter", function(event) {
console.log("inside");
event.stopImmediatePropagation();
var $checkBox = $(this).find("input");
if ($checkBox.prop("checked"))
$(this).addClass("selected");
else
$(this).removeClass("selected");
});
});
.outter {
width: 100px;
height: 100px;
border-style: solid;
border-width: 1px;
}
.outter:hover,
.inputCheck:hover {
cursor: pointer;
}
<!DOCTYPE HTML>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<div class="outter">
<input class="inputCheck" type="checkbox">
<div>This is a test</div>
</div>
</body>
</html>
I have a problem i'm working on, my program will highlight words if typed in an input field. It wont highlight words from both.(Example Input1 type "Test1", Input2 type "Test2") is there a way to keep the highlighted words active from one field when the user switches to another?
JSBIN: http://jsbin.com/xovisayaso/edit?html,css,js,output
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<title>JS Bin</title>
</head>
<body>
<div id="listArray">
<span>Test1</span>
<span>Test2</span>
<span>Test3</span>
</div>
<input type="text" class="form-control" id="userArray">
<input type="text" class="form-control" id="userArray2">
</body>
</html>
<script
$("#userArray, #userArray2").on('change keyup paste', function() {
var input = $(this).val().toLowerCase().split(" ");
$('#listArray span').each(function(){
$(this).removeClass('active');
if( $.inArray( $(this).text().toLowerCase(), input ) != -1 ) {
$(this).addClass('active');}});});
</script>
<style>#list_input > div { border:4px solid; padding: 1em; margin: 1em auto; }
#listArray { overflow: auto; }
#listArray span { display: block; float: left; clear: left; padding:4px; margin:1px; }
#listArray span.active { background: green; }
}
</style>
You can achieve the desired effect by removing the active class whenever the text changes and then checking against both inputs:
$("#userArray, #userArray2").on('change keyup paste', function() {
$('#listArray span').removeClass('active');
$('input').each(function() {
var input = $(this).val().toLowerCase().split(" ");
$('#listArray span').each(function() {
if ($.inArray($(this).text().toLowerCase(), input) != -1) {
$(this).addClass('active');
}
});
});
});
#list_input > div {
border: 4px solid;
padding: 1em;
margin: 1em auto;
}
#listArray {
overflow: auto;
}
#listArray span {
display: block;
float: left;
clear: left;
padding: 4px;
margin: 1px;
}
#listArray span.active {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="listArray">
<span>Test1</span>
<span>Test2</span>
<span>Test3</span>
</div>
<input type="text" class="form-control" id="userArray">
<input type="text" class="form-control" id="userArray2">
Try this code :
$("#userArray, #userArray2").on('change keyup paste', function() {
var input = $("input").map(function(){return $(this).val().toLowerCase();}).get();
$('#listArray span').each(function(){
if( $.inArray( $(this).text().toLowerCase(), input ) != -1 ) {
$(this).addClass('active');
}
else
$(this).removeClass('active');
});
});
Reason : In your code you are only getting single value at a time to compare, rather the both textbox's values !!!