Mouse position shifting after binding click event - html

I am binding a click event to generate a content-editable textbox.
Following is the code which I use to achieve that
$('.clickable-div').bind('click', function(ev) {
var $div = $(ev.target);
var offset = $div.offset();
var x = ev.clientX - offset.left;
var y = ev.clientY - offset.top;
$("#main-div")
.append(
'<div class="handle bar" style="top:'+y+'px;left:'+x+'px">');
});
The problem is when I click on the page, the textbox appears as expected but the mouse position moves abruptly to another location on the page.
Also this unexpected behaviour occurs only under following two conditions together:
1) When something is written in the text box and then new click is made to generate another text box.
2) When page is scrolled and the old textbox is no more visible.
Below are the snapshots of the ideal and the faulty cases
Any help will be appreciated.

Related

Wrong code in tutorial for event listeners

I am following this tutorial to build a store locator page with a Mapbox map.
I don't want to add custom markers because I already have custom map labels (symbols?), which means I don't need the optional last section of the tutorial and stop right after Add Event Listeners.
Once this is completed, the page should react to clicks in the side panel list, as well as on the map (2 event listeners). However, in the demo provided in the tutorial for that particular step, you can tell the code for the second event listener, the one making the map clickable, is not functioning, which makes me believe there is a mistake in the provided code:
// Add an event listener for when a user clicks on the map
map.on('click', function(e) {
// Query all the rendered points in the view
var features = map.queryRenderedFeatures(e.point, { layers: ['locations'] });
if (features.length) {
var clickedPoint = features[0];
// 1. Fly to the point
flyToStore(clickedPoint);
// 2. Close all other popups and display popup for clicked store
createPopUp(clickedPoint);
// 3. Highlight listing in sidebar (and remove highlight for all other listings)
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
// Find the index of the store.features that corresponds to the clickedPoint that fired the event listener
var selectedFeature = clickedPoint.properties.address;
for (var i = 0; i < stores.features.length; i++) {
if (stores.features[i].properties.address === selectedFeature) {
selectedFeatureIndex = i;
}
}
// Select the correct list item using the found index and add the active class
var listing = document.getElementById('listing-' + selectedFeatureIndex);
listing.classList.add('active');
}
});
Would anyone be able to tell what is wrong with this code?
Turns out the code is incomplete in that the cursor doesn't change to a pointer as you hover over a map label/marker so it doesn't clue you into realising you can click on it, hence my assumption it wasn't working at all. I assume the general users who would then face the map would be equally deceived unless the pointer shows up. So in the tutorial, if you do go ahead and click the marker, it will have the expected behaviour and display the popup, although no pointer is shown.
Here is how to create the pointer, based on this fiddle: https://jsfiddle.net/Twalsh88/5j70wm8n/25/
map.on('mouseenter', 'locations', function(e) {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'locations', function() {
map.getCanvas().style.cursor = '';
});

knowing the location of where a user has clicked

I am looking at creating a webpage with user feedback where the user can click within a certain element of the page, which brings up a comment box for the user to enter details, if the user left a note a post-it note would be left where they clicked. this note indication has to move when the user scrolls so that the note does not move away from the element it was left on.
Is this possible? I have been trying to search this on google but I only seem to get how to disable right click.
If it is possible where could I find the relevant information.
Cheers
To get via JS the coordinates where a user has clicked:
(function() {
window.onmousedown = handleMouseMove;
function handleMouseMove(event) {
event = event || window.event; // IE-ism
console.log(event.clientX);
console.log(event.clientY);
}
})();
Here you have an example of how to move a DIV where user clicks:
(function() {
window.onmousedown = handleMouseMove;
function handleMouseMove(event) {
event = event || window.event; // IE-ism
console.log(event.clientX);
moveDiv(event.clientX,event.clientY);
}
})();
function moveDiv(x_pos,y_pos){
var d = document.getElementById('myDiv');
d.style.left = x_pos + "px";
d.style.top = y_pos + "px";
}
Example
First, get mouse click coordinates: getting the X/Y coordinates of a mouse click on an image with jQuery
Than put element with 'position: absolute' at specified location.

Toggle widget visibility with single button

The following code should write the inverse of true/false as found in the textbox back into the textbox when the button is clicked - but it doesn't work correctly. It will work correctly one way, but not the other (the one that works is whichever ClickHandler was defined last). I've tried using validateNotMatches too but no joy.
If I change the code so that the label's text is updated instead of the textbox's then that works fine.
I am aware of suggested workarounds such as using two buttons, but I just want to know if I'm doing something wrong or if this looks like a bug in GAS. Thanks.
function doGet(e)
{
var app = UiApp.createApplication();
var tb = app.createTextBox().setText('true');
var button = app.createButton('button');
var label = app.createLabel().setText('-');
button.addClickHandler(app.createClientHandler()
.validateMatches(tb, 'true')
//.forTargets(label).setText('false')
.forTargets(tb).setText('false')
);
button.addClickHandler(app.createClientHandler()
.validateMatches(tb, 'false')
//.forTargets(label).setText('true')
.forTargets(tb).setText('true')
);
return app.add(app.createHorizontalPanel().add(tb).add(button).add(label));
}
It's not a bug... both events fire. The validation happens on the current state of the widget, not on the state when the event was fired, so after you flip it to "false" the second handler validates and flips it back to "true".

User confirmation from a formatted screen

I developed an app that runs from a Spreadsheet. It has a formatted screen, ie. doc.show(app
). There is a mass change function. I'd like to prompt the user for 'Are you sure ... OK to Continue'.
The ideal solution would be a pop-up form with an "OK to continue" response.
I can't find a way to prompt the user and accept a response that doesn't simultaneously take down the formatted screen.
I know there must be a easy way to do this. I searched this forum and others, but cannot find a solution that applies to Google Spreadsheets.
When using the GUI Builder I've found a very simple solution that is to create a panel or a label that is actually masking the whole UI (or part of it) and that is normally invisible.
When I make it visible I can click on it, it turns invisible again and I'm back on the standard UI. It uses the ability in GUI builder to move elements backwards and forwards so masking is very easy (a sort of multi layer design). I guess the same behavior is achievable with script defined UI but I'm not sure how...
regards,
Serge
EDIT : For information : I just set up an interface using this technique and I noticed that panels that have been made invisible must be restored along with all their elements otherwise they reappear empty. Using Clienthandlers here is an example with two panels and two buttons that do the job :
var panhandler0 = app.createClientHandler()
.forTargets(panel1).setVisible(false);// hide panel1 when button 'ENTER'on panel1 is pressed
enter.addClickHandler(panhandler0);
var panhandler1 = app.createClientHandler()
.forTargets(panel2,msg,grid2).setVisible(true);// show panel2 when button 'ENTER' on panel1 is pressed
enter.addClickHandler(panhandler1);
var panhandler2 = app.createClientHandler()
.forTargets(panel2,msg,grid2).setVisible(true);// re-show panel2 when button 'retry'on panel2 is pressed
retry.addClickHandler(panhandler2);
var panhandler3 = app.createClientHandler()
.forTargets(panel2).setVisible(false);// hide panel2 when button 'retry'on panel2 is pressed
retry.addClickHandler(panhandler3);
var panhandler4 = app.createClientHandler()
.forTargets(panel1,txt,grid,hpanel).setVisible(true);// re-show panel1 when button 'retry'on panel2 is pressed
Works nicely !
You can use Browser.MsgBox() and add buttons into it for users confirmation.
Refrence URL
https://developers.google.com/apps-script/class_browser
This is indeed not an easy thing to do. You'll have to use your own GUI (formatted screen) to show the message. This way you can restore the state of your GUI again. Here is an example:
function uiTest() {
var app = UiApp.createApplication().setTitle("UI");
app.add(app.createGrid(1,1).setId('main'));
createGUI(app,{});
SpreadsheetApp.getActive().show(app);
}
function createGUI(app,p) {
var panel = app.createVerticalPanel();
var handler = app.createServerHandler('handler').addCallbackElement(panel);
panel.add(
app.createTextBox().setName('text').setId('text').setText(p.text ? p.text : "")).add(
app.createButton('Do it').addClickHandler(handler));
app.getElementById('main').setWidget(0,0, panel);
}
function handler(e) {
var app = UiApp.getActiveApplication();
var hidden = app.createHidden('oldValues', JSON.stringify(e.parameter));
app.getElementById('main').setWidget(0,0, app.createVerticalPanel().add(
hidden).add(
app.createLabel("Question message")).add(
app.createButton('Ok').addClickHandler(app.createServerHandler('after').addCallbackElement(hidden))));
return app;
}
function after(e) {
var app = UiApp.getActiveApplication();
createGUI(app,JSON.parse(e.parameter.oldValues));
return app;
}
The difficulty will really depend on how much state you need to restore. If none, then it's a lot, lot easier. In this example I restore the value of the textbox. You can type in anything there to see that it will be there after the popup.

how to get a button in an Openlayers popup?

I am trying to put a button inside of an Openlayers popup. While the button appears to display correctly with the following code, the function 'handlerFunc' does not execute when the button is clicked. The segment of code I have posted is all within another function (so handlerFunc is actually a nested function). I'm using JQuery for the button itself. Any ideas on what might be going wrong? Thanks!
var feature = new OpenLayers.Feature(presences, ll);
feature.popupClass = popupClass;
feature.data.popupContentHTML = "<button id='popupButton'>Click me</button>";
feature.data.overflow = (overflow) ? "auto" : "hidden";
feature.data.icon = markerIcon;
$('#popupButton').button();
$('#popupButton').click(handlerFunc);
function handlerFunc() {
// do something
}
Most likely reason is that your button doesn't exist when you bind to a click event. $('#popupButton') returns null. Instead of using $('#popupButton').click(handlerFunc); try $('#popupButton').live('click', handlerFunc);. That means that we bind to an event not only when DOM is built, but when object appears.