How I can use my jquery plugin in Next.js? - import

i'm developing web app using Next.js and I'd like to use jQuery in Next.js.
But I can't import jquery plugin.
please check my code and Help me.
import React from 'react';
import Document, { Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';
export default class MyDocument extends Document {
static getInitialProps({ renderPage }) {
const sheet = new ServerStyleSheet();
const page = renderPage(App => props => sheet.collectStyles(<App {...props} />));
const styleTags = sheet.getStyleElement();
return { ...page, styleTags };
}
render() {
return (
<html lang="en">
<Head>{this.props.styleTags}
<link
href="//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.css"
rel="stylesheet"
/>
<script src="../static/js/jquery.main.js" async/>
</Head>
<body>
<Main />
<div id="modal" />
<NextScript />
</body>
</html>
);
}
}

One typical issue you will get into if you do jQuery is, After importing the jQuery plugins they will register for onClick events, and by that time you can't guarantee that the actual DOM Element is ready, elements may get created later and may get refreshed.
One way of solving the issues is call the jQuery code which does the initialization in componentDidMount() and also in componentDidUpdate() so that you can make sure the DOM elements are present before the jQuery plugin register them.

Related

How to read full DOM source including frames in Electron?

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.

swagger custom layout from scala-rho

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.

Document null when testing with Testing Library

I'm trying to test a single component in my react app and getting the following error:
TypeError: Cannot read property 'clientWidth' of null
20 |
21 | resize = () => {
> 22 | const contentWidth = document.getElementById('root').clientWidth;
Here's the test:
import React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { render, screen } from '#testing-library/react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducer from '../store/reducer';
import Navigation from '../App/layout/AdminLayout/Navigation'
const store = createStore(reducer);
describe('Menu', () => {
it('Estate Planning points to classic estate planning page', () => {
render(
<MemoryRouter>
<Provider store={store}>
<Navigation />
</Provider>
</MemoryRouter>
);
screen.debug()
})
})
I tried with defining the container render(..., { container: document.body}), but got the same error. I'm not sure what I'm missing.
You are getting this error because your document does not contain an element with id "root" when running a test with react-testing-library. This is likely because react-testing-library renders your component to a different container than ReactDOM (which is used to run your application).
The Problem
Let's look at a typical React application setup.
<!-- public/index.html -->
<html>
<body>
<div id="root"></div>
</body>
</html>
// src/index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
ReactDOM.render(<App />, document.querySelector("#root"));
// src/components/App.js
import React from "react";
const App = () => <div>Hello World!</div>;
export default App;
As we can see, index.js looks for an HTML element with an id of "root" and renders our App component inside that element. We can confirm that is happening by inspecting the element in your browser's developer tools:
<html>
<body>
<div id="root">
<div>Hello World!</div>
</div>
</body>
</html>
Now, let's write a simple test, and see what the DOM looks like.
// src/components/App.test.js
import React from "react";
import { render, screen } from "#testing-library/react";
import App from "./App";
test("renders the component", () => {
render(<App />);
screen.debug();
});
screen.debug() prints the DOM for debugging purposes. We can see that it does not include an element with id "root":
<body>
<div>
<div>
Hello World!
</div>
</div>
</body>
So the DOM container is slightly different for your test vs. runtime.
The Solution
One way to fix this problem is to refactor your code not to be dependent on the "root" element. Another option is to tell react-testing-library to render your component in a custom container. Here is an example of what that might look like:
// src/components/App.test.js
import React from "react";
import { render, screen } from "#testing-library/react";
import App from "./App";
test("renders the component in a specific container", () => {
const container = document.createElement("div");
container.id = "root";
render(<App />, { container: document.body.appendChild(container) });
screen.debug();
});
Now, we can see an element with id of "root" in the DOM, so your component should be able to find that element.
<body>
<div id="root">
<div>
Hello World!
</div>
</div>
</body>

Flutter : Use Froala-editor in Flutter web

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 !

Error while loading a basic react-leaflet map

I am new to react-leaflet.
I'm working on a Flask React project and I'm trying to load a react-leaflet map.
I'm getting the below error :
Uncaught TypeError: Cannot use 'in' operator to search for 'default' in undefined
at react-leaflet.js:7
at React__default (react-leaflet.js:4)
at react-leaflet.js:5
Versions :
react-leaflet : v1.9.1
leaflet.css : v1.3.1
react-leaflet.js : v1.9.1
I have added the necessary routes for rendering the Appbody.
But I'm unable to figure out what is wrong.
import React, {Component} from 'react'
import {Map, Marker, Popup, TileLayer} from 'react-leaflet'
const position = [51.505, -0.09]
class MainMap extends Component {
render() {
return (
<div>
<Map center={position} zoom={13}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
/>
<Marker position={position}>
<Popup>
<span>A pretty CSS3 popup.<br/>Easily customizable.</span>
</Popup>
</Marker>
</Map>
</div>
);
}
}
export default MainMap;
import React, {Component} from 'react';
import MainMap from "./map";
class AppBody extends Component {
render() {
return (
<div>
<MainMap/>
</div>
);
}
}
export default AppBody;
.leaflet-container {
position: absolute;
height: 100%;
width: 100%;
}
I'm currently using react-leaflet and I never had this kind of error, but I can see something wrong in the code (I don't know if those resolve the problem).
Firstly have you imported the leaflet.css file? You need to import this in the index.js or in the current file
import "leaflet/dist/leaflet.css";
You have also to add a ref props in the map component like this
<Map ref = "map" {...otherprops} >
I think the only problem in your code is surrounding the Map element by div tags.
So if you remove them and make the Map element at the top, then the problem should be solved.
TL;DR
Do not include the react-leaflet CDN in your index.html if you have installed it with npm or yarn.
Well, after much probing around with the problem myself I think you may have set up things incorrectly in the <head> of your index.html, this is how I had it set up before with the error happening:
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-leaflet/2.0.0/react-leaflet.js"></script>
and solving the issue:
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
Notice the difference? If you have installed react-leaflet with npm or yarn, you'll see that you don't need to add the leaflet script in your <head>. What was happening before is that the react-leaflet script was loading before the webpacked js files and it therefore could not find React. The react-leaflet source code that threw the error looked like this:
var React__default = 'default' in React ? React['default'] : React;
And obviously, if there was no React object in the first place, there will be an error when trying to find the 'default' key.
Hope this helps someone some day!