SAPUI5 mixing mobile (sap.m) and desktop (sap.ui.commons) - sapui5

I am working on a desktop SAPUI5 application and need to use TileContainer/Tiles in one of the page but noticed that press event is not working for this. Tried other mobile controls e.g. sap.m.Button press events but they are also not working.
Any idea?

Mobile controls will be work fine with touch events only. You need to set onclick events. You have 3 options to do this:
1) Attach onclick to target control:
var oButton = new sap.m.Button({
text : "Hello",
press : function() { alert('You've pressed me!') }
}).attachBrowserEvent('click',
function(event){
sap.ui.getCore().byId(event.target.id).firePress()
});
2) Extend standart mobile controls:
sap.m.Button.extend('my.Button');
my.Button.prototype.onclick = function(){
this.ontap.apply(this, arguments);
};
my.Button.prototype.onmousedown = function(){
this.ontouchstart.apply(this, arguments);
};
my.Button.prototype.onmousemove = function(){
this.ontouchmove.apply(this, arguments);
};
my.Button.prototype.onmouseup = function(){
this.ontouchend.apply(this, arguments);
};
3) Modify standart controls(not really good idea):
sap.m.Button.prototype.onclick = function(){
this.ontap.apply(this, arguments);
};
...

I was not adding sap.m in sap-ui-bootstrap, adding this made moible ui controls working.
data-sap-ui-libs="sap.ui.commons, sap.m"
thanks any way qmacro and Nikolay...

Related

Leaflet-geoman remove button not working after bind a new layer click function

I need to bind a custom click function on the drawn shapes. I'm using the following code for that:
map.on('pm:create', function(e) {
e.layer.on('click', function(e) {
document.getElementById('info-pane').style.display = 'block';
});
});
When I bind this new click function, I'm not able to remove the shape anymore. When I am in the remove mode, the click is triggering the show info-pane instead of remove the shape.
How can I bind a custom click function to the shapes without "deactivate" any leaflet-geoman functionality such as the Remove ?
Well,
Including this L.DomEvent.stopPropagation(e); seems to be working now.
map.on('pm:create', function(e) {
e.layer.on('click', function(e) {
document.getElementById('info-pane').style.display = 'block';
});
L.DomEvent.stopPropagation(e);
});

Leaflet - How to add click event to button inside marker pop up in ionic app?

