How to clear the Dropzone in React Dropzone Component after file upload? - reactjs

I need to destroy the dropzone component after file upload, not able to get the dropzone object to apply the dropzone.destroy() method.

To clear the dropzone, we need to get the dropzone object and use the dropzone.destroy() method. We need to first initialize a variable outside the complete component as:
var myDropzone;
To get the dropzone object we need to use the init event of the dropzone which gives us the dropzone object like below:
initCallback (dropzone) {
myDropzone = dropzone;
console.log("dropzone"+myDropzone);
}
const eventHandlers = {
addedfile: this.onDrop.bind(this),
removedfile: this.removeFile.bind(this),
init: this.initCallback.bind(this)
}
Then we can call the dropzone.destroy() method after our upload is completed like this:
myDropzone.destroy();
It will reset our files array to [] and remove the files from the view also.

Related

Data Tables inside of a Modal

Does anyone know how to get datatables to work inside of a modal? I've been following the example at https://docs.abp.io/en/abp/latest/UI/AspNetCore/Modals#modals-with-script-files and bascially did all of my work to load the datatable inside the initModal function but it doesn't seem to work.
I was able to figure this out on my own. I tried to specify my class as an object (no quotes) rather than a string as in their example:
var productInfoModal = new abp.ModalManager({
viewUrl: '/Products/ProductInfoModal',
scriptUrl: '/Pages/Products/ProductInfoModal.js', //Lazy Load URL
modalClass: 'ProductInfo' // << Make sure to specify as a string
});
You may want to check CmsKit.Admin.Web project for view the usage of modal in datatable.
1-) Create your modal view. (.cshtml file):
Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/CreateModal.cshtml
2-) Define your abp.modals class. (.js file for your modal):
Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/createModal.js
3-) Define your modal by using ModalManager and call the modal wherever its needed:
Define Modal Manager
Open the modal when an event triggered
You can create a row action and open the modal when the action is clicked.
...
rowAction: {
items: [
{
text: l('MyRowAction'),
action: function (data) {
myModal.open();
}
},
]
}
...
Refresh the datatable according to the changes of your modal

React Component getting added in Vaadin 7 only on button click

I have a vaadin7 application to which I am trying to integrate a sample react application. It is working properly when I implement the React component creation inside a button click. But it is not working if I put the code outside the button click. It shows error "Uncaught TypeError: Cannot read property 'appendChild' of null
at Module.11 (index.js:9)
at u (bootstrap:84)
at t (bootstrap:45)
at Array.r [as push] (bootstrap:32)
at main.90a85973.chunk.js:1" while inspecting.
In vaadin application, i am creating div named "root" and in the index.js of sample react application, I am trying to get the root div created from vaadin and appending "react-root" to "root" div so as to fit the react application in my vaadin layout.
Please find below code for vaadin ui
CustomLayout layout = null;
try {
String dynamicHtml = "<div id=\"root\"></div>";
layout = new CustomLayout(new ByteArrayInputStream(dynamicHtml.getBytes()));
System.out.println("JS Layout");
} catch (IOException e) {
System.out.println("could not create custom layaout"+ e);
}
uimainLayout.addComponent(layout);
//If the below 4 lines of code are added inside the button click, the reactcomponent is rendered inside the layout properly on clicking the button . Otherwise it is showing the "Uncaught TypeError: Cannot read property 'appendChild' of null"
VerticalLayout jsmainLayout = new VerticalLayout();
ReactComponent reactComponent=new ReactComponent();
jsmainLayout.addComponent(reactComponent);
uimainLayout.addComponent(jsmainLayout);
getMainLayout().addComponent(uimainLayout);
setCompositionRoot(getMainLayout());
My Reactcomponent
#JavaScript({"<ip:port>/static/js/2.1f3e22a9.chunk.js","<ip:port>/static/js/3.583f7bad.chunk.js","<ip:port>/static/js/runtime-main.23689a58.js","<ip:port>/static/js/main.90a85973.chunk.js","ReactComponentConnector.js"})
#StyleSheet("<ip:port>/static/css/main.a617e044.chunk.css")
public class ReactComponent extends AbstractJavaScriptComponent {
public ReactComponent() {
System.out.println("Inside ReactComponent");
}
#Override
protected ReactComponentState getState() {
return (ReactComponentState) super.getState();
}
}
ReactComponentState
public class ReactComponentState extends JavaScriptComponentState {
private static final long serialVersionUID = -3283446856435450054L;
}
ReactComponentConnector.js
window.com_p1_p2_ReactComponent = function () {
}
Index.js of my sample react application
const rootEl = document.createElement('div')
rootEl.setAttribute('id', 'react-root');
//error points to the below line
const parentEl =document.getElementById('root');
parentEl.appendChild(rootEl)
ReactDOM.render(
<App />
,
rootEl
);
reportWebVitals();
It's not clear exactly what it is that triggers running the code listed for index.js, but it would seem like it's run before the contents of the custom layout has been initialized. In that way, no element with the id root exists and this would cause the reported error.
I assume creation happens through new ReactComponent(this.getElement()) from inside the JS connector initializer. If this is the case, then they reason for the problem is that both the actions (set custom layout content and initialize the JS connector) are sent to the browser in the same batch, but the connector is initialized in an earlier phase. If the JS component is sent in a batch triggered though a click listener, then this won't be a problem.
To solve this, you could use a direct element reference instead of relying on getElementById in combination with an id defined in the content of a custom layout. The easiest way would be if you'd restructure to use the this.getElement() instance that you're now passing to the ReactComponent constructor.

