I wanted to use a rich text editor in flutter web, but I could not find anything like that in flutter web. So I thought If I could implement the froala-editor in flutter web. So is there any possibility of inserting the froala-editor javascript library to flutter web.
https://froala.com/wysiwyg-editor/
Is it possible to use froala-editor in flutter web or Is there anythings else possible to get a rich text editor in flutter web?
Thanks in advance.
Yes it is possible mate! But you can use this as a temporarily until Flutter web goes stable.
The Hack is you can have that froala or Quill any editor in plain html and you can render it in Flutter IFrame element and you can pass the data via Js Connector vice versa.
Here Example Code :
import 'dart:js' as js;
js.JsObject connector;
js.IFrameElement element;
String createdViewId = 'map_element';
js.context["connect_content_to_flutter"] = (js.JsObject content) {
connector = content;
};
element = html.IFrameElement()
..src = "/assets/assets/editor.html"
..style.border = 'none';
ui.platformViewRegistry
.registerViewFactory(createdViewId, (int viewId) => element);
// SO the above code defines your plain html(Place inside the Project folder ex:assets/editor.html) and registered with UI, now you can use the HTMLElementView(Widget) to render the view in screen.
HtmlElementView(
viewType: createdViewId,
);
// Now in your html file
<!DOCTYPE html>
<html>
<title>Sample</title>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css">
<link href="https://cdn.jsdelivr.net/npm/froala-editor#3.1.0/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form method="post">
<textarea id='edit' style="margin-top: 30px;"></textarea>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor#3.1.0/js/froala_editor.pkgd.min.js"></script>
<style>
span.fr-emoticon{
background-repeat: no-repeat !important;
font-size: 28px;
}
</style>
<script>
(function () {
new FroalaEditor("#edit", {
theme: 'royal',
height: 450
})
})()
parent.connect_content_to_flutter && parent.connect_content_to_flutter(window)
function getValue(){
return $('#edit').val();
}
window.addEventListener("message", (message) => {
if (message.data.id === "value") {
quill.root.innerHTML = message.data.msg;
}
})
</script>
</body>
</html>
// Above parent connect to flutter is very important line that you should include because that is the one connecting to flutter and the window listener is listening for sending the data from flutter.
//so in your dart
connector.callMethod(
'getValue',
) as String;
element.contentWindow.postMessage({
'id': 'value',
'msg': "Hi /n Welcome <b>sending data from dart</b>",
}, "*");
Yeah good to go.Happy coding !
Related
I can't figure out how to get access to the full source of the HTML page including iframes. It should be similar to what we see in DevTools > Elements, but via Electron.
By source I mean either text representation of the DOM (including content of all iframes on the page), or the list of all elements and having a way to get access to their text-representations.
Any help is highly appreciated! Thanks.
If you're just looking to get a string of all the HTML, you can do so via the executeJavaScript API:
const {app, BrowserWindow, dialog} = require('electron')
async function createWindow () {
const mainWindow = new BrowserWindow()
await mainWindow.loadFile('index.html')
const result = await mainWindow.webContents.executeJavaScript("document.documentElement.outerHTML");
dialog.showMessageBox(mainWindow, {
message: result
});
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
For an HTML page like:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="./styles.css" rel="stylesheet">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
<iframe src="https://google.com/chrome"></iframe>
</body>
</html>
You'll get a dialog like this:
It is not however possible to just grab DOM elements in the main process that you can manipulate.
I have a nice and simple API swagger standard layout documentation url, auto generated by the rho-routes swagger support. I want to customize the layout with let's say colors, logo, phrases and examples.
In my scala backend the SwaggerUI service is generated by this:
case GET -> Root =>
implicitly[Applicative[F]].pure(
Response[F]()
.withStatus(Status.SeeOther)
.withHeaders(Location(Uri.fromString(
s"${webjarPath}/swagger-ui/3.40.0/index.html?url=${swaggerApiJsonPath}&layout=BaseLayout").right.get)
)
)
}
Is it possible to customize this "BaseLayout" direclty from the backend without importing a React dependency? If not: can I redirect the whole thing on my website to customize it from a ReactJS repo? If yes, how? Do I need a swagger npm integration? I'm a backend dev and I'm not very solid on FE infrastructures matters.
I'd appreciate someone to pointing me some articles or solutions I can study and apply with this case. Thanks all
You serve a webjar which is easy to set up but difficult (if not impossible, I'm no expert) to customize.
What you can do to at least serve a customized Swagger UI, is handle it like any Play Twirl template:
add all the Swagger frontend resources needed in your project:
find the links in the /app/views/index.scala.html contents below. I have:
ls public/swagger-ui
swagger-ui-bundle.js swagger-ui.js
oauth2-redirect.html swagger-ui.css swagger-ui-standalone-preset.js
call the template from your controller:
See https://www.playframework.com/documentation/2.8.x/ScalaTemplates as well
def api: Action[AnyContent] =
Action { implicit request =>
Ok(views.html.index(s"https://${appConfig.apiUrl}", giveItSomeArgs)
}
customize your Swagger in the Twirl template:
mine is in /app/views/index.scala.html:
#import play.api.libs.json.JsValue
#import play.api.libs.json.Json
#(apiUrl: String, giveItSomeArgs: Set[String])
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="assets/swagger-ui/swagger-ui.css" >
<link rel="icon" type="image/png" href="../favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="../favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="assets/swagger-ui/swagger-ui-bundle.js"> </script>
<script src="assets/swagger-ui/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "/assets/openapi.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl,
{
statePlugins: {
spec: {
wrapActions: {
updateJsonSpec: function(oriAction, system) {
return (spec) => {
// change spec.servers here to add new entry, use concat to put it as the first & default one
spec.servers = [{url: "#apiUrl"}]
spec.components.schemas["swagger"]["docs"]["are"]["very"]["dynamic"] = #Html(Json.toJson(giveItSomeArgs).toString);
return oriAction(spec)
}
}
}
}
}
}
],
layout: "StandaloneLayout",
onComplete: function() {
}
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>
There's your layout StandaloneLayout so I guess you have a handle there. You can add all the JavaScript in the world and knock yourself out. Check the Swagger docs on how to customize the layout.
Not sure about the whole React thing you suggest, that's another thing.
I am trying to use vuetify component like tables in my sails project. I can get the UI working fine, but all actions (button clicks) are not working unless I disable parasails for that page. Anyone has experience integrating sails with vuetify?
I followed this example:
https://github.com/ndabAP/vue-sails-example
But instead of using vue-bootstrap I did with Vuetify with the vue-cli:
vue create frontend
cd frontend
vue add vuetify
And in the vue.config.js I used:
// frontend/vue.config.js
outputDir: "../backend/assets/dependencies",
In the backend generate a controller route to index.js:
// config/routes.js
'/*': { action:'index', skipAssets: true, skipRegex: /^\/api\/v1\/.*$/ },
with the content:
// controllers/index.js
module.exports = {
friendlyName: 'View homepage',
description: 'Display homepage view',
exits: {
success: {
statusCode: 200,
description: 'Display the view index page.',
viewTemplatePath: 'pages/index'
},
},
fn: async function () {
return {};
}
};
The view layouts/layout.ejs should content:
<% /* views/layouts/layout.ejs */ %>
<!DOCTYPE html>
<html>
<head>
<title><%=typeof title == 'undefined' ? 'New Sails App' : title%></title>
<!-- Viewport mobile tag for sensible mobile support -->
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel=icon href=/favicon.ico>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!--STYLES-->
<!--STYLES END-->
</head>
<body>
<noscript>
<strong>We're sorry but frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id=app></div>
<!--TEMPLATES-->
<!--TEMPLATES END-->
<%- exposeLocalsToBrowser() %>
<!--SCRIPTS-->
<!--SCRIPTS END-->
</body>
</html>
And that is the better way that I figured it out. If there is another simplest way I want to know, because I think that is necessary modifying parasails.js to upload components directly or change the form of registering pages by registering components instead, using a unique page in a similar way.
controller.js
var app = angular.module('startervideo', ['ionic','ngCordova'])
app.controller('VideoCtrl', function($scope,$cordovaCapture) {
$scope.data = {
videoPath: ""
};
$scope.captureVideo = $scope.captureVideo = function() {
var options = {duration: 15 };
$cordovaCapture.captureVideo(options).then(
function(videoData) {
// Success! Video data is here
$scope.data.videoPath = "file:/" + videoData[0].fullPath;
console.log(videoData);
}, function(err) {
// An error occurred. Show a message to the user
console.log(err);
});
}
});
app.js
var app = angular.module('starter', ['ionic','ngCordova','startervideo'])
app.directive("cordovaVideo", function () {
return {
restrict: 'AEC',
scope: {src: '='},
link: function(scope, element, attrs) {
scope.$watch('src', function(newVal, oldVal) {
if (scope.src != "") {
// Create a div object
var div = document.createElement('div');
div.innerHTML = "<video id=\"myCordovaVideo\"controls>"+
"<source src=\"" + scope.src + "\" type=\"video/quicktime\">"+ "</video>";
// Delete previous video if exists
var previousDiv = document.getElementById('myCordovaVideo');
if (previousDiv)
previousDiv.remove();
// Append new <video> tag into the DOM
element.append(div);
}
}); }
} });
#myCordovaVideo {
background: red;
width: 100%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link rel="manifest" href="manifest.json">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controller.js"></script>
</head>
<body ng-app="starter" ng-controller="VideoCtrl">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">VideoPro</h1>
</ion-header-bar>
<ion-content>
<button class="button button-calm button-full"
ng-click="captureVideo()">Capture Video</button>
<cordova-video src="data.videoPath"></cordova-video>
</ion-content>
</ion-pane>
</body>
</html>
Hi everyone I am new in ionic1 framework been trying to develop an application that can capture video display them on the UI and ultimately store in a remote serve, so far the code that I have can capture video but it does not display it on the UI.The example that I am following comes from ionic cookbook I am in desperate need of help here is the code that I have
I've created a similar Ionic app that captures video and uploads it to a remote server. You may find it useful
https://github.com/aliasav/ionic-video
I would like to create a ionic project for wifi-network-detection. I came across some plugins like wifiwizards,cordova plugin diagnostic to check wifi connection and also cordova plugin hotspot. But how should I include these plugins to my ionic project. Should I create a blank ionic project to add these plugins or how should I put these plugins to my index.html and app.js file. Please someone help me with these as I'm new to these.
Sample Project:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!--ngCordova script-->
<script src = "lib/ngCordova/dist/ng-cordova.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content padding = "true">
<div class = "card">
<div class = "item item-text-wrap">
<h1>Network: {{network}}</h1>
</div>
</div>
<div class = "card">
<div class = "item item-text-wrap">
<ion-toggle ng-model = "isOnline" ng-checked = "item.checked">
<h1 ng-show = "isOnline">I'm into Wifi</h1>
<h1 ng-show = "! isOnline">I'm out off Wifi</h1>
</ion-toggle>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
app.js where I included the plugin(ngCordova)
angular.module('starter', ['ionic', 'ngCordova'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('MyCtrl', function($scope, $cordovaNetwork, $rootScope){
document.addEventListener("deviceready", function(){
$scope.network = $cordovaNetwork.getNetwork();
$scope.isOnline = $cordovaNetwork.isOnline();
$scope.$apply();
//listen for onloine event
$rootscope.$on('$cordovaNetwork:online', function(event, networkState){
$scope.isOnline = true;
$scope.network = $cordovaNetwork.getNetwork();
$scope.$apply();
})
//listen for offline event
$rootScope.$on('$cordovaNetwork:offline', function(event, networkState){
console.log("got offline");
$scope.isOnline = false;
$scope.network = $cordovaNetwork.getNetwork();
$scope.$apply();
})
}, false);
});
Now how to write to check for the wifi detection and connectivity. The plugin I used is the cordova-network-information
Choose a template to start from (blank, sidemenu, tabs etc). Create your new project using ionic start [name] [templateName] step into the folder and add the plugins you need by calling ionic plugin add [plugin].
Now read the documentation for the plugins and start by implementing the examples they often show in their github repo. Then modify to your needs.