Load external javascript to component dynamically - javascript

I am trying to load an external library (Javascript) to an Angular2 component (TypeScript).
Take example: https://github.com/fengyuanchen/cropperjs
My approach:
index.html
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/0.8.1/cropper.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/0.8.1/cropper.js"></script>
</head>
myCropper.js
window.addEventListener('DOMContentLoaded', function () {
var image = document.querySelector('#image');
var cropper = new Cropper(image, {
viewMode: 3,
dragMode: 'move',
autoCropArea: 1,
restore: false,
modal: false,
guides: false,
highlight: false,
cropBoxMovable: false,
cropBoxResizable: false,
toggleDragModeOnDblclick: false,
});
});
photo.component.ts
#Component({
selector: 'photo-crop',
template: `
<div class="row">
<img id="image" src="http://img01.ibnlive.in/ibnlive/uploads/875x584/jpg/2015/09/new-google-logo-010915.png" class="img-responsive"/>
<div class="row">
`,
styles: []
})
export class PhotoComponent {
public ngOnInit() {
this.loadScript('src/assets/js/myCropper.js');
});
}
public loadScript(url) {
console.log('preparing to load...')
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
}
}
Problem: the image is loaded without zoom/crop effect. I inspected the page and saw the script was added correctly in . I refreshed page, no luck. I had no error at all. It seems Angular2 does not activate the script.
I also tried a workaround: putting script in index.html directly (This workaround return error when the page is not loaded yet)
<head>
...
<script src="src/assets/js/myCropper.js"></script>
</head>
Photo is loaded without zoom/crop effect at start. But after I refresh the page, zoom/crop effect is activated. This is not a good practice where all scripts kept in index.html, but at least the script works after refresh.
Any suggestion is appreciated.

Related

Framework-7 With Cordova Not Opening and Linking Pages and Links

Curious. Is Framework7 really adapted to function with Cordova on a local server? If I run the kitchen sink from npm core, I'm able to navigate through pages and open links. When I create projects with framework7-cli and run cordova run browser, I am unable to trigger opened any page or linked. Is this caused by Webview? Any solution? I've looked into page events but nothing happens and no error in the console.
app.js (with routes)
function initFramework7(){
var $$ = Dom7;
var device = Framework7.getDevice();
var app = new Framework7({
name: 'My App', // App name
theme: 'auto', // Automatic theme detection
el: '#app', // App root element
id: 'io.framework7.ragg', // App bundle ID
// App store
store: store,
//view
view : {
stackPages: true
},
// App routes
routes: [
{
path: '/',
componentUrl: './pages/home.html',
name: 'home',
master(f7) {
return f7.theme === 'aurora';
},
},
{
path: '/about/',
url: './pages/about.html',
name: 'about',
},
{
path: '/messages/',
url: './pages/messages.html',
name: 'messages',
},
// Default route (404 page). MUST BE THE LAST
{
path: '(.*)',
url: './pages/404.html',
},
],
popup: {
closeOnEscape: true,
},
sheet: {
closeOnEscape: true,
},
popover: {
closeOnEscape: true,
},
actions: {
closeOnEscape: true,
},
// Input settings
input: {
scrollIntoViewOnFocus: device.cordova && !device.electron,
scrollIntoViewCentered: device.cordova && !device.electron,
},
// Cordova Statusbar settings
statusbar: {
iosOverlaysWebView: true,
androidOverlaysWebView: false,
},
on: {
init: function () {
var f7 = this;
if (f7.device.cordova) {
// Init cordova APIs (see cordova-app.js)
cordovaApp.init(f7);
}
},
},
});
}
this wont event work (app.main.router returns undefined)
$$('.p').on('click', function(){
app.views.main.router.navigate('/messages/', {reloadCurrent: true});
});
index.html
<body>
<div id="app">
<div class="view">
<!-- Initial Page, "data-name" contains page name -->
<div data-name="home" class="page">
<!-- Scrollable page content -->
<div class="page-content">
preview page content
<a class="p" href="/messages/">messages</a>
</div>
</div>
</div>
</div>
</body>
<!-- Framework7 library -->
<script src="framework7/framework7-bundle.min.js"></script>
<!-- Cordova APIs -->
<script src="js/cordova-app.js"></script>
<script src="cordova.js"></script>
<!--custom app-->
<script src="js/app.js"></script>
pages/messages.html
<div class="view">
<div data-name="messages" class="page">
...Im the messages page
</div>
</div>

why jquery UI Widgets doesn't work in my laravel application?

