ESRI WAB custom widget popup disappears after 1 second - javascript

I am working on an in-panel custom widget for our WebApp on ESRI. When the widget is active the map is listening to mouse click events. When fired, a REST service is called via ajax and the result will be displayed in a popup.
If there is no other layer like WMS/WFS active everything is working fine. But with another active layer, the popup appears for a second and then disappears.
Any idea?
define(['dojo/_base/declare', 'jimu/BaseWidget', 'esri/layers/layer', 'dojo/dom-construct', 'esri/geometry/webMercatorUtils', 'https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'],
function(declare, BaseWidget, Layer, domConstruct, webMercatorUtils) {
var map;
return declare([BaseWidget], {
baseClass: 'jimu-widget-myTest',
name: 'myTest',
customPopup: new Popup({
offsetX: 10,
offsetY: 10,
visibleWhenEmpty: true
},domConstruct.create("div")),
startup: function() {
map = this.map;
this.map._mapParams.infoWindow = this._customPopup;
},
onOpen: function(){
document.getElementById(this.map.id).addEventListener("click", myClickListener);
},
onClose: function(){
document.getElementById(this.map.id).removeEventListener("click", myClickListener);
}
});
function myClickListener(evt) {
if(evt.mapPoint) {
var content = "";
var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint);
lon = mp.x;
lat = mp.y;
var service_url = "xxxxxx";
$.ajax({
method: 'GET',
url: service_url,
dataType: 'json',
error: function() {
console.log("Could not load data.");
},
success: function(result) {
for(var i = 0; i < result.values.length; i++) {
content += "<div class='test'>";
content += "<table style='width:100%'><tr><td><b>bli</b></td><td>" + result.values[i].bli + "</td></tr>" +
"<tr><td><b>bla</b></td><td>" + result.values[i].bla + "</td></tr>" +
"<tr><td><b>blub</b></td><td>" + result.values[i].blub + "</td></tr>";
content += "</table></div>";
}
map.infoWindow.setTitle("myTest");
map.infoWindow.setContent(content);
map.infoWindow.show(evt.screenPoint);
}
});
}
}
});

Problem solved by adding the Listener this way
onOpen: function(){
map.on("click", myClickListener);
},
and not like this
onOpen: function(){
document.getElementById(this.map.id).addEventListener("click", myClickListener);
},

Related

button function is not defined with htmlstring

I am able to display out all the details including the button. However, the main problem is that the when I click the button, nothing happens. It says that BtnRemoveAdmin() is not defined when I inspect for errors. However, I have function BtnRemoveAdmin()?? I have tried to move the function to htmlstring. Nothing works. I am not sure what went wrong.
(function () {
$(document).ready(function () {
showadmin();
});
function showadmin() {
var url = serverURL() + "/showadmin.php";
var userid = "userid";
var employeename = "employeename";
var role ="role";
var JSONObject = {
"userid": userid,
"employeename": employeename,
"role": role,
};
$.ajax({
url: url,
type: 'GET',
data: JSONObject,
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (arr) {
_getAdminResult(arr);
},
error: function () {
alert("fail");
}
});
}
function _getAdminResult(arr) {
for (var i = 0; i < arr.length; i++) {
htmlstring = '<div class="grid-container">' +
'<div>' + arr[i].userid + '</div>' +
'<div>' + arr[i].employeename + '</div>' +
'<div>' + arr[i].role + '</div>' +
'<div>' + '<button onclick="BtnRemoveAdmin()">Remove</button>' + // 'BtnRemoveAdmin' is not defined
'</div>' ;
$("#name").append(htmlstring);
}
function BtnRemoveAdmin() {
var data = event.data;
removeadmin(data.id);
}
}
function removeadmin(userid) {
window.location = "removeadmin.php?userid=" + userid;
}
})();
All your code is defined inside an IIFE.
That includes BtnRemoveAdmin.
When you generate your JavaScript as a string, it is evaled in a different scope.
BtnRemoveAdmin does not exist in that scope.
Don't generate your HTML by mashing strings together.
Use DOM instead.
function _getAdminResult(arr) {
var gridcontainers = [];
for (var i = 0; i < arr.length; i++) {
var gridcontainer = $("<div />").addClass("grid-container");
gridcontainer.append($("<div />").text(arr[i].userid));
gridcontainer.append($("<div />").text(arr[i].employeename));
gridcontainer.append($("<div />").text(arr[i].role));
gridcontainer.append($("<div />").append(
$("<button />")
.on("click", BtnRemoveAdmin)
.text("Remove")
));
gridcontainers.push(gridcontainer);
}
$("#name").append(gridcontainers);
}
I use JQuery, and sometimes I get the same problem with plain JS functions not being called.
So I create JQuery functions :
$.fn.extend({
btnRemoveAdmin: function() {
...//Do what you want here
}
});
To call it use :
<button onclick="$().btnRemoveAdmin();"></button>
Hope it helps you !

