Placing a floating info panel - css

I'm using Jame Ferreira's Google Script: Enterprise Application Essentials to create a product page (Chapter 5). I've created the app that displays thumbnails of the products all on a page, and then the info panel with more detail that pops up when the user mouses over. It's using CSS to achieve this styling.
Problem comes in when placing the info panel. It pops up in only one location, as opposed to being tied to the thumbnail with which it is associated.
Here's the code related to the info panel. I believe the problem exists in the placement of the last few lines, but have tried everything I can think of:
function onInfo(e){
var app = UiApp.getActiveApplication();
var id = e.parameter.source;
for (var i in productDetails){
if(productDetails[i].id == id){
var r = 50;
var c = 0;
var infoPanel = app.createVerticalPanel().setSize('300px', '300px');
var horzPanel = app.createHorizontalPanel();
var image = app.createImage(productDetails[i].imageUrl).setHeight('100px');
var title = app.createLabel(productDetails[i].title);
horzPanel.add(image);
horzPanel.add(title);
var description = app.createLabel(productDetails[i].description);
infoPanel.add(horzPanel);
infoPanel.add(description);
applyCSS(infoPanel, _infoPanel);
applyCSS(image, _infoImage);
applyCSS(horzPanel, _infoBoxSeparator);
applyCSS(title, _infoTitle);
applyCSS(description, _infoDescription);
app.getElementById('infoGrid').setVisible(true)
.setWidget(0,0, infoPanel);
break;
}
c++
if (c == 3){
c = 0;
r = r+250;
}
switch (c)
{
case 0:
c=250;
break;
case 1:
c=500;
break;
case 2:
c=250;
break;
}
}
var _infoLocation =
{
"top":r+"px",
"left":c+"px",}
applyCSS(infoPanel, _infoLocation);
return app;
}

You may get the position of the mouse using e.parameter.x and e.parameter.y based on which you can position the infoPanel
infoPanel.setStyleAttribute('top',e.parameter.y)
.setStyleAttribute('left',e.parameter.x).setStyleAttribute('zIndex','1')
.setStyleAttribute('position','fixed');
You may add some offset to x and y positions of mouse to display it according to your needs.
Position related parameter which you get in handler function are
e.parameter.x
e.parameter.y
e.parameter.clientX
e.parameter.clientY
e.parameter.screenX
e.parameter.screenY

Related

Player character won't go in front of buildings

