Creating an easy-to-update catalog utilizing an external file: A step-by-step guide

I am looking to create a product catalog with 1-4 products in a row, each displayed in a box with details and prices. I would like to be able to generate the catalog easily using an XML/CSV file that can be updated. Can anyone provide guidance on how to accomplish this? I have basic knowledge of HTML/CSS and can learn JavaScript if needed.

Once completed, the page will include a header followed by the products below. I plan to convert the page into a PDF for sharing with other users.

Answer №1

To start, it's essential to read your file and load it using JavaScript.

Once the file is loaded, you can then parse it into a JSON object.

Next step is to preview the content within an HTML table. (This HTML table will be used to create the PDF)

Using the library jsPDF and its plugin AutoTable, we create a PDF file with the previously generated HTML table.

Here is a sample CSV file that was used for testing:

Product,Price,Barcode
Sample product 1,100,802760000926
Sample product 2,95,802760000926
Sample product 3,20,802760000926

You can test it on my fiddle: https://jsfiddle.net/rogeliomonter/2f9m0qse/

let myList = {};
/*Function to load from CSV file*/
function openFile(event) {
    var input = event.target;
    var node = document.getElementById('output');
    node.innerText = '';
    var reader = new FileReader();
    reader.onload = function () {
        text = reader.result;
       //set to myList variable to be used later
        myList = JSON.parse(csvJSON(reader.result));
        buildHtmlTable('#output');
    };
    reader.readAsText(input.files[0]);
};

/*this function generates the HTML table*/
function buildHtmlTable(selector) {
    var columns = addAllColumnHeaders(myList, selector);

    for (var i = 0; i < myList.length; i++) {
        var row$ = $('<tr/>');
        for (var colIndex = 0; colIndex < columns.length; colIndex++) {
            var cellValue = myList[i][columns[colIndex]];
            if (cellValue == null) cellValue = "";
            row$.append($('<td/>').html(cellValue));
        }
        $(selector).append(row$);
    }
}

/*Supports the function that generates the HTML table*/
function addAllColumnHeaders(myList, selector) {
    var columnSet = [];
    var headerTr$ = $('<tr/>');

    for (var i = 0; i < myList.length; i++) {
        var rowHash = myList[i];
        for (var key in rowHash) {
            if ($.inArray(key, columnSet) == -1) {
                columnSet.push(key);
                headerTr$.append($('<th/>').html(key));
            }
        }
    }
    $(selector).append(headerTr$);

    return columnSet;
}

/*Converts CSV values into JSON object*/
function csvJSON(csv) {
    var lines = csv.split("\n");
    var result = [];
    var headers = lines[0].split(",");
    for (var i = 1; i < lines.length; i++) {

        var obj = {};
        var currentline = lines[i].split(",");
        for (var j = 0; j < headers.length; j++) {
            obj[headers[j]] = currentline[j];
        }
        result.push(obj);
    }
    //return result; //JavaScript object
    return JSON.stringify(result); //JSON
}

