SAPUI5 Web content widget - widget

So I'm trying to develop a so called "Web Content Widget" to use in the SAP Cloud Portal, as described here: https://help.sap.com/viewer/3ca6847da92847d79b27753d690ac5d5/Cloud/en-US/b3b13c6b75244a18887180353ce49599.html
What I'm trying to create is a title with an icon next to it. Clicking the icon should open a popover with some text.
The title and the popover text should be configurable from the Cloud Portal.
Right now I have a configurable title and configurable text, but how do I implement a mechanism to open and close the popover in that framework?
Is there a way to use event handlers in a "Web Content Widget"?
Or perhaps: Is there a way to use sap.m.popover?
(i.e. Transforming a SAPUI5 app in a portal widget and adding options? But how?)
Edit:
Folder structure looks like this:
CustomContentWidget
ContentUnits
popover.json (contains the "settings/configuration" that can be edited in the Portal)
renderers
popoverRenderer.js
snippets
popover.html
Component.js
manifest.json
cp.app.descriptor.json
The "popoverRenderer.js and "popover.html" snippet:
sap.ui.define([
"sap/ushell/cpv2/services/control/contentUnit/WebContentRenderer"
], function(WebContentRenderer) {
"use strict";
return WebContentRenderer.extend("infoblockpopover.renderers.popoverRenderer", {
getDefaultSettings: function() {
var defaultSettings = {
height: "10rem"
};
return defaultSettings;
},
onInit: function() {
},
onThemeChanged: function() {
},
createSettingsEditor: function(propertyEditorManager) {
var propertyEditor = propertyEditorManager.editor;
this.addPropertyEditor({
key: "height",
category: propertyEditorManager.bundle.getText("WIDGET_CATEGORY_DIMENSIONS"),
title: propertyEditorManager.bundle.getText("WIDGET_SETTINGS_LABEL_HEIGHT"),
editor: propertyEditor.Size,
flags: propertyEditor.Size.AUTO | propertyEditor.Size.UNIT_PX | propertyEditor.Size.UNIT_PT | propertyEditor.Size.UNIT_REM
});
},
renderer: {
render: function(oRm, oControl) {
var settings = oControl.getSettings();
oRm.write("<div");
oRm.writeClasses();
oRm.writeControlData(oControl);
oRm.write(">");
oRm.write("<div>");
var uiComps = oControl.getItems();
jQuery.each(uiComps, function() {
oRm.write("<div style='position: relative;height:" + settings.height + "'>");
oRm.renderControl(this);
oRm.write("<div style='clear: both'></div>");
oRm.write("</div>");
});
oRm.write("</div>");
oRm.write("</div>");
}
}
});
}, true);
<component>
<style>
/* Some style here */
</style>
<div class="{$dir} {$device}">
<div class="zBILink ['{popoverText}'?'':'zBILinkHide']" >
<span class="icon-wl-icon-question onclick-menu" tabindex="0">
<div class="onclick-menu-content">{popoverText}</div>
</span>
</div>
</div>
</component>

Related

TinyMCE Insert/edit image source button

I'm using tiny mce and want in the insert image dialog a button to a special page
just behind the source input a simple link to a different page that opens in a new browser window. how can I achieve that?
TinyMCE has an init options called file_browser_callback and file_picker_callback that allow you to add your own file browsing functionality to the insert dialogs:
https://www.tinymce.com/docs/configure/file-image-upload/#file_browser_callback
https://www.tinymce.com/docs/configure/file-image-upload/#file_picker_callback
https://www.tinymce.com/docs/configure/file-image-upload/
So for example, you could do the following in your init:
tinymce.init({
file_picker_callback: function(callback, value, meta) {
imageFilePicker(callback, value, meta);
}
});
Then the imageFilePicker function would just call out to a function that does the real work of opening a window to do the selection:
var imageFilePicker = function (callback, value, meta) {
tinymce.activeEditor.windowManager.open({
title: 'File and Image Picker',
url: '/myapp/getfilesandimages',
width: 700,
height: 600,
buttons: [{
text: 'Insert',
onclick: function () {
//do some work to select an item and insert it into TinyMCE
tinymce.activeEditor.windowManager.close();
}
},
{
text: 'Close',
onclick: 'close'
}],
},
{
oninsert: function (url) {
callback(url);
}
});
};
Eighter create your own plugin using a copy of the tinymce core plugin OR add it to the DOM after the dialogue has been created.

how to change the popup content based on the current url extension page action

