React - download file button - reactjs

I'd like to use a button to download file stored in public folder. I have test.xlsx in public folder, and here is my code
<a href={"/test.xlsx"} download target='_blank'>
<button> click </button>
</a>
However, when I go to the website, it says Failed - No file. How can I fix it? Do I have to edit webpack.config.js?

Could you try this method, this should work. Using a file-saver hook.
import React from "react";
import { saveAs } from "file-saver";
export default function App() {
const saveFile = () => {
saveAs(
"https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
"example.pdf"
);
};
return (
<div>
<button onClick={saveFile}>download</button>
</div>
);
}

Your code works 100% but you only need the download
<a href="/test.xlsx" download ><button> click </button></a>
I would suggest remove the target='_blank' as every browser can respond differently and may not trigger the download especially if it is counted as an attempt to redirect to a viral alternative like a popup advert etc.
What is wrong is checking the URL so if a browsers sees / it will attempt to open the download from its own root and logically I do not have your /test.xlsx in my c:\ folder. but it is in the working folder
However it is in the HTML working folder
so all I need to do is simply ensure I use the correct relative call to the valid files location e.g. this if its in the same folder
<body>
<a href="./test.xlsx" download ><button> click </button></a>
<body>
or simpler for current work folder if it is the public folder remove the path
<body>
<a href="test.xlsx" download ><button>Click to download test.xlsx</button></a>
<body>

Related

Embed image file and use it on page

i am trying to add static file to single page blazor app. I created new folder Images uder wwwroot set image as embeded but its not showing.
private void ConfigureVirtualFiles(IWebHostEnvironment hostingEnvironment)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<SimplyMapModule>();
if (hostingEnvironment.IsDevelopment())
{
/* Using physical files in development, so we don't need to recompile on changes */
options.FileSets.ReplaceEmbeddedByPhysical<SimplyMapModule>(hostingEnvironment.ContentRootPath);
}
});
<div class="col-md-auto text-center">
<img src="~/Files/rent-kollagenprotein.png" style="max-width: 400px;" class="w-100 mb-5 my-md-3">
</div>
this is default virtual files system registration. any help is welcome.

How can I inject arbitrary string HTML content into the head of my gatsbyjs site?

