What's the best way to cancel an upload in progress using filepicker.io? - filepicker.io

I'm using filepicker.makeDropPane to play around with some simple uploads. One thing that I cannot find in the docs at filepicker.io's web documentation is a method for canceling an upload that is in progress.
Intuitively I feel that the onStart function should be passed an additional parameter. An object that represents the upload that has a cancel() function which when called would immediately cancel the file uploads. Something like this does not seem to be available.

we don't actually have this functionality yet, but it makes sense. I'll take a look at adding something along these lines and let you know

Here's an ugly hack I figured out to protect against unwanted returned files as well some other fancy stuff around progress and multiple files etc. You definitely want to use a static js file include so it doesn't get changed on you and break this.
Use this in your progress handler:
var event = event || window.event;
// For firefox, go and grab the XHR progress event object.
if (typeof event == 'undefined' || event == null) {
if (typeof arguments.callee.caller.arguments[0] == 'object') {
event = arguments.callee.caller.arguments[0];
}
else {
event = arguments.callee.caller.arguments.callee.caller.arguments.callee.caller.arguments[0];
}
}
var sUploadId;
if (event.type.toLowerCase() == 'progress') {
// if we haven't already tagged this XHR object (one per file), tag it now
// if we receive further progress from this file, it will already have been tagged
if (!('id' in event.currentTarget)) {
sUploadId = goUploadProgress.files.length;
event.currentTarget.id = sUploadId;
goUploadProgress.files.push({id: sUploadId, total:event.total});
}
else {
sUploadId = event.currentTarget.id;
}
// get the loaded bytes for this file
goUploadProgress.files[sUploadId].loaded = event.loaded;
}
else {
// ignore readystatechange events
return;
}
I modified this to make more sense for this context, so I may have made a logical mistake, but this is the gist. You can get the event in Firefox by looking up the call stack, and you can append an id to each file's XHR upload object, which will exist until it finishes.
I repeat, this is a hack! Don't trust that it won't break.

Related

Angular Ag Grid - Has anyone figured out a way to wait for a cell node update to happen and THEN fire a function, like a callback?

I am utilizing cellChanged.node.setDataValue(fieldChanged, oldValue) inside of the (cellValueChanged) event emitter, and I'm having trouble figuring out how to call a function once the setDataValue function has finished executing. I need to do this to do a check to see if a user has the permission to update a cell.
Here is the full code that checks:
if(this.showPaywallNotification) {
// Okay, so the budget is above what we allow HOWEVER...
if(budget > BUDGET_AMOUNT) {
this.showPaywallNotification = false;
cellChanged.node.setDataValue(fieldChanged, oldValue)
// Note: This timeout is in place to prevent the infinite updating bug
// This is problematic because if the user changes the cells fast enough, they can get around the paywall. If I change the timeout to be smaller, the resulting change triggers the update, which ends up creating an infinite loop of updates.
setTimeout(() => {
this.showPaywallNotification = true;
}, 230)
}
}
Is there a way I can replace my setTimeout() function with something better that can always ensure the user can't get around my paywall by just updating the cell faster than the timeout can execute?
You don't have to do polling. setDataValue is a not an async function.
Also, onCellValueChanged won't get called again if you call node.setDataValue.
Have a look at this plunk: Cell Editing - Revert to old value. Try updating any Age value to negative.
onCellValueChanged($event) {
if ($event.colDef.field === 'age' && $event.newValue < 0) {
// debugger
$event.node.setDataValue('age', $event.oldValue);
console.log('value reverted');
}
}
Let me know if something is not clear, or this is not sufficient.

postMessage() event listener not working