Google map : How to create a custom infowindow used custom overlay

i'm a newbie in javascript
use custom overlay but always detect 'cannot read property 'setContent' of undefined'
my javascript code is https://github.com/SaneMethod/CGWin/blob/master/src/cGWin.js
and i use jquery because of parsing Exel file
////https://github.com/SaneMethod/CGWin/blob/master/src/cGWin.js/////
function GenCustomWindow () {
var CustomWindow = function () {
....
}
}
////parsing code////
$(document).ready(function () {
$.ajax({
type: "GET",
url: "",
datatype: "text",
success: function (data) { processData(data); }
});
});
function processData(allText) {
....
var info = new GenCustomWindow();
for(i = 0;i < name.length;i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(a, b),
map: map,
icon: markerImage,
optimized: false
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
content =
'<div class="iw-title">' +
name[i] + '</div>' +
'<div class="iw-content">' +
'<div class="iw-subTitle">' + add[i] + '</div>' +
'</div>' +
'<div class="iw-bottom-gradient"></div>' +
'</div>';
info.CustomWindow.setContent('content');
}
})(marker, i));
}
}
there is always error in info.CustomWindow.setContent
why is this code an error?
and can you recommend another custom infowindow?
GenCustomWindow() returns a CustomWindow, which means info is alread a CustomWindow.
Change
info.CustomWindow.setContent('content');
to
info.setContent('content');
And everything should work fine.

Fullcalendar only loading event after view changed, then wont remove events until view changed again

I am having issues on my live server with fullcalendar. It was working just fine on localhost.
Basically:
when the page loads, it does an ajax call to load all events into the calendar. When the user selects a location, it redoes that ajax request to update all the events in that location. Which it must a) remove the events and b) load the new events returned from the server.
Here is my code:
on page load:
$('#calendar').fullCalendar({
fixedWeekCount: false,
defaultView: 'month',
eventRender: function(event, element) {
element.html('');
var seats_available = (typeof counts[event.post_id] != 'undefined') ? event.seats - counts[event.post_id] : event.seats;
var dateString = moment(event.start).format('YYYY-MM-DD');
var cal = $('#calendar').find('.fc-day-number[data-date="' + dateString + '"]').css('background-color', 'red').addClass('tooltip-here');
var html = '<div><span>Course: </span><p>' + event.title + '</p><br /><span>Seats Available: </span><p>' + seats_available + ' / ' + event.seats + '</p><br /><span>Price: </span><p>R ' + event.cost.toCurrency(2, '.', ',') + '</p><br /><br /><div class="button"><button type="button" class="primary book-course" data-date="' + dateString + '" >Book Course</button></div></div>';
Tipped.create('.tooltip-here[data-date="' + dateString + '"]', html, {position: 'bottom'});
}
});
The get events method:
function getEventData() {
$.ajax({
url: EVENT.ajaxurl, // this is a variable passed through by wordpress
type: 'POST',
dataType: 'json',
data: {
action: 'get_event_data',
selected_location: $('#location-select').val(),
security: NINJA_EVNT.security
},
success: function( res ) {
console.log('#location-select', $('#location-select').val());
console.log('response', res);
var events_raw = JSON.parse(res.data.posts);
counts = res.data.counts;
var events = [];
console.log('events', events);
var seats_available = (typeof counts[events_raw.post_id] != 'undefined') ? events_raw.seats - counts[events_raw.post_id] : events_raw.seats;
$('#calendar').fullCalendar( 'removeEvents'); // this isn't removing the events anymore
for(var i = 0; i < events_raw.length; i++) {
console.log('events_raw[i]', events_raw[i]);
var obj = {
post_id: events_raw[i].post_id,
title: events_raw[i].title,
start: moment(events_raw[i].start_date).toDate(),
seats: events_raw[i].seats,
seats_available: seats_available,
description: events_raw[i].description,
cost: events_raw[i].cost,
eventMouseover : function(data, event, view) {
var content = '<span class="hint--bottom"><h3>'+events_raw[i].title+'</h3>' +
'<p><b>Start:</b> '+moment(events_raw[i].start_date).toDate()+'</p>' +
'<p><b>Seats:</b> '+ seats_available +' / ' + events_raw[i].seats + '</p>' +
'<p><b>Description</b> '+events_raw[i].description+ '</p></span>';
tooltip.set({
'content.text': content
})
.reposition(event).show(event);
}
};
events.push(obj);
console.log('obj', obj);
$('#calendar').fullCalendar('renderEvent', obj, true); // this adds the new events just fine
}
},
error: function( error ) {
console.log('error', error);
}
});
}
UPDATE:
Forgot to add, if I reload the events and the events don't remove, if I go to the next month and back, it loads just fine.
I realized that this was just a latency issue. Putting a loading overlay until it had loaded properly and populated the dropdown worked just fine.

