GeoXml3 Display Custom Field From KML File In A DIV Tag - geoxml3

I am trying to get data from a custom field in the KML file to display in the div id=summary section when that KML file is selected from either the map or the sidebar. I just simply copied the sidebar html to make a summary html section and wanted the content from the KML at (Document/Folder/Placemark/summary.text) to be displayed in that div tag.
<table style="width:100%;">
<tr>
<td>
<div id="loaddiv">Loading.....    please wait!
<br />
</div>
<div id="map_canvas">
</div>
</td>
<td>
<div id="sidebar" style="width:300px;height:600px; overflow:auto"></div>
</td>
<td>
<div id="summary" style="width:300px;height:600px; overflow:auto"></div>
</td>
</tr>
<tr>
<td colspan="2">
<div id="link"></div>
</td>
</tr>
</table>
I feel like this may require some function overrides from the geoxml3.js file. I saw a section that had the below in geoxml3.js and it seemed like there may need to be something added to pull info from the KML file.
placemark = {
name: geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
description: geoXML3.nodeValue(node.getElementsByTagName('description')[0]),
styleUrl: geoXML3.nodeValue(node.getElementsByTagName('styleUrl')[0]),
id: node.getAttribute('id')
};
Website with summary table column next to the sidebar column:
https://s20.postimg.cc/6jjcrnke5/geo1.png
KML files XML view:
https://s20.postimg.cc/4eyzqkqh9/geo2.png

Create the below functions:
function showSummary(pm, doc) {
summaryHtml = geoXmlDoc[doc].placemarks[pm].summary;
document.getElementById("summary").innerHTML = summaryHtml;
}
function clickPoly(poly, polynum, doc) {
google.maps.event.addListener(poly, "click", function() {
showSummary(polynum, doc);
});
}
In the function useTheData(doc) add clickPoly(placemark.polygon, i, j); under the line highlightPoly(placemark.polygon, i, j); and add clickPoly(placemark.polyline, i, j); under the line highlightPoly(placemark.polyline, i, j);.
Lastly add showSummary(pm, doc); to the first line in the function kmlPlClick(pm, doc).