I am working with a 3rd party who supplies a URL to be put into an iFrame to display some hosted video playback.
this is cross-domain
they use JWPlayer as their player of choice
I requested a way to 'know' when the video playback is complete. From reading, looks like the postMessage() callback is what many use.. and is what the 3rd vendor suggested, and mentioned they would implement.
I was given a TEST url that has this 'call back' function in it... and to see if I can could use it.
I can not seem to get any alert from the callback/listener functions?
As this is the first time I am implementing this, Im not sure if the error stems from my end or theirs?
I'm thinking it may be the path form the postMessage() function?
After firebugging the code.. I eventually fund their JS/callback set up here:
jwPI.on('complete', function(event){
playbackTime= playbackTime + (jwPI.getPosition() - positionA);
positionA=jwPI.getPosition();
parent.postMessage('EndVideo','*');
});
My side of things has the simple event listener added like so:
window.addEventListener("message", function(evt) {
//do whatever
alert("VIDEO CALLBACK FIRED");
});
My questions are:
1.) Why is this not working? a target/scope issue?
2.) Do I need to have the 3rd party vendor update the path in their postMessage() callback? where does '.parent' actually point to? (if this is an embedded iFrame?) and there are DIV's..etc..etc..etc housing the nested iFrame content?
my listener function is in the main parent file that loads this iFrame?
3.) Can I just leave it as 'as-is' and somehow change the path/target in my listener?
Solution posted:
here is a both a jQuery and JS solution
** note the jQuery approach need to use originalEvent in the scope
//jQuery approach
$(window).on("message onmessage", function(evt) {
//message
var targetData = evt.originalEvent.data;
//origin
var targetOrigin = evt.originalEvent.origin;
//check origin for security and to make Scott proud
if(targetOrigin !== 'https://example.com'){
//no same origin, exploit attempt in process possibly
}
//do whatever
});
//Javascript approach
window.addEventListener("message", function(evt) {
//message
var targetData = evt.data;
//source
var targetSource = evt.source; //iframe source message stems from - doesnt work
//origin
var targetOrigin = evt.origin;
if(targetOrigin !== 'https://example.com'){
//no same origin, exploit attempt in process possibly
}
//do whatever
});
(Posted an answer on behalf of the question author).
Here is a both a jQuery and JS solution. Note the jQuery approach need to use originalEvent in the scope.
//jQuery approach
$(window).on("message onmessage", function(evt) {
//message
var targetData = evt.originalEvent.data;
//origin
var targetOrigin = evt.originalEvent.origin;
//check origin for security and to make Scott proud
if(targetOrigin !== 'https://example.com'){
//no same origin, exploit attempt in process possibly
}
//do whatever
});
//Javascript approach
window.addEventListener("message", function(evt) {
//message
var targetData = evt.data;
//source
var targetSource = evt.source; //iframe source message stems from - doesnt work
//origin
var targetOrigin = evt.origin;
if(targetOrigin !== 'https://example.com'){
//no same origin, exploit attempt in process possibly
}
//do whatever
});

Having trouble attaching event listener to a kml layer's polygon