I am trying to add a click listener to a button in a leaftlet popup in my ionic app.
Here I am creating the map & displaying markers, also the method I want called when the header tag is clicked is also below:
makeCapitalMarkers(map: L.map): void {
let eventHandlerAssigned = false;
this.http.get(this.capitals).subscribe((res: any) => {
for (const c of res.features) {
const lat = c.geometry.coordinates[0];
const lon = c.geometry.coordinates[1];
let marker = L.marker([lon, lat]).bindPopup(`
<h4 class="link">Click me!</h4>
`);
marker.addTo(map);
}
});
map.on('popupopen', function () {
console.log('Popup Open')
if (!eventHandlerAssigned && document.querySelector('.link')) {
console.log('Inside if')
const link = document.querySelector('.link')
link.addEventListener('click', this.buttonClicked())
eventHandlerAssigned = true
}
})
}
buttonClicked(event) {
console.log('EXECUTED');
}
When I click this header, Popup Open & Inside if are printed in the console, so I know I'm getting inside the If statement, but for some reason the buttonClicked() function isn't being executed.
Can someone please tell me why this is the current behaviour?
I just ran into this issue like 2 hours ago. I'm not familiar with ionic, but hopefully this will help.
Create a variable that keeps track of whether or not the content of your popup has an event handler attached to it already. Then you can add an event listener to the map to listen for a popup to open with map.on('popupopen', function(){}). When that happens, the DOM content in the popup is rendered and available to grab with a querySelector or getElementById. So you can target that, and add an event listener to it. You'll have to also create an event for map.on('popupclose', () => {}), and inside that, remove the event listener from the dom node that you had attached it to.
You'd need to do this for every unique popup you create whose content you want to add an event listener to. But perhaps you can build a function that will do that for you. Here's an example:
const someMarker = L.marker(map.getCenter()).bindPopup(`
<h4 class="norwayLink">To Norway!</h4>
`)
someMarker.addTo(map)
function flyToNorway(){
map.flyTo([
47.57652571374621,
-27.333984375
],3,{animate: true, duration: 5})
someMarker.closePopup()
}
let eventHandlerAssigned = false
map.on('popupopen', function(){
if (!eventHandlerAssigned && document.querySelector('.norwayLink')){
const link = document.querySelector('.norwayLink')
link.addEventListener('click', flyToNorway)
eventHandlerAssigned = true
}
})
map.on('popupclose', function(){
document.querySelector('.norwayLink').removeEventListener('click', flyToNorway)
eventHandlerAssigned = false
})
This is how I targeted the popup content and added a link to it in the demo for my plugin.
So yes you can't do (click) event binding by just adding static HTML. One way to achieve what you want can be by adding listeners after this new dom element is added, see pseudo-code below:
makeCapitalMarkers(map: L.map): void {
marker.bindPopup(this.popUpService.makeCapitalPopup(c));
marker.addTo(map);
addListener();
}
makeCapitalPopup(data: any): string {
return `` +
`<div>Name: John</div>` +
`<div>Address: 5 ....</div>` +
`<br/><button id="myButton" type="button" class="btn btn-primary" >Click me!</button>`
}
addListener() {
document.getElementById('myButton').addEventListener('click', onClickMethod
}
Ideally with Angular, we should not directly be working with DOM, so if this approach above works you can refactor adding event listener via Renderer.
Also I am not familiar with Leaflet library - but for the above approach to work you need to account for any async methods (if any), so that you were calling getElementById only after such DOM element was successfully added to the DOM.

Tracking url of external site launched in cordova-inappbrowser-plugin

I'm currently building an ionic app which is to be a wrapper for an external web application. What I want to do is to be able to track the url being redirected to when the user changes location in the external web app.
In my main controller I have the following code.
app.controller('MainCtrl', function ($rootScope) {
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use the Codova API
var url = "https://external-site/";
var target = "_self";
var options = "location=no";
var ref = cordova.InAppBrowser.open(url, target, options);
ref.addEventListener('loadstart', function () {
console.log("loadstart");
});
}
});
When the page loads I don't get the event listener to fire or when the user changes locations in the external site. I have tried pointing the target to _system and _blank which makes no difference for me.
Can anybody help me?
Thanks in advance.
It's my experience that all the events not always fires on all platforms. Try subscribing to all the events and print some debug info. Then test on different devices (iOS, android) and see what events are fired.
$rootScope.$on('$cordovaInAppBrowser:loadstart', function(e, event){console.log('start')};
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event){console.log('stop')});
$rootScope.$on('$cordovaInAppBrowser:loaderror', function(e, event){console.log('err')});
$rootScope.$on('$cordovaInAppBrowser:exit', function(e, event){console.log('exit')});
btw: I'm using ngCordova here...
very strange.. all I did was update ionic, run 'ionic start test blank' add the plugin modify app.js to this
angular.module('starter', ['ionic'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
if (window.cordova && window.cordova.plugins.Keyboard) {
var inAppBrowserRef;
var target = "_self";
var options = "location=no";
inAppBrowserRef = cordova.InAppBrowser.open('https://onesignal.com/', target, options);
inAppBrowserRef.addEventListener('loadstart', function () { console.log('start') });
inAppBrowserRef.addEventListener('loadstop', function () { console.log('stop') });
inAppBrowserRef.addEventListener('loaderror', function () { console.log('err') });
}
});
})
and then run 'ionic run android' and all events fires perf.

Uncaught TypeError: Cannot read property 'setVisible' of undefined

