I have added this jspdf script on my website to download pdf. However I get this error.
Uncaught TypeError: Cannot read property '1' of undefined
at f.renderParagraph (jspdf.min.js:202)
at f.setBlockBoundary (jspdf.min.js:202)
at k (jspdf.min.js:202)
at k (jspdf.min.js:202)
at k (jspdf.min.js:202)
at jspdf.min.js:202
at l (jspdf.min.js:202)
at Image.i.onerror.i.onload (jspdf.min.js:202)
This happens on certain pages while others work fine.I have added the code I am using below. I am not sure if it is anything to do with my code or the jspdf.
//Code I am using:
<script type="text/javascript">
function HTMLtoPDF(){
var pdf = new jsPDF('p', 'pt', 'letter');
source = $('#HTMLtoPDF')[0];
specialElementHandlers = {
'#bypassme': function(element, renderer){
return true
}
}
margins = {
top: 50,
left: 60,
right:60,
width: 545
};
pdf.fromHTML(
source // HTML string or DOM elem ref.
, margins.left // x coord
, margins.top // y coord
, {
'width': margins.width // max width of content on PDF
, 'elementHandlers': specialElementHandlers
},
function (dispose) {
// dispose: object with X, Y of the last line add to the PDF
// this allow the insertion of new lines after html
pdf.save('Download.pdf');
}
)
}
</script>
<button type="button" onclick="HTMLtoPDF()" style=" height: 40px; width: 154px; background-color: #008800; color: #ffffff; font-size: 150%;">Download PDF </button>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"> </script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var str_pdf = $("#HTMLtoPDF").html();
var regex = /<br\s*[\/]?>/gi;
$("#HTMLtoPDF").html(str_pdf.replace(regex, '<p data-empty="true"><br></p>'));
});
function HTMLtoPDF(){
var pdf = new jsPDF('p', 'pt', 'a4');
source = $('#HTMLtoPDF')[0];
specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true
}
};
margins = {
top: 30,
bottom: 30,
left: 40,
width: 522
};
pdf.fromHTML(
source,
margins.left,
margins.top, {
'width': margins.width,
'elementHandlers': specialElementHandlers
},
function (dispose) {
pdf.save('Download.pdf');
}, margins);
}
</script>
<!-- these js files are used for making PDF -->
Related
This question already has answers here:
Google Maps API v3: How to remove all markers?
(32 answers)
Closed 4 years ago.
Could someone be kind enough to share how I can clear the markers in google map before refreshing it with a new set of markers?
In my map, I'm adding markers from an array that contains name, lat and long. The name can be picked from a drop down menu, and then all the markers for that name are added to the page.
Prtoject : Asp.Net Mvc
Link image: https://i.hizliresim.com/V927Py.jpg
When the user adds markers, the previous set of markers remain. I'd like to remove any existing markers before adding the new set.
After reading the documentation, I tried this:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#model List<Project_Map.Models.KONUM>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Complex Marker Icons</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<style>
#map_wrapper {
height: 700px;
}
#map_canvas {
width: 100%;
height: 100%;
}
</style>
<div id="map_wrapper">
<div class="mapping" id="map_canvas">
</div>
</div>
<div id="map"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
jQuery(function ($) {
var script = document.createElement('script');
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyBT56XlfxnK2OB4K93vWdrZci_CKjZyQOM&callback=initMap";
document.body.appendChild(script);
});
</script>
<!-- Google Maps Kodu -->
<script type="text/javascript">
var contentString = '<div id="content">' +
'<div id="siteNotice">' +
'<img src="#IMG_SRC#" />' +
'</div>' +
//'<h2 id="firstHeading" class="firstHeading">#PERSONEL#</h2>' +
'<div id="bodyContent">' +
'<b>Mesafe: </b>#MESAFE# Km<br />' +
'<b>Tarih: </b> #TARIH#' +
'</p>' +
'</div>' +
'</div>';
$(document).ready(function () {
initMap();
});
function initMap() {
var mapCenter = { lat: 39.684536, lng: 35.337094 };
var map = new google.maps.Map(document.getElementById('map_wrapper'), {
zoom: 6,// haritanın yakınlık derecesi
center: mapCenter, // haritanın merkezi
mapTypeId: google.maps.MapTypeId.HYBRID
});
var infoWindow = new google.maps.InfoWindow();
setInterval(function () {
$.ajax({
url: '#Url.Action("GetMapLocations", "Konum")',
type: "POST",
success: function (data) {
var json = JSON.parse(data);
for (var i = 0; i < json.length; i++) {
var position = {
lat: parseFloat(json[i].lat.replace(',', '.')),
lng: parseFloat(json[i].lng.replace(',', '.'))
};
var marker = new google.maps.Marker({
position: position,
animation: google.maps.Animation.BOUNCE,
map: map,
});
// infoWindow içeriğini replace et
var cs = contentString;
cs = cs.replace("#PERSONEL#", json[i].name);
cs = cs.replace("#MESAFE#", json[i].mesafe);
cs = cs.replace("#TARIH#", json[i].tarih);
cs = cs.replace("#IMG_SRC#", json[i].img);
google.maps.event.addListener(marker, 'click', (function (marker, cs, infoWindow) {
return function () {
infoWindow.setContent(cs);
infoWindow.open(map, this);
passive: true;
};
})(marker, cs, infoWindow));
};
},
error: function (data) { alert("Malesef Sunucunuza Ulaşamıyoruz. Lütfen Tekrar Deneyiniz..."); },
});
}, 5000);
};
</script>
</body>
</html>
You have to set up an array, where you can store the added marker
var gmarkers = [];
If you add a marker you have to store the marker object in the array.
gmarkers.push(marker);
If you want to remove these markers you can use something like:
function removeMarker() {
if (gmarkers.length > 0) {
for (var i=0; i<gmarkers.length; i++) {
if (gmarkers[i] != null) {
gmarkers[i].setMap(null);
}
}
}
gmarkers = [];
}
I have a problem with the Zindex in konva.js. After I added everything to the layer
I am trying to assign a property to a node for each element separately. But it does not work. For example
for(let i = 0; i<=this.layer['children']; i++){
this.layer['children'][i].setZIndex(someInt);
}
How can i set zindex for all elements in layer?
zIndex in Konva is just index of the element in an array of children of the parent element. So you can't set any number to it and it can not be bigger than children.length - 1.
Working snippet illustrating the getZIndex(), setZIndex(), moveUp() and moveDown() methods of the Kovajs.Shape object. See also example at Konvajs site.
Buttons allow use to move green circle up and down the z-index list by increments of 1, then also to try to move up +10 and down -100. Resulting z-index is shown in text below circles.
// Create the stage
var stage = new Konva.Stage({
container: 'container',
width: $('#container').width(),
height: $('#container').height()
});
// create the layer
var layer = new Konva.Layer();
var data = [ {x: 60, color: 'red'}, {x: 90, color: 'limegreen'}, {x: 120, color: 'gold'}]
var circles = [];
for (var i = 0; i < data.length; i = i + 1){
// create some circles
var circle = new Konva.Circle({
x: data[i].x,
y: 60,
radius: 50,
fill: data[i].color,
stroke: 'black',
strokeWidth: 2
});
layer.add(circle);
circles.push(circle);
}
stage.add(layer);
var green = circles[1];
function sayIndex(){
$('#info').html("Green zIndex=" + circles[1].getZIndex());
}
$('#greenup').on('click', function(){
green.moveUp();
sayIndex();
layer.draw();
})
$('#greendn').on('click', function(){
green.moveDown();
sayIndex();
layer.draw();
})
$('#greenup10').on('click', function(){
var ind = circles[1].getZIndex();
green.setZIndex(ind + 10);
sayIndex();
layer.draw();
})
$('#greendn100').on('click', function(){
var ind = circles[1].getZIndex();
green.setZIndex(ind - 100);
sayIndex();
layer.draw();
})
#container
{
width: 200px;
height: 150px;
border: 1px solid #666;
float: left;
}
#buttons
{
width: 200px;
height: 150px;
border: 1px solid #666;
float: left;
}
#info
{
position: absolute;
left: 20px;
top: 135px;
}
p
{
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>
<div id="container"></div>
<div id="buttons">
<p><button id='greenup'>Move Green + 1</button></p>
<p><button id='greendn'>Move Green -1</button></p>
<p><button id='greenup10'>Move Green +10</button></p>
<p><button id='greendn100'>Move Green -100</button></p>
<span id='info'></span>
</div>
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva#2.4.2/konva.min.js"></script>
<meta charset="utf-8">
<title>Konva Shape Layering Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
#buttons {
position: absolute;
left: 10px;
top: 0px;
}
button {
margin-top: 10px;
display: block;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="buttons">
<button id="toTop">
yellow z-index -2
</button>
<button id="toBottom">
yellow -9
</button>
<button id="up">
yellow z-index 1
</button>
<button id="down">
yellow z-index -5
</button>
<button id="zIndex">
Set yellow box zIndex to 3
</button>
</div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
var offsetX = 0;
var offsetY = 0;
var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
var yellowBox = null;
for(var n = 0; n < 6; n++) {
// anonymous function to induce scope
(function() {
var i = n;
var box = new Konva.Rect({
x: i * 30 + 210,
y: i * 18 + 40,
width: 100,
height: 50,
fill: colors[i],
stroke: 'black',
strokeWidth: 4,
draggable: true,
name: colors[i]
});
box.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
box.on('mouseout', function() {
document.body.style.cursor = 'default';
});
if(colors[i] === 'yellow') {
yellowBox = box;
}
layer.add(box);
})();
}
stage.add(layer);
// add button event bindings
document.getElementById('toTop').addEventListener('click', function() {
yellowBox.setZIndex(-2);
layer.draw();
}, false);
document.getElementById('toBottom').addEventListener('click', function() {
yellowBox.setZIndex(-9);
layer.draw();
}, false);
document.getElementById('up').addEventListener('click', function() {
yellowBox.setZIndex(1);
layer.draw();
}, false);
document.getElementById('down').addEventListener('click', function() {
yellowBox.setZIndex(-5);
layer.draw();
}, false);
document.getElementById('zIndex').addEventListener('click', function() {
yellowBox.setZIndex(3);
layer.draw();
}, false);
</script>
</body>
</html>
Last
Fun messing with ZIndex code,
the setZIndex is all you need; It will vain the z-index inside Konva.JS
If you would prefer to be able to set the render order of nodes using arbitrary numbers (like CSS, or how it works in most game engines, etc), you can use this fork of Konva. Alternatively, you could also grab & apply just the rejected pull request for this feature if you already have a customized Konva version.
The new feature works by adding a zOrder property to all Nodes, and a special kind of group AbsoluteRenderOrderGroup that reads and understands this property for all children.
i want to add content after a table in a pdf file that was created with jsPDF autotable.
My Code:
$('#printBtn').on('click', function() {
var pdf = new jsPDF('p', 'pt', 'a4');
var res = pdf.autoTableHtmlToJson(document.getElementById("tablePrint"));
var anfang = "Anfang";
pdf.text(anfang, 14, 30);
pdf.autoTable(res.columns, res.data, {
theme : 'plain',
styles: {
fontSize: 12
},
showHeader: 'never',
createdCell: function(cell, data) {
var tdElement = cell.raw;
if (tdElement.classList.contains('hrow')) {
cell.styles.fontStyle = 'bold';
}
}
});
var ende = $('#ende_text').text();
pdf.text(ende, 0, 12);
pdf.save("test.pdf");
});
My Problem is that the code isn't formatted. The tags and everything else was ignored by jsPDF.
How can i fix that or what can i do that the text has line breaks and not overflow?
Thanks for help!
margins={
top=50,
left=30,
bottom=50,
width=520
}
var pdf = new jsPDF("p", "pt","a4");
var res = pdf.autoTableHtmlToJson(document.getElementById("table2"));
pdf.autoTable(res.columns, res.data,{
margin: { left: 30,bottom:100},
startY: 30, pageBreak: 'always',
styles: {overflow: 'linebreak', columnWidth: 'wrap', font: 'arial',
cellPadding: 8, overflowColumns: 'linebreak'}
});
pdf.fromHTML($("#editor1").get(0), 30, pdf.autoTableEndPosY() + 20, {
'width': margins.width
},function(dispose)
{
var iframe = document.createElement('iframe');
iframe.setAttribute('style','position:absolute;right:0; top:0; bottom:0; height:100%; width:40%; padding:20px;');
document.body.appendChild(iframe);
iframe.src = pdf.output('datauristring');
//pdf.save('name.pdf');
},
margins);
iam using the latest version of jspdf.min.js and jspdf.autotable.js
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/2.3.5/jspdf.plugin.autotable.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js"></script>
Now I'm moving my project from openlayers 2 to openlayers 3. Unfortunately I can't find how to show title (tooltip) for feature. In OL2 there was a style named graphicTitle.
Could you give me advice how to implement tooltip on OL3?
This is example from ol3 developers.
jsfiddle.net/uarf1888/
var tooltip = document.getElementById('tooltip');
var overlay = new ol.Overlay({
element: tooltip,
offset: [10, 0],
positioning: 'bottom-left'
});
map.addOverlay(overlay);
function displayTooltip(evt) {
var pixel = evt.pixel;
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
tooltip.style.display = feature ? '' : 'none';
if (feature) {
overlay.setPosition(evt.coordinate);
tooltip.innerHTML = feature.get('name');
}
};
map.on('pointermove', displayTooltip);
Here's the Icon Symobolizer example from the openlayers website. It shows how to have a popup when you click on an icon feature. The same principle applies to any kind of feature. This is what I used as an example when I did mine.
This is a basic example using the ol library. The most important is to define the overlay object. We will need an element to append the text we want to display in the tooltip, a position to show the tooltip and the offset (x and y) where the tooltip will start.
const tooltip = document.getElementById('tooltip');
const overlay = new ol.Overlay({
element: tooltip,
offset: [10, 0],
positioning: 'bottom-left'
});
map.addOverlay(overlay);
Now, we need to dynamically update the innerHTML of the tooltip.
function displayTooltip(evt) {
const pixel = evt.pixel;
const feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
tooltip.style.display = feature ? '' : 'none';
if (feature) {
overlay.setPosition(evt.coordinate);
tooltip.innerHTML = feature.get('name');
}
};
map.on('pointermove', displayTooltip);
let styleCache = {};
const styleFunction = function(feature, resolution) {
// 2012_Earthquakes_Mag5.kml stores the magnitude of each earthquake in a
// standards-violating <magnitude> tag in each Placemark. We extract it from
// the Placemark's name instead.
const name = feature.get('name');
const magnitude = parseFloat(name.substr(2));
const radius = 5 + 20 * (magnitude - 5);
let style = styleCache[radius];
if (!style) {
style = [new ol.style.Style({
image: new ol.style.Circle({
radius: radius,
fill: new ol.style.Fill({
color: 'rgba(255, 153, 0, 0.4)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(255, 204, 0, 0.2)',
width: 1
})
})
})];
styleCache[radius] = style;
}
return style;
};
const vector = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://gist.githubusercontent.com/anonymous/5f4202f2d49d8574fd3c/raw/2c7ee40e3f4ad9dd4c8d9fb31ec53aa07e3865a9/earthquakes.kml',
format: new ol.format.KML({
extractStyles: false
})
}),
style: styleFunction
});
const raster = new ol.layer.Tile({
source: new ol.source.Stamen({
layer: 'toner'
})
});
const map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
const tooltip = document.getElementById('tooltip');
const overlay = new ol.Overlay({
element: tooltip,
offset: [10, 0],
positioning: 'bottom-left'
});
map.addOverlay(overlay);
function displayTooltip(evt) {
const pixel = evt.pixel;
const feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});
tooltip.style.display = feature ? '' : 'none';
if (feature) {
overlay.setPosition(evt.coordinate);
tooltip.innerHTML = feature.get('name');
}
};
map.on('pointermove', displayTooltip);
#map {
position: relative;
height: 100vh;
width: 100vw;
}
.tooltip {
position: relative;
padding: 3px;
background: rgba(0, 0, 0, .7);
color: white;
opacity: 1;
white-space: nowrap;
font: 10pt sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map" class="map">
<div id="tooltip" class="tooltip"></div>
</div>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.8.1/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.8.1/css/ol.css">
By default, while sorting, items are replaced (for example, if I take the third element and move it to the first, than the first and the second elements will move down)
I do not need this behaviour. I'd like elements not to change order while I finish sorting (release mouse).
I need this because I want to ask user if he want to change element or to re-order?
P.S. option tolerance have only 2 options, and they don't help in this situation.
I meant something like this (sortable list with option of replacing elements):
$(function() {
var
/**
* Sortable List, that can insert or replace elements
*/
SortableList = (function() {
var
// Configuration of Sortable list
// css classes of separator and sortable elements
// jQuery UI droppable and sortable init configuration
CONFIG = {
'confirm-message': 'Insert? Element will be removed',
'separator-class': 'sortable-separator',
'sortable-class': 'sortable-elem',
// Initialization of jQuery UI Droppable
'separators-droppable-init': {
drop: function(e, ui) {
// Insertation
var drag = ui.draggable,
drop = $(this),
a = drop.prev(),
b = drop.next();
Separators.clean();
Elements.insert(a, b, drag);
Separators.init();
},
over: function(e, ui) {
$(this).css({
'background-color': 'lightgreen'
});
},
out: function(e, ui) {
$(this).css({
'background-color': 'white'
});
}
},
'sortable-droppable-init': {
drop: function(e, ui) {
// Replace
var drag = ui.draggable,
drop = $(this);
if (Elements.replace(drop, drag)) {
Separators.init();
}
}
},
'sortable-draggable-init': {
revert: true,
start: function(e, ui) {
$(this).css({
'z-index': '999',
'cursor': 'move'
});
},
stop: function(e, ui) {
$(this).css({
'z-index': '1',
'cursor': 'default'
});
}
}
},
getSeparators = function() {
return $('.' + CONFIG['separator-class']);
},
getSortables = function() {
return $('.' + CONFIG['sortable-class']);
},
/**
* Separators Handler
*/
Separators = (function() {
var
// create separator html element
_create = function() {
return $('<div />').addClass(CONFIG['separator-class']);
},
// create all separators and insert them
createAll = function() {
getSortables().each(function() {
$(this).before(_create());
}).last().after(_create());
return Separators;
},
// remove all separators
clean = function() {
var s = getSeparators();
if (s.length) {
s.remove();
}
return Separators;
},
// init jQuery UI Droppable interface
initDroppable = function() {
getSeparators().droppable(CONFIG['separators-droppable-init']);
return Separators;
},
// Initialization of separators
init = function() {
if (getSeparators().length) {
Separators.clean();
}
return Separators.createAll().initDroppable();
};
// Return result
Separators = {
clean: clean,
createAll: createAll,
init: init,
initDroppable: initDroppable
};
return Separators;
}()),
Elements = (function() {
var
init = function() {
getSortables().droppable(CONFIG['sortable-droppable-init']).draggable(CONFIG['sortable-draggable-init']);
return Elements;
},
// replaces element A with element B
replace = function(A, B) {
if (!confirm(CONFIG['confirm-message'])) {
return false;
}
B.draggable("option", "revert", false).css({
top: 0,
left: 0
});
A.replaceWith(B);
return Elements;
},
// insert element C between elements A and B
insert = function(A, B, C) {
C.draggable("option", "revert", false).css({
top: 0,
left: 0
});
if (!A.length) {
B.before(C);
} else {
A.after(C);
}
return Elements;
},
// result to return
Elements = {
init: init,
replace: replace,
insert: insert
};
return Elements;
}()),
init = function() {
Separators.init();
Elements.init();
};
return {
init: init
};
}());
SortableList.init();
});
.sortable-elem {
width: 32px;
height: 32px;
background-color: darkred;
border: 1px solid brown;
color: white;
}
.sortable-separator {
width: 100px;
height: 16px;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<link href="//code.jquery.com/ui/1.8.16/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="//code.jquery.com/ui/1.8.16/jquery-ui.min.js"></script>
<div class="sortable-elem" data-order="1">1</div>
<div class="sortable-elem" data-order="2">2</div>
<div class="sortable-elem" data-order="3">3</div>
<div class="sortable-elem" data-order="4">4</div>
<div class="sortable-elem" data-order="5">5</div>
<div class="sortable-elem" data-order="6">6</div>
<div class="sortable-elem" data-order="7">7</div>
<div class="sortable-elem" data-order="8">8</div>
<div class="sortable-elem" data-order="9">9</div>
<div class="sortable-elem" data-order="10">10</div>
View on JSFiddle