In my project using React with Typescript I am trying to print a div with some data.
Basicaly This div is in a modal, I gave it an id (id='printablediv'). Then when you press print on the modal I run this function :
const Print = () => {
let printContents = document.getElementById('printablediv')?.innerHTML!;
let originalContents = document.body.innerHTML;
document!.body!.innerHTML! = printContents;
window.print();
document.body.innerHTML = originalContents;
setIsModalOpen(false)
}
Then problem is that when I click print and the print page opens and I print the div, after that the page freezes. and I cant do anything. I have to reload the page. Even if i don't print and press cancel, it still freezes. Has anyone encountered with problem?
I am trying not to use a library such as react-to-print.
Edit:
This is where i call the Print function:
<TicketModal
isOpen={isTicketModalOpen}
onAnulla={onCloseTicketModal}
onPrint={Print}
code={createResponseCode}
pin={createResponsePin}
id={user.uid}
currency={createResponseCurrency}
amount={createResponseAmount}
/>
the onPrint is the prop connected to the modal button
<Button size="lg"
variant="primary"
className='ticket-modal-card__button'
onClick={onPrint}
>
Print Ticket</Button>
I found the solution.
Apparently the problem is I'm removing the original content, and then replacing it with new, different content, so all the event listeners and metadata react had attached to the original content is lost. innerHTML doesn't include those things (setting innerHTML is probably never what you actually want to do in any situation).
To print just part of a page, I set up a print stylesheet that changes the styling of your page when printing, and not change the HTML itself.
.printme {
display: none;
}
#media print {
.no-printme {
display: none;
}
.printme {
display: block;
}
}
This way I can Display and hide everything I want and print only the part I need.
Related
I have .js file called Edit which is used for edit purpose. I have another .js file called Add. I have a dialog box in edit.js which will open when I click a button. But I don't want to use a button instead I want to get that a dialog box when I click anywhere on box. I tried using onclick in div tag but I didn't get any response.
this is the output
so if you observe we got a edit button there if click it I am getting form/dialog box for editing the content. but I want that form or dialog box to open when I click anywhere on the yellow box.
<div id='color' className='div2' key={item.id} style={{width: 340,
# border: '5px solid white',textIndent:-30,paddingRight:32,paddingLeft:40,whiteSpace:'pre',paddingTop:15, backgroundColor:item.currentColor}} onClick={()=>{editpage(item.id)}} >
this is what I used for calling function for getting form in another .js file. It is part of a mapping function.` there is a onclick event I used that whenever I click on the box or content which is all under div tag I need to go to that function and there go to edit and then form but it didn't work
the function to which it goes is this:
const editpage=(id)=>{ <Edit id={id}></Edit> }
I want to send a id as a parameter which is passed to Edit.js.
I used <Edit/> because it is a another js file which I am importing in Add.js file.
I am not able to get the output can you please me with this.
how I can use this when I click on color box should open a form which is indeed in another file.
This is successfully calling a function on the click event:
onClick={()=>{editpage(item.id)}}
But what does that function do? Absolutely nothing:
const editpage=(id)=>{ <Edit id={id}></Edit> }
The function doesn't return anything (not that returning from a click handler does anything either of course), doesn't perform any operations, nothing. It's just a single JSX expression.
Take a different approach entirely. Add your component to the markup, but wrap it in a condition based on state. For example, consider this state value:
const [openEditPage, setOpenEditPage] = useState();
The purpose of this state value is to keep track of which item.id should currently have its "edit" component visible. (Default to undefined so none are visible by default.)
Use this value when rendering the components:
<div id='color' className='div2' key={item.id} style={/*...*/} onClick={()=>{editpage(item.id)}}>
{openEditPage === item.id ? <Edit id={item.id}></Edit> : null}
</div>
So in this case the <Edit> component will only be rendered if openEditPage === item.id. Which is what the editpage() function can do:
const editpage = id => setOpenEditPage(id);
Clicking on the <div> would invoke the editpage function, which updates the state value, which triggers a re-render, and in the new render the <Edit> component is shown because the condition would be true.
we are loading 100 records in the grid initially, after that when we scroll down , loading another set of data.
But when we try to print the page its loading just 100 records in the print preview screen, we are using react-to-print, functional component.
const handlePrint = useReactToPrint({
content: () => componentRef.current,
});
we want load all the data available in the List, please help.
I found myself in a similar problem and this answer from github helped me.
You have to surround your render with a div of styling overflow: scroll and also remove overflow styling, maximum height and any other view limiting styling from the surrounded element's "stylings" like the example below.
Disclaimer: I used MUI in some instances.
render() {
<div sx={{ overflow: "scroll" }}>
{
sampleIterable.map((x,n) => {
...
})
}
</div>
}
I would like to find out how you can hide and show div element in react typescript. This is the code that I have so far. Any feedbacks
function GetUserInfo (user:User)
{
let userInfo = USERINFO.find((d) => d.Address === user.Address);
if(userInfo)
{
//Show Div
showDiv
}
return userInfo.data
}
function showDiv(props) {
return <div id="missingPO">Unable at identify user info.</div>
}
The code you have written is a bit unclear about how you wanna hide it,
But for example, you want to hide an element in case a variable is true, in your case can be something with an address or what you are trying to do.
for example, I want to hide a value when const isHidden=true
I will discuss two ways.
You can declare a class that hides the div, for example in your global class add a CSS class
.hidden{
display: none;
}
then in your div, you can check if isHidden enables class.
<div className={isHidden && 'hidden'} />
you can check like this
//in your method return div in case you are not hidden, pass the isHidden as props.
function showDiv(props) {
return props.isHidden ?<></>: <div id="missingPO">Unable at identify user info</div>
}
// or just check with &&
!isHidden && <div> will show only if is hidden false</div>
// the pros of using the second one are because you are unmounting div, but this can be a downside too, depends what you need
// with display it will remove from the page, but now from the dom, also you can make visibility: hidden if you do not want to remove it from the page just to hide.
If you have any question please ask 😄
I am using React dropzone for file upload
<DropZone
accept='.pdf,.pptx,.ppt,.docx,.doc,.xls,.xlsx,.xslx,.png,.xsl,.jpg,.jpeg,.gif,.zip'
onDrop={ files => {
this.handleFileDrop(files);
this.dragLeaveHandler();
} }
onDragEnter={ this.dragOverHandler }
onDragLeave={ this.dragLeaveHandler }
multiple={ false }
style={ { height: '100%' } }
>
dragOverHandler = () => {
console.log('enter');
this.setState({
isDragOver: true,
});
};
dragLeaveHandler = () => {
console.log('exit');
this.setState({
isDragOver: false,
});
};
When a file is moving above the drop zone onDragLeave event fires simultaneously.
Should I use some other events?
How can I fix this issue?
You could use pointer-events: none; on the element(s) that are firing the drag leave. That should still allow the dropped event and getting the accepted file though would stop overriding the dropzone events.
The problem you're facing is most likely caused by the DOM events dragEnter and dragLeave getting messed up instead of any flaw in the react-dropzone package. Some elements may cause hovering over them in certain positions not to register as hovering over their parent element. For example, there is a thin sliver at the top edge of any plain string rendered inside a block displayed element. Most commonly this happens inside a <p> tag.
Without seeing the children rendered inside your dropzone, it is impossible to give a specific fix. Generally, you will have to mess with the styling of the children, though. <p> tags for example will not be a problem if their size is set to 0 pixels or if they're replaced with <span> tags. Both options will disrupt the displaying of the children, which is unfortunatley unavoidable.
As for using other events, you're out of luck. The DropZone component relies on the onDragEnter and onDragLeave HTML DOM events. Therefore any fix you might come up with won't fix the component itself.
All in all, it's an unfortunate issue that just has to be dealt with. The simplest way to deal with it is to just have at most one piece of text inside the dropzone and to set its size to 0 pixels with css: height: 0px;. Regular <div> elements won't cause issues, so you can craft an intricate dropzone using them.
I'm using a Modal based on the example code from the docs: https://react-bootstrap.github.io/components.html#modals-live. What I want is for a child component to be rendered only when 1) it's data is ready, and 2) when the modal is opened. Also, the child component needs to know how wide the area is it has to work with (because it's doing some d3.js svg drawing inside).
I'm also, btw, using fixed-data-table, so the data (a concept) is put in state and the Model is opened on row click:
onRowClick={(evt, idx, obj)=>{
let concept = filteredDataList.getObjectAt(idx);
this.openModal();
this.setState({concept});
}}
As per the Modal docs example, the Modal sits there in the render and exists in the DOM in a closed state until something opens it. However, the Modal.Body doesn't seem to exist till the Modal is open. My bright idea is that the child, ConceptDetail, can get the ClientWidth from a ref to its containing div.
let conceptDetail = '';
if (this.state.concept) {
conceptDetail = <ConceptDetail
containerRefs={this.refs}
concept={concept} />/
}
<Modal>
...
<Modal.Body>
<div ref="modalBody" style={{width:'100%'}}>
{conceptDetail}
</div>
</Modal.Body>
...
</Modal>
This would work, except the ref isn't ready until after the child component is rendered. To figure out what's going on, I did this:
componentWillUpdate(){
if (this.refs.modalBody) {
let { clientWidth } = this.refs.modalBody;
alert(`will update, width: ${clientWidth}`);
} else {
alert('will update, no modalBody ref');
}
}
componentDidUpdate(){
if (this.refs.modalBody) {
let { clientWidth } = this.refs.modalBody;
alert(`did update, width: ${clientWidth}`);
} else {
alert('did update, no modalBody ref');
}
}
When I click a row, I see the alert will update, no modalBody ref, followed by the alert did update, width: 868, and then the child component displays. But the child didn't get the width (or the updated ref) because it actually renders before the componentDidUpdate. The reason I see the alert first (I assume) is because the Modal is animated and doesn't appear instantly on rendering. When I close the Modal, I actually do see for a quick flash that it has finally received the correct width, but at that point I don't need it anymore.
So, most specifically, my question is: How can a child component of a Modal be informed of the modal body's width? I would be even more grateful if someone might explain the right way to do what I'm trying to do in general: Trigger display of a Modal with a child component that would like to receive data and container dimensions as props.
Ok, so a partial answer that got me going is here: Trigger modal shown for React Bootstrap
So, onEntered doesn't fire till the modal is all ready, so that's the time to get the width:
<Modal ...
onEntered={(() => {
let { clientWidth } = this.refs.modalBody;
if (this.state.modalWidth !== clientWidth)
this.setState({modalWidth:clientWidth});
}).bind(this)}>
...
<Modal.Body>
<div ref="modalBody">
{this.getConceptDetail()}
</div>
</Modal.Body>
...
</Modal>
Then a separate method to get the child component (if ready):
getConceptDetail() {
const {concept, modalWidth} = this.state;
if (concept && modalWidth) {
let conceptId = concept.records[0].rollupConceptId;
return <ConceptDetail
width={modalWidth}
concept={concept}
conceptId={conceptId}/>;
}
return <h3>no concept detail</h3>;
}
This isn't terrible, I guess, and it works. If someone knows a better way to structure it, I'd be happy to hear.
ADDENDUM: Sort of works, that is. The child component that actually needs to know the width is a couple levels down from the Modal body, so it needs to know the width of its direct parent... grrr How are react components supposed to know their container directions??