Ok, so I managed to get all the buildings to stay in place, but now for some reason, the player character won't go in front of the buildings.
I tried switching the places in the code where the if the command for checking if the character's going behind the building and the if-else for checking if it's going in front of the code, but nothing changed.
here's the code:
var _dg = depth_grid;
var _inst_num = instance_number(obj_depth_buildings);
//below is for resizing the grid
ds_grid_resize(depth_grid,2, _inst_num);
//below adds instance info to grid
var _yy = 0;
with (obj_depth_buildings)
{
_dg[# 0,_yy] = id;
_dg[# 1,_yy] = y;
_yy++;
}
//below sorts the grid so that the ones with the biggest y variables end up at the top
ds_grid_sort(_dg,1,false);
//below goes through the grid and identifies everything
var _inst;
_yy = 0;
repeat (_inst_num)
{
//below pulls out an id
_inst = _dg[# 0, _yy];
//below gets the instance execute depth
with(_inst)
{
_inst.depth= layer_get_depth("collision") + _yy;
with (obj_nonbuilding_depths)
{
if object_index.y > _inst.y
{
object_index.depth = (_inst.depth + 1);
}
else if object_index.y <= _inst.y
{
object_index.depth = (_inst.depth - 1);
}
}
}
_yy++;
}
you should change the object depth by change the leyar depth in GMS2

Very simple if else check in Google App Maker

This is likely embarrassingly easy but I'm new and I've been beating my head against the wall on this for a while now. What I am attempting to do is basically a modified version of the "Hello App Maker!" If else test.
The necessary info I have the following widgets attached to the appropriate data sources:
Dropdown widget called source_name (string - list)
Label widget I've called name (string)
Text Box widget called qty_duration (number)
Label widget I've called hours (number)
I have a dropdown widget called source_name with 5 options. On selection I have the value appear in a label widget I've called name. If the option selected from the drop down widget is ever LABOUR I am trying to then have the value of a Text Box widget called qty_duration appear in a label widget I've called hours
On the source_name dropdown event - onValueChange I have the following code:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget = nothing;
}
It's not giving me any errors, but it's also not outputting to the hours label. If I edit the code as follows just to muck with it:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = nothing;
}
I'm not sure what I'm doing wrong.
Assuming all labels and input widgets are inside a table row you will want to adjust your code as follows:
var tablerow = widget.parent;
var nameWidget = tablerow.descendants.name.text;
var outputWidget = tablerow.descendants.hours;
var techhours = tablerow.descendants.qty_duration.value;
if(nameWidget === 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = null;
}
By using widget.parent in the onValueChange event of the dropdown you will automatically reference the table row and then by using descendants you are referencing only the descendants of that table row. This will bridge the error by using an absolute reference when using table rows. If it still doesn't work let me know.

xpages view panel display computed icon

I'm trying to display an icon in a view panel based on a column value. This page will display if I only display the column value and/or use a static database image. If however I try to compute the image based on the column value I get an Http Code 500 error. Looking at the error-log I see two errors, the first is CLFAD0211E: Exception thrown and the second CLFAD0246E: Exception occurred servicing request for .
I have reviewed this simple explanation on how to add a dynamic icon (https://www.youtube.com/watch?v=27MvLDx9X34) and other similar articles and still not working. Below is the code for the computed icon.
var urlFull:XSPUrl = new XSPURL(database.getHttpURL());
var url = urlFull.getHost();
var path = "/icons/vwicn";
// var idx = rowData.getColumnValues().get(1); Removed for testing
var idx = "82.0"; //Hard coded the value for testing
if (idx < 10){
path += ("00" + idx).left(3);
}else if (idx < 100){
path += ("0" + idx).left(3);
}else {
path += idx.left(3);
}
path += ".gif";
//path = "/icons/vwicn082.gif"; I have also tried hard coding the path value - still a no go
url = setPath(path);
url.removeAllParameters();
return url.toString();
The view panel is configured as xp:viewPanel rows="40" id="viewPanel1" var="rowData".
Any suggestions on what to look for or a better option to compute a view panel icon would be appreciated.
Cheers!!!
You have a typo: url = setPath(path);should be url.setPath(path);

OpenLayer Popups for markers imported from google spreadsheet

I'm looking for a way to use framecloud type popup with my current setup. Unfortunately all my attempts have either not worked or will only work on the most recently placed maker.
In the course of trying to get it to work I have converted my original script from using Markers to using Vectors to placing the marker points (as I've seen that it's easier to customize vectors than markers.)
Now which ever one I can get to work I'll use, but after working on this for a few days I'm at my wits end and need a helping hand in the right direction.
My points are pulled from a google spreadsheet using tabletop.js. The feature is working how I wish it to, with the markers being placed on their respective layer based on a field I called 'type'.
While I have a feeling that might have been the source of my problem with the Markers type layer, I'm not sure how to fix it.
You can view the coding through these pages
(Links removed due to location change.)
Thanks for all help in advance.
I finally got it to work. For anyone in a similar situation here's my final code for the layers. I did change the names of the layers from what they are originally and blacked out the spreadsheet I used, but the changes should be noticeable.
//
//// Set 'Markers'
//
var iconMarker = {externalGraphic: 'http://www.openlayers.org/dev/img/marker.png', graphicHeight: 21, graphicWidth: 16};
var iconGeo = {externalGraphic: './images/fortress.jpg', graphicHeight: 25, graphicWidth: 25};
var iconAero = {externalGraphic: './images/aeropolae.jpg', graphicHeight: 25, graphicWidth: 25}; // Image is the creation of DriveByArtist: http://drivebyartist.deviantart.com/
var vector1 = new OpenLayers.Layer.Vector("1");
var vector2 = new OpenLayers.Layer.Vector("2");
var vector3 = new OpenLayers.Layer.Vector("3");
// Pulls map info from Spreadsheet
//*
Tabletop.init({
key: 'http://xxxxxxxxxx', //Spreadsheet URL goes here
callback: function(data, tabletop) {
var i,
dataLength = data.length;
for (i=0; i<dataLength; i++) { //following are variables from the spreadsheet
locName = data[i].name;
locLon = data[i].long;
locLat = data[i].lat;
locInfo = data[i].info;
locType = data[i].type; // Contains the following string in the cell, which provides a pre-determined output based on provided information in the spreadsheet: =ARRAYFORMULA("<h2>"&B2:B&"</h2><b>"&G2:G&"</b><br /> "&C2:C&", "&D2:D&"<br />"&E2:E&if(ISTEXT(F2:F),"<br /><a target='_blank' href='"&F2:F&"'>Read More...</a>",""))
locLonLat= new OpenLayers.Geometry.Point(locLon, locLat);
switch(locType)
{
case "Geopolae":
feature = new OpenLayers.Feature.Vector(
locLonLat,
{description:locInfo},
iconGeo);
vector1.addFeatures(feature);
break;
case "POI":
feature = new OpenLayers.Feature.Vector(
locLonLat,
{description:locInfo},
iconMarker);
vector2.addFeatures(feature);
break;
case "Aeropolae":
feature = new OpenLayers.Feature.Vector(
locLonLat,
{description:locInfo},
iconAero);
vector3.addFeatures(feature);
break;
}
}
},
simpleSheet: true
});
map.addLayers([vector1, vector2, vector3]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
//Add a selector control to the vectorLayer with popup functions
var controls = {
selector: new OpenLayers.Control.SelectFeature(Array(vector1, vector2, vector3), { onSelect: createPopup, onUnselect: destroyPopup })
};
function createPopup(feature) {
feature.popup = new OpenLayers.Popup.FramedCloud("pop",
feature.geometry.getBounds().getCenterLonLat(),
null,
'<div class="markerContent">'+feature.attributes.description+'</div>',
null,
true,
function() { controls['selector'].unselectAll(); }
);
feature.popup.autoSize = true;
feature.popup.minSize = new OpenLayers.Size(400,100);
feature.popup.maxSize = new OpenLayers.Size(400,800);
feature.popup.fixedRelativePosition = true;
feature.popup.overflow ="auto";
//feature.popup.closeOnMove = true;
map.addPopup(feature.popup);
}
function destroyPopup(feature) {
feature.popup.destroy();
feature.popup = null;
}
map.addControl(controls['selector']);
controls['selector'].activate();
}

Flex 4 Printing Error with dynamic components

I have a set of components that are added to my Flex 4 stage dynamically.
Problem 1:
How do I address these objects when adding them to print.I cant generate objects on the fly and append them because then the print manager does not wait for the dynamic data to populate.
I currently use the following code to address items dynamically which fails:
public function PrintDashPreview():void{
var ItemsDrawn:int = 0;
var printJob:FlexPrintJob = new FlexPrintJob();
if(printJob.start()){
for each (var item:Object in GetDashBoardPreviewItems.lastResult.DashboardItem)
{
ItemsDrawn ++
this.addElement(dashPreview["flexShape" + TheID]);
printJob.addObject(dashPreview["flexShape" + TheID]);
this.removeElement(dashPreview["flexShape" + TheID]);
}
printJob.send()
Alert.show('Sent: ' + ItemsDrawn + ' items to page for printing.','Print Progress Debug');
}
}
How can I tell flex to grab these specific items and add them to the print job.
Problem 2:
How do I tell flex to lay each item out one below the other 2 per page.
Please and thank you for any help you can provide.
Regards
Craig Mc
The recipe for printing dynamic content usually goes like this:
(1) Start the printJob:
printJob = new FlexPrintJob();
printJob.printAsBitmap = false;
printJob.start();
(2) Obtain the print page dimensions. Use it if you have overflowing content:
printerPageHeight = printJob.pageHeight;
printerPageWidth = printJob.pageWidth;
(3) Create all of the dynamic objects and wait for the corresponding CREATION_COMPLETE events:
var componentsToBeInitialized:Number = 0;
var pages:Array = [];
for each (var itemData:Object in dataProvider) {
var component:UIComponent = new PageComponent();
someContainerOnTheDisplayList.addChild(component);
component.data = itemData;
componentsToBeInitialized ++;
pages.push(component);
component.addEventListener(FlexEvent.CREATION_COMPLETE, handlePageCompletion);
}
(4) Waiting for all CREATION_COMPLETE events:
function handlePageCompletion(e:Event):void {
componentsToBeInitialized --;
if (componentsToBeInitialized == 0)
printAllPages();
}
(5) Print the pages:
function printAllPages():void {
for each (var printPage:UIComponent in pages) {
printJob.addObject(printPage);
}
printJob.send();
}

Resources