/*Uses jsPDF libary to generate a PDF File from the HTML table*/
function download() {
    // Default export is a4 paper, portrait, using millimeters for units
    const doc = new jsPDF();

    doc.text("My List", 10, 10);

    var columns = ["Product", "Price", "Barcode"];
    
    //Here we use the id of the table
    doc.autoTable({ html: '#output' })

    doc.save("myList.pdf");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.6/jspdf.plugin.autotable.min.js"></script>  
<input type='file' accept='text/csv' onchange='openFile(event)'>
  <br>
  <!-- the HTML table that will have the csv table -->
  <table id='output' border="1"></table>
  <br>
  <button onclick="download()">Generate PDF</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The parsing of source maps fails due to issues with the .htaccess file

After analyzing the web page, I found that the .htaccess file contains the following code: RewriteEngine On RewriteBase / Options -MultiViews DirectorySlash Off # skip POST requests RewriteCond %{REQUEST_METHOD} POST RewriteRule ^ - [L] RewriteCond %{R ...

Express API encounters an issue with multer and body-parser as req.file is undefined

I am in the process of developing an API that will need to handle file uploads along with other GET and POST requests. To manage file uploads, I am using 'multer' while utilizing 'body-parser' for all other HTTP requests. My goal is to ...

Expanding Image with HTML and CSS: A Guide

In the process of creating my website, I encountered an issue with the logo placement. I wanted the logo to be in the top left corner, similar to the one shown in this image. Initially, everything was working fine until I made some adjustments to move the ...

Experiencing Excessive Recursion While Dynamically Attaching Click Event Listener With Post Method to a Div Element

I'm encountering 'too much recursion' errors when trying to dynamically add a click handler to specific div tags with the class name 'reportLink'. Despite successfully logging the innerText of the divs, the code fails when attempti ...

Troubleshooting: AngularJS - Issues with nested controllers not functioning properly within ng-include

According to the AngularJS documentation (refer to nested controller fragment), I am attempting to implement nested controllers using ng-include Main.html <body id="spaWrapperApp" ng-app="spaWrapperApp"> <div class="container-fluid" id=" ...

Challenges when it comes to exporting files using Firebase Cloud Functions

I've been working with Firebase Cloud Functions using JavaScript, but I'm encountering issues with the import and export statements. Is there a solution to replace them? const firebase = require('firebase'); const config = { apiKe ...

Express js routing issue ("Page Not Found")

Why do I receive a "Cannot GET /" message when I access my HTTP server at http://localhost:8000/? I am using Express JS for server-side routing and Angular for client-side. Some sources suggest that this error occurs because I haven't set a route for ...

Is there a similar alternative to ignoring in webpack or browserify?

My code works perfectly in the browser after ignoring two packages with browserify: browserify files.js -i fs-extra -i request --standalone files > files.browserify.js. However, when I try to use webpack instead, the code throws errors about missing mod ...

Is there a way to instantly show the contents of a newly opened tab in BootstrapVue?

Good day, my objective is as follows: Whenever a new tab is opened, it should become 'active' and display its content on the browser Issue: Currently, when a new tab is opened, the previous tab remains 'active'. Check out a simple e ...

Designing a toggle button interface with Material UI

Looking to add a toggle button to my page. Here is an image of what I have in mind: https://i.sstatic.net/tiQAP.png Unable to find any material-ui component or API for this specific toggle button design. Considering building a custom toggle button with CS ...

Arranging divs using inline-block display. How to adjust the heights consecutively?

After much searching and attempting, I am still unable to achieve a simple task. My goal is to apply display inline-block to some divs while aligning them in a row, similar to the image below: https://i.sstatic.net/iLhLS.png The issue arises when number ...

React Native encounters issues with removing the reference to the callback attribute upon unmounting

Utilizing a component that I place in an array (of various sizes) and controlling individual components through refs, while adding refs to an object to keep track of each separately. constructor(props){ super(props); this.stamps = []; this.get ...

Determine whether either of these elements has the mouse hovering over it using jQuery

In my DOM, I have two separate elements that need to change when either one is hovered over. If the link is hovered over, not only does the image src need to change (which is easy), but also the link color needs to change. Similarly, if the image is hovere ...

decoding json field containing forward slashes using javascript

Seems easy enough, but I'm having trouble figuring it out. let data="[{name:\"House\",id:\"1\"},{name:\"House and Land\",id:\"5\"},{name:\"Land\",id:\"6\"},{name:\"Terrace\",id:&bs ...

Comparing the use of jQuery click event with the button to trigger a function that calculates the

Currently, I am grappling with a JQuery function that checks if any checkboxes are ticked within my form. My version of JQuery is v1.10.2. The code functions as expected when triggered by a button, but when I attempt to trigger it with a checkbox within t ...

Struggling to get the picture and text to line up

I've been struggling with a seemingly simple task but just can't seem to make it work. My goal is to create a basic comment structure that looks like this: *image* *name* *comment* The issue I'm facing is trying to position the ...

Automatically calculate the product of two columns in a gridview

Greetings, I am currently working on a project that involves calculating values from two textboxes within a gridview and displaying the result in a third textbox using JavaScript. The calculation should occur as soon as a value is entered into the second ...

Enhancing the appearance of the MUI DatePicker

I'm currently using a DatePicker component from Mui Lab and I'm attempting to customize the appearance of the Calendar component by incorporating some border or background color. Although I've tried utilizing the PaperProps prop for DatePick ...

In the world of MUI, how should one interpret the symbols '&', '>', and '*' when used together?

Currently, I am in the process of building a website using React. To help with this project, I purchased a Material-UI React template. As I was going through the code, I came across the line 4 where it mentions '& > *', and I'm not qu ...

Best practices for managing an array of buttons and handling click events in ReactJs

While working on my react class component, I encountered an issue. The alert popup keeps appearing constantly without any button click as soon as the component renders. onHandleOnClick(data, e) { console.log(data); alert("got it" + data); } rend ...