Im fairly new to SAPUI5 and when I click on button I get the error in the title
what I did in Is I used the SAP web IDE to create new MVC project .
in the main view JS I put
createContent : function(oController) {
var btn = new sap.m.Button({
id:"myBtn",
text : "Content Button"
});
return new sap.m.Page({
title: "TitleT",
content: [ btn ]
});
}
in the Main controller JS I put the following code
onInit: function() {
var that = this;
window.setTimeout(function() {
that.byId("myBtn").setVisible(true);
}, Math.random() * 10000);
},
onPress: function() {
this.byId("pressMeButton").setText("I got pressed");
}
When I run it I see the button but when I click on it I get the error in the on Init,
what am I doing wrong here?
The actual problem with your code is that you create a static id in your javascript view, but the controller will search the id with a prefix like "__jsview0--myBtn" if you call that.byId("myBtn").
Therefore you either have to use createId("myBtn") in your javascript view for defining the id or sap.ui.getCore().byId("myBtn") in the controller and it will work fine. The first approach is recommended though to avoid name clashes.
PS:
i did not really get the use case, it seems like you want to display the button only after a certain (random) timeframe. But the visible flag by default is already true, so the button will always be visible.
Use the standard timeout and byId function from SAPUI5 like this:
onInit: function() {
setTimeout(function() {
sap.ui.getCore().byId("myBtn").setVisible(true);
}, Math.random() * 10000);
},

Twitter Bootstrap Modal Form: How to drag and drop?

I would like to be able to move around (on the greyed-out background, by dragging and dropping) the modal form that is provided by Bootstrap 2. Can anyone tell me what the best practice for achieving this is?
The bootstrap doesn't come with any dragging and dropping functionality by default, but you can add a little jQuery UI spice into the mix to get the effect you're looking for. For example, using the draggable interaction from the framework you can target your modal ID to allow it to be dragged around within the modal backdrop.
Try this:
JS
$("#myModal").draggable({
handle: ".modal-header"
});
Demo, edit here.
Update: bootstrap3 demo
Whatever draggable option you go for, you might want to turn off the *-transition properties for .modal.fade in bootstrap’s CSS file, or at least write some JS that temporarily disables them during dragging. Otherwise, the modal doesn’t drag exactly as you would expect.
You can use a little script likes this.
simplified from Draggable without jQuery UI
(function ($) {
$.fn.drags = function (opt) {
opt = $.extend({
handle: "",
cursor: "move"
}, opt);
var $selected = this;
var $elements = (opt.handle === "") ? this : this.find(opt.handle);
$elements.css('cursor', opt.cursor).on("mousedown", function (e) {
var pos_y = $selected.offset().top - e.pageY,
pos_x = $selected.offset().left - e.pageX;
$(document).on("mousemove", function (e) {
$selected.offset({
top: e.pageY + pos_y,
left: e.pageX + pos_x
});
}).on("mouseup", function () {
$(this).off("mousemove"); // Unbind events from document
});
e.preventDefault(); // disable selection
});
return this;
};
})(jQuery);
example : $("#someDlg").modal().drags({handle:".modal-header"});
Building on previous answers utilizing jQuery UI, this, included once, will apply to all your modals and keep the modal on screen, so users don't accidentally move the header off screen so they can no longer access the handle. Also sets the cursor to 'move' for better discoverability.
$(document).on('shown.bs.modal', function(evt) {
let $modal = $(evt.target);
$modal.find('.modal-content').draggable({
handle: ".modal-header",
containment: $modal
});
$modal.find('.modal-header').css('cursor', 'move')
});
evt.target is the .modal which is the translucent overlay behind the actual .modal-content.
jquery UI is large and can conflict with bootstrap.
An alternative is DragDrop.js: http://kbjr.github.io/DragDrop/index.html
DragDrop.bind($('#myModal')[0], {
anchor: $('#myModal .modal-header')
});
You still have to deal with transitions, as #user535673 suggests. I just remove the fade class from my dialog.