Structure of MarkerList array in Wikitude Javascript SDK - javascript

WikiTude Augmented reality JavaScript SDK has an array of markers named markerList. I want to know what is the structure of the array (It is no in the documentation). For example, I want to know how to access the enabled property of a geoObject in markerlist.
Example, can it be like,
World.markerList[i].enabled=false
What the the structure and sub-structures of the markerlist array?
Can I do like the following. Please help. I am really stuck here. I don't want to reload and recreate POIS every time I change my custom slider. I want the GeoOjects to activate and deactivate, so that it would prevent flickering.
marker.js
// Labels and properties described here.
this.markerObject = new AR.GeoObject(markerLocation, {
drawables: {
cam: [this.markerDrawable_idle,this.markerDrawable_selected,this.titleLabel,this.distanceUpdate,this.descriptionLabel],
enabled : true,
indicator: this.directionIndicatorDrawable,
radar: this.radardrawables
}
});
this.markerObject.changeVisibilitysetter= function(markerObject) {
this.markerObject.enabled = false;
}
and call the function from fromwebservice like
World.changeVisibilitysetter(marerList[i].markerObject);

The elements in the array are of type 'Marker'. Such a Marker does not have a enabled property. You need to extend the class with such a setter and in the implementation, access the underlying AR.GeoObject and change it's enabled property.

Related

Using methods for the menu item callbacks in Google Apps Script

