OpenLayers.Control.Button's trigger parameter won't get called - button

I'm trying to add a button to the OpenLayers map that is supposed to call a JS function when clicked. I've managed to get it to appear how I would like, but the trigger functionality does not work.
If I have the Control.Navigation present, clicking on the button seems to start a dragging event and I can drag the map by clicking even on that button. But even if I remove all other controls, the button's trigger handler does not get called.
I've also tried adding "autoActivate" parameter (which does not make the control automatically active for some reason anyway), I've tried to call activate() function for the button after I've added it, which seem to toggle the control's "active" property, but it still does not respond to the clicks.
Can someone point me to the right direction, please, or post a working example? My non-working example is below.
Thanks,
Janis
<html>
<head>
<title>OpenLayers.Control.Button</title>
<style text="text/css">
.olControlButton {
position: absolute;
top: 0;
right: 0;
background: red;
width: 22px;
height: 22px;
}
</style>
<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
var map;
var panel;
function buttonClicked()
{
alert ('Button clicked.');
}
function init()
{
map = new OpenLayers.Map ('map', {controls: [/*new OpenLayers.Control.Navigation()*/]});
map.addLayer (new OpenLayers.Layer.WMS ("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'}));
map.zoomToMaxExtent();
panel = new OpenLayers.Control.Panel();
map.addControl (panel);
panel.addControls ([new OpenLayers.Control.Button ({autoActivate: true, displayClass: 'olControlButton', trigger: buttonClicked, title: 'Button is to be clicked'})]);
//panel.controls[0].activate(); <-- this does not help.
}
</script>
</head>
<body onload="init()">
<div id="map" style="border: 2px solid black; height: 500px"></div>
</body>
</html>

The button DIV can't receive click events since the panel DIV (which contains the button) has no dimensions. You should style the panel DIV as well. Also the class given to the button under the panel is olControlButtonItemActive so you need to style it instead of olControlButton.
OpenLayers.Control.Panel handles activation of child controls, to have it activate the button automatically you should set the defaultControl option to button when instantiating a new Panel instance. Otherwise, you'll have to click the button once before you can actually trigger it.
<html>
<head>
<title>OpenLayers.Control.Button</title>
<style text="text/css">
.olControlButtonItemActive {
position: absolute;
top: 0;
right: 0;
background: red;
width: 22px;
height: 22px;
}
.olControlPanel {
width: 50px;
height: 50px;
border: 1px solid black;
}
</style>
<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
var map;
var panel;
function buttonClicked()
{
alert ('Button clicked.');
}
function init()
{
map = new OpenLayers.Map ('map', {controls: [/*new OpenLayers.Control.Navigation()*/]});
map.addLayer (new OpenLayers.Layer.WMS ("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'}));
map.zoomToMaxExtent();
button = new OpenLayers.Control.Button ({displayClass: 'olControlButton', trigger: buttonClicked, title: 'Button is to be clicked'});
panel = new OpenLayers.Control.Panel({defaultControl: button});
panel.addControls([button]);
map.addControl (panel);
}
</script>
</head>
<body onload="init()">
<div id="map" style="border: 2px solid black; height: 500px"></div>
</body>
</html>

Related

How do i open the pickadate.js calender on top of the input field

I have a problem in pickadate calender. I found an issue in pickadate at end of the page please go through the attachment . I have to open the pickadate calendar top of the input field while the input field at the end of the browser.
I have tried below code:
$('#description_award').pickadate({
format: 'yyyy-mm-dd',
formatSubmit: 'mm/dd/yyyy',
min: scriptDate,
max: maxDate,
drops: "up"
});
Specify the root for the picker by using the container-option i.e.: container: '#my-root'. You can put that root element anywhere. And then you can target the picker with css. for example #my-root .picker__holder { bottom:0; } would make it appear above the root (because it's absolutely positioned)
jQuery(document).ready(function(){
jQuery('.datepicker').pickadate({container:"#my-root"});
});
html { padding-top: 150px; /* just for stack-overflow */ }
#my-root { outline: 1px solid red; /* just a visual clue */ }
#my-root .picker__holder { bottom: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pickadate.js/3.5.6/compressed/picker.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pickadate.js/3.5.6/compressed/picker.date.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/pickadate.js/3.5.6/compressed/themes/classic.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/pickadate.js/3.5.6/compressed/themes/classic.date.css" rel="stylesheet"/>
<div id="my-root">
<!-- datepicker will appear where this element is -->
</div>
<input class="datepicker" placeholder="clickme">

Lay a .png image partially over (on top of) menu

I have an accordion menu that I have tweaked to suit my needs. My last stumbling block is that I have an image (see attached image) of a FedEx Courier that I need to lay on top of the menu and yet still allow users to click through it to activate (access) the accordion menu. The image is a separate image that is set to the desired alpha as created in Photoshop. The file is merely a snapshot of how it would look if it was the way I wanted it.
If this is even possible, what code would I use and exactly where would I place it? If in the CSS file, where does it go and between which lines?
Original full size Image file
You can apply the css:
pointer-events: none;
to the image above the links.
See fiddle https://jsfiddle.net/4zgcrkyz/
pointer-events: none; is a suitable solution if you do not need to care about IE < 11. More info on compatibility here.
Alternatively you can use elementFromPoint() which has compatibility IE > 5.5
The following trick allow you to select under your cover image without using pointer-events: none;
https://jsbin.com/tuhotagize/edit?html,output
Explanation:
At click on cover image.
Hide cover image temporary.
Get mouse coordinates.
Get HTML element under that mouse coordinates (so you know what under the cover).
Trigger click event on that HTML element.
Show cover image again.
Another alternative solution to your problem, which does not include any JS is:
Trim your image in PhotoShop as should appear inside the menu. Use CSS background-image property on it
Use the courier FedEx image only as CSS background-image the body of your page.
You can achieve the same visual effect using only CSS.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<style>
img {
position: absolute;
top: 0;
left: 0;
opacity: 0.4;
}
a {
display: block;
width: 300px;
height: 20px;
background-color: greenyellow;
}
a:hover {
background-color: #FF0000;
}
</style>
<script>
window.app = {
show: function () {
document.getElementById('cover').style.display = '';
},
hide: function () {
document.getElementById('cover').style.display = 'none';
},
event: null,
start: function () {
document.getElementById('cover').addEventListener('click', function (event) {
this.hide();
this.event = event;
var target = document.elementFromPoint(event.pageX, event.pageY);
this.show();
target.click();
}.bind(this));
var links = document.querySelectorAll('a');
for (var i = 0, len = links.length; i < len; i++) {
links[i].addEventListener('click', function (event) {
alert('click on ' + event.target.id);
}.bind(this));
}
}
};
</script>
</head>
<body onload="window.app.start();">
<img id="cover" src="http://placehold.it/200x200" />
<a id="a1">link</a>
<a id="a2">link</a>
<a id="a3">link</a>
<a id="a4">link</a>
<a id="a4">link</a>
<a id="a6">link</a>
</body>
</html>

OpenStreetMap overrides map div position

I'm starting to learn the OpenStreetMap / OpenLayers API to put maps in my web app. While I've got to grips with the mapping itself, I've found that the div which contains the map won't stay where I put it. Here's my code so far:
maptest.htm
<html>
<head>
<title>OpenStreetMap Test</title>
<script language="JavaScript" src="/resources/OpenLayers-2.13.1/OpenLayers.js"></script>
<script language="JavaScript" src="/resources/proj4js/lib/proj4js-combined.js"></script>
<script language="JavaScript" src="maptest.js"></script>
</head>
<body onload="init()">
<h2>OpenStreetMap Test</h2>
<div id="map" style="border: 1px solid black; margin-left: auto; margin-right: auto; margin-top: 10%; height: 300px; width:300px;"></div>
</body>
</html>
maptest.js
function init() {
Proj4js.defs["EPSG:27700"] = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs ";
var EPSG27700 = new OpenLayers.Projection("EPSG:27700");
var EPSG900913 = new OpenLayers.Projection("EPSG:900913");
var map = new OpenLayers.Map("map",{
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.LayerSwitcher({'ascending':false}),
new OpenLayers.Control.ScaleLine(),
new OpenLayers.Control.KeyboardDefaults()
]});
var OSM = new OpenLayers.Layer.OSM("OpenStreetMap");
var OSMcycle = new OpenLayers.Layer.OSM("OSM Cycle", ['http://a.tile.thunderforest.com/cycle/${z}/${x}/${y}.png',
'http://b.tile.thunderforest.com/cycle/${z}/${x}/${y}.png',
'http://c.tile.thunderforest.com/cycle/${z}/${x}/${y}.png']);
map.addLayers([OSMcycle,OSM]);
var position = new OpenLayers.LonLat(321550,507250).transform(EPSG27700,EPSG900913);
var markers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(position));
var zoom = 13;
map.setCenter(position,zoom);
}
Without the onload="init()" the div is in the centre of the page, horizontally, and a short way down from the top. However, with init() called, the div snaps back to the left-hand side, just below the title. It still has the correct size and the border, so the CSS styling isn't being ignored completely, but I don't understand why it's not staying in position? I've tried putting the CSS into a stylesheet instead of inline, and the same thing happens.
OpenLayers comes with a default stylesheet that contains the following CSS
div.olMap {
margin: 0 !important;
}
This is overriding your inline css margin-right: auto, margin-left: auto, and margin-top: 10%.
You can fix this by applying your preferred styles to the #map selector in an external style sheet (or internal).
#map {
margin-left: auto !important;
margin-right: auto !important;
margin-top: 10% !important;
}
This works because your reference to an ID'ed selector, #map, has a higher priority than the class'ed selector, .olMap.
Here's a jsfiddle of a working solution.

Inline form editing on client side

I see some web sites use dynamic forms(I am not sure about how to call them!) to edit a group of data. For example: there is a group of data such as name, last name, city, country.etc. when user clicks on EDIT button, instead of doing postback, a form, consisisting of 2 textboxes + 2 comboboxes, dynamically opens to edit,And then when you click on Save button, edit form disappears, and all data updates..
Now, I know what happens over here is using Ajax for server calls and some javascript for dom manipulation.. I even found some jquery plugins for textbox editing.. However, I could not found anything for full implementation of form fields. Therefore I have implemented it on asp.net by jquery ajax calls and dom manipulation manually. here is my process:
1) when Edit button clicked: Make a ajax call to server to retrieve necessary formedit.aspx
2) it returns editable form fields with values assigned.
3) when Save button clicked: make ajax call to server to retrieve formupdateprocess.aspx page. it basically do the database updates and then return necessary DOM snipplet (...) to insert current page..
well ıt works but MY PROBLEM, is performance.. Result seems slower than samples I see in other sites.:((
IS there anything that I dont know? a better way to implement this??
I would keep the edit form on the client, but hidden with e.g. "style="display:none;", and then show it when the user clicks the edit button. Loading a form from the server in this event is very costly performance wise.
This is a very basic example and doesn't consider positioning the edit form etc.
<head>
<script type="text/javascript">
$(function () {
$("#showEdit").click(function () {
$("#editForm").css("display", "block");
});
});
</script>
</head>
<body>
<div id="editForm" style="display: none; position: absolute; z-index: 999;">
<fieldset>
<label for="surnameInput">Surname:</label>
<input id="surnameInput" type="text" />
<label for="firstNameInput">Surname:</label>
<input id="firstNameInput" type="text" />
</fieldset>
</div>
<input id="showEdit" type="button" value="Edit" />
</body>
This does mean your main page will have to carry the edit field values from first load, but very often that is a small price to pay, because the user accepts a wait at that time, not when they click a button.
I've used jQGrid in the past with ASP.NET (MVC doesn't support GridViews).
http://www.trirand.com/blog/
and demos at
http://trirand.com/jqgrid/jqgrid.html
(Check out the Row Editing ones).
Just an idea, but have you looked at Jeditable plugin which allows you to edit inline content?
And here is a tutorial, and the tutorial code with some improvements.
Here is how it is done if you are like me who loathes using plugins now and again.
The HTML:
<div id="pesa"><p>PERSONAL INFORMATION</p>
<ul>
EMAIL:<li class="editable">email</li>
NAME:<li class="editable">name</li>
TELLPHONE:<li class="editable">tel</li>
COUNTRY:<li class="editable">country</li>
CITY:<li class="editable">city</li>
</ul>
Then the CSS to cool things up:
#pesa a{
color: #000;
}
#pesa a:hover{
color: #;
}
#pesa a:hover{
text-decoration: none;
}
h1{
font-size: 30px;
padding: 0;
margin: 0;
}
h2{
font-size: 20px;
}
.editHover{
background-color: #E8F3FF;
}
.editBox{
width: 326px;
min-height: 20px;
padding: 10px 15px;
background-color: #fff;
border: 2px solid #E8F3FF;
}
#pesa ul{
list-style: none;
}
#pesa li{
width: 330px;
min-height: 20px;
padding: 10px 15px;
margin: 5px;
}
li.noPad{
padding: 0;
width: 360px;
}
#pesa form{
width: 100%;
}
.btnSave, .btnCancel{
padding: 6px 30px 6px 75px;
}
.block{
float: left;
margin: 20px 0;
}
Then the JavaScript:
$(document).ready(function()
{
var oldText, newText;
$(".editable").hover(
function()
{
$(this).addClass("editHover");
},
function()
{
$(this).removeClass("editHover");
}
);
$(".editable").bind("dblclick", replaceHTML);
$(".btnSave").live("click",
function()
{
newText = $(this).siblings("form")
.children(".editBox")
.val().replace(/"/g, """);
$(this).parent()
.html(newText)
.removeClass("noPad")
.bind("dblclick", replaceHTML);
}
);
$(".btnDiscard").live("click",
function()
{
$(this).parent()
.html(oldText)
.removeClass("noPad")
.bind("dblclick", replaceHTML);
}
);
function replaceHTML()
{
oldText = $(this).html()
.replace(/"/g, """);
$(this).addClass("noPad")
.html("")
.html("<form><input type=\"text\" class=\"editBox\" value=\"" + oldText + "\" /> </form>Save changes Discard changes")
.unbind('dblclick', replaceHTML);
}
}
);
So when someone hovers over the li items it turns blue just some colour to let the user know they can edit. When they double-click using the dblclick event, a form shows up with the value of the <li> item, just check the code. When they edit in the form and save, the form is removed and a list with the new htmlvalue is placed. You can then use an $ajax method to send the variables to the server side for processing.