Using Google Earth I have a loaded kml layer that displays polygons of every county in the US. On click a balloon pop's up with some relevant info about the state (name, which state, area, etc) When a user clicks the polygon I want the information to also pop up on a DIV element somewhere else.
This is my code so far.
var ge;
google.load("earth", "1");
function init() {
google.earth.createInstance('map3d', initCB, failureCB);
}
function initCB(instance) {
ge = instance;
ge.getWindow().setVisibility(true);
ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
ge.getNavigationControl().setStreetViewEnabled(true);
ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);
//here is where im loading the kml file
google.earth.fetchKml(ge, href, function (kmlObject) {
if (kmlObject) {
// show it on Earth
ge.getFeatures().appendChild(kmlObject);
} else {
setTimeout(function () {
alert('Bad or null KML.');
}, 0);
}
});
function recordEvent(event) {
alert("click");
}
// Listen to the mousemove event on the globe.
google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);
}
function failureCB(errorCode) {}
google.setOnLoadCallback(init);
My problem is that when I change ge.getGlobe() to kmlObject or ge.getFeatures() it doesn't work.
My first question is what should I change ge.getGlobe() to to be able to get a click listener when a user clicks on a kml layer's polygon?
After that I was planning on using getDescription() or getBalloonHtml() to get the polygons balloons information. Am I even on the right track?
...what should I change ge.getGlobe() to...
You don't need to change the event object from GEGlobe. Indeed it is the best option as you can use it to capture all the events and then check the target object in the handler. This means you only have to set up a single event listener in the API.
The other option would be to somehow parse the KML and attach specific event handlers to specific objects. This means you have to create an event listener for each object.
Am I even on the right track?
So, yes you are on the right track. I would keep the generic GEGlobe event listener but extend your recordEvent method to check for the types of KML object you are interested in. You don't show your KML so it is hard to know how you have structured it (are your <Polygon>s nested in <Placemarks> or ` elements for example).
In the simple case if your Polygons are in Placemarks then you could just do the following. Essentially listening for clicks on all objects, then filtering for all Placmark's (either created via the API or loaded in via KML).
function recordEvent(event) {
var target = event.getTarget();
var type = target.getType();
if(type == "KmlPolygon") {
} else if(type == "KmlPlacemark") {
// get the data you want from the target.
var description = target.getDescription();
var balloon = target.getBalloonHtml();
} else if(type == "KmlLineString") {
//etc...
}
};
google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);
If you wanted to go for the other option you would iterate over the KML Dom once it has loaded and then add events to specific objects. You can do this using something like kmldomwalk.js. Although I wouldn't really recommend this approach here as you will create a large number of event listeners in the api (one for each Placemark in this case). The up side is that the events are attached to each specific object from the kml file, so if you have other Plaemarks, etc, that shouldn't have the same 'click' behaviour then it can be useful.
function placeMarkClick(event) {
var target = event.getTarget();
// get the data you want from the target.
var description = target.getDescription();
var balloon = target.getBalloonHtml();
}
google.earth.fetchKml(ge, href, function (kml) {
if (kml) {
parseKml(kml);
} else {
setTimeout(function () {
alert('Bad or null KML.');
}, 0);
}
});
function parseKml(kml) {
ge.getFeatures().appendChild(kml);
walkKmlDom(kml, function () {
var type = this.getType();
if (type == 'KmlPlacemark') {
// add event listener to `this`
google.earth.addEventListener(this, 'click', placeMarkClick);
}
});
};
Long time since i have worked with this.. but i can try to help you or to give you some tracks...
About your question on "google.earth.addEventListener(ge.getGlobe(), 'click', recordEvent);"
ge.getGlobe can not be replaced with ge.getFeatures() : if you look in the documentation ( https://developers.google.com/earth/documentation/reference/interface_g_e_feature_container-members) for GEFeatureContainer ( which is the output type of getFeatures() , the click Event is not defined!
ge.getGlobe replaced with kmlObject: waht is kmlObject here??
About using getDescription, can you have a look on the getTarget, getCurrentTarget ...
(https://developers.google.com/earth/documentation/reference/interface_kml_event)
As I told you, i haven't work with this since a long time.. so I'm not sure this can help you but at least, it's a first track on which you can look!
Please keep me informed! :-)

Preloader in Wicket Application

In a wicket application on search event it takes few secons and sometimes minutes to show the result as its a long data . I want to show a preloader while the data is fetched from the database to let the user know something is going on when they click search . I am very new to wicket application , dont understands the things very deeply but I find AjaxLazyPreloader but as I said I want to show the preloader when the search method is called ...I am sharing the SearchSubmit method ...
private void processSearchSubmit(AjaxRequestTarget ajaxRequestTarget) {
ajaxRequestTarget.add(tableHolder);
ajaxRequestTarget.add(productTableHolder);
if (zipcode == null) {
ajaxRequestTarget
.appendJavaScript("$().toastmessage('showWarningToast','Please enter a zipcode')");
} else if (!ZipCodeValidator.isValid(zipcode)) {
useZones = true;
currentZone = zipcode;
ajaxRequestTarget.add(tableHolder);
if (searchProduct != null) {
ajaxRequestTarget.add(productTableHolder);
if (lstProduct.getList().size() == 0) {
ajaxRequestTarget
.appendJavaScript("$().toastmessage('showErrorToast','Sorry! This product is not avialable .')");
}
}
} else if (lstMerchants.getList().size() == 0) {
ajaxRequestTarget
.appendJavaScript("$().toastmessage('showWarningToast','Sorry! There are currently no services')");
}
if (ZipCodeValidator.isValid(zipcode)) {
ajaxRequestTarget.add(tableHolder);
if (searchProduct != null && !searchProduct.equals("")) {
ajaxRequestTarget.add(productTableHolder);
if (lstProduct.getList().size() == 0) {
ajaxRequestTarget
.appendJavaScript("$().toastmessage('showErrorToast','Sorry! This product is not avialable in this zip code or zone.')");
}
}
}
}
I want when this method is called till the times it fetch the result data , it should show a preloader or spinner . Can anybody suggest how to do that .??
If you need to call long execution method by clicking button check this answer.
You can also use AjaxLazyLoadPanel, check this demo (it's Java part and html part)
Either use an AjaxLazyLoadPanel or an IndicatingAjaxLink/-Button. Both will work fine in either normal or Ajax calls.
To use an AjaxLazyLoadPanel: create a subclass of AjaxLazyLoadPanel which loads the panel you want to display and add it to the AjaxRequest.
IndicatingAjaxLinks just display a spinner while the request is being processed and can be used straightforward in your current application. Use this instead of the button/link you use for formsubmits now.

What is the proper way in OpenLayers (OSM) to trigger a popup for a feature?

I have the feature ID, I can grab the marker layer on GeoRSS loadend, but I'm still not sure how to cause the popup to appear programmatically.
I'll create the popup on demand if that's necessary, but it seems as though I should be able to get the id of the marker as drawn on the map and call some event on that. I've tried using jQuery and calling the $(marker-id).click() event on the map elements, but that doesn't seem to be working. What am I missing?
Since I was asked for code, and since I presumed it to be boilerplate, here's where I am so far:
map = new OpenLayers.Map('myMap');
map.addLayer(new OpenLayers.Layer.OSM());
map.addLayer(new OpenLayers.Layer.GeoRSS(name,url));
//I've done some stuff as well in re: projections and centering and
//setting extents, but those really don't pertain to this question.
Elsewhere I've done a bit of jQuery templating and built me a nice list of all the points that are being shown on the map. I know how to do a callback from the layer loadend and get the layer object, I know how to retrieve my layer out of the map manually, I know how to iter over the layers collection and find my layer. So I can grab any of those details about the popup, but I still don't know how to go about using the built-in methods of the DOM or of this API to make it as easy as element.click() which is what I would prefer to do.
You don't have to click the feature to open a popup.
First you need a reference to the feature from the feature id. I would do that in the loadend event of the GeoRSS layer, using the markers property on the layer.
Assuming you have a reference to your feature, I would write a method which handles the automatic popup:
var popups = {}; // to be able to handle them later
function addPopup(feature) {
var text = getHtmlContent(feature); // handle the content in a separate function.
var popupId = evt.xy.x + "," + evt.xy.y;
var popup = popups[popupId];
if (!popup || !popup.map) {
popup = new OpenLayers.Popup.Anchored(
popupId,
feature.lonlat,
null,
" ",
null,
true,
function(evt) {
delete popups[this.id];
this.hide();
OpenLayers.Event.stop(evt);
}
);
popup.autoSize = true;
popup.useInlineStyles = false;
popups[popupId] = popup;
feature.layer.map.addPopup(popup, true);
}
popup.setContentHTML(popup.contentHTML + text);
popup.show();
}
fwiw I finally came back to this and did something entirely different, but his answer was a good one.
//I have a list of boxes that contain the information on the map (think google maps)
$('.paginatedItem').live('mouseenter', onFeatureSelected).live('mouseleave',onFeatureUnselected);
function onFeatureSelected(event) {
// I stuff the lookup attribute (I'm lazy) into a global
// a global, because there can be only one
hoveredItem = $(this).attr('lookup');
/* Do something here to indicate the onhover */
// find the layer pagination id
var feature = findFeatureById(hoveredItem);
if (feature) {
// use the pagination id to find the event, and then trigger the click for that event to show the popup
// also, pass a null event, since we don't necessarily have one.
feature.marker.events.listeners.click[0].func.call(feature, event)
}
}
function onFeatureUnselected(event) {
/* Do something here to indicate the onhover */
// find the layer pagination id
var feature = findFeatureById(hoveredItem);
if (feature) {
// use the pagination id to find the event, and then trigger the click for that event to show the popup
// also, pass a null event, since we don't necessarily have one.
feature.marker.events.listeners.click[0].func.call(feature, event)
}
/* Do something here to stop the indication of the onhover */
hoveredItem = null;
}
function findFeatureById(featureId) {
for (var key in map.layers) {
var layer = map.layers[key];
if (layer.hasOwnProperty('features')) {
for (var key1 in layer.features) {
var feature = layer.features[key1];
if (feature.hasOwnProperty('id') && feature.id == featureId) {
return feature;
}
}
}
}
return null;
}
also note that I keep map as a global so I don't have to reacquire it everytime I want to use it