I have a GatsbyJS site that I am working on where the main content source is a Wordpress install. One of the things I like to add to my sites is the ability to have placeholder areas in the site where I can control the content via the CMS. Usually I have a header_scripts area that goes at the bottom of the <head> tag, a body_scripts area that goes at the start of the <body> tag, and a footer_scripts area that goes at the bottom of the page <body>. With these three, I can usually integrate third-party add-ins pretty easily without having to do code deployments.
Sometimes I need to embed stylesheets, sometimes I need to embed script tags, and sometimes I need to throw in <meta> tags. Really the content could be anything. This data comes back as a raw string from my Wordpress GraphQL endpoint.
So now my question is, how do I get this content injected into my Gatsby site in the following places:
<html>
<head>
...
{header_scripts}
</head>
<body>
{body_scripts}
...
{footer_scripts}
</body>
</html>
I've found so far that I can just include the body_scripts and footer_scripts in a fairly regular manner in my Gatsby page template. In gatsby-node.js, I pass in the property values using the pageContext. It's kind of a bummer that they need to be wrapped in a <div /> tag, but they seem to work just fine.
import React from 'react'
export default class PageTemplate extends React.Component {
render = () => {
return (
<React.Fragment>
{this.props.pageContext.bodyScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.bodyScripts}} />
)}
{/* my page content here */}
{this.props.pageContext.footerScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.footerScripts}} />
)}
</React.Fragment>
)
}
}
Now for the real question. I am stumped on how to get the dynamic content from the header_scripts into the Gatsby server-side-rendering <head> tag. The closest thing I have found to being able to inject content into the head is to leverage the gatsby-ssr.js onRenderBody function. However, this seems to require pre-determined React component instances in order to function. I can't just pass it in plain raw string content and see the output in the page source:
export const onRenderBody = async ({
pathname,
setHeadComponents,
setHtmlAttributes,
setBodyAttributes,
setPreBodyComponents,
setPostBodyComponents,
setBodyProps
}, pluginOptions) => {
setHeadComponents(['<script>alert("hello");</script>'])
}
This results in an escaped string getting inserted into the <head> tag:
<html>
<head>
...
<script>alert("hello");</script>
</head>
<body>
...
</body>
</html>
I'm at a loss as to how to proceed. I can't just wrap my string in a <div /> tag like in the body because div tags can't go inside the head tag. I can't think of any head-capable HTML tags that would accept this kind of content.
The only idea I've had is to actually parse the string content into full React components. This seems daunting given the number of possible tags & formatting that I would need to support.
Am I going about this the wrong way? How can I get my arbitrary content into my Gatsby site's head tag?
It's a broad question and it will need some trials and errors to ensure that it's fully working without caveats in all scenarios but, among the things you've tried, you can add a few more options to the list to check which ones fit better.
Regarding the body_scripts and footer_scripts both can be inserted using the:
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.footerScripts}} />
In any desired page or template. For the header_scripts and the meta tags (SEO), you can use the <Helmet> component. Basically, using this component, everything that is wrapped inside, it's becomes transpiled inside the <head> tag once compiled.
export default class PageTemplate extends React.Component {
render = () => {
return (
<React.Fragment>
<Helmet>
{this.props.pageContext.headerScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.headScripts}} />
)}
</Helmet>
{this.props.pageContext.bodyScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.bodyScripts}} />
)}
{/* my page content here */}
{this.props.pageContext.footerScripts && (
<div dangerouslySetInnerHTML={{__html:this.props.pageContext.footerScripts}} />
)}
</React.Fragment>
)
}
}
However, if the data comes from a CMS, it won't be available in the SSR yet, so, one easy thing you can do is to customize the outputted HTML (html.js) that Gatsby generates in each compilation. From the docs:
Customizing html.js is a workaround solution for when the use of the
appropriate APIs is not available in gatsby-ssr.js. Consider using
onRenderBody or onPreRenderHTML instead of the method above. As a
further consideration, customizing html.js is not supported within a
Gatsby Theme. Use the API methods mentioned instead.
Run:
cp .cache/default-html.js src/html.js
Or manually, copy the .cache/default-html.js file and paste it /src folder. There you can customize the final HTML.

Vue.js how to import SVG logo