So, I am doing a small project in Google Apps Script, to make adding/exporting leads from it...less painful.
How do I plan to do this?
I plan on doing this via adding some Actions menu, for the importing and exporting of leads. The imported sheet will, for now, be assumed to be of the same columns as the Google Sheet this script is bound to. (We can support some sheet column conversion features later, but it's probably a YAGNI for my use case.) The exported sheet will be converted from the columns of this sheet, to some simplified, ready-to-send-to-the-mailers columns.
How do I plan to code this (or how am I coding this)?
I am using MVVM design pattern, and have spent last night plugging away at writing MVVM wrappers for everything that I need to (keeping KISS in mind).
The MenuItemViewModels have some name,functionName that the Google Apps Script seem to be looking for. I note that there is some major pain-in-the-ass limitation, though: Google Apps Script wants function NAME and it cannot be method!
OK, show me some code or gtfo
I have some SpreadsheetPageViewModel that look like this:
class SpreadsheetPageViewModel extends BaseViewModel {
init() {
this.exportVM = new ExportSpreadsheetEditViewModel();
this.importVM = new ImportSpreadsheetEditViewModel();
this.menuVM = new MenuViewModel(new MenuModel(),
[
'exportLeads', // this is utility function. I want/need to use openExport method
'importLeads', // this is utility function. I want/need to use openImport method
]);
this.childEditVM = null;
}
openExport() {
this.childEditVM = this.exportVM;
this.childEditVM.view.doShow();
}
openImport() {
this.childEditVM = this.importVM;
this.childEditVM.view.doShow();
}
}
The business logic for the modals that spawn on menu item click, will live in the child view models to this: the ExportSpreadsheetEditViewModel and ImportSpreadsheetEditViewModel.
I was trying to get around the limitation via this hack:
changing
function onOpen(event) {
// show the menu here....
new SpreadsheetPageView().doShow();
}
to something like:
var mainView;
function onOpen(event) {
mainView = new SpreadsheetPageView();
// show the menu here....
mainView.doShow();
}
and then, in the MenuActionUtils.gs, crawling down that mainView like:
function exportLeads() {
mainView.viewModel.showExport();
}
function importLeads() {
mainView.viewModel.showImport();
}
What was the result of that hack?
It didn't work. Why? Because when Google Apps Script fired that exportLeads (or importLeads), mainView was no longer defined!!
Does this mean I have to give up my approach?
How can I use the main view/view model in the onClick of the menu items?
Failing all that, is there a way to create our menu, using this MVVM design pattern (and some HTML/React/....), and inject it in?
By using Google Apps Script it's not possible to modify the look and feel of a Google Workspace editor (Docs, Forms, Sheets, Slides) custom menu, in other words, it's not possible to use HTML/React for this but you might use them in dialogs/sidebars.
Regarding using a design pattern, you might use any design pattern that you want but you should have in mind that every time that a Google Apps Script is triggered by an event the whole project is loaded, so if you need that some objects persist between events then you should find a place to save those objects.
To store an object you might use the Google Apps Script Properties Service and/or the Cache Service, just bear in mind that you should convert it to JSON before saving it. Also you might use a Google spreadsheet but this has several limitations or you might use an external service, i.e. nosql database, by using Google Apps Script URL Fetch service.
Related
using and modifying global variables within handler functions
Styling a custom spreadsheet menu item using Google Apps Script
How to define global variable in Google Apps Script
Google Apps Script (V8); why can't I use an object instance inside of onOpen?
With #Ruben's help, I was able to get this working!
What I did
I didn't give up on the MVVM/OOP design.
Instead, I created singleton static method on the drive class, like so:
static GetMainInstance() {
if (!this._mainInstance) {
this._mainInstance = new this();
}
return this._mainInstance;
}
and use it instead of directly creating the new drive object.
Also, it is view's responsibility to spawn stuff, so I did some refactoring:
In PageView.gs I added the following methods:
showExport() {
this.viewModel.showExport((childVM) => {
this.editView.viewModel = childVM;
this.editView.doShow();
})
}
showImport() {
this.viewModel.showImport((childVM) => {
this.editView.viewModel = childVM;
this.editView.doShow();
})
}
in the PageViewModel.gs, I changed the methods to accept onDone callback:
showExport(onDone) {
this.childEditVM = this.exportVM;
onDone(this.childEditVM);
}
showImport(onDone) {
this.childEditVM = this.importVM;
onDone(this.childEditVM);
}
Simple fix, it works, while staying consistent with the principles!

Custom and first options in ember-power-select

I'm using Ember-power-select-with-create to make custom selections possible in my dropdowns.
This is the power-select part in the .hbs file.
{{#power-select-multiple-with-create
options=options //array for prefill values
selected=offer.offer //is where we save it to (offer is the model and has an array named offer)
onchange=(action (mut offer.offer)) //default onchange for prefill options
onfocus=(action "handleFocus")
onblur=(action "handleBlur")
oncreate=(action "createOffer" offer.offer) //This calls "createOffer"
buildSuggestion=suggestion
as |offer|}}
{{offer}}
{{/power-select-multiple-with-create}}
The "createOffer" function in my .js file looks like this:
It gets two values passed: selected which is offer.offer and searchText which is the input that the user is trying to add.
createOffer(selected, searchText)
{
if (selected == null)
{
selected = []; //This is what I'm currently trying: if its null initialize it
}
if (selected.includes(searchText)) { //Don't add if it's already added
this.get('notify').alert("Already added!", { closeAfter: 4000 });
}
else { // if it's not yet added push it to the array
selected.pushObject(searchText);
}
}
This code works perfectly fine for adding those that we predefined as well for custom options, however it does not work if it is the first and a custom offer that we try to add to a new group of offers.
I'm assuming it has something to do with the fact that the array is not yet initialized. A pointer to the fact that it is due to the array not being initialized is that I get an error message along the lines of: Can't call pushObject on undefined. And I'm assuming the reason that it works with predetermined values is that ember-power-select probably initializes it somewhere but I couldn't find any documentation about it.
Thanks for your answers!
If anyone ever stumbles upon this, this was the solution
Calling that when we create the offer and then initializing the offer array like that:
offer.set('offer', []);

Leaflet control Joomla issue

I've created a Joomla Component and i have a Leaflet map in the component window.
I've used Leaflet with Omnivore plugin to add GPX and KML to my map and I used the Leaflet controls to allow to add and remove the layers.
I've tested the controls in a clean joomla development installation and the controls are OK, as seen in the first image
enter image description here
When I use the component in my Joomla site che controls are not OK, there are some dirty entry as seen in the second figures
enter image description here
I think this is because of the templates and some script that interfere with Leaflet but I can't fix it.
The joomla versions are the same, the template no, the joomla site use gantry.
This is the function I used to populate the map:
function showRouteTracks(tracce, baseURI, popup=false, enableLayers=true, enableElevation=false){
var layerControl = new Array();
for (var i = 0; i < tracce.length; i++) {
var customLayer = L.geoJson(null, {
style: getStyle(i)
});
if(tracce[i][3]=='GPX'){
var layer = omnivore.gpx(baseURI+tracce[i][2], null, customLayer).on('ready', function() {
elevation(enableElevation,layer);
});
if(popup){
link=''+tracce[i][5]+''
layer.bindPopup(tracce[i][0]+"➝"+tracce[i][1]+"<br/>"+link);
}
lvrtMap.addLayer(layer);
layerControl[tracce[i][0]+"➝"+tracce[i][1]]=layer;
}
if(tracce[i][3]=='KML'){
var layer = omnivore.kml(baseURI+tracce[i][2], null, customLayer).on('ready', function() {
elevation(enableElevation,layer);
});
if(popup){
link=''+tracce[i][5]+''
layer.bindPopup(tracce[i][0]+"➝"+tracce[i][1]+"<br/>"+link);
}
lvrtMap.addLayer(layer);
layerControl[tracce[i][0]+"➝"+tracce[i][1]]=layer;
}
}
if(!enableLayers)
layerControl=null;
if(enableElevation)
L.control.layers(lvrtMapLayers,layerControl,{'position':'bottomright'}).addTo(lvrtMap);
else
L.control.layers(lvrtMapLayers,layerControl).addTo(lvrtMap);
}
Currently you're creating an array to store the title/layer items:
var layerControl = new Array();
But L.Control.Layers takes object literals as baselayer/overlay parameters:
var baseLayers = {
"Mapbox": mapbox,
"OpenStreetMap": osm
};
var overlays = {
"Marker": marker,
"Roads": roadsLayer
};
L.control.layers(baseLayers, overlays).addTo(map);
So you should use an object literal:
var layerControl = {};
You can add items the same way as you did before:
layerControl['MyTitle'] = myLayerInstance;
I'll bet you'll have no problem then. What happening now is that your trying to assign string keys to items in an array, which isn't supported (even supposed to work but that aside). A javascript array can only have numeric keys and nothing else.
That it works for you with a clean install and not in your production setup is that probably in production you have a javascript library/framework loaded which adds methods/properties to javascript's native array prototype and they are enumerable. Thus when the layercontrol instance iterates the array it also finds these extra methods/properties and tries to add them to the layercontrol.
Just use a object literal: {} not an Array, you'll be fine, good luck.
EDIT: Got curious and did some digging. As it turns out this is caused by Mootools and then i ran into this question: Looping through empty javascript array returns array object functions which gives some explanation and some other solutions but it's best if you just use a object literal because at the moment you're kind of abusing Array.

AngularJS Google Map directive map instance

I'm using http://angular-google-maps.org/ it's nice angular google maps library. But i want use map instance which is loaded not in angularjs context by something like this:
$scope.map = {
events: {
tilesloaded: function (map) {
$scope.$apply(function () {
$scope.mapInstance = map;
});
}
}
}
Ok nice i have mapInstance and I CAN use it programmatically. But in application lifecycle this fire to late- so in other words I want to load whole directive (and get map instance) before other code- where I just wan't to use other map events.
In recently looking up ways to get the map instance from the example on the docs page, I came across this instead:
$scope.map.control.getGMap().
Make sure on your google-maps HTML markup, you have the options attribute set as control="map.control" and an empty object set in your $scope.map object.
$scope.map= { control : {}, ...other map options...};
That empty objects is filled when google map is initiated. I hope this helps and isn't too late.
Enjoy Angular!!!

Extjs 4.1 pagingtoolbar default page

I want to change default page of pagination toolbar to 1 of 1 instead 0 of 0 in case of no record.Plus I am not using store proxy to request any records, so is there any way to accomplish it without using store proxy. According to my requirement user can add rows manually to the grid with the pagination toolbar showing page 1 and when rows exceeds 10 it moves to 2nd page.
In Ext it is possible to overload a component like Ext.toolbar.Paging with your own custom version. Simply specify an alias in your definition and you can us it just like the "native control."
In order to be sure that the approach would work, I set up a test project with a simple datasource and implemented enough of a replacement definition that I could see the "Ext.toolbar.Paging".getPagingItems method being fired in my custom definition.
From that point you can replace the code inside the definition of the original method to allow for a custom minimum in addition to the opportunity to overload the "updateInfo" method to make sure that during data reloads you're not plowing through your customizations.
In addition to these two things, you should (with a relatively small amount of effort) be able to implement on top of the control to support dynamically changing it's values based on the contents of your grid.
If you look at the documentation for ux.data.PagingStore you should be able to suss out the differences in using a remotely supplied store from something that is served with data locally.
Hope this helps you.
Code Sample:
Ext.define(
"Test.view.testview.TvPageBar",
{
extend: "Ext.toolbar.Paging",
alias: "widget.tvpagebar",
title: "Bob",
strictInit: function () {
"use strict";
console.log("TvPageBar init");
},
getPagingItems: function () {
console.log("getPagingItems", this);
this.callParent(arguments);
},
initComponent: function () {
this.strictInit();
this.callParent(arguments);
}
}
);

Categories

Resources