ASCX controls and window.onload function

Is it possible for asp.nt ascx controls to have their own client side load event, like a window.onload for each, so I can hide the loading divs and show the content div when http transfer is complete.
I have image menus and cycle galleries that seriously need some loading progress don't know how to implement them. The site is http://techlipse.net. Thx in advance.
There are a few ways you can do this. I would take advantage of the fact that the onload event is not triggered until all content on the page is completely loaded. Since it looks like your site is already using jQuery, all of the examples below will use that.
In your user controls, you can have them hidden by default. To do this, place a style attribute in a wrapper tag for your control:
<div style="display: none">
<!-- Optionally you could use "visibility: hidden"
instead of "display: none". This will keep the
control's placeholder, but not physically show it to the user.
-->
<!-- Your control content here -->
</div>
Inside of your control, you can then have JavaScript code like this (assuming jQuery will be included at the top of the page, which is the way your site is now). This would be placed directly in your control.
<script type="text/javascript">
$(window).load(function() {
$("#" + <%= this.ClientID %>).css("display", "block");
// If you chose to use visibility, try the following line instead
//$("#" + <%= this.ClientID %>).css("visibility", "visible");
});
</script>
To explain how this works...
When the browser initially loads the page, the control defaults to being hidden. It will not be rendered at all. jQuery subscribes to the load() event of your page. When the load event triggers, it will then display the control. This only happens once everything is finished loading.
You can also hide any "loading..." <div /> in this load event also.
Another option, which may be better depending on what you're doing, is to structure your page so you have 2 main divs. A "loading" div and a "content" div. The loading div would be shown by default with a generic loading message. The content div would be hidden by default (or just hidden behind an overly like my example below). The onload event removes the loading objects from the page and allows the images to be shown.
This example below displays a loading message over top of the entire page until it is finished loading.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Dynamic Loading Test</title>
<style type="text/css">
body {
margin: 0px;
padding: 0px;
overflow: hidden/* Prevent user from scrolling. */
} /* Scrolling is re-enabled on load by JavaScript */
.loadingBackground {
background: #000;
filter: alpha(opacity=70); /* internet explorer */
-khtml-opacity: 0.7; /* khtml, old safari */
-moz-opacity: 0.7; /* mozilla, netscape */
opacity: 0.7; /* fx, safari, opera */
height: 100%;
width: 100%;
position: absolute;
}
.loadingWrapper {
position: absolute;
top: 15%;
width: 100%;
}
.loading {
margin: 0 auto;
width: 300px;
text-align: center;
background: #ffffff;
border: 3px solid #000;
}
</style>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function() {
$('.loadingBackground, loadingWrapper, .loading').fadeOut('normal');
$('body').css('overflow', 'auto');
});
</script>
</head>
<body>
<div class="loadingBackground"></div>
<div class="loadingWrapper">
<div class="loading">
Please Wait...<br />
<img src="http://www.ajaxload.info/cache/FF/FF/FF/00/00/00/30-1.gif" />
</div>
</div>
<!-- Large Images included to increase load time to show the loading effect -->
<img src="http://upload.wikimedia.org/wikipedia/commons/3/3c/KillaryHarbour.jpg"
style="height: 100%; width: 100%" />
<img src="http://upload.wikimedia.org/wikipedia/commons/6/6c/Ireland_-_Plains_of_South_Kildare.jpg"
style="height: 100%; width: 100%" />
</body>
</html>
You can add a listener to the load event... ( don't tie into the event directly as you might cause a different tie in to not be called )
Try using a JS library to help you listen to events, YUI, jQuery are fun.
http://developer.yahoo.com/yui/event/#start
var oElement = document.getElementById("myBody");
function fnCallback(e) { alert("i am loaded"); }
YAHOO.util.Event.addListener(oElement, "load", fnCallback);
YUI Library has a way to listen to when an area is "ready"
http://developer.yahoo.com/yui/event/#onavailable
You could have a listener that waits so see when a div is loaded, and then fire off some ajax to your long running processes.

Resources