create a custom parse function for the custom tag in your KML (parses that information from the KML and populates a custom field in the object processed by geoxml3
example: http://www.geocodezip.com/geoxml3_test/votemap_address2.html)
// Custom placemark parse function
function parsePlacemark (node, placemark) {
var summaryNodes = node.getElementsByTagName('summary');
var summary = null;
if (summaryNodes && summaryNodes.length && (summaryNodes .length > 0)) {
placemark.summary = geoXML3.nodeValue(summaryNodes[0]);
}
}
add code to put that information in the <div> on a click (from #PieDev's answer):
function showSummary(pm, doc) {
summaryHtml = geoXmlDoc[doc].placemarks[pm].summary;
document.getElementById("summary").innerHTML = summaryHtml;
}
function clickPoly(poly, polynum, doc) {
google.maps.event.addListener(poly, "click", function() {
showSummary(polynum, doc);
});
}
function kmlPlClick(pm,doc) {
showSummary(pm, doc);
if (geoXmlDoc[doc].placemarks[pm].polyline.getMap()) {
google.maps.event.trigger(geoXmlDoc[doc].placemarks[pm].polyline,"click", {vertex: 0});
} else {
geoXmlDoc[doc].placemarks[pm].polyline.setMap(map);
google.maps.event.trigger(geoXmlDoc[doc].placemarks[pm].polyline,"click", {vertex: 0});
}
}
function useTheData(doc){
var currentBounds = map.getBounds();
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
// Geodata handling goes here, using JSON properties of the doc object
sidebarHtml = '<table><tr><td>Show All</td></tr>';
geoXmlDoc = doc;
for (var j = 0; j<geoXmlDoc.length;j++) {
if (!geoXmlDoc[j] || !geoXmlDoc[j].placemarks || !geoXmlDoc[j].placemarks.length)
continue;
for (var i = 0; i < geoXmlDoc[j].placemarks.length; i++) {
var placemark = geoXmlDoc[j].placemarks[i];
if (placemark.polygon) {
if (currentBounds.intersects(placemark.polygon.bounds)) {
makeSidebarPolygonEntry(i,j);
}
var kmlStrokeColor = kmlColor(placemark.style.color);
var kmlFillColor = kmlColor(placemark.style.fillcolor);
var normalStyle = {
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.width,
strokeOpacity: kmlStrokeColor.opacity,
fillColor: kmlFillColor.color,
fillOpacity: kmlFillColor.opacity
};
placemark.polygon.normalStyle = normalStyle;
highlightPoly(placemark.polygon, i, j);
clickPoly(placemark.polygon, i, j);
}
if (placemark.polyline) {
if (currentBounds.intersects(placemark.polyline.bounds)) {
makeSidebarPolylineEntry(i,j);
}
var kmlStrokeColor = kmlColor(placemark.style.color);
var normalStyle = {
strokeColor: kmlStrokeColor.color,
strokeWeight: placemark.style.width,
strokeOpacity: kmlStrokeColor.opacity
};
placemark.polyline.normalStyle = normalStyle;
highlightPoly(placemark.polyline, i, j);
clickPoly(placemark.polyline, i, j);
}
if (placemark.marker) {
if (currentBounds.contains(placemark.marker.getPosition())) {
makeSidebarEntry(i,j);
}
}
}
}
sidebarHtml += "</table>";
document.getElementById("sidebar").innerHTML = sidebarHtml;
};
working example

Related

select2 v4 dataAdapter.query not firing

I have an input to which I wish to bind a dataAdapter for a custom query as described in https://select2.org/upgrading/migrating-from-35#removed-the-requirement-of-initselection
<input name="pickup_point">
My script:
Application.prototype.init = function() {
this.alloc('$pickupLocations',this.$el.find('[name="pickup_point"]'));
var that = this;
$.fn.select2.amd.require([
'select2/data/array',
'select2/utils'
], function (ArrayData, Utils) {
var CustomData = function($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
};Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
var data = {
results: []
};
console.log("xxx");
for (var i = 1; i < 5; i++) {
var s = "";
for (var j = 0; j < i; j++) {
s = s + params.term;
}
data.results.push({
id: params.term + i,
text: s
});
}
callback(data);
};
that.$pickupLocations.select2({
minimumInputLength: 2,
language: translations[that.options.lang],
tags: [],
dataAdapter: CustomData
});
});
}
But when I type the in the select2 search box the xxx i'm logging for testing doesn't appear in my console.
How can I fix this?
I found the solution on
https://github.com/select2/select2/issues/4153#issuecomment-182258515
The problem is that I tried to initialize the select2 on an input field.
By changing the type to a select, everything works fine.
<select name="pickup_point">
</select>

How to get table row image in PDF using jsPDF?

i have a html table with images.When i was trying to convert as PDF Only data are coming.Image not displaying in PDF.
How to get table td images in pdf ?
Contract Title Contains a Checkbox image.But is not coming in pdf ?
my pdf code :
function fnExportDIVToPDF() {
var pdf = new jsPDF('l', 'pt', 'a2');
pdf.setFontSize(8);
source = $('#divReport')[0];
specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true
}
};
margins = {
top: 30, bottom: 40, left: 10, width: 1300};
pdf.fromHTML(
source, margins.left, margins.top, {
'elementHandlers': specialElementHandlers},
function (dispose) {
pdf.save('Report.pdf');
}
, margins);
}
Div:
<div id="divReport">
<div width="100%">
<p><span id="oHeadingSummary" class="rptheader"></span></p>
</div>
<table class="table table-striped rpttable" border="1" cellspacing="0" id="oReportContractDetailsByCA" width="100%">
<colgroup>... <col width="10%">
</colgroup></table>
Autogenerate table i added a image :
function GenerateTable(data) {
document.getElementById('divExport').style.display = "";
if (i == 0) {
$('#oReportContractDetailsByCA').append("<tr style='background-color:" + bkColor + ";'><td><img src='../../../_layouts/15/1033/IMAGES/eContracts/checked-checkbox-512.jpg'></img></td></tr>")
}
You can use the didDrawCell hook to add any content to a cell.
https://codepen.io/someatoms/pen/vLYXWB
function generate() {
var doc = new jsPDF();
doc.autoTable({
html: '#mytable',
bodyStyles: {minCellHeight: 15},
didDrawCell: function(data) {
if (data.column.index === 5 && data.cell.section === 'body') {
var td = data.cell.raw;
// Assuming the td cells have an img element with a data url set (<td><img src="data:image/jpeg;base64,/9j/4AAQ..."></td>)
var img = td.getElementsByTagName('img')[0];
var dim = data.cell.height - data.cell.padding('vertical');
var textPos = data.cell.textPos;
doc.addImage(img.src, textPos.x, textPos.y, dim, dim);
}
}
});
doc.save("table.pdf");
}

syncing jquery ui select menu with knockout observable array

probably going about this the wrong way but I have an html table that is populated using a knockout observable array using foreach. in each row I have a drop down. I like the jquery ui select menu so I am using that. unfortunately when you run the fiddle you will notice that when updating the drop down the corresponding knockout selected value is not being updated.
here is the fiddle https://jsfiddle.net/8rw4ruze/3/
here is the html.
<table class="table table-condensed table-responsive">
<thead>
<th>id</th>
<th>animal</th>
<th>Selected Value</th>
</thead>
<tbody data-bind="foreach: tableRows">
<tr>
<td data-bind="text: id"></td>
<td>
<select class="form-control" data-bind="options: recordList,
optionsText: 'desc',
optionsValue: 'val',
value: selectedVal,
attr: {id: selectId}">
</select>
</td>
<td data-bind="text: selectedVal"></td>
</tr>
</tbody>
</table>
and here is the javascript
function record(val, desc) {
var self = this;
this.val = ko.observable(val);
this.desc = ko.observable(desc);
}
function tableRow(id, recordList) {
var self = this;
this.id = ko.observable(id);
this.recordList = ko.observable(recordList)
this.selectedVal = ko.observable('A');
this.selectId = ko.computed(function() {
return 'mySelect' + self.id()
}, this);
}
function Model() {
var self = this;
this.records = ko.observableArray("");
this.tableRows = ko.observableArray("");
}
var mymodel = new Model();
$(function() {
mymodel.records.push(new record('A', 'ant'));
mymodel.records.push(new record('B', 'bird'));
mymodel.records.push(new record('C', 'cat'));
mymodel.records.push(new record('D', 'dog'));
mymodel.tableRows.push(new tableRow(1, mymodel.records()));
mymodel.tableRows.push(new tableRow(2, mymodel.records()));
mymodel.tableRows.push(new tableRow(3, mymodel.records()));
mymodel.tableRows.push(new tableRow(4, mymodel.records()));
ko.applyBindings(mymodel);
for (var i = 0; i < 4; i++) {
var id = '#mySelect' + (i + 1)
$(id).selectmenu({
width: 125,
change: function(event, ui) {
var newVal = $(this).val();
mymodel.tableRows()[i].selectedVal(newVal);
}
});
}
});
thanks all I went with a data attribute. I'd prefer to use the custom binding but I'm not smart enough to figure that out so I went with this.
for (var i = 0; i < 4; i++) {
var id = '#mySelect' + (i + 1)
$(id).selectmenu({
width: 125,
change: function(event, ui) {
var newVal = $(this).val();
var index = $(this).data( "index" );
mymodel.tableRows()[index].selectedVal(newVal);
}
}).data( "index", i );
}
here is the fiddle https://jsfiddle.net/8rw4ruze/7/
I think I got it working with the custom binding here it is
https://jsfiddle.net/8rw4ruze/8/
Matt.k is correct that your value of i is not what you want it to be when it is used. One way around that is to use this loop instead of a simple for:
$('select').each(function (i, e) {
e.selectmenu({
width: 125,
change: function(event, ui) {
var newVal = $(this).val();
mymodel.tableRows()[i].selectedVal(newVal);
}
});
});
This is a little fragile, as it relies on the i and the e to correspond correctly. A more robust (and typical in Knockout) approach is to use a binding handler, which would allow you to specify the binding and have Knockout go through the elements and make the necessary calls. Surprisingly, a little web-searching didn't turn one up for me.
I see there is a knockout-jqueryui project on github that might also give you a clean way of using the widgets you want.

Kendo UI and knockout.js rowTemplate sorting

I have a MVC site where I use Kendo UI and knockout.js to display the pages. One scenario is to get the database information from server through $.getJSON and then display this information on a KendoUI grid.
<div data-bind="kendoGrid:{sortable:true, data:users, rowTemplate:'userRowTemplate'}>
<table>
<thead>
<tr>
<th>Username</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead> </table>
</div>
<script type="text/html">
<tr>
<td data-bind="text: Username"></td>
<td data-bind="text: FirstName"></td>
<td data-bind="text: LastName"></td>
<tr>
</script>
and the javascript :
<script type="text/javascript">
var ViewModel = function () {
var self=this;
self.users=ko.mapping.fromJS([]);
$getJSON("/UserManagementController/GetUsers",function(data){
ko.mapping.fromJS(data,{},self.users);
});
};
$(document).ready(function(){
var newViewModel=new ViewModel();
ko.applyBindings(newViewModel);
});
</script>
I want this data to be sortable on specific columns (the ones specified here are for example's sake), but I haven't been able to achieve this successfully. I have tried the solution from this knockout-kendo plugin issue post, which works well on simple objects, but does not work on observables. So my question is : how to map data from database through MVC controller to observables in knockout and displaying them in a Kendo grid, but still be able to sort them?
Thanks,
Alex Barac
You can do this by creating a JS view model to represent the data coming back from the server, and mapping the data into the view model. Then you can have simple objects that get set by subscribing to the matching observable properties to implement the sort.
Here is an example:
http://jsfiddle.net/R4Jys/1/
HTML:
<div data-bind="kendoGrid: gridOptions(myList)"></div>
<script id="rowTmpl" type="text/html">
<tr>
<td>
<span data-bind="text: firstName" />
</td>
<td>
<span data-bind="text: lastName" />
</td>
<td>
<span data-bind="text: userName" />
</td>
</tr>
</script>
JavaScript:
var gridItem = function () {
var self = this;
self.firstName = ko.observable();
self.firstNameSort;
self.firstName.subscribe(function (value) {
self.firstNameSort = value;
});
self.lastName = ko.observable();
self.lastNameSort;
self.lastName.subscribe(function (value) {
self.lastNameSort = value;
});
self.userName = ko.observable();
self.userNameSort;
self.userName.subscribe(function (value) {
self.userNameSort = value;
});
self.other = ko.observable('test');
return self;
};
var vm = function() {
var self = this;
self.myList = ko.observableArray();
self.test = ko.observable();
self.gridOptions = function (data) {
return {
data: data,
rowTemplate: 'rowTmpl',
useKOTemplates: true,
scrollable: true,
sortable: true,
columns: [
{
field: "firstNameSort",
title: "First Name",
width: 130
},
{
field: "lastNameSort",
title: "Last Name",
filterable: true
},
{
field: "userNameSort",
title: "Username"
}
]
}
};
var data = [{'firstName':'Steve', 'lastName':'Jones', 'userName': 'steve.jones'},
{'firstName':'Janet', 'lastName':'Smith', 'userName': 'janet.smith'},
{'firstName':'April', 'lastName':'Baker', 'userName': 'april.baker'},
{'firstName':'Dave', 'lastName':'Lee', 'userName': 'dave.lee'},
{'firstName':'Jack', 'lastName':'Bennet', 'userName': 'jack.bennet'},
{'firstName':'Chris', 'lastName':'Carter', 'userName': 'chris.carter'}];
self.myList(ko.utils.arrayMap(data, function(item) {
var g = new gridItem();
ko.mapping.fromJS(item, {}, g);
return g;
}));
};
var pageVm = new vm();
ko.applyBindings(pageVm);
As an alternative you can modify the kendo.web.js (version 2013.3.1119) on line 6844 & 6844.
Replace
compare: function(field) {
var selector = this.selector(field);
return function (a, b) {
a = selector(a);
b = selector(b);
With
compare: function(field) {
var selector = this.selector(field);
return function (a, b) {
a = ko.utils.unwrapObservable(selector(a));
b = ko.utils.unwrapObservable(selector(b));
By using the knockout utility "ko.utils.unwrapObservable" you can get the value of the observable for use when kendo compares the values of the column
DEFINE CUSTOM COMPARE FUNCTION will serves solution, where you can override the comparing function in field definition.
So you can do something like this:
$("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
columns: [{
field: "item",
sortable: {
compare: function(a, b) {
var valueA = a["item"];
var valueB = b["item"];
if (typeof valueA === "function") valueA = valueA();
if (typeof valueB === "function") valueB = valueB();
if (this.isNumeric(valueA) && this.isNumeric(valueB))
{
valueA = parseFloat(valueA);
valueB = parseFloat(valueB);
}
if (valueA && valueA.getTime && valueB && valueB.getTime)
{
valueA = valueA.getTime();
valueB = valueB.getTime();
}
if (valueA === valueB)
{
return a.__position - b.__position;
}
if (valueA == null)
{
return -1;
}
if (valueB == null)
{
return 1;
}
if (valueA.localeCompare)
{
return valueA.localeCompare(valueB);
}
return valueA > valueB ? 1 : -1;
}
}
}]
});
private isNumeric(input)
{
return (input - 0) == input && ('' + input).trim().length > 0;
}
The compare method is stolen from kendo script, but change is where the property is typeof function (what ko.observable is), it unwraps the value. Plus, I added support for numbers.

load data from db knockoutjs + mv3

attached the file EXAMPLE: http://jsfiddle.net/brux88/9fzG4/1/
hi,
I'm starting to use knockoutjs in an asp.net mvc project.
i have a view :
<button data-bind='click: load'>Load</button>
<table>
<thead>
<tr>
<th>Cliente</th>
<th>Colli</th>
<th>Tara</th>
<th>Peso Tara</th>
<th> </th>
</tr>
</thead>
<tbody data-bind='foreach: righe'>
<tr>
<td>
<select data-bind="
value: selectedCli,
options: clienteList,
optionsText: function(item) { return item.Rscli + '-' + item.Codcli },
optionsCaption: '--Seleziona un Cliente--'"
style=" width: 150px">
</select>
</td>
<td >
<input data-bind='value: Ncolli' />
</td>
<td>
<select data-bind="value: selectedTara,
options: taraList,
optionsText: function(item) { return item.Destara +
'-' + item.Codtara},
optionsCaption: '--Seleziona un Cliente--'"
style=" width: 150px">
</select>
</td>
<td >
<input data-bind="value: Ptara" />
</td>
<td>
<a href='#' data-bind='click: $parent.rimuoviRiga'>Elimina</a>
</td>
</tr>
</tbody>
</table>
<button data-bind='click: aggiungiRiga'>Aggiungi</button>
<button data-bind='click: salva'>Salva</button>
<button data-bind='click: annulla'>Annulla</button>​
my result from data db:
[{"Codcli":4,"Rscli":"antonio","Codtart":"1002","Despar":"ciliegino","Ncolli":10,"Pcolli":100,"Codtara":"03","Destara":"","Ptara":82,"Pnetto":18,"Prezzo":1},{"Codcli":1,"Rscli":"bruno","Codtart":"1001","Despar":"pomodoro","Ncolli":10,"Pcolli":100,"Codtara":"03","Destara":"","Ptara":10,"Pnetto":90,"Prezzo":1}]
my viewmodel knockoutjs:
<script type="text/javascript">
var listCli= [{Codcli: 1,Rscli: "Bruno"},{Codcli: 2,Rscli: "Pippo"},{Codcli: 3,Rscli: "Giacomo"}];
var listTa= [{Codtara: 01,Destara: "Plastica",Pertara:4},{Codtara: 02,Destara: "Legno",Pertara:6},{Codtara: 03,Destara: "Ploto",Pertara:8}];
var mydataserver = [{"Codcli":3,"Rscli":"Giacomo","Ncolli":10,"Codtara":"03","Destara":"Legno","Ptara":82},{"Codcli":1,"Rscli":"Bruno","Ncolli":10,"Codtara":"02","Destara":"Plastica","Ptara":10}];
var RigaOrdine = function () {
var self = this;
self.selectedCli = ko.observable();
self.clienteList = ko.observableArray(listCli);
self.Ncolli = ko.observable();
self.selectedTara = ko.observable();
self.taraList = ko.observableArray(listTa);
self.Ptara = ko.observable();
self.Ncolli.subscribe(function () {
self.Ptara(self.Ncolli() ? self.selectedTara().Pertara * self.Ncolli() : 0);
});
self.selectedTara.subscribe(function () {
self.Ptara(self.Ncolli() ? self.selectedTara().Pertara * self.Ncolli() : self.selectedTara().Pertara);
});
};
var Ordine = function () {
var self = this;
self.righe = ko.observableArray([new RigaOrdine()]); // Put one line in by default
// Operations
self.aggiungiRiga = function () {
self.righe.push(new RigaOrdine());
};
self.rimuoviRiga = function (riga) {
self.righe.remove(riga);
};
self.salva = function() {
var righe = $.map(self.righe(), function (riga) {
return riga.selectedCli() ? {
Codcli: riga.selectedCli().Codcli,
Rscli: riga.selectedCli().Rscli,
Ncolli: riga.Ncolli(),
Codtara: riga.selectedTara().Codtara,
Ptara: riga.Ptara(),
} : undefined;
});
alert( ko.toJSON(righe));
//save to server
/* $.ajax({
url: "/echo/json/",
type: "POST",
data: ko.toJSON(righe),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
}
});*/
self.righe([new RigaOrdine()]);
};
//load from server
self.load = function() {
$.ajax({ url: '/echo/json/',
accepts: "application/json",
cache: false,
statusCode: {
200: function (data) {
alert(ko.toJSON(mydataserver));
//i do not know apply to viewmodel
},
401: function (jqXHR, textStatus, errorThrown) {
alert('401: Unauthenticated');
// self.location = "../../Account/Login.html?returnURL=/Index.html";
}
}
});
};
self.annulla = function() {
self.righe([new RigaOrdine()]);
};
};
var viewmodel = new Ordine();
ko.applyBindings(viewmodel);
​
</script>
if I want to load data from a db, how do I? Whereas there are dropdownlist
Your question is a bit weak so I will give you a more general answer.
To answer your question regarding how to load data from a db, it looks like that you have started on the right track. Usually you use an AJAX request to do the async request of data. To do this, knockoutJS provides the following function:
$.getJSON("/some/url", function(data) {
// Now use this data to update your view models,
// and Knockout will update your UI automatically
})
Source: http://knockoutjs.com/documentation/json-data.html
In the callback provided you will have access to the data returned from the server. It depends on the logic of your application what you want to do here - for some applications it might make sence to update the state of the viewmodel to make corresponding updates in the view.
If your question is more specific, please elaborate. Otherwise, I hope I got you on the right track.
As i can see.. you may want some good pratice to load.
I'll share with you mine.
Well.. return a Json as an JsonResult.
// POST: /Client/LoadClient
[HttpPost]
public JsonResult LoadClient(int? id)
{
if (id == null) return null;
var client = _business.FindById((int) id);
return Json(
new
{
id = cliente.id,
name = cliente.name,
list = cliente.listOfSomething.Select(s => new {idItemFromList = s.idWhatever, nameItemFromList = s.nameWhatever})
});
}
JS
viewmodel.Client.prototype.LoadClient= function (id) {
var self = this;
if (id == 0) {
return null;
}
$.ajax({
url: actionURL("LoadClient", "Client"),
data: { id: parseInt(id) },
dataType: "json",
success: function (result) {
if (result != null)
self.Load(result);
}
});
Load method.
viewmodel.Client.prototype.Load = function (result) {
var self = this;
self.idClient(result.id);
self.nameCliente(result.name);
self.ListOfSomething(result.list);
};
and..
ko.applyBinding(yourModel);
as u can see I'm using prototype it's a good practice too.

Resources