am new in creating chrome extensions, I'm developing an extension page action it works in certain urls, I would like to put different text in the popup for each url, i can do it? please help me.
My background.js is thus
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (~tab.url.indexOf('url1.com.br')) {
chrome.pageAction.show(tabId);
}
if (~tab.url.indexOf('url2.com.br')) {
chrome.pageAction.show(tabId);
}
});
OK. First of all, to show page_action icon on specific URLs you can use declarative content.
// When the extension is installed or upgraded ...
chrome.runtime.onInstalled.addListener(function() {
// Replace all rules ...
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// With a new rule ...
chrome.declarativeContent.onPageChanged.addRules([
{
// That fires when a page's on a specific URL
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'url1.com.br' },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'url2.com.br' }
})
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
Don't forget adding a permission for declarative content in manifest.json. Another thing is different texts for different urls.
popup.js
chrome.tabs.query({'active': true, 'currentWindow': true}, function (tabs) {
var dynamicText = "You are here;"+ tabs[0].url;
document.getElementById("textbox").value = dynamicText ;
});
This sample gets the currentWindow's URL and insert it into the element that has textbox id. I hope samples are enough to solve the problem.

Bind Kendo Grid datasource(RestURL) with dynamic input param

I have an input text box, a button and a kendo grid. The datasource for the kendo grid is Rest webservice url. My Rest web service needs an input parameter on the basis of which it sends the appropriate json data. My requirement is whenever I click on the button it takes the data from the input box, appends it to the Rest url as its input param, fetches and display the corresponding data from web service. If I change the value in input text box and click on button again then the kendo grid should be refreshed with new set of data returned from web service. Below is my code.
HTML:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div>
<form>
Enter Param
<div>
<input type="text" ng-model="param">
</div>
<button type="submit" ng-click="submitParam()">Submit</button>
</form>
</div>
<div id="grid" kendo-grid k-options="kendoGrid"></div>
</div>
</div>
Controller:
var myApp = angular.module('myApp',[]);
myApp.controller('myCtrl', function ($scope, myService) {
$scope.param = "";
$scope.kendoGrid = myService.getKGrid();
$scope.submitParam = function(){
**//here param should be appended in the Rest URL and kendo grid data should change as per the** new URL.
}
});
Service:
myApp.service('myService', function () {
this.getKGrid = function () {
var kGrid = {
dataSource: {
transport: {
read: {
url: MyRestURL/param,**//Here the param will be appended**
dataType: "json"
}
},
},
columns: [{
field: "Col1",
title: "Col1"
},
{
field: "Col2",
title: "Col2"
}
]
};
return kGrid;
};
});
I am able to resolve the problem by changing the Datasource URL dynamically by using grid.dataSource.transport.options.read.url property of Grid datasource.
Reference link: Kendo UI Dynamically Change Datasource String (XML)

Current location in sencha touch

I am using the following code to display my current location on Sencha Touch 2. Its showing the correct latitude in console.log() but not showing the map. Please help.
Ext.define('restApp.view.GreetingView', {
extend: 'Ext.Map',
alias: 'widget.mymap',
config: {
fullscreen: true,
//tpl: '<p>The ID is {uuid}</p><p>The content is {display}</p>',
layout: {
type: 'fit'
}
},
initialize:function(){
Ext.Viewport.add({
xtype: 'map',
id:'geomap',
itemId:'ma'
});
var geo = Ext.create('Ext.util.Geolocation', {
autoUpdate: true,
frequency: '10000',
listeners: {
locationupdate: function (geo) {
var center = new google.maps.LatLng(geo.getLatitude(), geo.getLongitude());
Ext.getCmp('geomap').setData(center);
//restApp.view.GreetingView.getComponent('ma').update(center);
var marker = new google.maps.Marker({
position: center,
map: Ext.getCmp('geomap').map
});
console.log('New latitude: '+ geo.getLatitude());
},
locationerror: function (geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
if (bTimeout) {
alert('Timeout occurred.');
}
else {
alert('Error occurred.');
}
}
}
});
}
});
OLD ANSWER
Comparing it to a snippet I use for the same purpose (shown below), I realised the issue is a simple one. "center" is a reserved word. Try using a different variable name.
PART OF EDIT: removal of code snippets.
NEW ANSWER
I looked around and noticed your "project" is but a piecemeal collection of demo code.
Here's a complete code solution, with all excess pieces removed for simplicity, as well as over use of variables, also expanded to a longwinded format to be obvious.
/*
The application, including a simple launcher.
*/
Ext.application({
requires : ['Ext.device.Geolocation'],
views : ['MainView'],
controllers : ['Maps'],
name : 'Geo',
launch: function() {
Ext.create('Geo.view.MainView', {fullscreen: true});
}
});
/*
The View to display the map, as well as how to include the navigation bar
and include a "you are here" button.
*/
Ext.define('Geo.view.MainView', {
extend: 'Ext.navigation.View',
alias: 'widget.mainview',
requires: [
'Ext.Panel',
'Ext.Map',
'Ext.navigation.Bar',
'Ext.Button'
],
config: {
items: [
{
xtype : 'panel',
title : 'Map',
itemId : 'mapPanel',
items : [
{
xtype: 'map',
height: '100%',
itemId: 'map'
}
]
}
],
navigationBar: {
docked: 'top',
items: [
{
xtype: 'button',
itemId: 'youAreHereButton',
text: 'You Are Here'
}
]
}
}
});
/*
The Controller with functionality for the "you are here" button tap
*/
Ext.define('Geo.controller.Maps', {
extend: 'Ext.app.Controller',
config: {
refs: {
mapView: {
selector: 'mainview #map',
xtype: 'Ext.Map'
},
mainView: {
selector: 'mainview',
xtype: 'Ext.navigation.View'
}
},
control: {
"mainview #youAreHereButton": {
tap: 'onYouAreHereTap'
}
}
},
onYouAreHereTap: function(button, e, eOpts) {
// set 'mapView' as the parent view displaying the map
var mapView = this.getMapView();
// control measure for old browsers or denied permission for location detection.
if (Ext.feature.has.Geolocation) {
/*
Ext.device.Geolocation uses native (phone) Geolocation capabilities if available,
and falls back to Ext.util.Geolocation if only browser support detected.
*/
Ext.device.Geolocation.getCurrentPosition({
allowHighAccuracy : true,
maximumAge : 0,
timeout : 20000,
success : function(position) {
var latitude = position.coords.latitude,
longitude = position.coords.longitude,
location = new google.maps.LatLng(latitude, longitude),
marker = new google.maps.Marker({
position : location,
map : mapView.getMap(),
animation : google.maps.Animation.DROP
});
mapView.setMapOptions({ // Move to the center
center: location
});
},
failure: function() {
console.log('something went wrong!');
}
});
}
}
});
Yes, I could have simplified it further down to a single view, containing also the controller's handler for the "you are here" tap. I have chosen to present it this way to assist you with understanding the MVC pattern and how it applies in Sencha Touch.
For this to work, it'll require the Sencha Touch library, as well as this following line:
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
This is the script which includes Google Maps in your page and is essential for displaying.
Learn more:
https://www.sencha.com/learn/hello-world/ - getting started
http://docs.sencha.com/touch/2.3.1/#!/guide - complete documentation for how to do anything in Sencha Touch, starting with the Guides page.

Back button support using routing in Sencha

I am newbie to Sencha. Can anyone please explain how to support back button in android using Sencha touch2 Routing. I have gone through Sencha document, they explained there with senarios like "#products/123". But in my case only views get changed not url which is always like "../index.html".
Lets consider i have one login page. On login button tap it navigates to Home page. Now on device back button tap it should navigate back to login. So what format should i put inside route:{}.
Please anyone explain me with simple code.
Thanks in advance.
in your button actions you should redirect like this:
control: {
'button[action=login]' : {
tap: function() {
this.redirectTo('login');
}
}
Then add the route in your controller:
config: {
refs: {
main: 'main'
},
routes: {
'login': 'showLogin'
}
}
and finally in the showDetail function you make the view change, the url should show something like index.html#detail:
showLogin: function() {
this.getMain().push({
xtype: 'loginView'
});
}
I hope this helps!
After doing lot of Google search finally got the answer with proper example. So this is for reference http://thanksmister.com/?p_=336
You can also give yourself better control by defining the Back Button, as well as its references, instead of using the default.
Ext.define('Mov.view.BackButton', {
extend: 'Ext.Button',
alias: 'widget.backbutton',
config: {
hidden: true,
id: 'back',
ui: 'back',
text: 'Back',
backStack: {
}
},
addToBackStack: function(dispatchOptions) {
var found = false;
this.backStack.forEach(function(el) {
found = found || (Ext.encode(el) == Ext.encode(dispatchOptions));
});
if (!found) {
this.backStack.push(dispatchOptions);
}
this.show();
},
clearBackStack: function() {
this.backStack = [];
this.hide();
},
handler: function(button, event) {
var dispatchOptions = this.backStack.pop();
Ext.dispatch(dispatchOptions);
if(this.backStack.length === 0) {
this.hide();
}
}
});
Then on your app's navigation bar, you apply this widget. (onInitialize of initial view works well).
nav = this.getNavigationBar(),
nav.setBackButton(Ext.widget('backbutton'));
#jurodr has a nice example for routing, reference and control, which works well with this custom component.