I have laravel application and trying to use dialog widget, but I keep getting this error in the console:
TypeError: $(...).dialog is not a function[Learn More]
I tried to test normal jquery functions and it works fine, it is just jquery UI.
<head>
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<!-- Scripts -->
<script>
window.Laravel = {!! json_encode([
'csrfToken' => csrf_token(),
]) !!};
</script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="text/javascript">
$( function() {
$( "#dialog" ).dialog({
autoOpen: false,
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
}
});
$( ".opener" ).on( "click", function() {
$( "#dialog" ).dialog( "open" );
});
} );
</script>
</head>
<body>
<div id="dialog" title="Basic dialog">
<p>This is an animated dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
</div>
Update:
there is a conflict between these lines:
<script src="{{ asset('js/app.js') }}"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
but still can't remove any of them.
Update 2
webpack.mix.js
const { mix } = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example', require('./components/Example.vue'));
const app = new Vue({
el: '#app'
});
bootstrap.js
window._ = require('lodash');
try {
window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');
} catch (e) {}
window.axios = require('axios');
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = window.Laravel.csrfToken;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
See this link: https://github.com/JeffreyWay/laravel-mix/blob/master/docs/jquery-ui.md
NOTE: I am fairly new to Laravel Mix (webpack) and still learning.
In the linked example his resources/assets/js/app.js contains the lines:
import $ from 'jquery';
window.$ = window.jQuery = $;
but in my case I'm editing resources/assets/js/bootstrap.js, which contains the line:
window.$ = window.jQuery = require('jquery');
so I added the widget import line:
import 'jquery-ui/ui/widgets/dialog.js';
After the edits, to run the Mix tasks, I ran this command at my project root: npm run dev
And in my Chrome browser, on the page calling $(...).dialog(), I opened the devtools console and then right clicked on the browser page reload icon and clicked Empty cache and hard reload
Since I am using Laravel Mix (webpack) I do not need to include the jquery specific script tags and stylesheet links.
Are you using the .sass file that you're mixing in your webpack.mix.js file?
If not, try changing your webpack.mix.js to this:
const { mix } = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js');
New to Laravel and web development in general; that worked for me.
Try inserting app.js before jquery-ui.js. This makes jquery-ui.js overwrite any common code. I found it does not cause significant side-effects. Some items like tooltips will look different, but you can just modify the linked js files to handle that if necessary.

Cherrypy and JS, can't find image

I have a simple Cherrypy script that for now just serves a page. I want the page to be able to display images dynamically. For this I wrote a simple JS script. However when I try to run the page, it can't find the image. The code is run from ~/image_player/test_app.py and the image is at ~/image_player/app/public. See the python code for the static path:
import cherrypy
import os
import sys
class image_player(object):
#cherrypy.expose
def index(self):
return open('app/index.html')
if __name__ == '__main__':
if len(sys.argv) == 2:
port = int(sys.argv[1])
else:
port = 3030
host = '0.0.0.0'
conf = {
'/': {
'tools.sessions.on': True,
'tools.staticdir.root': os.path.abspath(os.getcwd())
},
'/query': {
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.response_headers.on': True,
'tools.response_headers.headers': [('Content-Type', 'text/plain')],
},
'/static': {
'tools.staticdir.on': True,
'tools.staticdir.dir': 'app/public'
},
'/js': {
'tools.staticdir.on': True,
'tools.staticdir.dir': 'app/js'
}
}
webapp = image_player()
# Configure server and port
cherrypy.config.update({'server.socket_host': host,
'server.socket_port': port})
cherrypy.quickstart(webapp, '/', conf)
And here's the index.html containing the js:
<!DOCTYPE html>
<html>
<head>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
hello
<div id="imageDiv"></div>
<script>
var par = document.getElementById('imageDiv');
var img = document.createElement('img');
img.src = '/LPROFILE.jpg';
par.appendChild(img);
</script>
</body>
</html>
The error I get is GET http://hostname/LPROFILE.jpg 404 (Not Found) I'm clearly missing something simple here but I'm not sure what.
Given the configuration that you showed, the static files are served under the /static path, which means all the files under app/public (relative to the initial directory from which you started the server) are going to be accessible from http://hostname/static/, in the case of LPROFILE.jpg, that should be available in: http://hostname/static/LPROFILE.jpg
It works for me (win x64):
conf = {
'/': {
'tools.sessions.on': True,
'tools.staticdir.root': os.path.abspath(os.getcwd())
},
'/css': {
'tools.staticdir.on': True,
'tools.staticdir.dir': './css'},
'/img': {
'tools.staticdir.on': True,
'tools.staticdir.dir': './img'},
'/js': {
'tools.staticdir.on': True,
'tools.staticdir.dir': './js'},
'global': {
'environment': 'production',
'log.screen': True,
'server.socket_host': '127.0.0.1',
'server.socket_port': 8080,
'engine.autoreload_on': True,
}}
for example:
url(../img/backgr.jpg)

