initial commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# csv-data-generator
|
||||
A client side website that allows the user to create CSV data that is meaningful that can be used as data source for any data requirements
|
||||
@@ -0,0 +1 @@
|
||||
./csv-data-generator.sh
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
dir="$(dirname $(readlink -f $0))"
|
||||
cd "$dir"
|
||||
serve ./
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 694 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 510 KiB |
+143
@@ -0,0 +1,143 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CSV File Generator</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css"
|
||||
integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ=" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" href="./style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Intro container with a brief description of the Application -->
|
||||
<div class="introduction">
|
||||
<h1>CSV File Generator</h1>
|
||||
<p class='intro-details'>Welcome to the one stop solution for all your data generating needs. The CSV Data
|
||||
Generator can generate a large amount of meaningul data depending on your data requirements in almost no
|
||||
time.
|
||||
<br><br>
|
||||
It's a simple 4 step quick process
|
||||
<br>
|
||||
  Step 1) Add as many columns as you want
|
||||
<br>
|
||||
  Step 2) Set the type of data you want for each column
|
||||
<br>
|
||||
  Step 3) Put in the number of rows you want to generate
|
||||
<br>
|
||||
  Step 4) Generate the File
|
||||
<br><br>
|
||||
No Installations, No Sign-ins, No Hiccups.
|
||||
<br>
|
||||
<small class="intro-footer">This works best on a Chrome/Firefox Browser</small>
|
||||
</p>
|
||||
<button class="btn" id='getStarted'>Get Started</button>
|
||||
</div>
|
||||
<!-- Main Content of the Website -->
|
||||
<div id="main-content">
|
||||
<!-- Header -->
|
||||
<div class="header-section cover">
|
||||
<h1>CSV File Generator</h1>
|
||||
<div class="info">Easy, Customizable, Open Source, Fast & Free</div>
|
||||
</div>
|
||||
<!-- Main Container with the table, buttons and QnA -->
|
||||
<div class="main-container">
|
||||
<div class="data-input-container">
|
||||
<div class="row header" id="tableColNames">
|
||||
<div class="column">Column Name</div>
|
||||
<div class="column">Type of Data</div>
|
||||
<div class="column actions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
</div>
|
||||
<div class="config">
|
||||
<div class='row-count-input'>
|
||||
<label for="row-count">Number of Rows</label>
|
||||
<div class="help-tip">
|
||||
<p>Enter the total number of rows that you want to generate</p>
|
||||
</div>
|
||||
<input type="number" class="row-count" value="1000" name="row-count" id="row-count" max="1000">
|
||||
|
||||
</div>
|
||||
<div class='buttons'>
|
||||
<!-- <button class="btn" id="view-sample">View Sample</button> -->
|
||||
<button class="btn" id="generate-button">Generate File</button>
|
||||
<!-- <button class="btn" id="generate-SQL">Generate SQL Script</button> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="additional-details">
|
||||
<h3>Why generate test data?</h3>
|
||||
<p>You should always have a good
|
||||
volume of mocked up data when testing your application. This will help catch performance issues in
|
||||
your code
|
||||
early on in the cycle as well as issues with the UI. Maybe you need to use a larger width to display
|
||||
the name of your customer because you saw that some customers have long names which are getting
|
||||
trimmed. Or maybe you see that you dont have enough space in your DB for the addresses you want to
|
||||
store.
|
||||
</p>
|
||||
<h3>Is having realistic data really important?</h3>
|
||||
<p>If you are trying to showcase your project as a real time application, it adds a lot of value to
|
||||
actually show realistic names, addresses and data instead of random alphabets typed out in a hurry
|
||||
by you. Creating
|
||||
data and testing it on your app will also add realstic issues like an apostrophe in a name or
|
||||
address which your code might not be able to handle.
|
||||
</p>
|
||||
<h3>Why use CSV Data Generator?</h3>
|
||||
<p>The CSV Data Generator is Light, Easy and Customizable with absolutely NO registration. Other data
|
||||
generators available either do not have the various options provided here OR try and get you to sign
|
||||
in and pay for the more advanced features which are available here for absolutely free!!
|
||||
<br>
|
||||
This is a light-weight solution and all the data gets created entirely on the client side using
|
||||
Vanilla Javascript.
|
||||
</p>
|
||||
<h3>How many rows/columns can I generate?</h3>
|
||||
<p>The CSV Data Generator is a light weight application that has been built using vanilla Javascript.
|
||||
You can create as much data as you like but your browser could crash if you are trying to create 1
|
||||
trillion records for a bunch of columns! So go easy :)
|
||||
</p>
|
||||
<h3>How can I see the code?</h3>
|
||||
<p>Head right down to the github repository in the footer and check it out
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- The popup displaying all the options -->
|
||||
<div class="select-input-background">
|
||||
|
||||
<div class="select-input-container">
|
||||
<div class="select-input-classification">
|
||||
<h2>Classification of Data</h2>
|
||||
</div>
|
||||
<div class="select-input-options">
|
||||
</div>
|
||||
<button class="close" id="closeInputSelector">X</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Footer with contact details -->
|
||||
<footer>
|
||||
<section id="contact" class="contact">
|
||||
<div class="profile-picture">
|
||||
<a href="http://www.markbdsouza.com" target="_blank">
|
||||
<img class="display-pic" src="images/Mark DSouza.jpeg" alt="Mark Dsouza">
|
||||
</a>
|
||||
</div>
|
||||
<div class="contact-section">
|
||||
<span class="">This open source application was developed by <br> Mark Dsouza </span>
|
||||
<div class="contact-details">
|
||||
<a href="https://www.linkedin.com/in/mark-dsouza-44692095/" class="" target="_blank"><i
|
||||
class="fab fa-linkedin-in"></i></a>
|
||||
<a href="https://twitter.com/MarkBDsouza" class="" target="_blank"><i
|
||||
class="fab fa-twitter"></i></a>
|
||||
<a href="https://github.com/markbdsouza/csv-data-generator" class="" target="_blank">
|
||||
<i class="fab fa-github"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="./scripts/faker.js" type="text/javascript"></script>
|
||||
<script src="./scripts/script.js" type="module"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,32 @@
|
||||
function generateDataArrayForColumn(totalRowCount, columnConfig) {
|
||||
let result = [];
|
||||
let columnCountArray = Array.from(Array(totalRowCount), (x, i) => i);
|
||||
columnCountArray.forEach((x, i) => {
|
||||
result.push(columnConfig.getData());
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function createHeaders(dataConfig) {
|
||||
let headers = dataConfig.map((a) => a.columnName);
|
||||
return headers;
|
||||
}
|
||||
|
||||
export function createExcelRowData(totalRowCount, dataConfig) {
|
||||
const rows = [];
|
||||
rows.push(createHeaders(dataConfig));
|
||||
let createDataSet = [];
|
||||
dataConfig.forEach((columnConfig) => {
|
||||
createDataSet.push(generateDataArrayForColumn(totalRowCount, columnConfig));
|
||||
});
|
||||
|
||||
for (let i = 0; i < totalRowCount; i++) {
|
||||
let rowData = [];
|
||||
createDataSet.forEach((columnData) => {
|
||||
rowData.push(columnData[i]);
|
||||
});
|
||||
rows.push(rowData);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
+70655
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
function downloadFile(csvFile, filename) {
|
||||
var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
|
||||
if (navigator.msSaveBlob) {
|
||||
//for IE
|
||||
navigator.msSaveBlob(blob, filename);
|
||||
} else {
|
||||
//Chrome and Firefox
|
||||
var link = document.createElement('a');
|
||||
if (link.download !== undefined) {
|
||||
var url = URL.createObjectURL(blob);
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', filename);
|
||||
link.style.visibility = 'hidden';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function generateFile(rows) {
|
||||
let csvFile = '';
|
||||
var d = new Date();
|
||||
|
||||
let filename = `CSV_Data_${d.getFullYear()}_${
|
||||
d.getMonth() + 1
|
||||
}_${d.getDate()} ${d.getHours()}:${d.getMinutes()}.csv`;
|
||||
|
||||
rows.forEach(function (rowArray) {
|
||||
let row = rowArray.join(',');
|
||||
csvFile += row + '\r\n';
|
||||
});
|
||||
downloadFile(csvFile, filename);
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
export const ALL_OPTIONS = [
|
||||
// name
|
||||
{
|
||||
name: 'First Name',
|
||||
value: 'firstName',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.firstName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Last Name',
|
||||
value: 'lastName',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.lastName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Full Name',
|
||||
value: 'findName',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.findName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Job Title',
|
||||
value: 'jobTitle',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.jobTitle();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Name Prefix',
|
||||
value: 'prefix',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.prefix();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Name Suffix',
|
||||
value: 'suffix',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.suffix();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Name Title',
|
||||
value: 'title',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.title();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Job Descriptor',
|
||||
value: 'jobDescriptor',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.jobDescriptor();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Job Area',
|
||||
value: 'jobArea',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.jobArea();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Job Type',
|
||||
value: 'jobType',
|
||||
type: 'Name',
|
||||
getData() {
|
||||
return faker.name.jobType();
|
||||
},
|
||||
},
|
||||
|
||||
//Address
|
||||
{
|
||||
name: 'Street Name',
|
||||
value: 'streetName',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.streetName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Street Address',
|
||||
value: 'streetAddress',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.streetAddress();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Secondary Address',
|
||||
value: 'secondaryAddress',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.secondaryAddress();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Zip Code',
|
||||
value: 'zipCode',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.zipCode();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'County',
|
||||
value: 'county',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.county();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'City',
|
||||
value: 'city',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.city();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'State',
|
||||
value: 'state',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.state();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'State Abbr',
|
||||
value: 'stateAbbr',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.stateAbbr();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Country',
|
||||
value: 'country',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.country();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Country Code',
|
||||
value: 'countryCode',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.countryCode();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Latitude',
|
||||
value: 'latitude',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.latitude();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Longitude',
|
||||
value: 'longitude',
|
||||
type: 'Address',
|
||||
getData() {
|
||||
return faker.address.longitude();
|
||||
},
|
||||
},
|
||||
//Company
|
||||
|
||||
{
|
||||
name: 'Company Name',
|
||||
value: 'companyName',
|
||||
// type: 'company',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.company.companyName();
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name: 'bs',
|
||||
// value: 'bs',
|
||||
// type: 'company',
|
||||
// getData() {
|
||||
// return faker.company.bs();
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'companySuffix',
|
||||
// value: 'companySuffix',
|
||||
// type: 'company',
|
||||
// getData() {
|
||||
// return faker.company.companySuffix();
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'catchPhraseAdjective',
|
||||
// value: 'catchPhraseAdjective',
|
||||
// type: 'company',
|
||||
// getData() {
|
||||
// return faker.company.catchPhraseAdjective();
|
||||
// },
|
||||
// },
|
||||
|
||||
//finance
|
||||
{
|
||||
name: 'Account',
|
||||
value: 'account',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.account();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Account Name',
|
||||
value: 'accountName',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.accountName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Currency Code',
|
||||
value: 'currencyCode',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.currencyCode();
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Currency Name',
|
||||
value: 'currencyName',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.currencyName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Currency Symbol',
|
||||
value: 'currencySymbol',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.currencySymbol();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Bitcoin Address',
|
||||
value: 'bitcoinAddress',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.bitcoinAddress();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'IBAN',
|
||||
value: 'iban',
|
||||
type: 'Finance',
|
||||
getData() {
|
||||
return faker.finance.iban();
|
||||
},
|
||||
},
|
||||
//internet
|
||||
{
|
||||
name: 'Email',
|
||||
value: 'email',
|
||||
type: 'Internet',
|
||||
getData() {
|
||||
return faker.internet.email();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'User Name',
|
||||
value: 'userName',
|
||||
type: 'Internet',
|
||||
getData() {
|
||||
return faker.internet.userName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'URL',
|
||||
value: 'url',
|
||||
type: 'Internet',
|
||||
getData() {
|
||||
return faker.internet.url();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Domain Name',
|
||||
value: 'domainName',
|
||||
type: 'Internet',
|
||||
getData() {
|
||||
return faker.internet.domainName();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'IP Address',
|
||||
value: 'ip',
|
||||
type: 'Internet',
|
||||
getData() {
|
||||
return faker.internet.ip();
|
||||
},
|
||||
},
|
||||
|
||||
//Date
|
||||
{
|
||||
name: 'Past Date',
|
||||
value: 'past',
|
||||
type: 'Date',
|
||||
getData() {
|
||||
return faker.date.past();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Future Date',
|
||||
value: 'future',
|
||||
type: 'Date',
|
||||
getData() {
|
||||
return faker.date.future();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Recent Date',
|
||||
value: 'recent',
|
||||
type: 'Date',
|
||||
getData() {
|
||||
return faker.date.recent();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Month',
|
||||
value: 'month',
|
||||
type: 'Date',
|
||||
getData() {
|
||||
return faker.date.month();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Weekday',
|
||||
value: 'weekday',
|
||||
type: 'Date',
|
||||
getData() {
|
||||
return faker.date.weekday();
|
||||
},
|
||||
},
|
||||
//random
|
||||
|
||||
{
|
||||
name: 'UUID',
|
||||
value: 'uuid',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.random.uuid();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Boolean',
|
||||
value: 'boolean',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.random.boolean();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'word',
|
||||
value: 'word',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.random.word();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Random Character',
|
||||
value: 'randomCharacter',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
let characters =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
return characters[Math.floor(Math.random() * characters.length)];
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name: 'Sequence Generated Integer',
|
||||
// value: 'index',
|
||||
// index: 0,
|
||||
// type: 'a0',
|
||||
// getData: function () {
|
||||
// return this.index;
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: 'Random Integer',
|
||||
value: 'randomInteger',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return Math.floor(Math.random() * 10000);
|
||||
},
|
||||
},
|
||||
|
||||
//Commerce
|
||||
{
|
||||
name: 'Color',
|
||||
value: 'color',
|
||||
// type: 'commerce',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.commerce.color();
|
||||
},
|
||||
},
|
||||
// {
|
||||
// name: 'Price',
|
||||
// value: 'price',
|
||||
// type: 'commerce',
|
||||
// getData() {
|
||||
// return faker.commerce.price();
|
||||
// },
|
||||
// },
|
||||
{
|
||||
name: 'Product',
|
||||
value: 'product',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.commerce.product();
|
||||
},
|
||||
},
|
||||
//database
|
||||
// {
|
||||
// name: 'DataBase Column',
|
||||
// value: 'column',
|
||||
// type: 'database',
|
||||
// getData() {
|
||||
// return faker.database.column();
|
||||
// },
|
||||
// },
|
||||
|
||||
{
|
||||
name: 'Database Column Type',
|
||||
value: 'type',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.database.type();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Database Collation',
|
||||
value: 'collation',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.database.collation();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Database Engine',
|
||||
value: 'engine',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.database.engine();
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Phone',
|
||||
value: 'phone',
|
||||
type: 'Other',
|
||||
getData() {
|
||||
return faker.phone.phoneNumber();
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,189 @@
|
||||
import { generateFile } from './filegeneration.js';
|
||||
import { createExcelRowData } from './datageneration.js';
|
||||
import { ALL_OPTIONS } from './options.js';
|
||||
|
||||
const generateBtn = document.getElementById('generate-button');
|
||||
const rowCountEl = document.getElementById('row-count');
|
||||
const dataInputContainer = document.querySelector('.data-input-container');
|
||||
const introduction = document.querySelector('.introduction');
|
||||
const getStarted = document.getElementById('getStarted');
|
||||
const mainContent = document.getElementById('main-content');
|
||||
const closeBtnForInputSelector = document.getElementById('closeInputSelector');
|
||||
const inputSelectorBkg = document.querySelector('.select-input-background');
|
||||
const selectGroupingOptions = document.querySelector(
|
||||
'.select-input-classification'
|
||||
);
|
||||
const selectInputContainer = document.querySelector('.select-input-options');
|
||||
|
||||
const ROWS_TO_START_WITH = 8;
|
||||
let DOMrows = [];
|
||||
let i = 0;
|
||||
let selectedRow;
|
||||
|
||||
function addValuesToOptions(filter) {
|
||||
selectInputContainer.innerHTML = '';
|
||||
ALL_OPTIONS.forEach((option) => {
|
||||
if (!filter || option.type === filter) {
|
||||
let optionEl = document.createElement('button');
|
||||
optionEl.classList.add('btn');
|
||||
optionEl.classList.add('selectOption');
|
||||
optionEl.dataset.value = option.value;
|
||||
optionEl.innerText = option.name;
|
||||
optionEl.addEventListener('click', (e) => {
|
||||
//add value to current row
|
||||
selectedRow.querySelector(
|
||||
'.inputSelection'
|
||||
).innerHTML = `${e.target.textContent} <i class="fa fa-angle-down"></i>`;
|
||||
selectedRow.querySelector('.inputSelection').dataset.value =
|
||||
e.target.dataset.value;
|
||||
inputSelectorBkg.classList.remove('show');
|
||||
});
|
||||
selectInputContainer.appendChild(optionEl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function returnGetDataFunction(selectedOptionName) {
|
||||
let selectedOptionObject = ALL_OPTIONS.filter((option) => {
|
||||
return option.value === selectedOptionName;
|
||||
});
|
||||
return selectedOptionObject[0].getData;
|
||||
}
|
||||
|
||||
function fetchDOMValues() {
|
||||
let dataConfig = [];
|
||||
const rows = document.querySelectorAll('.row');
|
||||
rows.forEach((row, index) => {
|
||||
// to exclude the header which is the first row
|
||||
|
||||
if (index >= 1) {
|
||||
dataConfig.push({
|
||||
columnName: row.querySelector('.columnName').value,
|
||||
type: row.querySelector('.inputSelection').dataset.value,
|
||||
getData: returnGetDataFunction(
|
||||
row.querySelector('.inputSelection').dataset.value
|
||||
),
|
||||
maxLength: 100,
|
||||
minLength: 0,
|
||||
nullable: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
return dataConfig;
|
||||
}
|
||||
|
||||
function convertToColumnName(name) {
|
||||
return name.toUpperCase().split(' ').join('_');
|
||||
}
|
||||
|
||||
function addToDOMRows(rowClicked) {
|
||||
let randomOption =
|
||||
ALL_OPTIONS[Math.floor(Math.random() * ALL_OPTIONS.length)];
|
||||
let newRow = document.createElement('div');
|
||||
newRow.classList.add('row');
|
||||
newRow.classList.add('hide');
|
||||
newRow.innerHTML = `
|
||||
<div class="column">
|
||||
<input type="text" class="columnName" value="${convertToColumnName(
|
||||
randomOption.name
|
||||
)}">
|
||||
</div>
|
||||
<div class="column">
|
||||
<button class="inputSelection" data-value="${randomOption.value}">${
|
||||
randomOption.name
|
||||
}<i class="fa fa-angle-down"></i> </button>
|
||||
</div>
|
||||
<div class="column actions">
|
||||
<button class="add"> <i class="far fa-plus-square fa-2x add"></i><span class="tooltiptext">Add a New Row</span></button>
|
||||
<button class="delete"> <i class="fas fa-trash-alt fa-2x delete"></i><span class="tooltiptext">Delete Existing Row</span></button>
|
||||
</div>`;
|
||||
|
||||
DOMrows.push(newRow);
|
||||
if (rowClicked) {
|
||||
rowClicked.insertAdjacentElement('afterend', newRow);
|
||||
} else {
|
||||
dataInputContainer.insertAdjacentElement('beforeend', newRow);
|
||||
}
|
||||
setTimeout(() => {
|
||||
newRow.classList.remove('hide');
|
||||
}, 100);
|
||||
i++;
|
||||
}
|
||||
|
||||
function displayInputSelection(row) {
|
||||
inputSelectorBkg.classList.add('show');
|
||||
selectedRow = row;
|
||||
}
|
||||
|
||||
function deleteRowFromDOM(parentRow) {
|
||||
parentRow.classList.add('hide');
|
||||
setTimeout(() => {
|
||||
dataInputContainer.removeChild(parentRow);
|
||||
DOMrows = DOMrows.filter((row) => {
|
||||
return row !== parentRow;
|
||||
});
|
||||
if (DOMrows.length === 0) {
|
||||
addToDOMRows();
|
||||
}
|
||||
}, 600);
|
||||
}
|
||||
|
||||
function loadMainContainer() {
|
||||
introduction.classList.add('hide');
|
||||
mainContent.style.display = 'inline';
|
||||
setTimeout(() => {
|
||||
introduction.style.display = 'none';
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function documentClick(e) {
|
||||
const parentRow = e.target.closest('.row');
|
||||
if (e.target.classList.contains('add')) {
|
||||
addToDOMRows(parentRow);
|
||||
}
|
||||
if (e.target.classList.contains('delete')) {
|
||||
deleteRowFromDOM(parentRow);
|
||||
}
|
||||
if (e.target.classList.contains('inputSelection')) {
|
||||
displayInputSelection(parentRow);
|
||||
}
|
||||
}
|
||||
|
||||
function fetchDataAndGenerateFile() {
|
||||
let rowCount = +rowCountEl.value;
|
||||
let dataConfig = fetchDOMValues();
|
||||
let rows = createExcelRowData(rowCount, dataConfig);
|
||||
generateFile(rows);
|
||||
}
|
||||
|
||||
//event listeners
|
||||
generateBtn.addEventListener('click', fetchDataAndGenerateFile);
|
||||
document.addEventListener('click', documentClick);
|
||||
getStarted.addEventListener('click', loadMainContainer);
|
||||
closeBtnForInputSelector.addEventListener('click', () => {
|
||||
inputSelectorBkg.classList.remove('show');
|
||||
});
|
||||
|
||||
for (let i = 0; i < ROWS_TO_START_WITH; i++) {
|
||||
addToDOMRows();
|
||||
}
|
||||
addValuesToOptions();
|
||||
|
||||
let GROUPED_OPTIONS = {};
|
||||
ALL_OPTIONS.forEach((option) => {
|
||||
if (!GROUPED_OPTIONS[option.type]) {
|
||||
GROUPED_OPTIONS[option.type] = [];
|
||||
}
|
||||
GROUPED_OPTIONS[option.type].push(option);
|
||||
});
|
||||
|
||||
for (let key in GROUPED_OPTIONS) {
|
||||
let group = document.createElement('div');
|
||||
group.className = 'optionGroup';
|
||||
group.innerText = `${key}(${GROUPED_OPTIONS[key].length})`;
|
||||
group.addEventListener('click', () => {
|
||||
console.log('clicked');
|
||||
addValuesToOptions(key);
|
||||
});
|
||||
selectGroupingOptions.appendChild(group);
|
||||
}
|
||||
@@ -0,0 +1,621 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Lato&display=swap');
|
||||
|
||||
:root {
|
||||
--primary-color: rgb(17, 153, 158);
|
||||
--secondary-color: rgb(228, 249, 245);
|
||||
--btn-bg: rgba(255, 77, 77, 0.4);
|
||||
--text-color: rgba(10, 10, 10, 1);
|
||||
--option-1: rgb(48, 227, 202);
|
||||
--option-1-faded: rgba(48, 227, 202, 0.2);
|
||||
--option-2: rgb(64, 81, 78);
|
||||
--option-2-faded: rgba(64, 81, 78, 0.6);
|
||||
--background-img: linear-gradient(
|
||||
to top left,
|
||||
var(--primary-color),
|
||||
var(--option-2)
|
||||
);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
font-family: 'Lato', sans-serif;
|
||||
background-color: var(--secondary-color);
|
||||
color: var(--text-color);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Intro container with a brief description of the Application */
|
||||
.introduction {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
z-index: 1;
|
||||
margin: 0;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: url('./images/campaign-creators-pypeCEaJeZY-unsplash.jpg') center
|
||||
center no-repeat;
|
||||
z-index: 1;
|
||||
transition: all 1s ease-out;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.introduction.hide {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.introduction::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.introduction button {
|
||||
z-index: 1;
|
||||
display: block;
|
||||
width: 40%;
|
||||
padding: 2rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.introduction h1 {
|
||||
z-index: 1;
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
.introduction .intro-details {
|
||||
width: 50%;
|
||||
text-align: justify;
|
||||
line-height: 1.7;
|
||||
font-size: 2rem;
|
||||
padding: 3rem 0 2rem;
|
||||
color: white;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.introduction .intro-footer {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
#main-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*Header */
|
||||
.header-section {
|
||||
display: Flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
padding: 2rem 5rem;
|
||||
background-image: var(--background-img);
|
||||
color: var(--secondary-color);
|
||||
font-weight: bold;
|
||||
transition: all 1s ease-in;
|
||||
transform: translateY(0);
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.header-section .info {
|
||||
letter-spacing: 1.3px;
|
||||
}
|
||||
|
||||
/* The main container holds the configuration and the table container*/
|
||||
.main-container {
|
||||
display: Flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* Number of rows and generate File Button */
|
||||
.config {
|
||||
padding: 2rem 3rem;
|
||||
border-radius: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.6rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.config .row-count-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 5px;
|
||||
position: relative;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.config input {
|
||||
margin-top: 0.5rem;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.config .buttons {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
/* End of number of rows and generate file Button */
|
||||
|
||||
/* container and the entire column/row set */
|
||||
.data-input-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
max-width: 600px;
|
||||
width: 75%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.6s ease-in-out;
|
||||
transform: translateX(0%);
|
||||
opacity: 1;
|
||||
position: relative;
|
||||
align-items: flex-start;
|
||||
box-shadow: 2px 0px 3px var(--option-2);
|
||||
}
|
||||
.row.hide {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
.row:nth-child(odd) {
|
||||
background-color: var(--option-2-faded);
|
||||
}
|
||||
.row:nth-child(even) {
|
||||
background-color: var(--option-1-faded);
|
||||
}
|
||||
.row:first-child {
|
||||
background-color: var(--option-2);
|
||||
color: rgba(223, 249, 251, 1);
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.row:last-child {
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
box-shadow: 2px 2px 3px var(--option-2);
|
||||
}
|
||||
|
||||
.column {
|
||||
width: 40%;
|
||||
padding: 1rem;
|
||||
margin: 0 1rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: initial;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.column.actions {
|
||||
display: flex;
|
||||
width: 20%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions button:first-child {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.actions button {
|
||||
cursor: pointer;
|
||||
display: relative;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 1rem 3rem;
|
||||
margin: 1rem;
|
||||
border-radius: 1rem;
|
||||
cursor: pointer;
|
||||
background-image: var(--background-img);
|
||||
color: white;
|
||||
font-size: 1.6rem;
|
||||
border: 0;
|
||||
border: 2px solid var(--btn-bg);
|
||||
transform: translateX(0);
|
||||
transition: transform 0.5s ease-in;
|
||||
outline: 0;
|
||||
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.btn:hover,
|
||||
.btn:focus {
|
||||
border: 2px solid var(--option-2-faded);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
/* Tool tip for Number of Rows */
|
||||
.help-tip {
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
right: 18px;
|
||||
text-align: center;
|
||||
background-color: #bcdbea;
|
||||
border-radius: 50%;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 1.4rem;
|
||||
line-height: 26px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.help-tip:before {
|
||||
content: '?';
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.help-tip:hover p {
|
||||
display: block;
|
||||
transform-origin: 100% 0%;
|
||||
-webkit-animation: fadeIn 0.3s ease-in-out;
|
||||
animation: fadeIn 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.help-tip p {
|
||||
/* The tooltip */
|
||||
display: none;
|
||||
text-align: left;
|
||||
background-image: var(--background-img);
|
||||
padding: 1rem;
|
||||
width: 300px;
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
box-shadow: 1px 5px 5px rgba(0, 0, 0, 0.2);
|
||||
right: -4px;
|
||||
color: #fff;
|
||||
font-size: 1, 5rem;
|
||||
line-height: 1.4;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.help-tip p:before {
|
||||
/* The pointer of the tooltip */
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-bottom-color: #1e2021;
|
||||
right: 10px;
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
.help-tip p:after {
|
||||
/* Prevents the tooltip from being hidden */
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* For the Column Name and Option Grid Elements */
|
||||
input,
|
||||
.inputSelection {
|
||||
border-radius: 5px;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 1.4rem;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 0.5em;
|
||||
box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.04);
|
||||
background-color: #fff;
|
||||
outline: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inputSelection {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
.inputSelection:focus {
|
||||
border-color: #aaa;
|
||||
box-shadow: 0 0 1px 3px rgba(59, 153, 252, 0.7);
|
||||
box-shadow: 0 0 0 3px -moz-mac-focusring;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.inputSelection i {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
transform: translateX(-100%) translateY(15%);
|
||||
pointer-events: none;
|
||||
}
|
||||
/* End of Column Name and Option Grid Elements */
|
||||
|
||||
/* CSS for the tool tip for Add and Delete Row */
|
||||
.actions button .tooltiptext {
|
||||
visibility: hidden;
|
||||
width: fit-content;
|
||||
background-color: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 8px 8px;
|
||||
border-radius: 6px;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
transform: translateX(-120%) translateY(40%);
|
||||
}
|
||||
|
||||
.actions button:hover .tooltiptext,
|
||||
.actions button:focus .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* Second section of the main container containing the questions and answers */
|
||||
.additional-details {
|
||||
font-size: 1.5rem;
|
||||
padding: 1rem 5rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.additional-details h3,
|
||||
.additional-details p {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
/* End of Second Section */
|
||||
|
||||
/* Option selector popup Start */
|
||||
.select-input-background {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select-input-background.show {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: top;
|
||||
}
|
||||
|
||||
.select-input-background.show .select-input-container {
|
||||
justify-content: space-between;
|
||||
margin: auto;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
border-radius: 1rem;
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
top: 20vh;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.optionGroup {
|
||||
font-size: 1.6rem;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem 0 0.5rem;
|
||||
}
|
||||
|
||||
.select-input-container .selectOption {
|
||||
margin: 0.3rem;
|
||||
padding: 0.8rem 1.6rem;
|
||||
}
|
||||
|
||||
.select-input-container .select-input-classification {
|
||||
height: max-content;
|
||||
width: 25%;
|
||||
padding: 1rem 2.4rem;
|
||||
}
|
||||
|
||||
.select-input-classification h2 {
|
||||
padding-bottom: 1rem;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.select-input-container .close {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 1.4rem;
|
||||
font-weight: bold;
|
||||
padding: 1rem 1.2rem;
|
||||
border-radius: 50%;
|
||||
background-color: #d9455f;
|
||||
transform: translateX(50%) translateY(-50%) scale(1);
|
||||
outline: none;
|
||||
transition: all 1s ease-in;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select-input-background.show .select-input-container .close:hover {
|
||||
transform: translateX(50%) translateY(-50%) scale(1.3);
|
||||
}
|
||||
|
||||
.select-input-options {
|
||||
width: 75%;
|
||||
padding: 1rem 2.6rem;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
box-shadow: 2px 2px 5px var(--option-2);
|
||||
border-radius: 1rem;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
margin: 1rem 1rem 1rem 2rem;
|
||||
}
|
||||
/* Option selector popup End */
|
||||
|
||||
/* Footer Start */
|
||||
footer {
|
||||
width: 100%;
|
||||
background-image: var(--background-img);
|
||||
color: var(--secondary-color);
|
||||
margin: 0 auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
border: 1px solid;
|
||||
padding: 1rem 1rem 0.5rem 1rem;
|
||||
margin-top: 2rem;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
footer i {
|
||||
font-size: 3rem;
|
||||
padding: 1rem 3rem;
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
|
||||
footer .display-pic {
|
||||
height: 10rem;
|
||||
border-radius: 50%;
|
||||
border-style: solid;
|
||||
border-color: #393e46;
|
||||
border-width: 3px;
|
||||
margin-right: 3rem;
|
||||
}
|
||||
|
||||
footer .contact {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
footer .contact-details {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
/* Footer End */
|
||||
|
||||
/* CSS animation */
|
||||
@-webkit-keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.6);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 100%;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* On screens that are 992px wide or less*/
|
||||
@media screen and (max-width: 992px) {
|
||||
html {
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.introduction .intro-details {
|
||||
width: 70%;
|
||||
line-height: 1.6;
|
||||
font-size: 1.8rem;
|
||||
padding: 3rem 0 2rem;
|
||||
}
|
||||
.header-section {
|
||||
font-size: 1.8rem;
|
||||
padding: 2rem 1rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
.row {
|
||||
width: 80%;
|
||||
box-shadow: 2px 0px 3px var(--option-2);
|
||||
}
|
||||
.select-input-background.show .select-input-container {
|
||||
width: 90%;
|
||||
}
|
||||
.select-input-container .btn {
|
||||
padding: 1.2rem;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
.select-input-options {
|
||||
padding: 1rem;
|
||||
width: 75%;
|
||||
}
|
||||
.select-input-classification {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
/* On screens that are 600px wide or less*/
|
||||
@media screen and (max-width: 600px) {
|
||||
html {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.introduction .intro-details {
|
||||
width: 80%;
|
||||
line-height: 1.6;
|
||||
font-size: 1.8rem;
|
||||
padding: 3rem 0 2rem;
|
||||
}
|
||||
|
||||
.header-section {
|
||||
flex-direction: column;
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.header-section .info {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.row {
|
||||
width: 90%;
|
||||
}
|
||||
.select-input-container {
|
||||
width: 80%;
|
||||
}
|
||||
.select-input-container .btn {
|
||||
padding: 1rem;
|
||||
margin: 0.3rem;
|
||||
}
|
||||
|
||||
.select-input-options {
|
||||
padding: 1rem;
|
||||
width: 75%;
|
||||
}
|
||||
.select-input-classification {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user