Passing properties from DropzoneArea to Dropzone

I am using DropzoneArea:
import { DropzoneArea } from 'material-ui-dropzone';
which is based on react-dropzone.
Dropzone from:
import Dropzone from 'react-dropzone'
contains certain props, not exposed by DropzoneArea but available by Dropzone
For instance disabled.
I have several question regarding it:
When I create DropzoneArea component, is there a way to mark it as disabled?
Is there a way to pass original properties of Dropzone
And here is an original issue I try to solve, probably the solution is not the best one and there are alternatives:
When a user uploads a file to DropzoneArea, I can send it to the server via onChange handler. I'd like to disable the whole component, while server is processing a file, until we get a response back.
The DropzoneArea has the property dropzoneProps, which is an object that is being passed (as props) to the Dropzone:
<DropzoneArea
dropzoneProps={ { disabled: true} }
...
/>

Create Html from React Component including Style

I have a simple react component in which using ref I am getting the div but I have to generate a html includes styling as well. So I can pass this html to PDF generation backend server.
pdfRef(elem){
console.log(elem);
//<div><span>dataPDF</span> </div>
}
render() {
return (
<div ref={(elem) => this.pdfRef(elem)} className="SomeCssClass">
<span >dataPDF</span>
</div>
);
}
}
[Edit]
When I try to print the div via ref, the elements are printed with class name. But when I send this string to pdf service, since only html element is sent and class name without the actual css , the pdf is generated without style.
is there any way to generate html with css as as string so further it can be send to pdf service. Hope the question is clear
Any pointers?
The server.js script in react-dom lets you render a React component to static html string. You can require it in your code like:
const ReactDOMServer = require('react-dom/server');
Or using ES6 syntax:
import ReactDomServer from 'react-dom/server'
After this you can render your component to HTML string using the ReactDomServer.renderToString or ReactDomServer.renderToStaticMarkup functions as follows:
const htmlStr = ReactDomServer.renderToStaticMarkup(<MyComponent prop1={'value1'} />);
This looks almost exactly like ReactDom.render, except that it doesn't need the second parameter of dom node to render at, and the html string is returned. Additionally this method can be used on both client and server side. For your generate-pdf use case renderToStaticMarkup would suffice. If required check the documentation at following link for subtle difference between the two methods mentioned above: https://reactjs.org/docs/react-dom-server.html

Cannot test component inside a Panel using Jest/Enzyme

I need to test a component inside a Panel.
The main issue is that a panel is rendered outside of the react root element when it's opened.
When I mount my component the content of the panel is not displayed in the mount. I found that the content is outside of react. I'm able to access the content using the document but I want to leverage Jest/Enzyme to simulateClick, spyOn and so on...
How can I test elements inside the Panel using Jest/Enzyme?
Try to use jsdom in order to get the document or window.
import jsdom from 'jsdom'
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>')
global.document = doc
global.window = doc.defaultView
...

Resources