I'm setting up a custom zoom button and want to implement it. For some reason my defaults aren't applying to the popup.
I've tried including the out of the box structure, but to no avail.
jQuery(function($) {
$(document).ready(function() {
// Create template for zoom button
$.fancybox.defaults.tpl.zoom = '<button class="fancybox-button fancybox-zoom"><div class="zoom"><span class="zoom-inner"></span></div></button>';
// Choose what buttons to display by default
$.fancybox.defaults.buttons = [
'fullScreen',
'thumbs',
'zoom',
'close'
];
$( '.fancybox' ).fancybox({
onInit : function( instance ) {
// Make zoom icon clickable
instance.$refs.toolbar.find('.fancybox-zoom').on('click', function() {
if ( instance.isScaledDown() ) {
instance.scaleToActual();
} else {
instance.scaleToFit();
}
});
}
});
});});
Expected results is an understanding of how to implement the new zoom as well as other buttons.
The first step would be to learn to debug the code. Hit F12 to open developer tools and check Console tab. You will see this JS error message:
Uncaught TypeError: Cannot set property 'zoom' of undefined
And the reason is that you have used tpl instead of btnTpl property, so, replace that and it will work fine - https://codepen.io/anon/pen/OYaxeb?editors=1010
btw, you could also use $.extend() to tweak defaults:
$.extend(true, $.fancybox.defaults, {
btnTpl : {
// Create template for zoom button
zoom : '<button class="fancybox-button fancybox-zoom"><div class="zoom"><span class="zoom-inner"></span></div></button>'
},
// Choose what buttons to display by default
buttons : [
'fullScreen',
'thumbs',
'zoom',
'close'
]
});
Related
We are working with software supplied by a third party, and we are not allowed to modify it, can use only overrides.
I would like to create a new button and overlay it on top of a text input so that they are close together.
I'm having trouble getting the overlay to align, instead it appears top left on the screen. So of course it doesn't align to the text input. Sample code is below, in this case implemented in the view initComponent override after this.callParent([]); is called.
var viewport = Ext.ComponentQuery.query('viewport')[0];
var overlay = viewport.add({
xtype: 'panel',
fullscreen: true,
left: 0,
top: 0,
width: 120,
height: 40,
items:[{
xtype: 'button',
text: 'Find Address',
handler: function() {
alert('Got it!');
}
}],
styleHtmlContent: true
});
var textField = this.query('*[itemId=textField]')[0];
overlay.showBy(textField, 'c-c?');
I've tried using floating: true and lots of other approaches.
Once I get it to position properly, is there a way to have the button respond to tab order correctly? That is, tab out of the text field, then have the button get focus?
As I understand from your question, you have trouble with setting position to a component. If it is the problem, you can set xy coordinate. Look at this fiddle:
https://fiddle.sencha.com/#fiddle/tpl
viewport.down('#idOverlay').setXY([150, 140]);
Edit:
Ext.define('OverriddenViewport', {
override: 'ExampleViewPort',
initComponent: function() {
// Set up first
this.callParent([]);
this.add(overlay);
this.addListener('afterrender', function(viewport) {
viewport.down('#idOverlay').setXY([220,50]);
viewport.down('#idButton').addListener('blur', function(button) {
viewport.down('#idTextfield').focus();
console.log('textfield is focussed');
});
viewport.down('#idTextfield').addListener('blur', function(button) {
viewport.down('#idButton').focus();
console.log('button is focussed');
});
});
}
});
If you can access the source (just to look around) you maybe can create an override of the corresponding class. Create a override, and copy all of the code of the class (form?) into your override.
Here some additional info about creating overrides in ExtJs:
http://moduscreate.com/writing-ext-js-overrides/
https://sencha.guru/2014/12/04/abstract-vs-override/
In your override create a trigger (on the field you want to expand) with your functionality:
{
fieldLabel: 'My Custom Field',
triggers: {
foo: {
cls: 'my-foo-trigger',
handler: function() {
console.log('foo trigger clicked');
}
}
}
}
Thats it I want to create an onclick event on my marker, I'm using angular-openlayers-directive.
So far I've been able to make some markers show up, but I'm unable to get them after a click event.
I would like to perform some actions with these markers custom properties like name, remarks, etc. But it seems too hard to achieve this with openlayers 3.
<openlayers ol-center="ven" height="100vh">
<ol-layer ol-layer-properties="wms">
<ol-marker ng-repeat="marker in markers"
lat="marker.lat"
lon="marker.lon"
></ol-marker>
</ol-layer>
</openlayers>
So how could I handle an onclick event on these markers and get all their info, or a reference to the javascript object "marker" itself.
I wasn't sure if you wanted to have the click on the popover or the marker itself. Below there are instructions for both. Use the Plunker link at the bottom to see a working demo of both options.
To Register Click on Marker Popover:
If you take a look at the directive, you can see that the marker template uses ng-transclude, so you can do the following:
Markup:
<ol-marker ol-marker-properties="santiago" >
<p ng-click="showDetails(santiago)">Santiago de Compostela</p>
</ol-marker>
In your controller:
$scope.showDetails = function(id) {
alert('lat: '+ id.lat+', '+'lon: '+id.lon);
};
Here I'm passing in the marker object to the showDetails function. When you click the popover label for Santiago de Compostela in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
To Register Click on the Marker:
You can add an onClick property to the marker object as follows:
In your controller:
finisterre: {
lat: 42.907800500000000000,
lon: -9.265031499999964000,
label: {
show: false,
},
onClick: function (event, properties) {
console.log(properties);
alert('lat: '+ properties.lat+', '+'lon: '+properties.lon);
}
}
When you click the marker associated with finisterre in the Plunker Demo, you'll see the corresponding lat/lon in the alert.
NOTE:
I could only get this to work though under the following conditions:
The marker object must have a label property defined
The show property of the label must be set to false.
The ol-marker html element must have some transcluded content OR the message property must be set in the marker label object.
I was able to use CSS to prevent the popover from displaying as you can see in the demo, but it seems a little hacky. If you want the popover to display on click as well, you're all set, just remove the css hidden class I added and add your pop-over html.
Plunker Demo
I just got this working today as it happens. What I am doing for now is adding the properties to my markers once I get them from mongo.
function addMarkerProperties ()
// needed to enable click events on a marker!
// Have a label property defined for the marker.
// Have the show property of the label set to false.
// Have some transcluded content in the marker.
{
for (var i = $scope.markers.length - 1; i >= 0; i--) {
$scope.markers[i].onClick = function (event, properties) { console.log('Clicked a marker'); console.log(this); console.log(properties); };
$scope.markers[i].label = {
// Note: Duplication of data here # message. Fix this later.
"message": $scope.markers[i].name,
"show": false,
"showOnMouseOver": false
};
};
}
Once the markers have all the properties they need. It just sort of works but I do have a bug to iron out as well where the marker titles repeat above the map for.... reasons.
As you click the markers the words disappear.
With the latest release (April 6 2016) of the angular-openlayers-directive library (correct) ngClick-handling seems to be implemented. After a bit of searching I came up with the following solution:
The HTML (simplified):
<html ng-controller="mapController">
<openlayers width="100%" height="400px">
<ol-marker ng-repeat="marker in markers" ol-marker-properties="marker" ng-click="showDetails(marker)"></ol-marker>
</openlayers>
</html>
The Angular Javascript for the map controller (expects that your API endpoint called '/api/markerlist' returns a list of JSON objects with the fields: 'latitude', 'longitude'):
$scope.markers = [];
$scope.initializeMarkers = function() {
var markerList = $http.get("yoursite/api/markerlist")
.succes( function(result) {
angular.forEach(result, function(value, key) {
$scope.markers.push({
lat: value.latitude,
lon: value.longitude,
label: {
message: "Your message",
show: false,
showOnMouseOver: false
}
});
});
}
function showDetails(marker) {
alert('Clicked a marker on the map');
console.log(marker);
}
Finally, be sure that you have included the angular-openlayer-directive CSS, so the messages for the labels are not visible.
I have a problem.
I have a list of tweets to show in a page. For mobile devices I don't want to show the right vertical scrollbar.
I've build the page, with its slider and its tweets list. Then I put this page in a scroll container.
Then I return the scroll container.
The code is this:
sap.ui.jsview("ttest.initView", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* #memberOf ttest.initView
*/
getControllerName : function() {
return "ttest.initView";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* #memberOf ttest.initView
*/
createContent : function(oController) {
var oTweetList = new sap.m.List("items", {
threshold: 2,
inset : false,
showUnread : true,
scrollToLoad : true,
columns : [
new sap.m.Column({
styleClass : "data",
hAlign : "Left",
})
]
});
var oSlider = new sap.m.Slider({
id: "tweetSlider",
width: '100%',
min: 0,
change : function(oEvent){
//Update tweet list
var startIndex = 0;
var endIndex = this.getValue();
oController.updateTweetList("update", startIndex, endIndex);
}
});
var oPage = new sap.m.Page({
title: "Tweet list for #matteorenzi",
enableScrolling : false,
headerContent: [
new sap.m.Button({
icon: "sap-icon://refresh",
press : function(oEvent){
//Update tweet list with all tweets
oController.updateTweetList("first", "", "");
}
})
],
content: [
oSlider,
oTweetList
]
});
var oScroller = new sap.m.ScrollContainer({
vertical : true,
horizontal : false,
content : [
oPage
]
});
oEventBus.subscribe("it.besolution.PopulateList", "Go", function(chId, evId, data){
var template = new sap.m.ColumnListItem({
type : "Navigation",
cells : [
new it.besolution.Tweet({
user : "{user/name}",
username : "{user/screen_name}",
tweet : "{text}",
press : function(oEvent){
var path = this.getBindingContext().getPath();
sap.ui.getCore().byId("iduserDetails").setModel(oGlobalModel).bindElement(path);
app.to("iduserDetails");
}
})
]
});
oSlider.setMax(oGlobalModel.getProperty("/size") - 1);
oTweetList.setModel(oGlobalModel);
oTweetList.bindAggregation("items", "/tweets/", template);
});
return oScroller;
}
});
The page didn't load. I don't know how to do. Why the list is invisible?
Obviously, if I remove the scroll container and I return the oPage element, the list is visible.
Why? How I have to write my code to show the list without the scrollbar?
If you don't want to show the right vertical scrollbar. There is a property called enableScrolling.And you really want to use ScrollContainer, put it as Page content, not the other way around.
enableScrolling default: true
Whether the Page takes special measures to make page content scrollable and keep headers fixed. If set to false, there will be no scrolling at all; for performance reasons this is highly recommended when scrolling is not needed. The Page only allows vertical scrolling because horizontal scrolling is discouraged in general for full-page content. If it still needs to be achieved, disable the Page scrolling and use a ScrollContainer as full-page content of the Page. This allows you to freely configure scrolling. It can also be used to create horizontally-scrolling sub-areas of (vertically-scrolling) Pages.
I have this plugin that I want to be enabled in WYSIWYG and Source modes. Here is the simple code:
(function()
{
CKEDITOR.plugins.add('oovideo',
{
init : function(editor)
{
editor.addCommand('oovideo', new CKEDITOR.dialogCommand('oovideo'));
editor.ui.addButton('OOVideo',
{
label: 'OOVideo',
command: 'oovideo',
icon: 'http://www.google.com/favicon.ico',
modes : { source : 1, wysiwyg : 1, enhancedsource : 1 }
});
CKEDITOR.dialog.addIframe(
'oovideo',
'OOVideo',
'http://www.example.com/', 450, 500,
null, null
);
}
});
})();
Currently the button will only pull up the iFrame dialog when in WYSIWYG mode.
Because I added modes : { source : 1, wysiwyg : 1, enhancedsource : 1 } in the button control, the button is not grayed out in all modes, but the button will only function in WYSIWYG mode.
I found some hints in this post:
CKEditor plugin button disabled in source mode
It seems that I have to include the modes variable in the editor.addCommand() call, but I am passing a CKEDITOR.dialogCommand object in that parameter space and not JS code.
What is the best way to pass the dialog object and the mode parameter? Thanks for any assistance!
I found the solution - the editor.addCommmand can be assigned to a variable, and then have the modes property added on a new line.
var command = editor.addCommand('tgroovideo', new CKEDITOR.dialogCommand('tgroovideo'));
command.modes = { wysiwyg:1, enhancedsource:1 };
I'm implementing an OpenLayers SelectFeature control, and trying to position an JQuery UI dialog widget right on top of the selected feature. To use the JQuery UI Position utility, it requires either a DOM element or an Event.
The onSelect callback of the SelectFeature control gives me an OpenLayers.Feature.Vector object representing the selected feature. From this, how do I get either the DOM element of the selected feature, or the Event object of the click event?
var selectControl = new OpenLayers.Control.SelectFeature(clientsLayer, {
hover : false,
clickout: false,
multiple: false,
onSelect: function(feature) {
// how do I get the DOM element of the feature
// or alternately, the click event of the selection?
}
});
You are doing it right.
If you do a console.log(feature) You'll see that it returns an object with CLASS_NAME =
"OpenLayers.Feature.Vector"
onSelect: function(feature) {
console.log(feature);
}
Update:
I see.
You could add event listeners
var selectControl = new OpenLayers.Control.SelectFeature(clientsLayer, {
hover: false,
clickout: false,
multiple: false,
eventListeners: {
featurehighlighted: function (event) {
console.log(event);
console.log(event.feature);
}
}
});
Is it something like this you look for ?
onSelect: function onFeatureSelect(event) {
var feature = event.feature;
if ( feature.layer.name == 'theone') {
...
}
}
Note I have also posted this answer at How do I get the DOM element from openlayers vector feature
If you want to find the position of the mouse or feature on hover so you can display a custom overlay, create a custom hover control and define the featurehighlighted function as follows:
var featureHoverControl = new OpenLayers.Control.SelectFeature([myLayer], {
id: 'featureHoverControl',
hover: true,
autoActivate: true,
highlightOnly: true,
renderIntent: "temporary",
eventListeners: {
featurehighlighted: function(e) {
// either use the mouse's position when the event was triggered
var mouseXPosition = this.handlers.feature.evt.x;
var mouseYPosition = this.handlers.feature.evt.y;
// or retrieve the feature's center point
var featureCenterLonLat = e.feature.geometry.bounds.getCenterLonLat();
var featureCenterPoint = map.getPixelFromLonLat(featureCenterLonLat);
// display your custom popup here
// e.g. showTooltip(e.feature.attributes.name, featureCenterPoint.x, featureCenterPoint.y)
}
,
featureunhighlighted: function(e) {
// hide your custom popup here
// e.g. hideTooltip()
}
}
});
map.addControl(featureHoverControl);
If you require access to the SVG element representing your layer/feature (in the event you are using a third-party library and you don't feel like modifying the source code), use either of the following lines (depending if you require the layer or feature):
var layerElement = map.getLayersByName("My Layer")[0].features.root;
var layerElementId = map.getLayersByName("My Layer")[0].features.root.id;
var featureElementId = map.getLayersByName("My Layer")[0].getFeaturesByAttribute("name","My Feature Name")[0].geometry.components[0].id;
Note that since this only grabs the element's id, you'll still need to use an appropriate method to grab a reference to the element itself. Something like either of the following:
var elementReference1 = document.getElementById(featureElementId);
var elementReference2 = jQuery('#'+featureElementId)[0];