The documentation says the default value of observeChanges is false. But it seems to be setting the value to true. Is the default value applicable only when the sort plugin is disabled?
We are the noticing the rendering is invoked multiple times due to this and are wondering if it can be set to false explicitly.
Here is the jsfiddle:
$(document).ready(function() {
var container = document.getElementById('basic_example');
var data = function() {
return Handsontable.helper.createSpreadsheetData(10, 10);
};
var hot = new Handsontable(container, {
data: data(),
colHeaders: true,
rowHeaders: true,
stretchH: 'all',
columnSorting: true,
contextMenu: true
});
if (container.clientHeight < 500) {
container.height = container.clientHeight;
hot.updateSettings({
height: container.clientHeigh
});
hot.render();
}
setTimeout(function() {
var output = document.getElementById('output').innerHTML = hot.getSettings().observeChanges;
}, 1000);
});
</style> <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script> <link href="http://handsontable.com//styles/main.css" rel="stylesheet"> <link href="http://handsontable.com//bower_components/handsontable/dist/handsontable.full.css" rel="stylesheet"> <script src="http://handsontable.com//bower_components/handsontable/dist/handsontable.full.js"></script> <style type="text/css"> body {
background: white;
margin: 20px;
}
h2 {
margin: 20px 0;
}
div#basic_example {
border: 5px solid #ccc;
}
<span>Default value for observe changes</span>
<div id="basic_example"></div>
<span id="output">Output</span>
Click here for jsfiddle: http://jsfiddle.net/mpusarla/nva6b8e8/1/
Related
I put together a minimal working Cytoscape example. I can get the graph to display, but I am mostly interested in handling events, and that's where I'm having difficulty.
The problem is that instead of being able to access individual elements' properties, I can see that the target of any event is undefined.
Below is my entire html file. Please note - I am only interested in the line
cy.nodes().bind('mouseover', (e) => console.log(e.target));
When I'm looking at the console, I can only see "undefined" whenever I move the mouse pointer over a node. As I said above, I want to eventually be able to access element properties.
<!doctype html>
<html>
<head>
<title>Tutorial 1: Getting Started</title>
<script src="cytoscape.js"></script>
</head>
<style>
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<body>
<div id="cy"></div><script>
var cy = cytoscape({
container: document.getElementById('cy'),
elements: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
}]
});
cy.unbind("tap");
cy.bind("tap", "edge",function(evt) {
var tgt=this;
alert(tgt);
});
cy.nodes().bind('mouseover', (e) => console.log(e.target));
</script>
</body>
</html>
You can see a working example in the snippet below, I really just changed the import, nothing else:
var cy = cytoscape({
container: document.getElementById('cy'),
elements: [{
data: {
id: 'a'
}
},
{
data: {
id: 'b'
}
},
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
}
]
});
cy.unbind("tap");
cy.bind("click", "node, edge", function(evt) {
var tgt = evt.target.data();
console.log(tgt);
});
cy.nodes().bind('mouseover', (e) => console.log(e.target.data()));
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
<html>
<head>
<title>Tutorial 1: Getting Started</title>
<script src="https://cdn.jsdelivr.net/npm/cytoscape#3.11.0/dist/cytoscape.min.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
I want to display an path in Fabric.JS, in svg file:
<g>
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;"
d="M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72"/>
</g>
And code in my Fabricjs
var Path_0_1 = new fabric.Path('M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
fill: 'none',
stroke: '#000000',
strokeMiterLimit: 10,
opacity: 1,
});
But result is not same:
Expected:
Path in FabricJS display same as in SVG file.
Here is my code:
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
// fill : 'none',
stroke: '#000000',
strokeMiterLimit: 10,
opacity: 1,
});
canvas.add(Path_0_1);
canvas.moveTo(Path_0_1, 1);
setObjectCoords();
canvas.renderAll();
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
And here is my svg file:
https://svgur.com/s/Bw6
Set fill value '' || null || 'transparent', so on ctx.fill() it wont fill anything to the object.
DEMO
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M221.58-0.55c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
fill : null,
stroke: '#000000',
});
canvas.add(Path_0_1);
#canvasContainer {
width: 100%;
height: 100vh;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
I've built what I think is the most current solution for a nested selection with an update pattern.
However, each time update is clicked, I always get the outer selection, but not always the inner (nested) selection. The log to console show a correctly formed array of arrays.
Is this the correct setup for a nested selection in v5?
Here's a codepen
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>#</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style type="text/css">
.outer {
border: 1px solid black;
background-color: grey;
width: 100%;
height: 100px;
position: relative;
display: flex;
}
.inner {
display: flex;
justify-content: flex-start;
border: 1px solid blue;
background-color: cyan;
width: 50px;
height: 50px;
position: relative;
}
</style>
</head>
<body>
<button id='update'>update</button>
<div id="anchor"></div>
<script>
const updateButton = document.getElementById('update');
const anchor = d3.select('#anchor');
updateButton.addEventListener('click', function() {
update(
Array.from({
length: Math.ceil(Math.random() * 5)
}, function() {
return Array.from({
length: Math.ceil(Math.random() * 5)
}, function() {
return Math.ceil(Math.random() * 5);
});
})
);
});
function update(data) {
const outer = anchor.selectAll('.outer').data(data);
outer.exit().remove();
outer.enter()
.append('div')
.merge(outer)
.attr("class", "outer");
const inner = outer.selectAll('.inner').data(function(d) {
return d;
});
inner.exit().remove();
inner.enter()
.append('div')
.merge(inner)
.attr("class", "inner")
.text(function(d) {
return d;
});
}
</script>
</body>
</html>
In a case like this one you have to reassign the update selection, so its reference is merged with the enter selection (here I'm changing const for let in order to reassign the selection):
//here is the update selection:
let outer = anchor.selectAll('.outer').data(data);
//here is the enter selection:
const outerEnter = outer.enter()
.append('div')
.attr("class", "outer");
//reassigning here:
outer = outerEnter.merge(outer);
Otherwise other will be only the update selection, even if you have a merge method chained in the enter selection. You can clearly see this if you console outer.size().
Here is your code with that change:
const updateButton = document.getElementById('update');
const anchor = d3.select('#anchor');
updateButton.addEventListener('click', function() {
update(
Array.from({
length: Math.ceil(Math.random() * 5)
}, function() {
return Array.from({
length: Math.ceil(Math.random() * 5)
}, function() {
return Math.ceil(Math.random() * 5);
});
})
);
});
function update(data) {
let outer = anchor.selectAll('.outer').data(data);
outer.exit().remove();
const outerEnter = outer.enter()
.append('div')
.attr("class", "outer");
outer = outerEnter.merge(outer);
const inner = outer.selectAll('.inner').data(function(d) {
return d;
});
inner.exit().remove();
inner.enter()
.append('div')
.attr("class", "inner")
.merge(inner)
.text(function(d) {
return d;
});
}
.outer {
border: 1px solid black;
background-color: grey;
width: 100%;
height: 100px;
position: relative;
display: flex;
}
.inner {
display: flex;
justify-content: flex-start;
border: 1px solid blue;
background-color: cyan;
width: 50px;
height: 50px;
position: relative;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<button id='update'>update</button>
<div id="anchor"></div>
I'm using Magnific popup to display an upload form where the user can select multiple images to upload and preview them before submitting the form, I let the user preview the images plus add a from inputs underneath the image when he clicks on it to enter the caption and alt for it, here's the code that I have ...
(function() {
if ($("a.uploadMediaImageForm").length) {
$("a.uploadMediaImageForm").magnificPopup({
type: 'inline',
preloader: false,
closeOnBgClick: false,
enableEscapeKey: false,
focus: '#name',
removalDelay: 500, //delay removal by X to allow out-animation
// When elemened is focused, some mobile browsers in some cases zoom in
// It looks not nice, so we disable it:
callbacks: {
beforeOpen: function() {
if ($(window).width() < 700) {
this.st.focus = false;
} else {
this.st.focus = '#name';
}
this.st.mainClass = this.st.el.attr('data-effect');
},
open: function() {
if ($("input#imageUpload").length) {
$("input#imageUpload").on('change', function() {
//Get count of selected files
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extension = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var previewHolder = $("ul.imagePreview");
previewHolder.empty();
if (extension == "gif" || extension == "png" || extension == "jpg" || extension == "jpeg") {
if (typeof(FileReader) != "undefined") {
//loop for each file selected for uploaded.
for (var i = 0; i < countFiles; i++) {
var reader = new FileReader();
reader.onload = function(e) {
$("<li><img src='" + e.target.result +"'></li>").appendTo(previewHolder);
}
previewHolder.show();
reader.readAsDataURL($(this)[0].files[i]);
}
} else {
alert("This browser does not support FileReader.");
}
} else {
alert("Please select only images");
}
});
} //Image upload preview
if($("ul.imagePreview").length) {
$("ul.imagePreview").on("click", "li", function(event) {
if($(this).hasClass("selected")) {
$(this).removeClass("selected");
$(this).find("div").remove();
} else {
$(this).addClass("selected");
$(this).append("<div><label><span>Image Alt</span><input type='text'></label><label><span>Image Caption</span><input type='text'></label></div>");
}
});
$("ul.imagePreview").on("click", "div", function(event) {
event.stopPropagation();
});
}//add form when clicked on an image
},
beforeClose: function() {
// $("ul.imagePreview").empty();
var countFiles = "";
var imgPath = "";
var extension = "";
var previewHolder = $("ul.imagePreview");
previewHolder.empty();
}
},
midClick: true // allow opening popup on middle mouse click. Always set
});
}
})(); //popup Forms and Uploads
div.uploadPopup {
width: 80%;
margin: auto;
background: white;
position: relative;
padding: 40px;
}
label {
width: 100%;
margin-bottom: 20px;
clear: both;
}
ul.imagePreview {
width: 100%;
clear: both;
display: block;
}
ul.imagePreview li {
width: 100%;
display: block;
margin-bottom: 20px;
max-height: 150px;
cursor: pointer;
}
ul.imagePreview li.selected {
max-height: auto;
}
ul.imagePreview li img {
max-height: 150px;
display: block;
margin: auto;
}
<link href="https://cdn.jsdelivr.net/jquery.magnific-popup/1.0.0/magnific-popup.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.0.1/jquery.magnific-popup.min.js"></script>
Upload Media
<div id="uploadMediaImageForm" class="uploadPopup mfp-with-anim mfp-hide">
<form action="#">
<label class="upload">
<span>Upload Images</span>
<input id="imageUpload" type="file" multiple>
</label>
<ul class="imagePreview">
</ul>
</form>
</div>
Now everything works fine the first time, but when I close the popup and re-open it again, something wrong happens in the image previewer, it duplicates the images I choose and sometimes doesn't even show the image if it were the last image I choose before closing.
I tried to set all the variables before closing the popup and clear the image preview ul element, but that didn't help.
I need your help guys, what am I doing wrong here?
EDIT
I gave the form itself an id of "fileForm" and tried to reset the whole form and empty the ul.imagePreview before closing the popup with this code ...
$("#fileForm")[0].reset();
$("ul.imagePreview").empty();
But still no luck, it still duplicated any image I upload the second time after closing the popup and opening it again !!
need help here.
You are binding more and more listeners to the same event:
Your form always exists in your document even when the popup is closed, you just hide it most of the time (using the class mfp-hide).
Each time you open the popup, the callback "open" is called, which bind a function to the change event of your input, and this callback do the preview stuff.
But if you open the popup twice, it will bind again the same function to the same event on the same input. That's why you have duplicate: the code is called twice.
Move all your binding outside your callback so that they will be done once:
(function() {
if ($("input#imageUpload").length) {
$("input#imageUpload").on('change', function() {
//Get count of selected files
var countFiles = $(this)[0].files.length;
var imgPath = $(this)[0].value;
var extension = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase();
var previewHolder = $("ul.imagePreview");
previewHolder.empty();
if (extension == "gif" || extension == "png" || extension == "jpg" || extension == "jpeg") {
if (typeof(FileReader) != "undefined") {
//loop for each file selected for uploaded.
for (var i = 0; i < countFiles; i++) {
var reader = new FileReader();
reader.onload = function(e) {
$("<li><img src='" + e.target.result +"'></li>").appendTo(previewHolder);
}
previewHolder.show();
reader.readAsDataURL($(this)[0].files[i]);
}
} else {
alert("This browser does not support FileReader.");
}
} else {
alert("Please select only images");
}
});
} //Image upload preview
if($("ul.imagePreview").length) {
$("ul.imagePreview").on("click", "li", function(event) {
if($(this).hasClass("selected")) {
$(this).removeClass("selected");
$(this).find("div").remove();
} else {
$(this).addClass("selected");
$(this).append("<div><label><span>Image Alt</span><input type='text'></label><label><span>Image Caption</span><input type='text'></label></div>");
}
});
$("ul.imagePreview").on("click", "div", function(event) {
event.stopPropagation();
});
}//add form when clicked on an image
if ($("a.uploadMediaImageForm").length) {
$("a.uploadMediaImageForm").magnificPopup({
type: 'inline',
preloader: false,
closeOnBgClick: false,
enableEscapeKey: false,
focus: '#name',
removalDelay: 500, //delay removal by X to allow out-animation
// When elemened is focused, some mobile browsers in some cases zoom in
// It looks not nice, so we disable it:
callbacks: {
beforeOpen: function() {
if ($(window).width() < 700) {
this.st.focus = false;
} else {
this.st.focus = '#name';
}
this.st.mainClass = this.st.el.attr('data-effect');
},
beforeClose: function() {
///$("ul.imagePreview").empty();
var countFiles = "";
var imgPath = "";
var extension = "";
var previewHolder = $("ul.imagePreview");
previewHolder.empty();
$("#fileForm")[0].reset();
}
},
midClick: true // allow opening popup on middle mouse click. Always set
});
}
})(); //popup Forms and Uploads
div.uploadPopup {
width: 80%;
margin: auto;
background: white;
position: relative;
padding: 40px;
}
label {
width: 100%;
margin-bottom: 20px;
clear: both;
}
ul.imagePreview {
width: 100%;
clear: both;
display: block;
}
ul.imagePreview li {
width: 100%;
display: block;
margin-bottom: 20px;
max-height: 150px;
cursor: pointer;
}
ul.imagePreview li.selected {
max-height: auto;
}
ul.imagePreview li img {
max-height: 150px;
display: block;
margin: auto;
}
<link href="https://cdn.jsdelivr.net/jquery.magnific-popup/1.0.0/magnific-popup.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.0.1/jquery.magnific-popup.min.js"></script>
Upload Media
<div id="uploadMediaImageForm" class="uploadPopup mfp-with-anim mfp-hide">
<form action="#" id="fileForm">
<label class="upload">
<span>Upload Images</span>
<input id="imageUpload" type="file" multiple>
</label>
<ul class="imagePreview">
</ul>
</form>
</div>
Below is my KendoUI tree view, I am using templates to show edit link on each node, but I am getting this error: "Uncaught TypeError: Cannot read property 'replace' of undefined "
#section scripts{
<script src="~/scripts/kendo.all.min.js"></script>
<script type="text/javascript">
var territory = new kendo.data.HierarchicalDataSource({
transport: {
read: {
type:'POST',
url: rootURL + "Territory/AllTerritories",
dataType: "json"
}
},
schema: {
model: {
id: "ID",
hasChildren: "HasChildren",
children: territory
}
}
});
$("#treeview").kendoTreeView({
dataSource: territory,
dataTextField: "Name",
dataValueField: "ID",
template: kendo.template($("#treeview-template").html())
});
</script>
}
<script id="treeview-template" type="text/kendo-ui-template">
#
<a class='show-link' href='\#'><image src="/Content/images/select2.png"></a> #
</script>
<style scoped>
#territoryTree {
text-align: center;
}
#treeview .k-sprite {
background-image: url("../content/default/coloricons-sprite.png");
}
.rootfolder {
background-position: 0 0;
}
.demo-section {
display: inline-block;
vertical-align: text-bottom;
min-width: 320px;
min-height: 300px;
text-align: left;
margin: 0 2em;
}
</style>
Any solutions?? Please help
jquery can't find the element with Id #treeview-template when you say
kendo.template($("#treeview-template").html())
then first it will try to find the html element with the Id #treeview-template and then it will move forward. Try the F12 and the console by writing $("#treeview-template").html() in the console see if it can or cannot find the element