Sometimes the ge plugin wont load kml via the fetchKml function. When this happens I have to kill the ge plugin processes and then it works fine.
Is there a way to do this within the browser? A setTimeout will catch when it's not loading and I'd like to reset the plugin so it will work.
I would want something like google.earth.reset();
Thanks
There is no reset function, but there is an undocumented kill method for the GEPlugin object.
// where ge is a reference to the plugin.
ge.kill_();
That said there is probably a reason why the kml does not appear to be loading, as nuxy says, if you post and example of the actual code you are using then it would be easier to offer help.
EDIT:
Also rather than using an undocumented method you could just re-load the database which will reset the plugin. Something like the following set up should work well.
var ge = null;
google.earth.createInstance('map3d', initCallback, failureCallback);
var initCallback = function(object) {
ge = object;
ge.getWindow().setVisibility(true);
}
var failureCallback = function(error) {
alert(error):
}
var reset = function() {
document.getElementById('map3d').innerHTML = '';
google.earth.createInstance('map3d', initCallback, failureCallback);
}
To use simply call the reset method.
reset();
Related
I'm trying to convert the JavaScript code
if (window.ifEdit.editIsDirty()) { }
into Typescript. I got as far as the following
var iframe = document.getElementById('ifEdit');
var iWindow = <HTMLIFrameElement>(iframe).contentWindow;
var _editIsDirty = iWindow.editIsDirty();
I get the red squiggles under 'contentWindow' and 'editIsDirty' saying the method/property does not exist on the type. The .ts doesn't compile to a .js file.
I have searched, but did not manage to find a solution.
For the contentWindow part, the problem with your code is that the casting is done wrong, should be:
var iWindow = (<HTMLIFrameElement> iframe).contentWindow;
As for the editIsDirty, it's not a standard property of Window.
If it's something which is added in the environment in which you are running your javascript then you need to declare it like so:
interface IfEdit {
editIsDirty(): boolean;
}
interface Window {
ifEdit: IfEdit;
}
var iframe = document.getElementById("ifEdit");
var iWindow = (<HTMLIFrameElement> iframe).contentWindow;
var _editIsDirty = iWindow.ifEdit.editIsDirty();
Use the code in Playground.
Casting will be through as. this assures .contentWindow is accessible.
const iframe = document.getElementById('embed-player') as HTMLIFrameElement;
if (!iframe) {
// Handle case where iframe not found
return;
}
const contentWindow = iframe.contentWindow;
// Note: You will likely need more null handling for contentWindow's properties
console.log(contentWindow?.document);
Template.prices.rendered = function() {
OrderFormContent = new Meteor.Collection(null);
var orderSubmission = function() {
//code that inserts stuff into the OrderFormContent collection
//the key **sqft** is assigned the value of **4000** };
orderSubmission();
};
Template.prices.helpers({
sqft: function() {
return OrderFormContent.findOne().sqft;
}
});
The code above doesn't load. Meteor tries to create the helper of {{sqft}} but can't because OrderFormContent does not get defined until after the page renders. It appears that Meteor tries to define the helper before the page is even rendered.
But I need to define this helper. And I need to have it defined only after the template is rendered (not created).
I cannot just nest Template.prices.helpers inside Template.prices.rendered.
Clarification:
If I comment out the Template.prices.helpers code the page will load. If I then run OrderFormContent.findOne().sqft manually in the console a value of 4000 is returned.
When I un-comment the Template.prices.helpers code the page fails to load and I get a Exception from Deps recompute function: ReferenceError: OrderFormContent is not defined error.
1) Defining global variables inside a function is against good practices of Javascript, and is invalid in strict mode (and thus will be invalid in the future when strict mode becomes a standard).
2) You can easily achieve your goal without defining helper after rendering. In fact, the error is not thrown when the helper is created, but when it's called. To fix this problem it's enough to include a simple check.
var OrderFormContent = null;
var orderFormContentDep = new Deps.Dependency();
Template.prices.rendered = function() {
OrderFormContent = new Meteor.Collection(null);
...
orderFormContentDep.changed();
};
Template.prices.helpers({
sqft: function() {
orderFormContentDep.depend();
if(!OrderFormContent) return null;
var item = OrderFormContent.findOne();
if(!item) return null;
return item.sqft;
});
});
When I got that error I moved the template helper to the client js and it went away. Only that didn't work for my purposes because it executed too often. So, I put it into an Iron Router route method to be rendered.
I am dynamically adding kml files to google earth. For this, I have written javascript functions to add a kml and to remove a kml. These functions work fine for the first time for a kml. But if called again they do not respond. This happens for each kml that I try to add or remove. If I keep the page on browser for some time, then these functions again respond once and again become unresponsive.
function add(id, fileurl)
{
var link = ge.createLink('');
var href= fileurl;
link.setHref(href);
var networkLink = ge.createNetworkLink("'" + id + "'");
networkLink.set(link, true, true);
ge.getFeatures().appendChild(networkLink);
}
function remove(id)
{
for(var i=0; i<ge.getFeatures().getChildNodes().getLength(); i++)
{
if(ge.getFeatures().getChildNodes().item(i).getId() == id || ge.getFeatures().getChildNodes().item(i).getId() == "'" + id + "'")
{
id = ge.getFeatures().getChildNodes().item(i).getId();
ge.getFeatures().removeChild(ge.getElementById(id));
break;
}
}
The issue is that you can't re-add a feature using an ID that you have already used until all references to it have been released. This is usually done by the internal garbage collector - but you can also force it by calling release() on the object you are deleting. This ...
Permanently deletes an object, allowing its ID to be reused.
Attempting to access the object once it is released will result in an
error.
Also when an object is created with the API the object does not have a base address. In this case, the object can be returned by passing only its ID to getElementById(). This can then be used to remove the feature.
e.g.
function remove(id) {
ge.getElementById(id).release();
}
Really though I would look to avoid using IDs altogether and would simply keep a variable that points to the feature, then use that to remove. e.g.
function add(fileurl) {
var link = ge.createLink(''); //no id
link.setHref(fileurl);
var networkLink = ge.createNetworkLink(''); //no id
networkLink.set(link, true, true);
ge.getFeatures().appendChild(networkLink);
return networkLink;
}
var link1 = add("http://yoursite.com/file.kml");
var link2 = add("http://yoursite.com/file2.kml"); // etc...
// then to remove, simply...
link1.release();
link2.release();
OK. So I figured out that if you remove an object from GE, and then try to add another object with the same id, GE complains and won't create the object - unless some time (approx. 30 seconds in my case) has passed. This time actually is required by JavaScript to garbage collect the object.
Setting the object to null doesn't give immediate result but may help Garbage Collector.
Also release() method offered by GE does not help.
I used Flash player 10, and Flex SDK 3.4. The code as followings:
// Following comes callbacks
function imageLoadOpenCallback(evt:Event):void
{
trace("in--open");
}
function imageLoadCompleteCallback(evt:Event):void
{
trace("in--load");
var fr:FileReference = evt.target as FileReference;
trace(fr.data);
}
function imageLoadErrorCallback(evt:IOErrorEvent):void
{
trace("in--ioerror");
}
function imageSelectCancelCallback(evt:Event):void
{
trace("in cancel");
}
function imageSelectCallback(evt:Event):void
{
trace("in -- select");
for (var i:int=0; i<frl.fileList.length; i++)
{
frl.fileList[i].addEventListener(Event.OPEN, imageLoadOpenCallback);
frl.fileList[i].addEventListener(Event.COMPLETE, imageLoadCompleteCallback);
frl.fileList[i].addEventListener(IOErrorEvent.IO_ERROR, imageLoadErrorCallback);
frl.fileList[i].load();
trace(frl.fileList[i]);
trace(frl.fileList[i].creationDate);
trace(frl.fileList[i].creator);
trace(frl.fileList[i].data);
trace(frl.fileList[i].name);
}
}
// Following comes UI handlers
function onAddPictures():void
{
var imageFilter:FileFilter = new FileFilter("Images", "*.jpg;*.png");
frl.addEventListener(Event.SELECT, imageSelectCallback);
frl.addEventListener(Event.CANCEL, imageSelectCancelCallback);
frl.browse([imageFilter]);
}
Only the imageSelectCancelCallback handler get called when I select some files in the dialog. But no load/open/io_error handler get called at all. I have Google some code example, in which it used FileReference instead of FileReferenceList. I don't know the reason, could you please help me?
In Air the fileReference objects in fileReferenceList do not fire the complete event when doing fileList[i].load(). In a Flex project it works fine. Adobe has not responded to bug reports on this appropriately.
Make sure in your compiler settings for flex, that you have at least 10.0.0 for "Use a specific version".
The main reason to use FileReferenceList instead of FileReference would be if you need to upload multiple files at once. If you only want to allow uploading one file at once, simply use FileReference.
Some clarification: imageSelectCallback(), and NOT imageSelectCancelCallback(), should get called when you select some files in the file browser AND click OK. imageSelectCancelCallback() is only called when you click Cancel.
Other than that, I never used the load() API, but I did use the upload(URLRequest) API. I am not sure what's your use case, but if you need to upload an image to a server, you should use the upload() method.
Speaking of upload events, I experienced some reliability issues when listening to Event.COMPLETE events, so I actually got better results listening to DataEvent.UPLOAD_COMPLETE_DATA.
I have a custom validation function in JavaScript in a user control on a .Net 2.0 web site which checks to see that the fee paid is not in excess of the fee amount due.
I've placed the validator code in the ascx file, and I have also tried using Page.ClientScript.RegisterClientScriptBlock() and in both cases the validation fires, but cannot find the JavaScript function.
The output in Firefox's error console is "feeAmountCheck is not defined". Here is the function (this was taken directly from firefox->view source)
<script type="text/javascript">
function feeAmountCheck(source, arguments)
{
var amountDue = document.getElementById('ctl00_footerContentHolder_Fees1_FeeDue');
var amountPaid = document.getElementById('ctl00_footerContentHolder_Fees1_FeePaid');
if (amountDue.value > 0 && amountDue >= amountPaid)
{
arguments.IsValid = true;
}
else
{
arguments.IsValid = false;
}
return arguments;
}
</script>
Any ideas as to why the function isn't being found? How can I remedy this without having to add the function to my master page or consuming page?
Try changing the argument names to sender and args. And, after you have it working, switch the call over to ScriptManager.RegisterClientScriptBlock, regardless of AJAX use.
When you're using .Net 2.0 and Ajax - you should use:
ScriptManager.RegisterClientScriptBlock
It will work better in Ajax environments then the old Page.ClientScript version
Also you could use:
var amountDue = document.getElementById('<%=YourControlName.ClientID%>');
That will automatically resolve the client id for the element without you having to figure out that it's called 'ctl00_footerContentHolder_Fees1_FeeDue'.
While I would still like an answer to why my javascript wasn't being recognized, the solution I found in the meantime (and should have done in the first place) is to use an Asp:CompareValidator instead of an Asp:CustomValidator.