AngularJS + i18n localization loading JSON from another server

We are using angular 1.2.16 and i18next 0.2.6 for development. In our application localization works fine when JSON from same server.
Now we came across with the new requirement, to load resources string i.e. JSON files from another content server. let say load JSON from "http://mysite/locales/en-us/sample.json"
<head>
<meta charset="utf-8"/>
<title>i18next test</title>
<script src="i18next.js"></script>
<script src="angularjs/1.2.16/angular.min.js"></script>
<script src="ngI18next.js"></script>
<script>
angular.module('jm.i18next').config(function ($i18nextProvider) {
'use strict';
$i18nextProvider.options = {
lng: 'dev',
useCookie: false,
useLocalStorage: false,
fallbackLng: 'dev',
resGetPath: '../locales/__lng__/__ns__.json',
ns: {
namespaces: ['messages', 'options'],
defaultNs: 'messages'
}
};
});
angular.module('MyApp', ['jm.i18next']).controller('MyProviderCtrl', function ($rootScope, $scope, $i18next) {
$rootScope.$on('i18nextLanguageChange', function () {
$scope.hello = $i18next('messages:header.name');
});
});
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="MyProviderCtrl">
<div>{{hello}}</div>
<div ng-i18next="options:moment-i18n"></div>
<div ng-i18next="messages:header.name"></div>
<div ng-i18next="header.name"></div>
</div>
</body>
I tried to change resGetPath: '../locales/__lng__/__ns__.json' to resGetPath: 'http://mysite/locales/en-us/sample.json' its loading JSON file from server however its not translating text on UI.
Any suggestions how to translate?
Looks like you're using an older version of http://i18next.com. So i'm not sure that already allowed loading from other servers (CORS).
I would suggest upgrading to current release and enabling "crossDomain" access in the backend: https://github.com/i18next/i18next-xhr-backend

open sapui5 detail page in a new tab of the browser on click of a button

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m,sap.ui.table,sap.ui.commons"
data-sap-ui-theme="sap_bluecrystal">
</script>
<!-- only load the mobile lib "sap.m" and the "sap_mvi" theme -->
<script>
var bFlag;
sap.ui.localResources("views");
sap.ui.localResources("i18n");
sap.ui.localResources("utils");
jQuery.sap.registerModulePath('Application', 'Application');
jQuery.sap.require("Application");
var oApp = new Application({
root : "content"
});
</script>
<link href="css/stylesheet.css" rel="stylesheet" type="text/css">
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
I am developing a sapui5 application in which I have a split app,now on the detail page in the toolbar I have a button called open in new window.So I want to open this particular detail page(only detail page) in a new tab on clicking this button.
Can anyone help me on this as in how to go about it?
Thanks in advance.
Regards,
Shalini
Use the SAP's Router API.
Basically, define your router, routes, pattern and targets objects in your manifest.json file:
"sap.ui5": {
"rootView": {
"viewName": "path.to.view.name",
"type": "XML",
"async": true
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"viewPath": "path.to.view",
"controlId": "init",
"controlAggregation": "pages",
"async": true
},
"routes": {
"init": {
"pattern": "",
"target": "init",
"viewId": "vid_init"
},
"target_name": {
"pattern": "url_parameter",
"target": "target_name",
"viewId": "vid_view_name"
}
},
"targets": {
"target_name": {
"viewName": "view_name",
"transition": "show"
}
}
}
}
Assign a press event handler in your button's properties:
<Button id="myButton" press=".onOpenNewWindow" />
In your view's controller write a code to handle your event. Example:
onOpenNewWindow: funtion(oEvent){
sap.ui.require([
"sap/m/library"
], sapMLib => sapMLib.URLHelper.redirect("#/url_parameter", /*new window*/true));
},
Resources
API Reference: sap.m.URLHelper.redirect
Documentation: Routing and Navigation
Basically, you can open a new tab in JavaScript like this:
window.open("<yourURL>", _blank');
For your SAPUI5 Application you simply have to provide an additional .html file at a dedicated URL which loads your View/Controller. If you want to pass information from the Master/Detail application to the new tab you could add URL parameters.
As I can see in your edited question you´re using an Application. I don´t know the further structure (especially what your Application.js does) but in a separate .html a very simple solution could look like this:
<script>
sap.ui.localResources("views");
sap.ui.localResources("i18n");
sap.ui.localResources("utils");
sap.ui.jsview("name.of.your.detailView").placeAt("content");
</script>
If you want to reuse your Application.js file you can extend it and pass a simple parameter which tells to display only one View.
One more thing: I guess you´re using sap.m.SplitApp somewhere in your application. To display only the DetailView you should use sap.m.App instead at that point.

Categories