I'm new to vue.js and am used to React. I'm currently trying to import an SVG logo into my header component but I'm not sure how. In react, I would simply do import Logo from './path; and use Logo wherever I needed it within the current component. This is basically what I'm attempting to do right now but I keep getting errors. Could anyone tell me how this could be done in Vue.js?
<template>
<header class="nav">
<img src={Logo} alt="24G Logo">
</header>
</template>
<script>
import Logo from '../assets/76_logo.svg';
export default {
name: 'Header'
}
</script>
<style lang="scss" scoped>
</style>
Here are three options. The best in my opinion is the third:
Simply input src like in any webpage <img src='../path/to/file.svg' ... though that come with some drawbacks (regardless if it's :src='logoPath' where logoPath is variable containing the same. For a short overview see this stack answer, and for more details see this article from css tricks.
Check out svg-vue-loader. Vue won't automatically import svg without a loader.
Just paste it in! (Open the svg file and copy paste it into the template.) The best option in my opinion, especially when prototyping or for smaller projects. Like so:
<template>
<header class="nav">
<svg ....
</header>
</template>
If that would make it too crowded later on, just make a new component, call it say Logo, and paste svg in there and then import MainLogo component into your header.
No need for svg-loaders. Though loaders are a dev dependency, so not like it would cost you anyway; they would just do the same thing you can do manually.
// in MainLogo.vue
<template>
<svg ....
</template>
// in MainHeader.vue
<template>
<header class="nav">
<MainLogo>
</header>
</template>
<script>
import MainLogo from '../path/to/file.vue'
export default {
components: { MainLogo }
}
</script>
Cheers
After searching and searching, and seeing all the answers were old, I went ahead and tried the newish v-html prop.
The result, success!
<div v-html="avatar" style="width: 100%"></div>
The avatar is a full element that I stored in the database.
No loaders, no imports, just using the built in resources of Vue.js
If you leave out the style, then the svg will not show.
Also, loading the full element enables me to attach a ref prop to the element. Enabling me to access the svg through script.
Hope that helps someone!!
I used this with avataaar's random avatar generator and stored the resulting svg to the database (mongo)
Here is another approach that I used:
<template>
<a href="#"
class="log-link-css-class">
<!-- SVG Icon Start-->
<img alt="alt message" class="your-logo-css-class"
src="#/assets/images/logofilename.svg">
<!-- <SVG Icon End /> -->
</a>
</template>
No import required. Vue automatically converts it to the unique URL.
edit your code
<script>
import Logo from '../assets/76_logo.svg';
export default {
name: 'Header',
data(){
Logo: Logo
}
}

How to create external download link in React?

How to create link with preventDefault and on click it must run download file from external url in React
return (
<Link to="/page">
<img src={src} />
<a href="https://external_photo_uri/pic.jpg" download />
</Link>
)
You can create a normal anchor tag with download attribute.
Example
<a href="myurl" download> <img src={src} /></a>
You can use react-download-link
A simple component to download data from a client-side cache (e.g. flux, redux). Design to be used with browserify or webpack.
Install with:
npm install --save react-download-link
Include with:
import DownloadLink from "react-download-link";
Use:
<DownloadLink
filename="myfile.txt"
exportFile={() => "My cached data"}
>
Save to disk
</DownloadLink>
Or with Promises:
<DownloadLink
filename="myfile.txt"
exportFile={() => Promise.resolve("My cached data")}>
Save to disk
</DownloadLink>
The component will default to an anchor tag, but the tagName prop will accept a string of any other HTML tag you prefer, such as 'button'.
I solved this problem. I create parent div on anchor tag and onClick run e.stopPropagation()
Please try with this one.
<!DOCTYPE html>
<html>
<body>
<p>Click on the w3schools logo to download the image:<p>
<a href="/images/myw3schoolsimage.jpg" download>
<img src="/images/myw3schoolsimage.jpg" alt="W3Schools" width="104" height="142">
</a>
<p><b>Note:</b> The download attribute is not supported in Edge version 12, IE, Safari 10 (and earlier), or Opera version 12 (and earlier).</p>
</body>
</html>
Reference: https://www.w3schools.com/tags/att_download.asp

Angular.js Click on link to download is causing navigate to home page

Here is what I have
<div quick-list>
<br quick-link icon='download-alt' href='{{ getDownloadLink(assignment) }}' text="getMessage('assignmentListStudent.attachment.action.download')">
</div>
The concerned function for this is as follows
$scope.getDownloadLink = function(assignment) {
if (!assignment || !assignment.userAttachment || !assignment.userAttachment[0] ) {
return '';
}
return assignment.userAttachment[0].path.replace("equella/items", "equella/force-download/items");
};
I am not sure what is wrong here but the moment I click on the download link, I see that the page navigates to the home page where as it should be downloading an existing file.
This is what I see in chrome.
<li class="quick-link ng-scope" quick-link="" icon="download-alt" href="/community/proxy/equella/force-download/items/71c1f5d5-8a1f-4e85-84d6-7560a9e01b63/1/hanks.tomha.24066.PNG" text="getMessage('assignmentListStudent.attachment.action.download')"><i class="icon-download-alt"></i>Download</li>
Reality Student Central (5-15) UPDATED titleInSequence
Is there anything that i'm doing wrong? Should I change something? Any help would be appreciated.
That's because your router is likely redirecting you to the homepage.
See Angularjs simple file download

Resources