(window).scrollTop function doesn't fire at first click

I have a bar chart which is clickable, and when its clicked, it fires mainQuestBarClick function. In this function, I have this line $(window).scrollTop($('#scrollHere').offset().top); to scroll to scrollHere div. When I click to the bar, it doesn't scroll there but at second time I click it, it scrolls. What could be the reason?
Here is the function:
var mainQuestBarClick = function (event, pos, obj) {
if (!obj)
return;
$(window).scrollTop($('#scrollHere').offset().top);
//goToByScroll($("#scrollHere").attr("id"));
var selectedBranchName = encodeURIComponent(obj.series.label);
$("#SelectedBranchFromBarChart").val(selectedBranchName);
$("#content").block();
//Stats Chart
$.ajax({
type: "GET",
url: '#Url.Action("GetStatsForSpecificBranch", "SurveyReports")',
data: "BranchName="+encodeURIComponent(obj.series.label)+"&SurveyId=" + $("#SurveyId").val() + "&startDate=" + $("#ReportStartDate").val() + "&endDate=" + $("#ReportEndDate").val(),
cache: false,
success: function (r) {
if (r.success == false) {
noty({ text: r.resultText, type: 'error', timeout: 2000, modal: true });
} else {
$("#statboxSurveyCountTitle").html("<b>" + selectedBranchName + "</b> Şubesi Anket Sayısı");
$("#statboxSurveyAvgTitle").html("<b>" + selectedBranchName + "</b> Şubesi Anket Ortalaması");
$("#statboxSurveyRecommTitle").html("<b>" + selectedBranchName + "</b> Şubesi Tavsiye Oranı")
$("#StatboxesDiv").show();
$("#SurveyCountVal").text(r.FilledSurveyCount);
$("#SurveyAvgVal").text(r.FilledSurveyAverageRating.toFixed(2));
$("#SurveyRecommVal").text("%"+r.RecommendYesPercent);
}
},
error: function (error) {
noty({ text: "Bir hata oluştu lütfen tekrar deneyiniz!", type: 'error', timeout: 2000, modal: true });
}
});
$("#content").unblock();
}
This is a late solution to this problem but somehow I managed to do what I want to do. Here is how I solved the problem:
I created a function which takes the id of the element to be scrolled:
function goToByScroll(id){
#{int scroll = 600;
if(Model.BranchList.Count <= 1)
{
scroll = 750;
}
}
// Scroll
$('html,body').animate({scrollTop:#scroll}, 1000);
}
And changed this part in my code above in the question:
$(window).scrollTop($('#scrollHere').offset().top);
to this:
goToByScroll($("#scrollHere").attr("id"));

missing ] after element list json

I'm trying to call getPointOnMap function on the onclick event and to give it an json object as a parameter.
here is code samples:
$.ajax({
type: "POST",
url: "/getResult.json",
success: function(result) {
var html = '';
for (var i = 0; i < result.length; i++) {
var obj = result[i];
html += "<input type='checkbox' onClick='getPointOnMap(" + obj + ")'/>" + obj.address + "<br>";
}
$("#myDiv").append(html);
}
});
here is function getPointOnMap
function getPointOnMap(object) {
map.addMarker({
lat: object.lattitude,
lng: object.longtitude,
click: function(e) {
alert('You clicked in this marker');
}
});
}
firebug output(also in question name):
SyntaxError: missing ] after element list
getPointOnMap([object Object])
what should I do to pass correct object?
I don't think it is allowed to repost a question, anyway you should create your HTML Input not via string but via DOM, so you can attach the handler to the function and not on the "onclick".
$.ajax({
type: "POST",
url: "/getResult.json",
success: function(result) {
for (var i = 0; i < result.length; i++) {
(function (n) {
var obj = result[i],
element = $("<input>", {type: "checkbox"});
element.click(function () {
getPointMap(obj);
});
$(document.body).append(element, obj.address + "<br />");
})(i)
}
}
});
Ok, simple way:
html += "<input type='checkbox' onClick='getPointOnMap(" + obj.lattitude + ", " + obj.longtitude + ")'/>" + obj.address + "<br>";
function getPointOnMap(lat,lng) {
map.addMarker({
lat: lat,
lng: lng,
click: function(e) {
alert('You clicked in this marker');
}
});
}
$.ajax({
type: "POST",
url: "/getResult.json",
success: function(result) {
var myDiv = $('#myDiv');
$.each(result, function(i, obj) {
myDiv.append(
$('<INPUT>').attr('type', 'checkbox').on('click', function() {
getPointOnMap(obj);
},
obj.address,
"<br>"
);
});
}
});

Categories

Resources