I am using CodeIgniter.
I have two dropdowns called as status and action.
In the status drop-down, options are
Create
Pending
Verified
In action drop-down, options are
Paid
Refund
Dispute
Now, What I am doing is, When the user selects a status from the drop-down then onchage popup will display. Same onchage popup for action.
In the popup, I have a field which is message and two buttons called as submit and Cancel.
I am calling the controller on click on submit button to insert the message using AJAX. It's working for statusdrop-down but how to call the other controller for the action drop-down on click on submit button from the same popup?
I want to use the popup for action dropdown.
Any idea will be a great help.
Would you help me out in this issue?
$(function() {
$("#f_order_status, #f_order_status_confirm").change(function() {
$('#popup_verify').show();
});
});
function closePopup(obj) {
var id = $(obj).data('id');
$("#popup_verify").hide();
};
$("#o_order_status_action").on("submit", function(e) {
e.preventDefault(); //prevents form default action
var f_order_status = $('#f_order_status').val(); // get the selected value from dropdown
var f_order_status_confirm = $('#f_order_status_confirm').val(); // get the selected value from dropdown
$.ajax({ //do ajax to do update
type: "POST",
url: "<?php echo base_url('Customer_control/admin_order_verification');?>",
data: {
f_order_status: f_order_status,
f_order_status_confirm: f_order_status_confirm
},
success: function(dataReturned) {
if (dataReturned == 'true') {
location.href = baseUrl + "/Customer_control/list"
} else {
alert("There are some issue white updateing the records");
}
}
});
});
.confirmation_alert {
position: fixed;
/* Stay in place */
z-index: 9;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
-webkit-animation-name: fadeIn;
/* Fade in the background */
-webkit-animation-duration: 0.4s;
animation-name: fadeIn;
animation-duration: 0.4s;
}
.profile_content {
position: fixed;
top: 25%;
/*transform: translateY(-50%);*/
background-color: #fefefe;
width: 100%;
-webkit-animation-name: slideIn;
-webkit-animation-duration: 0.5s;
animation-name: slideIn;
animation-duration: 0.5s;
max-width: 922px;
margin: auto;
left: 0;
right: 0;
box-shadow: 0 0 15px rgba(0, 0, 0, .3);
margin-top: -65px;
}
.profile_header {
padding: 1px 20px;
background-color: #fafafc;
color: white;
/* min-height: 58px; */
border-bottom: 1px solid #f7f7f7;
display: block;
width: 100%;
}
.profile_content.p_v_popup {
border: 2px solid #666;
}
.confirmation_alert .profile_content {
max-width: 380px;
border: 2px solid #f96e64;
}
.p_v_popup .profile_header {
background: #666;
}
.confirmation_alert .profile_header {
padding: 6px 20px;
background-color: #f96e64;
}
.profile_body {
padding: 35px 50px;
}
.profile_footer {
padding: 15px;
background-color: #fdfdfe;
color: #858585;
text-align: center;
}
/* Add Animation */
#-webkit-keyframes slideIn {
from {
top: -500px;
opacity: 0
}
to {
top: 25%;
opacity: 1
}
}
#keyframes slideIn {
from {
top: -500px;
opacity: 0
}
to {
top: 25%;
opacity: 1
}
}
#-webkit-keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
#keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
.p_v_popup .profile_footer .submit_btn {
background: #666;
}
.confirmation_alert .profile_footer .submit_btn {
background: #f96e64;
color: #fff;
}
.confirmation_alert .profile_footer .btn_default {
padding: 5px;
display: inline-block;
outline: none;
border: none;
cursor: pointer;
text-transform: uppercase;
font-weight: 300;
min-width: 100px;
border-radius: 50px;
margin: 0 3px;
}
<select class="select_control" name="f_order_status" id="f_order_status">
<option value="" disabled selected>Select</option>
<option value="1">Create</option>
<option value="-1">Pending</option>
<option value="2">Verified</option>
</select>
<select class="select_control" name="f_order_status_confirm" id="f_order_status_confirm">
<option value="" disabled selected>Select</option>
<option value="1">Paid</option>
<option value="-1">Refund</option>
<option value="2">Dispute</option>
</select>
<div class="confirmation_alert" id="popup_verify" style="display: none;">
<div class="opacity"></div>
<form id="o_order_status_action" method="post">
<div class="profile_content p_v_popup">
<div class="profile_header clearfix">
x
<div class="profile_name_pic"> Confirmation!!! </div>
</div>
<div class="profile_body">
<div class="row">
<div class="col-md-12">
<div class="leave_reason">
<div class="form_group">
<input type="hidden" name="hidden_cust_id" id="hidden_cust_id" value="<?php echo $encryption_id;?>">
<input type="hidden" name="hidden_o_id" id="hidden_o_id" value="<?php echo $encript_o_id_id;?>">
<label>Message</label>
<textarea class="form_control" name="f_followup_message" rows="2" id="f_followup_message"></textarea>
</div>
</div>
</div>
</div>
</div>
<div class="profile_footer clearfix">
<button type="submit" class="btn_default submit_btn">Submit</button>
<button type="button" class="btn_default cancel_btn" onclick="closePopup(this)" data-id=""> Cancel</button>
</div>
</div>
</form>
</div>
</div>
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
You have to track the individual click. I have used java-script variable you could do that using data attribute on select boxes
var selectedBox = null;
$(function() {
$("#f_order_status_confirm").change(function() {
selectedBox = 2;
$('#popup_verify').show();
});
$("#f_order_status").change(function() {
selectedBox = 1;
$('#popup_verify').show();
});
});
On Ajax Part
url = "<?php echo base_url('Customer_control/admin_order_verification');?>";
if(selectedBox == 2){
url = "<?php echo base_url('Customer_control/admin_order_verification_something');?>";
}
$.ajax({ //do ajax to do update
type: "POST",
url: url,
data: {
f_order_status: f_order_status,
f_order_status_confirm: f_order_status_confirm
},
Related
Any time I have elements within my div ".packagebuilder" get class ".shown" added it adds code to fluidly transition. It works when the pricing table appears but not when all the other elements come into view. When ".hidden" gets added it should fluidly go back into place, but it doesn't transition at all, just immediately flashes back. What am I missing? Appreciate any help.
.hidden {
opacity: 0;
max-height: 0px;
transition: max-height 0s cubic-bezier(0, 1, 0, 1) 0s;
position:absolute;
top:-100000px;
}
.shown {
opacity: 1;
max-height: 1000px;
transition: max-height 1s ease-in-out 0s;
position:relative;
}
This is the code. Anything with the class "hidden" will get "shown" added onclick of an input.
var seoSelect = document.querySelector("select#seo");
var designSelect = document.querySelector("select#design");
var anySelect = document.querySelector(".packagebuilder select");
var seoOption = document.querySelector(".seo.option");
var designOption = document.querySelector(".design.option");
var anyOption = document.querySelector(".packagebuilder .option");
var estimateTable = document.querySelector(".estimate");
//Price Table Items
var seofirstmonthitem = document.querySelector(".item.seofirstmonth");
var seosetupfeeitem = document.querySelector(".item.setupfee");
var designdeposititem = document.querySelector(".item.designdeposit");
var designpayoffitem = document.querySelector(".item.designpayoff");
var seomonthlyitem = document.querySelector(".item.seomonthly");
var dueToday = document.querySelector(".today #val");
var dueLater = document.querySelector(".later #val");
var dueMonthly = document.querySelector(".monthly #val");
function hidePriceTable() {
$(estimateTable).addClass("hidden");
$(estimateTable).removeClass("shown");
$(".disclaimer.pricing").addClass("hidden");
$(".disclaimer.pricing").removeClass("shown");
$(".button.package").addClass("hidden");
$(".button.package").removeClass("shown");
}
function showPriceTable() {
$(estimateTable).removeClass("hidden");
$(estimateTable).addClass("shown");
$(".disclaimer.pricing").removeClass("hidden");
$(".disclaimer.pricing").addClass("shown");
$(".button.package").removeClass("hidden");
$(".button.package").addClass("shown");
}
function HideSE0() {
$(seoOption).addClass("hidden");
$(seoOption).removeClass("shown");
}
function ShowSEO() {
$(seoOption).addClass("shown");
$(seoOption).removeClass("hidden");
}
function HideDesign() {
$(designOption).addClass("hidden");
$(designOption).removeClass("shown");
}
function ShowDesign() {
$(designOption).addClass("shown");
$(designOption).removeClass("hidden");
}
function hideSEOcontent() {
$(".item.seofirstmonth").hide();
$(".item.seomonthly").hide();
$(".item.setupfee").hide();
$('select#seo').prop('selectedIndex', null);
$("input#seosetup").val("0");
$("input#seovalue").val("0");
HideSE0();
}
function showSEOcontent() {
$(".item.seofirstmonth").show();
$(".item.seomonthly").show();
$(".item.setupfee").show();
ShowSEO();
}
function hideDesigncontent() {
$(".item.designdeposit").hide();
$(".item.designpayoff").hide();
$('select#design').prop('selectedIndex', null);
$("input#designdeposit").val("0");
$("input#designpayoff").val("0");
$("input#designtotal").val("0");
HideDesign();
}
function showDesigncontent() {
$(".item.designdeposit").show();
$(".item.designpayoff").show();
ShowDesign();
}
function hideAll() {
hideSEOcontent();
hidePriceTable();
HideDesign();
HideSE0();
}
hideAll();
$(function () {
setInterval(constantChecker, 1);
});
/// Web Design Package Choices + Pricing /////////////////////////////////////////////////
function designSelectValues() {
// Set Default values
$('select#design').prop('selectedIndex', null);
//Check for new package choice
$(designSelect).change(function () {
if (designSelect.value == "1") {
$("input#designdeposit").val("1500");
$("input#designpayoff").val("1500");
$("input#designtotal").val("3000");
} else if (designSelect.value == "2") {
$("input#designdeposit").val("2500");
$("input#designpayoff").val("2500");
$("input#designtotal").val("5000");
} else if (designSelect.value == "3" || designSelect.value == "0" ) {
$("input#designdeposit").val("0");
$("input#designpayoff").val("0");
$("input#designtotal").val("0");
} else {
$("input#designdeposit").val("1500");
$("input#designpayoff").val("1500");
$("input#designtotal").val("3000");
}
});
}
/// SEO Package Choices + Pricing /////////////////////////////////////////////////
function seoSelectValues() {
// Set Default values
$('select#seo').prop('selectedIndex', null);
//Check for new package choice
$(seoSelect).change(function () {
if (seoSelect.value == "1") {
$("input#seosetup").val("500");
$("input#seovalue").val("750");
} else if (seoSelect.value == "2") {
$("input#seosetup").val("1000");
$("input#seovalue").val("1500");
} else if (seoSelect.value == "3") {
$("input#seosetup").val("1500");
$("input#seovalue").val("2500");
} else if (seoSelect.value == "4" || seoSelect.value == "0" ) {
$("input#seosetup").val("0");
$("input#seovalue").val("0");
} else {
$("input#seosetup").val("500");
$("input#seovalue").val("750");
}
});
}
// When service added, activate options and values ////////////////////////////////////
$('#chooseseo').change(function () {
if (!$('#chooseseo').is(':checked')) {
hideSEOcontent();
$("input#seosetup").val("0");
$("input#seovalue").val("0");
} else if ($('#chooseseo').is(':checked')) {
showSEOcontent();
seoSelectValues();
}
});
$('#choosedesign').change(function () {
if (!$('#choosedesign').is(':checked')) {
hideDesigncontent();
$("input#designdeposit").val("0");
$("input#designpayoff").val("0");
$("input#designtotal").val("0");
} else if ($('#choosedesign').is(':checked')) {
showDesigncontent();
designSelectValues();
}
});
// Convert String to US Currency ///////////////////////////////////////////////////////////
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
// Constanly check for new numbers /////////////////////////////////////////////////////////////
function constantChecker() {
// Show or Hide Custom Disclaimer ///
// if ($(seoSelect).val() == "4" || $(designSelect).val() == "3") {
// $(".disclaimer.custom").show();
// } else if ($(seoSelect).val() != "4" || $(designSelect).val() != "3") {
// $(".disclaimer.custom").hide();
// }
if (($("select#design")[0].selectedIndex === 0) && ($("select#seo")[0].selectedIndex === 0)) {
hidePriceTable();
}
else {
showPriceTable();
}
// Get Current Select Values /////
var currentSeoSetup = $("input#seosetup").val();
var currentSeoValue = $("input#seovalue").val();
var currentDesignDeposit = $("input#designdeposit").val();
var currentDesignPayoff = $("input#designpayoff").val();
var currentDueToday = formatter.format(+currentDesignDeposit + +currentSeoSetup + +currentSeoValue);
var currentDueLater = formatter.format(+currentDesignPayoff);
var currentMonthly = formatter.format(+currentSeoValue);
// Format individual Items ///
var seoSetupVal = formatter.format(+currentSeoSetup);
var seoMonthlyVal = formatter.format(+currentSeoValue);
var DesignDepositVal = formatter.format(+currentDesignDeposit);
var DesignPayoffVal = formatter.format(+currentDesignPayoff);
// Apply Current Values /////
$(dueToday).text(currentDueToday);
$(dueLater).text(currentDueLater);
$(dueMonthly).text(currentMonthly);
$(".setupfee span#val").text(seoSetupVal);
$(".seofirstmonth span#val").text(seoMonthlyVal);
$(".seomonthly span#val").text(seoMonthlyVal);
$(".designdeposit span#val").text(DesignDepositVal);
$(".designpayoff span#val").text(DesignPayoffVal);
}
/// Submit Button
$('.packagebuilder').on('submit', function (e) {
e.preventDefault();
var formData = $(this).serialize();
var fullUrl = window.location.href;
var finalUrl = fullUrl + "?&" + formData;
//window.location.href = finalUrl;
alert(finalUrl);
});
.hidden {
opacity: 0;
max-height: 0px;
transition: max-height 0s cubic-bezier(0, 1, 0, 1) 0s;
position:absolute;
top:-100000px;
}
.shown {
opacity: 1;
max-height: 1500px;
transition: max-height 1s ease-in-out 0s;
position:relative;
}
.packagebuilder {
max-width: 700px;
margin: auto;
box-sizing: border-box;
}
form .services {
display:
flex;
/* grid-gap: 30px; */
box-sizing: border-box;
/* padding-bottom: 20px; */
flex-direction: column;
width: auto;
}
form .option {display: flex;grid-gap: 10px;border-radius: 20px;padding-top: 30px;flex-direction: column;}
.services label {
font-size: 22px;
position: relative;
color: black;
font-weight:600!important;
}
.services select {
padding: 15px!important;
height: auto;
font-size: 20px!important;
padding-right: 45px!important;
font-weight: 300;
border-radius: 5px;
appearance: none;
-webkit-appearance:none;
overflow-wrap: break-word;
background: #ffffff;
border: solid 2px #e0e0e0!important;
}
.services select {
background-image: url("https://static1.squarespace.com/static/5ee80dfeb418dc785b48ee76/t/62ec6656067dab5da9df2fa0/1659659862901/angle-down-solid.svg");
background-size: 20px;
background-position: right 15px center;
background-repeat: no-repeat;
}
.services option {}
.services select:focus {
outline:none!important;
}
.estimate {
display: flex;
flex-direction: column;
/* background: linear-gradient(180deg, #eeeeee, transparent); */
margin: 30px 0px 20px;
overflow: hidden;
border-top: solid 1px #000000;
}
.figure {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0px;
border-bottom: solid 1px #dedede;
}
.figure span:first-child {
font-weight:600
}
.figure span:last-child {
font-size: 20px;
}
.figure:last-child {
border:none;
}
#val {
font-weight:600!important;
padding: 0;
border-radius: 5px;
}
.today #val {font-size: 30px;}
.figure.today {
color: black;
}
.figure {
}
.packagebuilder .disclaimer {
background: #f9f6e6;
padding: 10px;
display: flex;
align-items: center;
justify-content: center;
text-align: left;
font-size: 14px;
grid-gap: 10px;
}
.disclaimer i {
color: #ff9d00;
font-size: 20px;
}
.packagebuilder input.package {
background: #000000!important;
border: none!important;
color: white;
margin-top: 20px!important;
}
.packagebuilder input.package:hover {
background: var(--mainbrand)!important;
}
label.choose {
display:
block;
line-height:40px;
height:40px;
width: fit-content;
cursor: pointer;
min-width: 150px;
font-weight: 300!important;
pointer-events: all;
border-radius: 10px;
-webkit-font-smoothing: antialiased;
margin-top: 10px;
font-family:
Arial,Helvetica,sans-serif;
color: gray!important;
text-align:
center;
background: #e4e4e4;
padding: 1px 15px;
/* box-shadow: 11px 14px 20px #0000001a; */
}
label.add-label {
font-weight:600;
}
input.choose[type=checkbox] {
display: none;
}
input.choose:checked + label {
color: #ffffff!important;
background:
var(--mainbrand);
box-shadow: none;
}
.figure.item {
padding: 0px 20pxpx;
}
.figure.item span, .item span#val {
font-size: 13px;
font-weight: 300!important;
}
.today.item span#val, .today.item span {
color: #656565;
}
.other.item span#val, .other.item span {
color:#6c7674;
}
.today.item {
/* background: #f4f4f4!important; */
}
.other.item {
/* background: #f4f4f4!important; */
}
/* new stuff */
.packcheck {
visibility: hidden;
}
input.choose:checked + label .check {
visibility: visible;
}
input.choose.checkbox:checked + label:before {
content: "";
}
.addservices {
padding-bottom: 20px;
border-bottom: solid 1px #c0c0c0;
}
.flex-options {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
grid-gap: 10px;
}
:root {
--mainbrand: #006eff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="packagebuilder">
<div class="services">
<div class="addservices">
<label class="add-label">Add Services</label>
<div class="flex-options" name="addservices">
<div>
<input class="choose" id="chooseseo" type="checkbox" name="chooseseo">
<label for="chooseseo" class="choose">SEO</label>
</div>
<div>
<input class="choose" id="choosedesign" type="checkbox" name="choosedesign">
<label for="choosedesign" class="choose">Web Design</label>
</div></div></div>
<div class="seo option hidden">
<label for="seo">Pick your SEO Package</label>
<select type="text" id="seo" name="seo">
<option value="0" disabled selected value>-- Select an Option --</option>
<option value="1" class="one">Gold – $750 per month, $500 setup fee</option>
<option value="2">Essentials – $1500 per month, $1000 setup fee</option>
<option value="3">Local Authority – $2500 per month, $1500 setup fee</option>
</select>
</div>
<div class="design option hidden">
<label for="design">Pick your Design Package</label>
<select type="text" id="design" name="design">
<option value="0" disabled selected value>-- Select an Option --</option>
<option value="1">Vanity – $3000, $1500 deposit</option>
<option value="2">Lux – $5000, $2500 deposit</option>
</select>
</div>
</div><div class="estimate hidden">
<span class="figure today"><span>Due Today: </span><span id="val"></span>
</span><span class="figure today item setupfee" style="display:none;"><span style="">SEO Setup Fee</span><span id="val" style=""></span></span>
<span class="figure today item seofirstmonth" style="display:none;"><span style="">SEO First Month</span><span id="val" style=""></span></span><span class="figure today item designdeposit" style="display:none;"><span style="">Web Design 50% Deposit</span><span id="val" style=""></span></span><span class="figure later"><span>Due Later: </span><span id="val"></span></span><span class="figure other item designpayoff" style="display:none;"><span style="">Web Design Payoff</span><span id="val" style=""></span></span>
<span class="figure monthly"><span>Recurring Starting Next Month: </span><span id="val"></span></span><span class="figure other item seomonthly" style="display:none;"><span style="">SEO Monthly Fee</span><span id="val" style=""></span></span>
</div>
<div class="disclaimer pricing hidden"><i class="fas fa-exclamation-circle"></i>This is only an estimate before the final proposal. The final pricing will be reflected on an e-signature agreement we will send you.</div>
<div class="disclaimer custom" style="
display: none;
"><i class="fas fa-exclamation-circle"></i>Since you chose "Custom" on one of the options, the numbers may not reflect what you have discussed with us. Only choose this option if you spoke with us about a custom package prior.</div><input type="hidden" id="seovalue" name="seovalue" value="">
<input type="hidden" id="seosetup" name="seosetup" value=""><input type="hidden" id="designdeposit" name="designdeposit" value=""><input type="hidden" id="designpayoff" name="designpayoff" value="">
<input type="hidden" id="designtotal" name="designtotal" value=""><input type="submit" value="Continue" class="button package hidden">
</form>
The first one is working while the other one is not uploading and neither previewing the image I want to upload. I want both the image uploader and preview. But the first one is working only. I am using the same JavaScript for the Image uploader and preview. Simple word the code for HTML is copied and JavaScript is the same too. Kindly change it and make both inputs work correctly.
// Design By
// - https://dribbble.com/shots/13992184-File-Uploader-Drag-Drop
// Select Upload-Area
const uploadArea = document.querySelector('#uploadArea')
// Select Drop-Zoon Area
const dropZoon = document.querySelector('#dropZoon');
// Loading Text
const loadingText = document.querySelector('#loadingText');
// Slect File Input
const fileInput = document.querySelector('#fileInput');
// Select Preview Image
const previewImage = document.querySelector('#previewImage');
// File-Details Area
const fileDetails = document.querySelector('#fileDetails');
// Uploaded File
const uploadedFile = document.querySelector('#uploadedFile');
// Uploaded File Info
const uploadedFileInfo = document.querySelector('#uploadedFileInfo');
// Uploaded File Name
const uploadedFileName = document.querySelector('.uploaded-file__name');
// Uploaded File Icon
const uploadedFileIconText = document.querySelector('.uploaded-file__icon-text');
// Uploaded File Counter
const uploadedFileCounter = document.querySelector('.uploaded-file__counter');
// ToolTip Data
const toolTipData = document.querySelector('.upload-area__tooltip-data');
// Images Types
const imagesTypes = [
"jpeg",
"png",
"svg",
"gif"
];
// Append Images Types Array Inisde Tooltip Data
toolTipData.innerHTML = [...imagesTypes].join(', .');
// When (drop-zoon) has (dragover) Event
dropZoon.addEventListener('dragover', function (event) {
// Prevent Default Behavior
event.preventDefault();
// Add Class (drop-zoon--over) On (drop-zoon)
dropZoon.classList.add('drop-zoon--over');
});
// When (drop-zoon) has (dragleave) Event
dropZoon.addEventListener('dragleave', function (event) {
// Remove Class (drop-zoon--over) from (drop-zoon)
dropZoon.classList.remove('drop-zoon--over');
});
// When (drop-zoon) has (drop) Event
dropZoon.addEventListener('drop', function (event) {
// Prevent Default Behavior
event.preventDefault();
// Remove Class (drop-zoon--over) from (drop-zoon)
dropZoon.classList.remove('drop-zoon--over');
// Select The Dropped File
const file = event.dataTransfer.files[0];
// Call Function uploadFile(), And Send To Her The Dropped File :)
uploadFile(file);
});
// When (drop-zoon) has (click) Event
dropZoon.addEventListener('click', function (event) {
// Click The (fileInput)
fileInput.click();
});
// When (fileInput) has (change) Event
fileInput.addEventListener('change', function (event) {
// Select The Chosen File
const file = event.target.files[0];
// Call Function uploadFile(), And Send To Her The Chosen File :)
uploadFile(file);
});
// Upload File Function
function uploadFile(file) {
// FileReader()
const fileReader = new FileReader();
// File Type
const fileType = file.type;
// File Size
const fileSize = file.size;
// If File Is Passed from the (File Validation) Function
if (fileValidate(fileType, fileSize)) {
// Add Class (drop-zoon--Uploaded) on (drop-zoon)
dropZoon.classList.add('drop-zoon--Uploaded');
// Show Loading-text
loadingText.style.display = "block";
// Hide Preview Image
previewImage.style.display = 'none';
// Remove Class (uploaded-file--open) From (uploadedFile)
uploadedFile.classList.remove('uploaded-file--open');
// Remove Class (uploaded-file__info--active) from (uploadedFileInfo)
uploadedFileInfo.classList.remove('uploaded-file__info--active');
// After File Reader Loaded
fileReader.addEventListener('load', function () {
// After Half Second
setTimeout(function () {
// Add Class (upload-area--open) On (uploadArea)
uploadArea.classList.add('upload-area--open');
// Hide Loading-text (please-wait) Element
loadingText.style.display = "none";
// Show Preview Image
previewImage.style.display = 'block';
// Add Class (file-details--open) On (fileDetails)
fileDetails.classList.add('file-details--open');
// Add Class (uploaded-file--open) On (uploadedFile)
uploadedFile.classList.add('uploaded-file--open');
// Add Class (uploaded-file__info--active) On (uploadedFileInfo)
uploadedFileInfo.classList.add('uploaded-file__info--active');
}, 500); // 0.5s
// Add The (fileReader) Result Inside (previewImage) Source
previewImage.setAttribute('src', fileReader.result);
// Add File Name Inside Uploaded File Name
uploadedFileName.innerHTML = file.name;
// Call Function progressMove();
progressMove();
});
// Read (file) As Data Url
fileReader.readAsDataURL(file);
} else { // Else
this; // (this) Represent The fileValidate(fileType, fileSize) Function
};
};
// Progress Counter Increase Function
function progressMove() {
// Counter Start
let counter = 0;
// After 600ms
setTimeout(() => {
// Every 100ms
let counterIncrease = setInterval(() => {
// If (counter) is equle 100
if (counter === 100) {
// Stop (Counter Increase)
clearInterval(counterIncrease);
} else { // Else
// plus 10 on counter
counter = counter + 10;
// add (counter) vlaue inisde (uploadedFileCounter)
uploadedFileCounter.innerHTML = `${counter}%`
}
}, 100);
}, 600);
};
// Simple File Validate Function
function fileValidate(fileType, fileSize) {
// File Type Validation
let isImage = imagesTypes.filter((type) => fileType.indexOf(`image/${type}`) !== -1);
// If The Uploaded File Type Is 'jpeg'
if (isImage[0] === 'jpeg') {
// Add Inisde (uploadedFileIconText) The (jpg) Value
uploadedFileIconText.innerHTML = 'jpg';
} else { // else
// Add Inisde (uploadedFileIconText) The Uploaded File Type
uploadedFileIconText.innerHTML = isImage[0];
};
// If The Uploaded File Is An Image
if (isImage.length !== 0) {
// Check, If File Size Is 2MB or Less
if (fileSize <= 2000000) { // 2MB :)
return true;
} else { // Else File Size
return alert('Please Your File Should be 2 Megabytes or Less');
};
} else { // Else File Type
return alert('Please make sure to upload An Image File Type');
};
};
// :)
/* General Styles */
* {
box-sizing: border-box;
}
:root {
--clr-white: rgb(255, 255, 255);
--clr-black: rgb(0, 0, 0);
--clr-light: rgb(245, 248, 255);
--clr-light-gray: rgb(196, 195, 196);
--clr-blue: rgb(63, 134, 255);
--clr-light-blue: rgb(171, 202, 255);
}
body {
margin: 0;
padding: 0;
background-color: var(--clr-light);
color: var(--clr-black);
font-family: 'Poppins', sans-serif;
font-size: 1.125rem;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* End General Styles */
/* Upload Area */
.upload-area {
width: 100%;
max-width: 25rem;
background-color: var(--clr-white);
box-shadow: 0 10px 60px rgb(218, 229, 255);
border: 2px solid var(--clr-light-blue);
border-radius: 24px;
padding: 2rem 1.875rem 5rem 1.875rem;
margin: 0.625rem;
text-align: center;
}
.upload-area--open { /* Slid Down Animation */
animation: slidDown 500ms ease-in-out;
}
#keyframes slidDown {
from {
height: 28.125rem; /* 450px */
}
to {
height: 35rem; /* 560px */
}
}
/* Header */
.upload-area__header {
}
.upload-area__title {
font-size: 1.8rem;
font-weight: 500;
margin-bottom: 0.3125rem;
}
.upload-area__paragraph {
font-size: 0.9375rem;
color: var(--clr-light-gray);
margin-top: 0;
}
.upload-area__tooltip {
position: relative;
color: var(--clr-light-blue);
cursor: pointer;
transition: color 300ms ease-in-out;
}
.upload-area__tooltip:hover {
color: var(--clr-blue);
}
.upload-area__tooltip-data {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -125%);
min-width: max-content;
background-color: var(--clr-white);
color: var(--clr-blue);
border: 1px solid var(--clr-light-blue);
padding: 0.625rem 1.25rem;
font-weight: 500;
opacity: 0;
visibility: hidden;
transition: none 300ms ease-in-out;
transition-property: opacity, visibility;
}
.upload-area__tooltip:hover .upload-area__tooltip-data {
opacity: 1;
visibility: visible;
}
/* Drop Zoon */
.upload-area__drop-zoon {
position: relative;
height: 11.25rem; /* 180px */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
border: 2px dashed var(--clr-light-blue);
border-radius: 15px;
margin-top: 2.1875rem;
cursor: pointer;
transition: border-color 300ms ease-in-out;
}
.upload-area__drop-zoon:hover {
border-color: var(--clr-blue);
}
.drop-zoon__icon {
display: flex;
font-size: 3.75rem;
color: var(--clr-blue);
transition: opacity 300ms ease-in-out;
}
.drop-zoon__paragraph {
font-size: 0.9375rem;
color: var(--clr-light-gray);
margin: 0;
margin-top: 0.625rem;
transition: opacity 300ms ease-in-out;
}
.drop-zoon:hover .drop-zoon__icon,
.drop-zoon:hover .drop-zoon__paragraph {
opacity: 0.7;
}
.drop-zoon__loading-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
color: var(--clr-light-blue);
z-index: 10;
}
.drop-zoon__preview-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
padding: 0.3125rem;
border-radius: 10px;
display: none;
z-index: 1000;
transition: opacity 300ms ease-in-out;
}
.drop-zoon:hover .drop-zoon__preview-image {
opacity: 0.8;
}
.drop-zoon__file-input {
display: none;
}
/* (drop-zoon--over) Modifier Class */
.drop-zoon--over {
border-color: var(--clr-blue);
}
.drop-zoon--over .drop-zoon__icon,
.drop-zoon--over .drop-zoon__paragraph {
opacity: 0.7;
}
/* (drop-zoon--over) Modifier Class */
.drop-zoon--Uploaded {
}
.drop-zoon--Uploaded .drop-zoon__icon,
.drop-zoon--Uploaded .drop-zoon__paragraph {
display: none;
}
/* File Details Area */
.upload-area__file-details {
height: 0;
visibility: hidden;
opacity: 0;
text-align: left;
transition: none 500ms ease-in-out;
transition-property: opacity, visibility;
transition-delay: 500ms;
}
/* (duploaded-file--open) Modifier Class */
.file-details--open {
height: auto;
visibility: visible;
opacity: 1;
}
.file-details__title {
font-size: 1.125rem;
font-weight: 500;
color: var(--clr-light-gray);
}
/* Uploaded File */
.uploaded-file {
display: flex;
align-items: center;
padding: 0.625rem 0;
visibility: hidden;
opacity: 0;
transition: none 500ms ease-in-out;
transition-property: visibility, opacity;
}
/* (duploaded-file--open) Modifier Class */
.uploaded-file--open {
visibility: visible;
opacity: 1;
}
.uploaded-file__icon-container {
position: relative;
margin-right: 0.3125rem;
}
.uploaded-file__icon {
font-size: 3.4375rem;
color: var(--clr-blue);
}
.uploaded-file__icon-text {
position: absolute;
top: 1.5625rem;
left: 50%;
transform: translateX(-50%);
font-size: 0.9375rem;
font-weight: 500;
color: var(--clr-white);
}
.uploaded-file__info {
position: relative;
top: -0.3125rem;
width: 100%;
display: flex;
justify-content: space-between;
}
.uploaded-file__info::before,
.uploaded-file__info::after {
content: '';
position: absolute;
bottom: -0.9375rem;
width: 0;
height: 0.5rem;
background-color: #ebf2ff;
border-radius: 0.625rem;
}
.uploaded-file__info::before {
width: 100%;
}
.uploaded-file__info::after {
width: 100%;
background-color: var(--clr-blue);
}
/* Progress Animation */
.uploaded-file__info--active::after {
animation: progressMove 800ms ease-in-out;
animation-delay: 300ms;
}
#keyframes progressMove {
from {
width: 0%;
background-color: transparent;
}
to {
width: 100%;
background-color: var(--clr-blue);
}
}
.uploaded-file__name {
width: 100%;
max-width: 6.25rem; /* 100px */
display: inline-block;
font-size: 1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.uploaded-file__counter {
font-size: 1rem;
color: var(--clr-light-gray);
}
<!-- Upload Area -->
<div id="uploadArea" class="upload-area">
<!-- Header -->
<div class="upload-area__header">
<h1 class="upload-area__title">Upload your file</h1>
<p class="upload-area__paragraph">
File should be an image
<strong class="upload-area__tooltip">
Like
<span class="upload-area__tooltip-data"></span> <!-- Data Will be Comes From Js -->
</strong>
</p>
</div>
<!-- End Header -->
<!-- Drop Zoon -->
<div id="dropZoon" class="upload-area__drop-zoon drop-zoon">
<span class="drop-zoon__icon">
<i class='bx bxs-file-image'></i>
</span>
<p class="drop-zoon__paragraph">Drop your file here or Click to browse</p>
<span id="loadingText" class="drop-zoon__loading-text">Please Wait</span>
<img src="" alt="Preview Image" id="previewImage" class="drop-zoon__preview-image" draggable="false">
<input type="file" id="fileInput" class="drop-zoon__file-input" accept="image/*">
</div>
<!-- End Drop Zoon -->
<!-- File Details -->
<div id="fileDetails" class="upload-area__file-details file-details">
<h3 class="file-details__title">Uploaded File</h3>
<div id="uploadedFile" class="uploaded-file">
<div class="uploaded-file__icon-container">
<i class='bx bxs-file-blank uploaded-file__icon'></i>
<span class="uploaded-file__icon-text"></span> <!-- Data Will be Comes From Js -->
</div>
<div id="uploadedFileInfo" class="uploaded-file__info">
<span class="uploaded-file__name">Proejct 1</span>
<span class="uploaded-file__counter">0%</span>
</div>
</div>
</div>
<!-- End File Details -->
</div>
<!-- End Upload Area -->
<div class="mb-5 mt-5"></div>
<!-- Upload Area -->
<div id="uploadArea" class="upload-area">
<!-- Header -->
<div class="upload-area__header">
<h1 class="upload-area__title">Upload your file</h1>
<p class="upload-area__paragraph">
File should be an image
<strong class="upload-area__tooltip">
Like
<span class="upload-area__tooltip-data"></span> <!-- Data Will be Comes From Js -->
</strong>
</p>
</div>
<!-- End Header -->
<!-- Drop Zoon -->
<div id="dropZoon" class="upload-area__drop-zoon drop-zoon">
<span class="drop-zoon__icon">
<i class='bx bxs-file-image'></i>
</span>
<p class="drop-zoon__paragraph">Drop your file here or Click to browse</p>
<span id="loadingText" class="drop-zoon__loading-text">Please Wait</span>
<img src="" alt="Preview Image" id="previewImage" class="drop-zoon__preview-image" draggable="false">
<input type="file" id="fileInput" class="drop-zoon__file-input" accept="image/*">
</div>
<!-- End Drop Zoon -->
<!-- File Details -->
<div id="fileDetails" class="upload-area__file-details file-details">
<h3 class="file-details__title">Uploaded File</h3>
<div id="uploadedFile" class="uploaded-file">
<div class="uploaded-file__icon-container">
<i class='bx bxs-file-blank uploaded-file__icon'></i>
<span class="uploaded-file__icon-text"></span> <!-- Data Will be Comes From Js -->
</div>
<div id="uploadedFileInfo" class="uploaded-file__info">
<span class="uploaded-file__name">Proejct 1</span>
<span class="uploaded-file__counter">0%</span>
</div>
</div>
</div>
<!-- End File Details -->
</div>
<!-- End Upload Area -->
In JavaScript file you are using document.querySelector("")
That chooses only the first element in the HTML and you can't duplicate the two uploader and use the same selector in JavaScript.
You can with JavaScript select the two uploader & make the functions for the two uploaders with loop as an example.
If you need array of the elements you can use document.querySelectorAll("").
Since IDs such as #uploadArea, #dropZoon, etc. have become duplicated in the html code, then accordingly you install all handlers only for the first element.
I have slightly corrected your example so that you can install a lot of loaders:
// Design By
// - https://dribbble.com/shots/13992184-File-Uploader-Drag-Drop
uploadHandler({
uploadArea: document.querySelector("#uploadArea"),
dropZoon: document.querySelector("#dropZoon"),
loadingText: document.querySelector("#loadingText"),
fileInput: document.querySelector("#fileInput"),
previewImage: document.querySelector("#previewImage"),
fileDetails: document.querySelector("#fileDetails"),
uploadedFile: document.querySelector("#uploadedFile"),
uploadedFileInfo: document.querySelector("#uploadedFileInfo"),
uploadedFileName: document.querySelector(".uploaded-file__name"),
uploadedFileIconText: document.querySelector(".uploaded-file__icon-text"),
uploadedFileCounter: document.querySelector(".uploaded-file__counter"),
toolTipData: document.querySelector(".upload-area__tooltip-data"),
});
uploadHandler({
uploadArea: document.querySelector("#uploadArea-2"),
dropZoon: document.querySelector("#dropZoon-2"),
loadingText: document.querySelector("#loadingText-2"),
fileInput: document.querySelector("#fileInput-2"),
previewImage: document.querySelector("#previewImage-2"),
fileDetails: document.querySelector("#fileDetails-2"),
uploadedFile: document.querySelector("#uploadedFile-2"),
uploadedFileInfo: document.querySelector("#uploadedFileInfo-2"),
uploadedFileName: document.querySelector(".uploaded-file__name-2"),
uploadedFileIconText: document.querySelector(".uploaded-file__icon-text-2"),
uploadedFileCounter: document.querySelector(".uploaded-file__counter-2"),
toolTipData: document.querySelector(".upload-area__tooltip-data-2"),
});
function uploadHandler({
uploadArea,
dropZoon,
loadingText,
fileInput,
previewImage,
fileDetails,
uploadedFile,
uploadedFileInfo,
uploadedFileName,
uploadedFileIconText,
uploadedFileCounter,
toolTipData,
}) {
// Images Types
const imagesTypes = ["jpeg", "png", "svg", "gif"];
// Append Images Types Array Inisde Tooltip Data
toolTipData.innerHTML = [...imagesTypes].join(", .");
// When (drop-zoon) has (dragover) Event
dropZoon.addEventListener("dragover", function (event) {
// Prevent Default Behavior
event.preventDefault();
// Add Class (drop-zoon--over) On (drop-zoon)
dropZoon.classList.add("drop-zoon--over");
});
// When (drop-zoon) has (dragleave) Event
dropZoon.addEventListener("dragleave", function (event) {
// Remove Class (drop-zoon--over) from (drop-zoon)
dropZoon.classList.remove("drop-zoon--over");
});
// When (drop-zoon) has (drop) Event
dropZoon.addEventListener("drop", function (event) {
// Prevent Default Behavior
event.preventDefault();
// Remove Class (drop-zoon--over) from (drop-zoon)
dropZoon.classList.remove("drop-zoon--over");
// Select The Dropped File
const file = event.dataTransfer.files[0];
// Call Function uploadFile(), And Send To Her The Dropped File :)
uploadFile(file);
});
// When (drop-zoon) has (click) Event
dropZoon.addEventListener("click", function (event) {
// Click The (fileInput)
fileInput.click();
});
// When (fileInput) has (change) Event
fileInput.addEventListener("change", function (event) {
// Select The Chosen File
const file = event.target.files[0];
// Call Function uploadFile(), And Send To Her The Chosen File :)
uploadFile(file);
});
// Upload File Function
function uploadFile(file) {
// FileReader()
const fileReader = new FileReader();
// File Type
const fileType = file.type;
// File Size
const fileSize = file.size;
// If File Is Passed from the (File Validation) Function
if (fileValidate(fileType, fileSize)) {
// Add Class (drop-zoon--Uploaded) on (drop-zoon)
dropZoon.classList.add("drop-zoon--Uploaded");
// Show Loading-text
loadingText.style.display = "block";
// Hide Preview Image
previewImage.style.display = "none";
// Remove Class (uploaded-file--open) From (uploadedFile)
uploadedFile.classList.remove("uploaded-file--open");
// Remove Class (uploaded-file__info--active) from (uploadedFileInfo)
uploadedFileInfo.classList.remove("uploaded-file__info--active");
// After File Reader Loaded
fileReader.addEventListener("load", function () {
// After Half Second
setTimeout(function () {
// Add Class (upload-area--open) On (uploadArea)
uploadArea.classList.add("upload-area--open");
// Hide Loading-text (please-wait) Element
loadingText.style.display = "none";
// Show Preview Image
previewImage.style.display = "block";
// Add Class (file-details--open) On (fileDetails)
fileDetails.classList.add("file-details--open");
// Add Class (uploaded-file--open) On (uploadedFile)
uploadedFile.classList.add("uploaded-file--open");
// Add Class (uploaded-file__info--active) On (uploadedFileInfo)
uploadedFileInfo.classList.add("uploaded-file__info--active");
}, 500); // 0.5s
// Add The (fileReader) Result Inside (previewImage) Source
previewImage.setAttribute("src", fileReader.result);
// Add File Name Inside Uploaded File Name
uploadedFileName.innerHTML = file.name;
// Call Function progressMove();
progressMove();
});
// Read (file) As Data Url
fileReader.readAsDataURL(file);
} else {
// Else
this; // (this) Represent The fileValidate(fileType, fileSize) Function
}
}
// Progress Counter Increase Function
function progressMove() {
// Counter Start
let counter = 0;
// After 600ms
setTimeout(() => {
// Every 100ms
let counterIncrease = setInterval(() => {
// If (counter) is equle 100
if (counter === 100) {
// Stop (Counter Increase)
clearInterval(counterIncrease);
} else {
// Else
// plus 10 on counter
counter = counter + 10;
// add (counter) vlaue inisde (uploadedFileCounter)
uploadedFileCounter.innerHTML = `${counter}%`;
}
}, 100);
}, 600);
}
// Simple File Validate Function
function fileValidate(fileType, fileSize) {
// File Type Validation
let isImage = imagesTypes.filter(
(type) => fileType.indexOf(`image/${type}`) !== -1
);
// If The Uploaded File Type Is 'jpeg'
if (isImage[0] === "jpeg") {
// Add Inisde (uploadedFileIconText) The (jpg) Value
uploadedFileIconText.innerHTML = "jpg";
} else {
// else
// Add Inisde (uploadedFileIconText) The Uploaded File Type
uploadedFileIconText.innerHTML = isImage[0];
}
// If The Uploaded File Is An Image
if (isImage.length !== 0) {
// Check, If File Size Is 2MB or Less
if (fileSize <= 2000000) {
// 2MB :)
return true;
} else {
// Else File Size
return alert("Please Your File Should be 2 Megabytes or Less");
}
} else {
// Else File Type
return alert("Please make sure to upload An Image File Type");
}
}
}
// :)
/* General Styles */
* {
box-sizing: border-box;
}
:root {
--clr-white: rgb(255, 255, 255);
--clr-black: rgb(0, 0, 0);
--clr-light: rgb(245, 248, 255);
--clr-light-gray: rgb(196, 195, 196);
--clr-blue: rgb(63, 134, 255);
--clr-light-blue: rgb(171, 202, 255);
}
body {
margin: 0;
padding: 0;
background-color: var(--clr-light);
color: var(--clr-black);
font-family: 'Poppins', sans-serif;
font-size: 1.125rem;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* End General Styles */
/* Upload Area */
.upload-area {
width: 100%;
max-width: 25rem;
background-color: var(--clr-white);
box-shadow: 0 10px 60px rgb(218, 229, 255);
border: 2px solid var(--clr-light-blue);
border-radius: 24px;
padding: 2rem 1.875rem 5rem 1.875rem;
margin: 0.625rem;
text-align: center;
}
.upload-area--open { /* Slid Down Animation */
animation: slidDown 500ms ease-in-out;
}
#keyframes slidDown {
from {
height: 28.125rem; /* 450px */
}
to {
height: 35rem; /* 560px */
}
}
/* Header */
.upload-area__header {
}
.upload-area__title {
font-size: 1.8rem;
font-weight: 500;
margin-bottom: 0.3125rem;
}
.upload-area__paragraph {
font-size: 0.9375rem;
color: var(--clr-light-gray);
margin-top: 0;
}
.upload-area__tooltip {
position: relative;
color: var(--clr-light-blue);
cursor: pointer;
transition: color 300ms ease-in-out;
}
.upload-area__tooltip:hover {
color: var(--clr-blue);
}
.upload-area__tooltip-data {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -125%);
min-width: max-content;
background-color: var(--clr-white);
color: var(--clr-blue);
border: 1px solid var(--clr-light-blue);
padding: 0.625rem 1.25rem;
font-weight: 500;
opacity: 0;
visibility: hidden;
transition: none 300ms ease-in-out;
transition-property: opacity, visibility;
}
.upload-area__tooltip:hover .upload-area__tooltip-data {
opacity: 1;
visibility: visible;
}
/* Drop Zoon */
.upload-area__drop-zoon {
position: relative;
height: 11.25rem; /* 180px */
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
border: 2px dashed var(--clr-light-blue);
border-radius: 15px;
margin-top: 2.1875rem;
cursor: pointer;
transition: border-color 300ms ease-in-out;
}
.upload-area__drop-zoon:hover {
border-color: var(--clr-blue);
}
.drop-zoon__icon {
display: flex;
font-size: 3.75rem;
color: var(--clr-blue);
transition: opacity 300ms ease-in-out;
}
.drop-zoon__paragraph {
font-size: 0.9375rem;
color: var(--clr-light-gray);
margin: 0;
margin-top: 0.625rem;
transition: opacity 300ms ease-in-out;
}
.drop-zoon:hover .drop-zoon__icon,
.drop-zoon:hover .drop-zoon__paragraph {
opacity: 0.7;
}
.drop-zoon__loading-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
color: var(--clr-light-blue);
z-index: 10;
}
.drop-zoon__preview-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
padding: 0.3125rem;
border-radius: 10px;
display: none;
z-index: 1000;
transition: opacity 300ms ease-in-out;
}
.drop-zoon:hover .drop-zoon__preview-image {
opacity: 0.8;
}
.drop-zoon__file-input {
display: none;
}
/* (drop-zoon--over) Modifier Class */
.drop-zoon--over {
border-color: var(--clr-blue);
}
.drop-zoon--over .drop-zoon__icon,
.drop-zoon--over .drop-zoon__paragraph {
opacity: 0.7;
}
/* (drop-zoon--over) Modifier Class */
.drop-zoon--Uploaded {
}
.drop-zoon--Uploaded .drop-zoon__icon,
.drop-zoon--Uploaded .drop-zoon__paragraph {
display: none;
}
/* File Details Area */
.upload-area__file-details {
height: 0;
visibility: hidden;
opacity: 0;
text-align: left;
transition: none 500ms ease-in-out;
transition-property: opacity, visibility;
transition-delay: 500ms;
}
/* (duploaded-file--open) Modifier Class */
.file-details--open {
height: auto;
visibility: visible;
opacity: 1;
}
.file-details__title {
font-size: 1.125rem;
font-weight: 500;
color: var(--clr-light-gray);
}
/* Uploaded File */
.uploaded-file {
display: flex;
align-items: center;
padding: 0.625rem 0;
visibility: hidden;
opacity: 0;
transition: none 500ms ease-in-out;
transition-property: visibility, opacity;
}
/* (duploaded-file--open) Modifier Class */
.uploaded-file--open {
visibility: visible;
opacity: 1;
}
.uploaded-file__icon-container {
position: relative;
margin-right: 0.3125rem;
}
.uploaded-file__icon {
font-size: 3.4375rem;
color: var(--clr-blue);
}
.uploaded-file__icon-text {
position: absolute;
top: 1.5625rem;
left: 50%;
transform: translateX(-50%);
font-size: 0.9375rem;
font-weight: 500;
color: var(--clr-white);
}
.uploaded-file__info {
position: relative;
top: -0.3125rem;
width: 100%;
display: flex;
justify-content: space-between;
}
.uploaded-file__info::before,
.uploaded-file__info::after {
content: '';
position: absolute;
bottom: -0.9375rem;
width: 0;
height: 0.5rem;
background-color: #ebf2ff;
border-radius: 0.625rem;
}
.uploaded-file__info::before {
width: 100%;
}
.uploaded-file__info::after {
width: 100%;
background-color: var(--clr-blue);
}
/* Progress Animation */
.uploaded-file__info--active::after {
animation: progressMove 800ms ease-in-out;
animation-delay: 300ms;
}
#keyframes progressMove {
from {
width: 0%;
background-color: transparent;
}
to {
width: 100%;
background-color: var(--clr-blue);
}
}
.uploaded-file__name {
width: 100%;
max-width: 6.25rem; /* 100px */
display: inline-block;
font-size: 1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.uploaded-file__counter {
font-size: 1rem;
color: var(--clr-light-gray);
}
<!-- Upload Area -->
<div id="uploadArea" class="upload-area">
<!-- Header -->
<div class="upload-area__header">
<h1 class="upload-area__title">Upload your file</h1>
<p class="upload-area__paragraph">
File should be an image
<strong class="upload-area__tooltip">
Like
<span class="upload-area__tooltip-data"></span> <!-- Data Will be Comes From Js -->
</strong>
</p>
</div>
<!-- End Header -->
<!-- Drop Zoon -->
<div id="dropZoon" class="upload-area__drop-zoon drop-zoon">
<span class="drop-zoon__icon">
<i class='bx bxs-file-image'></i>
</span>
<p class="drop-zoon__paragraph">Drop your file here or Click to browse</p>
<span id="loadingText" class="drop-zoon__loading-text">Please Wait</span>
<img src="" alt="Preview Image" id="previewImage" class="drop-zoon__preview-image" draggable="false">
<input type="file" id="fileInput" class="drop-zoon__file-input" accept="image/*">
</div>
<!-- End Drop Zoon -->
<!-- File Details -->
<div id="fileDetails" class="upload-area__file-details file-details">
<h3 class="file-details__title">Uploaded File</h3>
<div id="uploadedFile" class="uploaded-file">
<div class="uploaded-file__icon-container">
<i class='bx bxs-file-blank uploaded-file__icon'></i>
<span class="uploaded-file__icon-text"></span> <!-- Data Will be Comes From Js -->
</div>
<div id="uploadedFileInfo" class="uploaded-file__info">
<span class="uploaded-file__name">Proejct 1</span>
<span class="uploaded-file__counter">0%</span>
</div>
</div>
</div>
<!-- End File Details -->
</div>
<!-- End Upload Area -->
<div class="mb-5 mt-5"></div>
<!-- Upload Area -->
<div id="uploadArea-2" class="upload-area">
<!-- Header -->
<div class="upload-area__header">
<h1 class="upload-area__title">Upload your file</h1>
<p class="upload-area__paragraph">
File should be an image
<strong class="upload-area__tooltip">
Like
<span class="upload-area__tooltip-data-2"></span> <!-- Data Will be Comes From Js -->
</strong>
</p>
</div>
<!-- End Header -->
<!-- Drop Zoon -->
<div id="dropZoon-2" class="upload-area__drop-zoon drop-zoon">
<span class="drop-zoon__icon">
<i class='bx bxs-file-image'></i>
</span>
<p class="drop-zoon__paragraph">Drop your file here or Click to browse</p>
<span id="loadingText-2" class="drop-zoon__loading-text">Please Wait</span>
<img src="" alt="Preview Image" id="previewImage-2" class="drop-zoon__preview-image" draggable="false">
<input type="file" id="fileInput-2" class="drop-zoon__file-input" accept="image/*">
</div>
<!-- End Drop Zoon -->
<!-- File Details -->
<div id="fileDetails-2" class="upload-area__file-details file-details">
<h3 class="file-details__title">Uploaded File</h3>
<div id="uploadedFile-2" class="uploaded-file">
<div class="uploaded-file__icon-container">
<i class='bx bxs-file-blank uploaded-file__icon'></i>
<span class="uploaded-file__icon-text-2"></span> <!-- Data Will be Comes From Js -->
</div>
<div id="uploadedFileInfo-2" class="uploaded-file__info">
<span class="uploaded-file__name-2">Proejct 1</span>
<span class="uploaded-file__counter-2">0%</span>
</div>
</div>
</div>
<!-- End File Details -->
</div>
<!-- End Upload Area -->
In fact, all your code was wrapped in a separate function, to which the arguments of the same name are passed.
Of course, in my opinion, for the final result, this should be refactored for final use, using querySelectorAll for a list of root elements, followed by obtaining individual nested elements with querySelector.
I have added a button on my site which let's the users change to dark or light mode whenever they want. I added the button with a moon icon on it, but the problem is that I want that the moon icon changes to sun icon when the user is in dark mode. And changes to moon icon when user is in light mode.
function myfunction(e) {
console.log("you clicked");
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
<button class="btn"><img src='moon.png'></img></button>
The .inverted class in js is because I don't want the images to invert their colors.. so I gave all the images a class='inverted'
So, this is what I've done and someone please let me know how I should change the icon to moon and sun depending on the current mode (light or dark)
Thanks!
You could add the sun as another image to the button and change the visibility of the two images via your .dark-mode css class.
So whenever the .dark-mode class is present the moon gets hidden and the sun gets shown.
function myfunction(e) {
console.log("you clicked");
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
/* button handling */
.moon {
display: block;
}
.sun {
display: none;
}
.dark-mode .moon {
display: none;
}
.dark-mode .sun {
display: block;
}
<button class="btn">
<img class="moon" src="moon.png" alt="moon"></img>
<img class="sun" src="sun.png" alt="sun"></img>
</button>
You could go with the CSS approach as in #Fabian's answer. If you would like to go with JS, you could simply use a flag to indicate whether or not the user switched to dark mode, and dynamically set the icon based on it.
let isDarkMode = document.documentElement.classList.contains("dark-mode");
function myfunction(e) {
document.documentElement.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
e.currentTarget.querySelector("img").src = isDarkMode ? "sun.png" : "moon.png";
}
You can use the below reference for the toggle button from light mode to dark mode and dark mode to light mode.
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.toggle-checkbox {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.toggle-slot {
position: relative;
height: 10em;
width: 20em;
border: 5px solid #e4e7ec;
border-radius: 10em;
background-color: white;
box-shadow: 0px 10px 25px #e4e7ec;
transition: background-color 250ms;
}
.toggle-checkbox:checked ~ .toggle-slot {
background-color: #374151;
}
.toggle-button {
transform: translate(11.75em, 1.75em);
position: absolute;
height: 6.5em;
width: 6.5em;
border-radius: 50%;
background-color: #ffeccf;
box-shadow: inset 0px 0px 0px 0.75em #ffbb52;
transition: background-color 250ms, border-color 250ms, transform 500ms cubic-bezier(.26,2,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .toggle-button {
background-color: #485367;
box-shadow: inset 0px 0px 0px 0.75em white;
transform: translate(1.75em, 1.75em);
}
.sun-icon {
position: absolute;
height: 6em;
width: 6em;
color: #ffbb52;
}
.sun-icon-wrapper {
position: absolute;
height: 6em;
width: 6em;
opacity: 1;
transform: translate(2em, 2em) rotate(15deg);
transform-origin: 50% 50%;
transition: opacity 150ms, transform 500ms cubic-bezier(.26,2,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .sun-icon-wrapper {
opacity: 0;
transform: translate(3em, 2em) rotate(0deg);
}
.moon-icon {
position: absolute;
height: 6em;
width: 6em;
color: white;
}
.moon-icon-wrapper {
position: absolute;
height: 6em;
width: 6em;
opacity: 0;
transform: translate(11em, 2em) rotate(0deg);
transform-origin: 50% 50%;
transition: opacity 150ms, transform 500ms cubic-bezier(.26,2.5,.46,.71);
}
.toggle-checkbox:checked ~ .toggle-slot .moon-icon-wrapper {
opacity: 1;
transform: translate(12em, 2em) rotate(-15deg);
}
<head>
<script src="https://code.iconify.design/1/1.0.4/iconify.min.js"> </script>
</head>
<label>
<input class='toggle-checkbox' type='checkbox'>
<div class='toggle-slot'>
<div class='sun-icon-wrapper'>
<div class="iconify sun-icon" data-icon="feather-sun" data-inline="false"></div>
</div>
<div class='toggle-button'></div>
<div class='moon-icon-wrapper'>
<div class="iconify moon-icon" data-icon="feather-moon" data-inline="false"></div>
</div>
</div>
</label>
function myfunction(e) {
const doc = document.documentElement
doc.classList.toggle("dark-mode");
document.querySelectorAll(".inverted").forEach((result) => {
result.classList.toggle("invert");
});
const img = e.currentTarget.querySelector('img')
const label = e.currentTarget.querySelector('span')
if (doc.classList.contains('dark-mode')) {
img.src = 'sun.png'
label.innerHTML = 'Light mode'
} else {
img.src = 'moon.png'
label.innerHTML = 'Dark mode'
}
}
const btn = document.querySelector('.btn')
btn.addEventListener('click', myfunction);
.dark-mode {
filter: invert(1) hue-rotate(180deg);
}
.invert {
filter: invert(1) hue-rotate(180deg);
}
'
<button class="btn">
<img src='moon.png' alt="" />
<span>Dark mode</span>
</button>
I have created a contact form that will appear when a button is clicked. This works fine. However, when I add js-code to close the contact via a button inside the contact form it won't open at all.
I think it's a problem with the logic, but I can't locate where. Syntax seems fine.
Be aware that the js code which renders everything useless has been commented out. I have added it in the descriptions, so it should hopefully be clear for anyone to make head and tales out of it. Also, you must click on the window to make the contact form appear because the display in css is set to 'none' and changes upon clicking to 'flex'.
//this function will make the contact-form open upon clicking the "get a quote" Button
window.addEventListener('click', function() {
let quoteButton = document.getElementById('quote-button');
let contactWrapper = document.getElementById('contact-wrapper');
if (contactWrapper.style.display == 'none') {
contactWrapper.style.display = 'flex';
} else {
(contactWrapper.style.display = 'none');
}
});
//this function shoud make the contact-form disappear upon clicking the "Back" Button, however above code (to make contact form appear) does not work if bellow code is enabled.
/*
window.addEventListener('click', function() {
let backbutton = document.getElementById('back-button');
let contactWrapper = document.getElementById('contact-wrapper');
if (contactWrapper.style.display == 'flex') {
contactWrapper.style.display = 'none';
}
});
*/
//this function will make the contact-form stick in place when opened
window.addEventListener('scroll', function() {
let contactForm = document.getElementById('contact-wrapper');
let maxTopYPosition = 0;
let maxBottomYPosition = 4000;
if (window.pageYOffset >= maxTopYPosition && window.pageYOffset < maxBottomYPosition) {
contactForm.classList.add('sticky-contact-wrapper');
} else {
contactForm.classList.remove('sticky-contact-wrapper');
}
});
/* Beginning of Contact-Form
The contact form is only visible on click*/
#contact-wrapper {
display: none;
left: 5%;
z-index: 10000;
font-family: Arial, Helvetica, sans-serif;
background-image: linear-gradient(to bottom right, rgba(122, 122, 122, 0.975), rgba(173, 173, 173, 0.975), rgba(235, 235, 235, 0.975), rgba(201, 201, 201, 0.975), rgba(122, 122, 122, 0.975));
width: 90%;
margin: 5vh auto;
padding: 1vh 1vw;
flex-direction: row;
flex-wrap: wrap;
border: 5px solid black;
border-radius: 10px;
box-shadow: 10px 10px rgb(206, 197, 197, 0.5);
}
.sticky-contact-wrapper {
position: absolute;
position: fixed;
top: 10vh;
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.flex-item {
padding: 2vh 2vw;
}
.flex-item1 {
flex-grow: 7;
}
.flex-item2 {
flex-grow: 3;
display: flex;
}
#contact-form p {
line-height: 0;
margin: 2vh 0 6px 0;
font-size: 16px;
}
#contact-form .input-field {
height: 5vh;
width: 80%;
}
#contact-form .message-field{
height: 12vh;
}
.button-flex-wrapper {
display: flex;
flex-direction: row;
width: 80%;
justify-content: space-between;
}
#contact-form button {
display: block;
height: 5vh;
width: 10vw;
min-width: 75px;
color: white;
background: rgb(173, 66, 66);
border: none;
border-radius: 5px;
text-transform: uppercase;
}
.dropZone {
width: 33vw;
height: 75%;
margin: auto;
border: 2px dashed #ccc;
line-height: -50%;
text-align: center;
display: table;
}
.dropZone h3 {
display: table-cell;
text-align: center;
vertical-align: middle;
background: rgb(235, 231, 231);
height: 200px; width:200px;
color: black;
}
.dropZone.dragover {
border-color: black;
color: #000;
}
/* End of contact form */
<!-- CONTACT-FORM -->
<div id="contact-wrapper">
<div class="flex-item flex-item1">
<form id="contact-form" action="" method="POST"
enctype="multipart/form-data">
<p>Name</p>
<input class="input-field" type="text" placeholder="name">
<p>Last Name</p>
<input class="input-field" type="text" placeholder="name">
<p>work email</p>
<input class="input-field" type="text" placeholder="email">
<p>phone</p>
<input class="input-field" type="text" placeholder="phone">
<p>message</p>
<input class="input-field message-field" type="text">
<br><br>
<p>Submit your request</p>
<br>
<div class="button-flex-wrapper">
<div>
<button id="back-button" type="button">Back</button>
</div>
<div>
<button id="submit-button" type="button">Submit</button>
</div>
</div>
</div>
<div id="uploads" class="flex-item flex-item2">
<div class="dropZone" id="dropZone">
<h3>Drop Files Here</h3>
</div>
</div>
</div>
As pointed out, the problem was that the event handler was listening for any kind of click event in the window object. Instead I refactored the code and put the respective buttons in variables and added the addEventListener.
// contact-form opens upon clicking the "get a quote" Button
let quoteButton = document.getElementById('quote-button');
quoteButton.addEventListener('click', function() {
let contactWrapper = document.getElementById('contact-wrapper');
if (contactWrapper.style.display == 'none') {
contactWrapper.style.display = 'flex';
} else {
(contactWrapper.style.display = 'none');
}
});
//contact-form disapears when clicking "back" Button
let backbutton = document.getElementById('back-button');
backbutton.addEventListener('click', function() {
let contactWrapper = document.getElementById('contact-wrapper');
if (contactWrapper.style.display == 'flex') {
contactWrapper.style.display = 'none';
}
});
Your JS is just listening for any 'click' right now, that seems to be the problem. You should add an onclick handler to your button via your html and have that perform the JS function.
<button onclick="openContactForm()" id="quote-button">Open Contact</button>
I turned your code into a codepen so you and others can check it out and provide some additional input. I also made the changes I spoke about in it for you.
I am intending to create a set of textboxes that can be rearranged. The user is to be allowed to create text boxes and then fill them with text.
As he keeps rearranging them the text gets automatically updated in the textarea.
I am using packery library
// external js: packery.pkgd.js, draggabilly.pkgd.js
$("#add_item").click(function(){
$("#grid").append("<input type='text' class='grid-item'></input>");
});
var $grid = $('.grid').packery({
itemSelector: '.grid-item',
columnWidth: 100
});
// make all grid-items draggable
$grid.find('.grid-item').each( function( i, gridItem ) {
var draggie = new Draggabilly( gridItem );
// bind drag events to Packery
$grid.packery( 'bindDraggabillyEvents', draggie );
});
// show item order after layout
function orderItems() {
var itemElems = $grid.packery('getItemElements');
var res_text = '';
$( itemElems ).each( function( i, itemElem ) {
res_text = ' '+$(itemElem).text();
});
$('#result_text').text(res_text);
}
$grid.on( 'layoutComplete', orderItems );
$grid.on( 'dragItemPositioned', orderItems );
* { box-sizing: border-box; }
body { font-family: sans-serif; }
/* ---- grid ---- */
.grid {
background: #DDD;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- .grid-item ---- */
.grid-item {
float: left;
width: 100px;
height: 100px;
background: #C09;
border: 2px solid hsla(0, 0%, 0%, 0.5);
color: white;
font-size: 20px;
padding: 10px;
}
.grid-item--width2 { width: 200px; }
.grid-item--height2 { height: 200px; }
.grid-item:hover {
border-color: hsla(0, 0%, 100%, 0.5);
cursor: move;
}
.grid-item.is-dragging,
.grid-item.is-positioning-post-drag {
background: #C90;
z-index: 2;
}
.packery-drop-placeholder {
outline: 3px dashed hsla(0, 0%, 0%, 0.5);
outline-offset: -6px;
-webkit-transition: -webkit-transform 0.2s;
transition: transform 0.2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://unpkg.com/packery#2.1.1/dist/packery.pkgd.js"></script>
<script src="https://unpkg.com/draggabilly#2.1.1/dist/draggabilly.pkgd.js"></script>
<h1>Packery - get item elements in order after drag</h1>
<button id="add_item" class="ui-button ui-widget ui-corner-all">A button element</button>
<div class="grid">
<input type="text" class="grid-item"></input>
<input type="text" class="grid-item"></input>
<input type="text" class="grid-item"></input>
</div>
<textarea id="result_text" readonly></textarea>
However, I can not add boxes at will using the Button
You should use class grid instead :
$(".grid").append("<input type='text' class='grid-item'/>");
Instead of :
$("#grid").append("<input type='text' class='grid-item'></input>");
Then you should destroy and reinit the packery after adding new grid-item.
NOTE : input tag is a sel-closing tag so it should be :
<input type='text' class='grid-item'/>
Hope this helps.
// external js: packery.pkgd.js, draggabilly.pkgd.js
$("#add_item").click(function() {
$(".grid").append("<input type='text' class='grid-item'/>");
grid.packery('destroy');
grid = initParckery();
});
function initParckery() {
var grid = $('.grid').packery({
itemSelector: '.grid-item',
columnWidth: 100
});
// make all grid-items draggable
grid.find('.grid-item').each(function(i, gridItem) {
var draggie = new Draggabilly(gridItem);
// bind drag events to Packery
grid.packery('bindDraggabillyEvents', draggie);
});
return grid;
}
// show item order after layout
function orderItems() {
setTimeout(function() {
var res_text = '';
var items = grid.packery('getItemElements');
items.forEach(function(itemElem) {
res_text += ' ' + $(itemElem).val();
});
$('#result_text').val(res_text);
}, 100)
}
var grid = initParckery();
grid.on('layoutComplete', orderItems);
grid.on('dragItemPositioned', orderItems);
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- grid ---- */
.grid {
background: #DDD;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- .grid-item ---- */
.grid-item {
float: left;
width: 100px;
height: 100px;
background: #C09;
border: 2px solid hsla(0, 0%, 0%, 0.5);
color: white;
font-size: 20px;
padding: 10px;
}
.grid-item--width2 {
width: 200px;
}
.grid-item--height2 {
height: 200px;
}
.grid-item:hover {
border-color: hsla(0, 0%, 100%, 0.5);
cursor: move;
}
.grid-item.is-dragging,
.grid-item.is-positioning-post-drag {
background: #C90;
z-index: 2;
}
.packery-drop-placeholder {
outline: 3px dashed hsla(0, 0%, 0%, 0.5);
outline-offset: -6px;
-webkit-transition: -webkit-transform 0.2s;
transition: transform 0.2s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://unpkg.com/packery#2.1.1/dist/packery.pkgd.js"></script>
<script src="https://unpkg.com/draggabilly#2.1.1/dist/draggabilly.pkgd.js"></script>
<h1>Packery - get item elements in order after drag</h1>
<button id="add_item" class="ui-button ui-widget ui-corner-all">A button element</button>
<div class="grid">
<input type="text" class="grid-item a"></input>
<input type="text" class="grid-item b"></input>
<input type="text" class="grid-item c"></input>
</div>
<textarea id="result_text" readonly></textarea>
It looks like you have an element with class grid, but in your JS, you are grabbing an element with id of grid.
For the fix, change your JS from grabbing the id to grabbing the class:
$("#add_item").click(function(){
$(".grid").append("<input type='text' class='grid-item' />");
});