Create a canvasjs on submit on a dynamically generated element - javascript

NEW to javascript, jquery, and CanvasJS!
Here's my problem:
As you can notice, I'm going to submit a bunch of data with ajax. Since some don't exist, I'm gonna attach the event onsubmit, to make it works.
Now, my problem is the chart: I'm using CanvasJS to create my chart, and right before the code to make it happens, I created a div dynamically with the id chartContainer, and right after I will initiate the cart with the function CanvasJS.Chart().
The problem is that, if I create the div in the html file, the code will work, but if I will create the div in the script, the code will fail because:
CanvasJS Error: Chart Container with id "chartContainer" was not found.
How can I overcome the problem?
$(document).ready(function() {
$(document).on('submit', 'form', function(event) {
$.ajax({
type: 'POST',
url: $(this).attr("action"),
data: $(this).serialize(),
dataType: 'json',
encode: true
}).done(function(data) {
var result = data.kg / Math.pow((data.centimeter / 100), 2);
var result3 = result.toFixed(2);
var result2 = '<div class="results">' + result.toFixed(2);
result2 += '<div id="clickhere">back</div>';
if (result > 25) {
result2 += '<div>Your should loose at least the 5% of your weight</div>'
} else if (result > 18.5) {
result2 += '<div>Your weight is ideal</div>'
} else {
result2 += '<div>You\'re underweight, you should take integrate your diet with different food and eat more often</div>'
}
result2 += '<div id="chartContainer"></div>'
var gauge = {
title: {
text: "BMI"
},
data: {
y: result3
},
maximum: 30
};
var chart = new CanvasJS.Chart("chartContainer");
createGauge(chart);
function createGauge(chart) {
gauge.unoccupied = {
y: gauge.maximum - gauge.data.y,
color: "#e3e3e3",
toolTipContent: null,
highlightEnabled: false,
click: function() {
gauge.unoccupied.exploded = true;
}
}
gauge.data.click = function() {
gauge.data.exploded = true;
};
if (!gauge.data.color)
gauge.data.color = "#6b58f2";
gauge.valueText = {
text: gauge.data.y.toString(),
verticalAlign: "center"
};
var data = {
type: "doughnut",
dataPoints: [{
y: gauge.maximum,
color: "transparent",
toolTipContent: null
},
gauge.data,
gauge.unoccupied
],
};
if (!chart.options.data)
chart.options.data = [];
chart.options.data.push(data);
if (gauge.title) {
chart.options.title = gauge.title;
}
if (!chart.options.subtitles)
chart.options.subtitles = [];
chart.options.subtitles.push(gauge.valueText);
chart.render();
}
result2 += '</div>';
var clickhere = $('#clickhere');
var form = $('form');
$('form').replaceWith(result2);
$(document).on("click", "#clickhere", function() {
$('.results').remove();
});
});
event.preventDefault();
});
});
<form action="/send.php" id="formid" method="post">
<div class="row">
<div class="col-md-4">
<div class="row">
<h3 class="col-md-9">Height</h3>
<p class="switch col-md-3">cm</p>
</div>
<div class="antbits-bmi-form_section_layer antbits-bmi-metric">
<div>
<label for="antbits-bmi-cm" class="antbits-bmi-form_section_label">Centimetres</label>
<input class="form-control" id="antbits-bmi-cm" aria-describedby="antbits-bmi-form_height-error" alt="height, centimeters" inputmode="numeric" type="text" step="0.1" min="0" maxlength="5" name="centimeter" placeholder="cm" required="">
</div>
</div>
</div>
<div class="col-md-4">
<div class="row">
<h3 class="col-md-9">Weight</h3>
<p class="col-md-3 switch">st, lb</p>
</div>
<div class="antbits-bmi-form_section_layer antbits-bmi-imperial">
<div>
<label for="antbits-bmi-kg" class="antbits-bmi-form_section_label">Kg</label>
<input class="form-control" id="antbits-bmi-kg" placeholder="Kg" alt="kg" type="text" inputmode="numeric" min="0" maxlength="2" name="kg" required="">
</div>
</div>
</div>
<div class="col-md-4">
<h3>Age</h3>
<div class="antbits-bmi-form_section_inner">
<div>
<label for="antbits-bmi-age" class="antbits-bmi-form_section_label antbits-accessible_hidden">Age in years</label>
<select class="form-control" id="age" name="age" required=""></select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Sex<small>?</small></h3>
<div class="info hide">
<h3>Sex<small>?</small></h3>
<p>For children, BMI centile is gender specific. For both children and adults, we give more personalised information based on whether you are male or female.</p>
</div>
<div class="radio-click row height">
<div class="radio-inline col-md-6 checked" id="male">
<input type="radio" name="optradio" value="male">Male
</div>
<div class="radio-inline col-md-6" id="female">
<input type="radio" name="optradio" value="female">Female
</div>
</div>
</div>
<div class="col-md-4">
<h3>Ethnic Group (optional)<small>?</small></h3>
<div class="info hide">
<h3>Ethnic</h3>
<p>Black, Asian and other minority ethnic groups with a BMI of 23 or more have a higher risk of getting type 2 diabetes and other long term illnesses.</p>
</div>
<select class="form-control" id="antbits-bmi-ethnicity" alt="Ethnic group" name="ethnic" required="">
<option disabled selected value class="antbits-bmi-form_option">Not stated</option>
<option value="2" class="antbits-bmi-form_option">White</option>
<option value="3" class="antbits-bmi-form_option">Black Caribbean</option>
<option value="4" class="antbits-bmi-form_option">Black African</option>
<option value="5" class="antbits-bmi-form_option">Indian</option>
<option value="6" class="antbits-bmi-form_option">Pakistani</option>
<option value="7" class="antbits-bmi-form_option">Bangladeshi</option>
<option value="8" class="antbits-bmi-form_option">Chinese</option>
<option value="9" class="antbits-bmi-form_option">Middle Eastern</option>
<option value="10" class="antbits-bmi-form_option">Mixed</option>
<option value="11" class="antbits-bmi-form_option">Other</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h3>Activity Level</h3>
<p>So we can personalize your results</p>
<div class="slidercontainer">
<input type="range" min="0" max="150" value="75" class="slider" id="myRange" name="range">
<div class="row center height activity">
<div class="col-md-4">
<p>Inactive</p>
</div>
<div class="col-md-4">
<p>Moderate Active</p>
</div>
<div class="col-md-4">
<p>Active</p>
</div>
</div>
<div class="row center height">
<div class="col-md-4">
<p>Less than 30 minutes a week</p>
</div>
<div class="col-md-4">
<p>Between 30 and 60 minutes a week</p>
</div>
<div class="col-md-4">
<p>Between 60 and 150 minutes a week</p>
</div>
</div>
<p>Value: <span id="demo"></span></p>
</div>
</div>
</div>
<!-- <div id="chartContainer"></div> -->
<div class="center">
<input type="submit" value="Calculate">
</div>
</form>

Append the div to the document before calling the chart.
You need to move
result2 += '</div>';
var clickhere = $('#clickhere');
var form = $('form');
$('form').replaceWith(result2);
to right before
var chart = new CanvasJS.Chart("chartContainer");
createGauge(chart);
You can even more the function outside as well. It is not needed inside the document.ready
And this
$(document).on("click", "#clickhere", function() {
$('.results').remove();
});
does not belong in the .done either
Here is a better version
function createGauge(chart) {
gauge.unoccupied = {
y: gauge.maximum - gauge.data.y,
color: "#e3e3e3",
toolTipContent: null,
highlightEnabled: false,
click: function() {
gauge.unoccupied.exploded = true;
}
}
gauge.data.click = function() {
gauge.data.exploded = true;
};
if (!gauge.data.color)
gauge.data.color = "#6b58f2";
gauge.valueText = {
text: gauge.data.y.toString(),
verticalAlign: "center"
};
var data = {
type: "doughnut",
dataPoints: [{
y: gauge.maximum,
color: "transparent",
toolTipContent: null
},
gauge.data,
gauge.unoccupied
],
};
if (!chart.options.data)
chart.options.data = [];
chart.options.data.push(data);
if (gauge.title) {
chart.options.title = gauge.title;
}
if (!chart.options.subtitles)
chart.options.subtitles = [];
chart.options.subtitles.push(gauge.valueText);
chart.render();
}
$(function() {
$(document).on("click", "#clickhere", function() {
$('.results').remove();
});
$(document).on('submit', 'form', function(event) {
event.preventDefault();
$.ajax({
type: 'POST',
url: $(this).attr("action"),
data: $(this).serialize(),
dataType: 'json',
encode: true
}).done(function(data) {
var result = data.kg / Math.pow((data.centimeter / 100), 2);
var result3 = result.toFixed(2);
var result2 = '<div class="results">' + result.toFixed(2);
result2 += '<div id="clickhere">back</div>';
if (result > 25) {
result2 += '<div>Your should loose at least the 5% of your weight</div>'
} else if (result > 18.5) {
result2 += '<div>Your weight is ideal</div>'
} else {
result2 += '<div>You\'re underweight, you should take integrate your diet with different food and eat more often</div>'
}
result2 += '<div id="chartContainer"></div>'
result2 += '</div>';
var form = $('form');
$('form').replaceWith(result2);
var gauge = {
title: {
text: "BMI"
},
data: {
y: result3
},
maximum: 30
};
var chart = new CanvasJS.Chart("chartContainer");
createGauge(chart);
});
});
});
<form action="/send.php" id="formid" method="post">
<div class="row">
<div class="col-md-4">
<div class="row">
<h3 class="col-md-9">Height</h3>
<p class="switch col-md-3">cm</p>
</div>
<div class="antbits-bmi-form_section_layer antbits-bmi-metric">
<div>
<label for="antbits-bmi-cm" class="antbits-bmi-form_section_label">Centimetres</label>
<input class="form-control" id="antbits-bmi-cm" aria-describedby="antbits-bmi-form_height-error" alt="height, centimeters" inputmode="numeric" type="text" step="0.1" min="0" maxlength="5" name="centimeter" placeholder="cm" required="">
</div>
</div>
</div>
<div class="col-md-4">
<div class="row">
<h3 class="col-md-9">Weight</h3>
<p class="col-md-3 switch">st, lb</p>
</div>
<div class="antbits-bmi-form_section_layer antbits-bmi-imperial">
<div>
<label for="antbits-bmi-kg" class="antbits-bmi-form_section_label">Kg</label>
<input class="form-control" id="antbits-bmi-kg" placeholder="Kg" alt="kg" type="text" inputmode="numeric" min="0" maxlength="2" name="kg" required="">
</div>
</div>
</div>
<div class="col-md-4">
<h3>Age</h3>
<div class="antbits-bmi-form_section_inner">
<div>
<label for="antbits-bmi-age" class="antbits-bmi-form_section_label antbits-accessible_hidden">Age in years</label>
<select class="form-control" id="age" name="age" required=""></select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<h3>Sex<small>?</small></h3>
<div class="info hide">
<h3>Sex<small>?</small></h3>
<p>For children, BMI centile is gender specific. For both children and adults, we give more personalised information based on whether you are male or female.</p>
</div>
<div class="radio-click row height">
<div class="radio-inline col-md-6 checked" id="male">
<input type="radio" name="optradio" value="male">Male
</div>
<div class="radio-inline col-md-6" id="female">
<input type="radio" name="optradio" value="female">Female
</div>
</div>
</div>
<div class="col-md-4">
<h3>Ethnic Group (optional)<small>?</small></h3>
<div class="info hide">
<h3>Ethnic</h3>
<p>Black, Asian and other minority ethnic groups with a BMI of 23 or more have a higher risk of getting type 2 diabetes and other long term illnesses.</p>
</div>
<select class="form-control" id="antbits-bmi-ethnicity" alt="Ethnic group" name="ethnic" required="">
<option disabled selected value class="antbits-bmi-form_option">Not stated</option>
<option value="2" class="antbits-bmi-form_option">White</option>
<option value="3" class="antbits-bmi-form_option">Black Caribbean</option>
<option value="4" class="antbits-bmi-form_option">Black African</option>
<option value="5" class="antbits-bmi-form_option">Indian</option>
<option value="6" class="antbits-bmi-form_option">Pakistani</option>
<option value="7" class="antbits-bmi-form_option">Bangladeshi</option>
<option value="8" class="antbits-bmi-form_option">Chinese</option>
<option value="9" class="antbits-bmi-form_option">Middle Eastern</option>
<option value="10" class="antbits-bmi-form_option">Mixed</option>
<option value="11" class="antbits-bmi-form_option">Other</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h3>Activity Level</h3>
<p>So we can personalize your results</p>
<div class="slidercontainer">
<input type="range" min="0" max="150" value="75" class="slider" id="myRange" name="range">
<div class="row center height activity">
<div class="col-md-4">
<p>Inactive</p>
</div>
<div class="col-md-4">
<p>Moderate Active</p>
</div>
<div class="col-md-4">
<p>Active</p>
</div>
</div>
<div class="row center height">
<div class="col-md-4">
<p>Less than 30 minutes a week</p>
</div>
<div class="col-md-4">
<p>Between 30 and 60 minutes a week</p>
</div>
<div class="col-md-4">
<p>Between 60 and 150 minutes a week</p>
</div>
</div>
<p>Value: <span id="demo"></span></p>
</div>
</div>
</div>
<!-- <div id="chartContainer"></div> -->
<div class="center">
<input type="submit" value="Calculate">
</div>
</form>

Related

javascript basic calculation price,quantity and discount

I would like to count price and discount and quantity for result which is the total. Is it possible to do with javascript and how? I have tried several ways to implement the function in javascript however none of my effort works.
<body style="background-image: linear-gradient(to right, seagreen , lightyellow");>
<div class="container-fluid">
<div class="row">
<div class="col-lg-3">
<div class="card">
<div class="card-body">
<div class="form-group col-lg-12 col-md-12 col-sm-12">
<div>
<label>Customer Name:</label>
<input type="text" class="form-control" id="cname" name="customername" />
</div>
<div>
<label>Test Rate:</label>
<input type="number" class="form-control calculationadd" id="testprice" name="testamt" />
</div>
<div>
<label>Quantity:</label>
<input type="number" class="form-control calculationadd" id="qty" name="qtyname" />
</div>
<div>
<label>Discount%:</label>
<input type="number" class="form-control calculationadd" id="discountid" name="dis" />
</div>
<div>
<label>Total:</label>
<input type="number" class="form-control calculationadd" id="totalid" name="total" />
</div>
<script>
$(".calculationadd").keyup(function () {
var customername = $("#cname").val();
var testamt = $("#testprice").val();
var quan = $("#qty").val();
var dis = $("#discountid").val();
var total = $("#totalid").val();
var rateqty = parseFloat(testamt) * parseFloat(quan);
var afterdiscount = parseFloat(rateqty) * parseFloat(dis) / (100)
var final = parseFloat(rateqty) - parseFloat(afterdiscount);
$("#totalid").val(rateqty);
}
);
</script>
</div>
</div>
</div>
</div>
</div>
</div>
</body>

How to show total value of two text box in another box - Javascript

I am new to javascript, I want to get two fees in text boxes and show sum of those two fees in another text box (which is disabled, so can't edit it, just for showing purpose) below is my html form.. result should show when entering in fee1 or fee2 not in submit button. How to do it?
<div class="row">
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Consulation Fees:</b><span class="text-danger">*</span></label><input type="number" class="form-control" id="fee1" name="fee1" required min="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Other Charges:</b></label><input type="number" class="form-control" id="fee2" name="fee2" min="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Total Fee:</b></label><input type="number" disabled class="form-control" id ="total_fee" name="total_fee" >
</div>
</div>
use input event on fee1 and fee2 and then sum their values and put as value of total_fee.
e.g.
const fee1 = document.getElementById("fee1");
const fee2 = document.getElementById("fee2");
const total_fee = document.getElementById("total_fee");
fee1.addEventListener("input", sum);
fee2.addEventListener("input", sum);
function sum() {
total_fee.value = Number(fee1.value)+Number(fee2.value);
}
see in action
https://jsbin.com/lizunojadi/edit?html,js,output
Basically you listen to input event on both of the controls, summing the values into the other input.
document.querySelectorAll("#fee1, #fee2").forEach(function(elem) {
elem.addEventListener("input", do_sum)
})
function do_sum() {
var total = 0
document.querySelectorAll("#fee1, #fee2").forEach(function(elem) {
total += +elem.value;
})
document.querySelector("#total_fee").value = total
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="container">
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label class="gr"><b>Consulation Fees:</b><span class="text-danger">*</span></label><input type="number" class="form-control" id="fee1" name="fee1" required min="0">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="gr"><b>Other Charges:</b></label><input type="number" class="form-control" id="fee2" name="fee2" min="0">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="gr"><b>Total Fee:</b></label><input type="number" disabled class="form-control" id="total_fee" name="total_fee">
</div>
</div>
</div>
</div>
Here is the simple solution for your code,
<div class="row">
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Consulation Fees:</b><span class="text-danger">*</span></label><input type="number" class="form-control" id="fee1" name="fee1" required min="0" value="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Other Charges:</b></label><input type="number" class="form-control" id="fee2" name="fee2" min="0" value="0">
</div>
</div>
<div class="col-xl-4">
<div class="form-group">
<label class="gr"><b>Total Fee:</b></label><input type="number" disabled class="form-control" id ="total_fee" name="total_fee" >
</div>
</div>
Here in the HTML code default value="0",
Now in Javascript,
const fee1 = document.getElementById('fee1');
const fee2 = document.getElementById('fee2');
const totalFee = document.getElementById('total_fee');
function doSum() {
const fee1Value = parseInt(fee1.value);
const fee2Value = parseInt(fee2.value);
const totalFeeValue = fee1Value + fee2Value;
totalFee.value = totalFeeValue;
}
fee1.addEventListener('input', doSum);
fee2.addEventListener('input', doSum);
doSum() function is executing oninput

Form Values Returning Null in localStorage When Editing Selects Using Javascript?

I have a form which sends data to localStorage, which I am able to view, delete and edit. My form has a mixture of input types, text select and textarea, when I submit the form, these values store correctly, however when I use my edit function, the values show correctly on the edit form, but if I don't change the values (even to the same value), they update/store as null.
For example:
I have a form with Name(type text), Address(type address) and Dog Breed(type select), when I edit, the values of all three will be there from the form before, but if I hit submit without changing any, the dog breed would return null. They update correctly if I change the values, but as this is an appointment scheduler, not every value will be changed (for eg they may only need to change the time or breed).
Here is my snippet - I know it can't be run fully because of sandboxing but just so you can see:
const BREEDS_URL = 'https://dog.ceo/api/breeds/list/all';
const select = document.getElementById('breed');
fetch(BREEDS_URL)
.then(res => {
return res.json();
})
.then(data => {
const breedsObject = data.message;
const breedsArray = Object.keys(breedsObject);
for (let i = 0; i < breedsArray.length; i++) {
const option = document.createElement('option');
option.value = breedsArray[i];
option.innerText = breedsArray[i];
select.appendChild(option);
}
console.log(breedsArray);
});
// ~~~ add bookings to localStorage
var bookings = JSON.parse(localStorage.getItem("bookings")) || [];
window.onload = showBooking();
window.onload = showTimes();
$("#submit").click(function() {
var newBookings = {
id: new Date().getTime(),
fname: $('#fname').val(),
lname: $('#lname').val(),
email: $('#email').val(),
number: $('#number').val(),
sdate: $('#sdate').val(),
stime: $('#stime').val(),
duration: $('#duration').val(),
address: $('#address').val(),
postcode: $('#postcode').val(),
dogname: $('#dogName').val(),
breed: $('#breed').val(),
info: $('#info').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
alert('Form submitted!');
showBooking();
});
$(document).on('click', '#edit', function(e) {
e.preventDefault();
var parent_form = $(this.form);
var fname = parent_form.find('.fname').val();
var lname = parent_form.find('.lname').val();
var email = parent_form.find('.email').val();
var number = parent_form.find('.number').val();
var sdate = parent_form.find('.datepicker').val();
var stime = parent_form.find('.select').val();
var duration = parent_form.find('.duration').val();
var address = parent_form.find('.address').val();
var postcode = parent_form.find('.postcode').val();
var dogname = parent_form.find('.dogname').val();
var breed = parent_form.find('.breed').val();
var info = parent_form.find('.info').val();
let i = bookings.findIndex(booking => booking.id == $(this).data("id"));
bookings[i].fname = fname;
bookings[i].lname = lname;
bookings[i].email = email;
bookings[i].number = number;
bookings[i].sdate = sdate;
bookings[i].stime = stime;
bookings[i].duration = duration;
bookings[i].address = address;
bookings[i].postcode = postcode;
bookings[i].dogname = dogname;
bookings[i].breed = breed;
bookings[i].info = info;
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
window.location.reload();
alert('Form updated!');
showBooking();
});
// ~~~ display bookings in browser
function showBooking() {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
bookingResult.innerHTML = `<h3 class="text-center">Your Bookings</h3>`;
for (let i = 0; i < bookings.length; i++) {
bookingResult.innerHTML += `
<div class="card card-body bg-light m-4">
<div class="row">
<p>${bookings[i].fname + " " + bookings[i].lname}</p>
</div>
<div class="row">
<div class="d-grid gap-2 d-md-block">
<button onclick="editBooking(${i})" class="col-md-4 btn btn-outline-danger ">Edit</button>
<button onclick="deleteBooking(${i})" class="col-md-4 btn btn-danger text-light ">Delete</button>
</div>
</div>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
$('#result').hide();
var currentItem = document.getElementById("currentItem");
var editBooking = document.getElementById("editAppt");
currentItem.innerHTML += `
<h3 class="text-center">Currently Amending</h3>
<div class="card card-body bg-light m-4">
<p data-id="${bookings[i].id}">${bookings[i].fname + " " + bookings[i].lname}</p>
</div>`;
editBooking.innerHTML = `
<h3 class="text-center">Amend Your Booking</h3>
<div class="row">
<div class="col-md-6">
<input type="text" class="fname form-control required" data-id="${bookings[i].id}" placeholder="First Name" name="${bookings[i].fname}" value="${bookings[i].fname}">
</div>
<div class="col-md-6">
<input type="text" class="lname form-control required" data-id="${bookings[i].id}" placeholder="Last Name" name="${bookings[i].lname}" value="${bookings[i].lname}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="email" class="email form-control required" data-id="${bookings[i].id}" placeholder="Email Address" name="${bookings[i].email}" value="${bookings[i].email}">
</div>
<div class="col-md-6">
<input type="number" class="number form-control required" data-id="${bookings[i].id}" onchange="validateContact()" placeholder="Contact Number" name="${bookings[i].number}" value="${bookings[i].number}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="date" id="sdate" class="datepicker form-control required" name="${bookings[i].sdate}" onchange="checkStartDate()" value="${bookings[i].sdate}">
</div>
<div class="col-md-6">
<select id="stime" name="${bookings[i].stime}" onfocus="showTimes()" class="time select form-control required" value="${bookings[i].stime}">${bookings[i].stime}
<option value="${bookings[i].stime}" selected disabled hidden>${bookings[i].stime}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<select name="${bookings[i].duration}" class="duration form-control required" data-id="${bookings[i].id}" value="${bookings[i].duration}">${bookings[i].duration}
<option value="${bookings[i].duration}" selected disabled hidden>${bookings[i].duration}</option>
<option value="30 mins">30 mins</option>
<option value="1 hour">1 hour</option>
<option value="1.5 hours">1.5 hours</option>
<option value="2 hours">2 hours</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}" class="address form-control required" placeholder="Address" name="${bookings[i].address}" value="${bookings[i].address}">
</div>
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}" class="postcode form-control " placeholder="Post Code" name="${bookings[i].postcode}" value="${bookings[i].postcode}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="${bookings[i].dogname}" value="${bookings[i].dogname}">
</div>
<div class="col-md-6">
<select id="breed" class="breed form-control required" name="${bookings[i].breed}" value="${bookings[i].breed}">
<option value="${bookings[i].breed}" selected disabled hidden>${bookings[i].breed}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-12">
<textarea id="info" name="info" class="info form-control required" placeholder="Any additional info - favourite toys or places?" name="${bookings[i].info}">${bookings[i].info}</textarea>
</div>
</div>
<div class="d-grid gap-2 d-md-block">
<input data-id="${bookings[i].id}" id="edit" class="btn btn-danger toggle-disabled" type="submit" value="Edit" disabled>
Cancel
</div>
`;
}
function showTimes() {
let startTime = document.getElementById('stime');
let times = ['9:00', '9:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'];
let options = times.map(time => `<option value="${time}">${time}</option>`).join('');
startTime.innerHTML += options;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i) {
alert('Are you sure you want to delete this booking?');
bookings.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookings));
showBooking();
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
<section class="form row">
<form id="regForm" name="regForm" action="" class="col-md-6">
<div id="editAppt">
<div class="row text-center">
<h3>Book your dog walk now</h3>
<p>Tell us about yourself first..</p>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" class="input form-control required" id="fname" placeholder="First Name" name="fname" required>
</div>
<div class="col-md-6">
<input type="text" class="input form-control required" id="lname" placeholder="Last Name" name="lname" required>
</div>
</div>
<div class="row text-center">
<p>When should we pick your dog up?</p>
</div>
<div class="row">
<div class="col-md-6">
<input type="date" id="sdate" class="datepicker form-control required" name="sdate" onchange="checkStartDate()" required>
</div>
<div class="col-md-6">
<select name="duration" class="duration form-control required" id="duration" required>
<option value="" selected disabled hidden>Duration</option>
<option value="30 mins">30 mins</option>
<option value="1 hour">1 hour</option>
<option value="1.5 hours">1.5 hours</option>
<option value="2 hours">2 hours</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="dogname">
</div>
<div class="col-md-6">
<select id="breed" class="breed form-control required">
<option value="" selected disabled hidden>Select Breed</option>
</select>
</div>
</div>
<div class="col-md-6">
<input id="submit" class="btn btn-danger toggle-disabled" type="submit" value="Submit">
</div>
</div>
</form>
<div class="col-md-6">
<div id="result" class="row"></div>
<div id="currentItem" class="row"></div>
</div>
There are a few issues in the code you'll need to take care of:
First thing is, I'd wrap everything in a "document.ready" event handler from jQuery:
$(function() {
...
});
The above is shorthand and just ensures your code runs once all of the HTML code has been parsed.
Now, the caveat with that is now all of your functions are no longer in the global scope, so you can't reference them in HTML attributes like onclick. So, you'll need to attach them to your elements using jQuery or plain old DOM methods.
You had two lines which set the window.onload property. In the code below I've changed it to use jQuery-style event handler attachment.
You were setting the name attribute of the form elements to the value of edited appointment, but the name attribute really shouldn't need to change that often.
$(function() {
const BREEDS_URL = 'https://dog.ceo/api/breeds/list/all';
function loadBreeds() {
const select = document.getElementById('breed');
fetch(BREEDS_URL)
.then(res => {
return res.json();
})
.then(data => {
const breedsObject = data.message;
const breedsArray = Object.keys(breedsObject);
for (let i = 0; i < breedsArray.length; i++) {
const option = document.createElement('option');
option.value = breedsArray[i];
option.innerText = breedsArray[i];
select.appendChild(option);
}
console.log(breedsArray);
});
}
// ~~~ add bookings to localStorage
var bookings = JSON.parse(localStorage.getItem("bookings")) || [];
$(window).on('load', function() {
showBooking();
showTimes();
loadBreeds();
});
$("#submit").click(function() {
var newBookings = {
id: new Date().getTime(),
fname: $('#fname').val(),
lname: $('#lname').val(),
email: $('#email').val(),
number: $('#number').val(),
sdate: $('#sdate').val(),
stime: $('#stime').val(),
duration: $('#duration').val(),
address: $('#address').val(),
postcode: $('#postcode').val(),
dogname: $('#dogName').val(),
breed: $('#breed').val(),
info: $('#info').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
alert('Form submitted!');
showBooking();
});
$(document).on('click', '#edit', function(e) {
e.preventDefault();
var parent_form = $(this.form);
var fname = parent_form.find('.fname').val();
var lname = parent_form.find('.lname').val();
var email = parent_form.find('.email').val();
var number = parent_form.find('.number').val();
var sdate = parent_form.find('.datepicker').val();
var stime = parent_form.find('.select').val();
var duration = parent_form.find('.duration').val();
var address = parent_form.find('.address').val();
var postcode = parent_form.find('.postcode').val();
var dogname = parent_form.find('.dogname').val();
var breed = parent_form.find('.breed').val();
var info = parent_form.find('.info').val();
let i = bookings.findIndex(booking => booking.id == $(this).data("id"));
bookings[i].fname = fname;
bookings[i].lname = lname;
bookings[i].email = email;
bookings[i].number = number;
bookings[i].sdate = sdate;
bookings[i].stime = stime;
bookings[i].duration = duration;
bookings[i].address = address;
bookings[i].postcode = postcode;
bookings[i].dogname = dogname;
bookings[i].breed = breed;
bookings[i].info = info;
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
window.location.reload();
alert('Form updated!');
showBooking();
});
$(document).on('change', '.datepicker', checkStartDate);
$(document).on('change', '.number', validateContact);
$(document).on('focusin', '.time', showTimes);
$(document).on('click', '.edit-booking', function(e) {
var index = +$(this).data('index');
editBooking(index);
});
$(document).on('click', '.delete-booking', function(e) {
var index = +$(this).data('index');
deleteBooking(index);
});
// ~~~ display bookings in browser
function showBooking() {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
bookingResult.innerHTML = `<h3 class="text-center">Your Bookings</h3>`;
for (let i = 0; i < bookings.length; i++) {
bookingResult.innerHTML += `
<div class="card card-body bg-light m-4">
<div class="row">
<p>${bookings[i].fname + " " + bookings[i].lname}</p>
</div>
<div class="row">
<div class="d-grid gap-2 d-md-block">
<button data-index="${i}" class="edit-booking col-md-4 btn btn-outline-danger ">Edit</button>
<button data-index="${i}" class="delete-booking col-md-4 btn btn-danger text-light ">Delete</button>
</div>
</div>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
$('#result').hide();
var currentItem = document.getElementById("currentItem");
var editBooking = document.getElementById("editAppt");
currentItem.innerHTML += `
<h3 class="text-center">Currently Amending</h3>
<div class="card card-body bg-light m-4">
<p data-id="${bookings[i].id}">${bookings[i].fname + " " + bookings[i].lname}</p>
</div>`;
editBooking.innerHTML = `
<h3 class="text-center">Amend Your Booking</h3>
<div class="row">
<div class="col-md-6">
<input type="text" class="fname form-control required" data-id="${bookings[i].id}" placeholder="First Name" name="fname" value="${bookings[i].fname}">
</div>
<div class="col-md-6">
<input type="text" class="lname form-control required" data-id="${bookings[i].id}" placeholder="Last Name" name="lname" value="${bookings[i].lname}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="email" class="email form-control required" data-id="${bookings[i].id}" placeholder="Email Address" name="email" value="${bookings[i].email}">
</div>
<div class="col-md-6">
<input type="number" class="number form-control required" data-id="${bookings[i].id}" placeholder="Contact Number" name="number" value="${bookings[i].number}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="date" id="sdate" class="datepicker form-control required" name="sdate" value="${bookings[i].sdate}">
</div>
<div class="col-md-6">
<select id="stime" name="stime" class="time select form-control required" value="${bookings[i].stime}">
<option value="${bookings[i].stime}">${bookings[i].stime}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<select name="duration" class="duration form-control required" data-id="${bookings[i].id}" value="${bookings[i].duration}">
<option value="${bookings[i].duration}">${bookings[i].duration}</option>
<option value="30 mins">30 mins</option>
<option value="1 hour">1 hour</option>
<option value="1.5 hours">1.5 hours</option>
<option value="2 hours">2 hours</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}" class="address form-control required" placeholder="Address" name="address" value="${bookings[i].address}">
</div>
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}" class="postcode form-control " placeholder="Post Code" name="postcode" value="${bookings[i].postcode}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="dogname" value="${bookings[i].dogname}">
</div>
<div class="col-md-6">
<select id="breed" class="breed form-control required" name="breed" value="${bookings[i].breed}">
<option value="${bookings[i].breed}">${bookings[i].breed}</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-12">
<textarea id="info" name="info" class="info form-control required" placeholder="Any additional info - favourite toys or places?" name="info">${bookings[i].info}</textarea>
</div>
</div>
<div class="d-grid gap-2 d-md-block">
<input data-id="${bookings[i].id}" id="edit" class="btn btn-danger toggle-disabled" type="submit" value="Edit" disabled>
Cancel
</div>
`;
loadBreeds();
}
function showTimes() {
let startTime = document.getElementById('stime');
let times = ['9:00', '9:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'];
let options = times.map(time => `<option value="${time}">${time}</option>`).join('');
startTime.innerHTML += options;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i) {
alert('Are you sure you want to delete this booking?');
bookings.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookings));
showBooking();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
<section class="form row">
<form id="regForm" name="regForm" action="" class="col-md-6">
<div id="editAppt">
<div class="row text-center">
<h3>Book your dog walk now</h3>
<p>Tell us about yourself first..</p>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" class="input form-control required" id="fname" placeholder="First Name" name="fname" required>
</div>
<div class="col-md-6">
<input type="text" class="input form-control required" id="lname" placeholder="Last Name" name="lname" required>
</div>
</div>
<div class="row text-center">
<p>When should we pick your dog up?</p>
</div>
<div class="row">
<div class="col-md-6">
<input type="date" id="sdate" class="datepicker form-control required" name="sdate" required>
</div>
<div class="col-md-6">
<select name="duration" class="duration form-control required" id="duration" required>
<option value="" selected disabled hidden>Duration</option>
<option value="30 mins">30 mins</option>
<option value="1 hour">1 hour</option>
<option value="1.5 hours">1.5 hours</option>
<option value="2 hours">2 hours</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="dogname">
</div>
<div class="col-md-6">
<select id="breed" class="breed form-control required">
<option value="" selected disabled hidden>Select Breed</option>
</select>
</div>
</div>
<div class="col-md-6">
<input id="submit" class="btn btn-danger toggle-disabled" type="submit" value="Submit">
</div>
</div>
</form>
<div class="col-md-6">
<div id="result" class="row"></div>
<div id="currentItem" class="row"></div>
</div>

How to show the JSON data into dynamic input text fields?

I have a JSON data coming through AJAX GET method is:The JsonData is stored in var trDataSecondTable and displayed when I did console.log(trDataSecondTable).
{
"assessCatAmount":[
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":1,
"assessReason":"A",
"assessAmount":1,
"assessPenalty":2,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":1,
"assessReason":"D",
"assessAmount":3,
"assessPenalty":4,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":2,
"assessReason":"B",
"assessAmount":5,
"assessPenalty":6,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":2,
"assessReason":"E",
"assessAmount":7,
"assessPenalty":8,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":3,
"assessReason":"C",
"assessAmount":9,
"assessPenalty":10,
"entryBy":"PCS",
"rStatus":"1"
},
{
"assessmentNo":1,
"assessmentType":"PRE",
"assessCatId":3,
"assessReason":"F",
"assessAmount":10,
"assessPenalty":10,
"entryBy":"PCS",
"rStatus":"1"
}
]
}
My form looks like this which is dynamic type (can be added by clicking "+" or can be deleted by pressing "-")
My form when page is loaded first looks like :
I need to show these six JSON data into this form.If there is three JSON data then there should be three row total along with data.If there is twelve json data then twelve row needs to appear along with data in input field.
function sumIt() {
$("#formContainer [type=number]").each(function() {
var $row = $(this).closest(".row");
var $fields = $row.find("[type=number]");
var val1 = $fields.eq(0).val();
var val2 = $fields.eq(1).val();
var tot = (isNaN(val1) ? 0 : +val1) + (isNaN(val2) ? 0 : +val2)
$row.find(".sum").text(tot);
});
var total = 0;
$(".sum").each(function() {
total += isNaN($(this).text()) ? 0 : +$(this).text()
});
$("#tot").text(total);
return total;
}
$(".customs-table .remove:lt(1)").hide();
$(".vat-table .remove:lt(1)").hide();
$(".excise-table .remove:lt(1)").hide();
$("#formContainer").on("click", "button", function() {
var selector = "div.row";
var $div = $(this).closest(selector);
if ($(this).is(".add")) {
var $newDiv = $div.clone();
$newDiv.find(":input").val(""); // clear all
$newDiv.find("[type=number]").val(0); // clear numbers
$newDiv.find(".sum").text(0); // clear total
$newDiv.insertAfter($div)
}
else {
$div.remove();
sumIt();
}
$(".customs-table .remove:gt(0)").show();
$(".vat-table .remove:gt(0)").show();
$(".excise-table .remove:gt(0)").show();
});
$("#formContainer").on("input", "[type=number]", sumIt);
$("form").submit(function() {
event.preventDefault();
var user_profile = [];
$(".row").each(function() {
var $fields = $(this).find(":input");
if ($fields.length > 0) {
var cat = $(this).find("div>label").eq(0).text(); // use the label of the row
var catId = ["","Customs","VAT","Excise"].indexOf(cat)
user_profile.push({
assessmentType: "PRE",
assessCatID : catId,
assessReason: $fields.eq(0).val(),
assessAmount: $fields.eq(1).val(),
assessPenalty: $fields.eq(2).val(),
assessTotal: +$fields.eq(1).val() + +$fields.eq(2).val() // the leading + makes it a number
});
}
});
console.log(user_profile);
});
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
</head>
<body>
<form id="myForm">
<div id="formContainer" class="col-md-12" style="float: none;">
<!-- <button onclick="myFunction()" class="pull-right">+</button> -->
<div style="margin-bottom: 30px;">
<div class="form-group row">
<div class="col-md-1"></div>
<div class="col-md-4">
<label>Reason</label>
</div>
<div class="col-md-2">
<label>Amount</label>
</div>
<div class="col-md-2">
<label>Penalty</label>
</div>
<div class="col-md-1">Total</div>
<div class="col-md-2">Action</div>
</div>
<div class="customs-table row">
<div class="col-md-1">
<label>Customs</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control customReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt customAmount" value="0" name="abc" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt customPenalty" value="0" name="abc" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="vat-table row">
<div class="col-md-1">
<label>VAT</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control vatReason" name="vatReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt1 vatAmount" value="0" name="vatAmount" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt1 vatPenalty" value="0" name="vatPenalty" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="excise-table row">
<div class="col-md-1">
<label>Excise</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control exciseReason" name="exciseReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt2 exciseAmount" value="0" name="exciseAmount" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt2 excisePenalty" value="0" name="excisePenalty" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="col-md-12 pull-right">
<label>Total:</label> <b><span id="tot">0</span></b>
</div>
</div>
<button type="submit" class="btn btn-success pull-right">Submit</button>
</div>
</form>
</body>
</html>
I tried to manipulate using the for loop but not able to show them into those dynamic field.How can i achieve this?
Updated Code:
Since there are customs,vats,excise i need their each number like 1,2.Each of their start with 1,2,3 so on.
So here is what i try:
i added customNo class.
<div class="col-md-1 customNo">
<label>Customs</label>
</div>
and to show 1,2,3 i declared 3 different variable.
var showEmpty=true;
var i=1,j=1,k=1;
$.each(data.assessCatAmount, function(_,cat) {
showEmpty = false; // there was data
var type = types[cat.assessCatId];
var $newDiv = $("#formContainer").find("."+type+"-table").eq(0).clone();
$.each(cat,function(key,value) {
$(".customNo").append("<div><label for="name"> i </label></div>");
var fieldName = key.replace("assess",type);
var $field = $newDiv.find("."+fieldName);
if ($field) $field.val(value);
i=i+1;
});
$("#formContainer").append($newDiv)
So i tried $(".customNo").append("<div><label for="name"> i </label></div>"); it is not displaying me 1,2. How can i get this?
You need to copy the clone part
var types = ["","customs","vat","excise"]; // 1,2,3 must match class names
$.each(data.assessCatAmount, function(_,cat) {
var type = types[cat.assessCatId];
var $newDiv = $("#formContainer").find("."+type+"-table").eq(0).clone(); // clone the FIRST one
$.each(cat,function(key,value) {
var fieldName = key.replace("assess",type);
var $field = $newDiv.find("."+fieldName);
if ($field) $field.val(value);
});
$("#formContainer").append($newDiv)
});
You may need to hide or fill the first 3 divs since I do not fill them, I only use them to clone from
Also move the total to the bottom like I did with the submit
var types = ["", "customs", "vat", "excise"]; // 1,2,3
function getText(str) {
return $.trim(/\s/.test(str)?str.split(/\s+/)[1]:str);
}
var data = {
"assessCatAmount": [{
"assessmentNo": 1,
"assessmentType": "PRE",
"assessCatId": 1,
"assessReason": "A",
"assessAmount": 1,
"assessPenalty": 2,
"entryBy": "PCS",
"rStatus": "1"
},
{
"assessmentNo": 1,
"assessmentType": "PRE",
"assessCatId": 1,
"assessReason": "D",
"assessAmount": 3,
"assessPenalty": 4,
"entryBy": "PCS",
"rStatus": "1"
},
{
"assessmentNo": 1,
"assessmentType": "PRE",
"assessCatId": 2,
"assessReason": "B",
"assessAmount": 5,
"assessPenalty": 6,
"entryBy": "PCS",
"rStatus": "1"
},
{
"assessmentNo": 1,
"assessmentType": "PRE",
"assessCatId": 2,
"assessReason": "E",
"assessAmount": 7,
"assessPenalty": 8,
"entryBy": "PCS",
"rStatus": "1"
},
{
"assessmentNo": 1,
"assessmentType": "PRE",
"assessCatId": 3,
"assessReason": "C",
"assessAmount": 9,
"assessPenalty": 10,
"entryBy": "PCS",
"rStatus": "1"
},
{
"assessmentNo": 1,
"assessmentType": "PRE",
"assessCatId": 3,
"assessReason": "F",
"assessAmount": 10,
"assessPenalty": 10,
"entryBy": "PCS",
"rStatus": "1"
}
]
}
function sumIt() {
$("#formContainer [type=number]").each(function() {
var $row = $(this).closest(".row");
var $fields = $row.find("[type=number]");
var val1 = $fields.eq(0).val();
var val2 = $fields.eq(1).val();
var tot = (isNaN(val1) ? 0 : +val1) + (isNaN(val2) ? 0 : +val2)
$row.find(".sum").text(tot);
});
var total = 0;
$(".sum").each(function() {
total += isNaN($(this).text()) ? 0 : +$(this).text()
});
$("#tot").text(total);
return total;
}
// data={} // test no data
function addNums(i) {
$(this).html(function() {
var text = $(this).text();
// Get the text without leading number - fake a space in case there are none yet
var type = getText(text);
var length = $("."+type.toLowerCase()+"-table").length;
return (length===1?"":i+ " ") + type; // only show numbers if more than one
});
}
function cleanUp() {
$(".customs-table .remove:gt(0)").show();
$(".vat-table .remove:gt(0)").show();
$(".excise-table .remove:gt(0)").show();
$(".customs-table.row > div > label").each(addNums);
$(".vat-table.row > div > label").each(addNums);
$(".excise-table.row > div > label").each(addNums);
}
$(function() {
$(".customs-table .remove:lt(1)").hide();
$(".vat-table .remove:lt(1)").hide();
$(".excise-table .remove:lt(1)").hide();
$("#formContainer").on("click", "button", function() {
var selector = "div.row";
var $div = $(this).closest(selector);
if ($(this).is(".add")) {
var $newDiv = $div.clone();
$newDiv.find(":input").val(""); // clear all
$newDiv.find("[type=number]").val(0); // clear numbers
$newDiv.find(".sum").text(0); // clear total
$newDiv.insertAfter($div)
} else {
$div.remove();
sumIt();
}
cleanUp();
});
$("#formContainer").on("input", "[type=number]", sumIt);
$("form").submit(function() {
event.preventDefault();
var user_profile = [];
$(".row:visible").each(function() {
var $fields = $(this).find(":input");
if ($fields.length > 0) {
var cat = getText($(this).find("div>label").eq(0).text()); // use the label of the row
var catId = types.indexOf(cat.toLowerCase())
user_profile.push({
assessmentType: "PRE",
assessCatID: catId,
assessReason: $fields.eq(0).val(),
assessAmount: $fields.eq(1).val(),
assessPenalty: $fields.eq(2).val(),
assessTotal: +$fields.eq(1).val() + +$fields.eq(2).val() // the leading + makes it a number
});
}
});
console.log(user_profile);
});
var showEmpty = true;
$.each(data.assessCatAmount, function(_, cat) {
showEmpty = false; // there was data
var type = types[cat.assessCatId];
var $newDiv = $("#formContainer").find("." + type + "-table").eq(0).clone();
$.each(cat, function(key, value) {
var fieldName = key.replace("assess", type);
var $field = $newDiv.find("." + fieldName);
if ($field) $field.val(value);
});
$("#formContainer").append($newDiv)
});
$(".customs-table").eq(0).toggle(showEmpty);
$(".vat-table").eq(0).toggle(showEmpty);
$(".excise-table").eq(0).toggle(showEmpty);
cleanUp();
});
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
</head>
<body>
<form id="myForm">
<div id="formContainer" class="col-md-12" style="float: none;">
<!-- <button onclick="myFunction()" class="pull-right">+</button> -->
<div style="margin-bottom: 30px;">
<div class="form-group row">
<div class="col-md-1"></div>
<div class="col-md-4">
<label>Reason</label>
</div>
<div class="col-md-2">
<label>Amount</label>
</div>
<div class="col-md-2">
<label>Penalty</label>
</div>
<div class="col-md-1">Total</div>
<div class="col-md-2">Action</div>
</div>
<div class="customs-table row">
<div class="col-md-1">
<label>Customs</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control customsReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt customsAmount" value="0" name="abc" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt customsPenalty" value="0" name="abc" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="vat-table row">
<div class="col-md-1">
<label>VAT</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control vatReason" name="vatReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt1 vatAmount" value="0" name="vatAmount" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt1 vatPenalty" value="0" name="vatPenalty" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
<div class="excise-table row">
<div class="col-md-1">
<label>Excise</label>
</div>
<div class="col-md-4">
<input type="text" class="form-control exciseReason" name="exciseReason" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt2 exciseAmount" value="0" name="exciseAmount" min="0" />
</div>
<div class="col-md-2">
<input type="number" class="form-control txt2 excisePenalty" value="0" name="excisePenalty" min="0" />
</div>
<div class="col-md-1">
<span class="sum">0</span>
</div>
<div class="col-md-2">
<button type="button" class="add">+</button>
<button type="button" class="remove">-</button>
</div>
</div>
</div>
</div>
<div class="col-md-12 pull-right">
<label>Total:</label> <b><span id="tot">0</span></b>
</div>
<button type="submit" class="btn btn-success pull-right">Submit</button>
</form>
</body>
</html>

How would I be able to multiple select and pass data in the given format in vue js html?

I need to pass the data in the given format.
rules : [{
name:null,
section:null,
data : [{head:null,value:null}]
}],
This is the problem I am facing. Hope somebody could help me sort out a solution. The snippet is given. I need to pass data in the format given above. If another array is needed inside rules[], it is also fine
Is another array needed for head and value inside data[]. This will be also fine, if needed. Hoping for a help. Please help me to have a solution.
Please change the select to read the issues
addForm = new Vue({
el: "#addForm",
data: {
rules: [{
name: null,
section: null,
data: [{
head: null,
value: null
}]
}],
},
methods: {
addNewRules: function() {
this.rules.push({
name: null,
section: null,
data: [{
head: null,
value: null
}]
});
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="addForm">
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<p>This is the first part which is fine for me</p>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Act</label>
<select class="form-control" v-model="bok.name">
<option value="Act,1972">Act,1972</option>
<option value="Rule,2012">Rule,2012(CEMR)</option>
<option value="Act,1961">Act,1961</option>
</select>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Section</label>
<input type="text" class="form-control" v-model="bok.section">
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1972'">
<p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms</label>
<input type="text" class="form-control" v-model="bok.data[0].head" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Item</label>
<input type="text" class="form-control" v-model="bok.data[0].head" required="">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Quantity Seized</label>
<input type="text" class="form-control" v-model="bok.data[0].head" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1961'">
<p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
to do this?</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Select</label>
<select class=" form-control" v-model="bok.data[0].head" multiple="">
<option value="1">life</option>
<option value="2">Enment</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="bok.data[0].head == 1">
<p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area1</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area2</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value">
</div>
</div>
</div>
<div class="row" v-if="bok.data[0].head == 2">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">No.</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Model</label>
<input type="text" class="form-control" required="">
</div>
</div>
</div>
</div>
<a #click="addNewRules">Add Another Rule</a>
</div>
My approach is basically change the type of the data[0].head and data[0].value depending on the options you selected.
So for example, if you select Rule,2012, then data[0].head would be an object with item and qty as its items. And if you select Act,1961, data[0].head would be an array of numbers (e.g. ['1', '2']) and data[0].value would be an object with area_1 and area_2 or number and model or all the four items.
See and try the code snippet to see the code I added/changed.
(Or compare your code with mine and you'd see the changes.)
addForm = new Vue({
el: "#addForm",
data: {
rules: [{
name: null,
section: null,
data: [{
head: null,
value: null
}]
}],
},
methods: {
addNewRules: function() {
this.rules.push({
name: null,
section: null,
data: [{
head: null,
value: null
}]
});
},
removeRuleDataValueProps: function(i) {
var d = this.rules[i].data[0];
if (jQuery.inArray('1', d.head) < 0) {
Vue.delete(d.value, 'area_1');
Vue.delete(d.value, 'area_2');
}
if (jQuery.inArray('2', d.head) < 0) {
Vue.delete(d.value, 'number');
Vue.delete(d.value, 'model');
}
},
_setRuleDataHeadDataType: function(i) {
var d = this.rules[i].data[0],
h = d.head,
_h = d._head,
_restore = true;
if (undefined === _h) {
d._head = h;
_restore = false;
}
switch (this.rules[i].name) {
case 'Rule,2012':
var a = Array.isArray(h);
if (a || null === h || 'object' !== typeof h) {
Vue.set(d, 'head', {});
}
break;
case 'Act,1961':
if (!Array.isArray(h)) {
Vue.set(d, 'head', []);
}
break;
default:
if (_restore && undefined !== _h) {
d.head = _h;
}
break;
}
},
_setRuleDataValueDataType: function(i) {
var d = this.rules[i].data[0],
v = d.value,
_v = d._value,
_restore = true;
if (undefined === _v) {
d._value = v;
_restore = false;
}
switch (this.rules[i].name) {
case 'Act,1972':
case 'Act,1961':
var a = Array.isArray(v);
if (a || null === v || 'object' !== typeof v) {
Vue.set(d, 'value', {});
}
if (_restore) {
this.removeRuleDataValueProps(i);
}
break;
default:
if (_restore && undefined !== _v) {
d.value = _v;
}
break;
}
},
setRuleDataType: function(i, k) {
if (this.rules[i] && this.rules[i].data[0]) {
if (!k || 'head' === k) {
this._setRuleDataHeadDataType(i);
}
if (!k || 'value' === k) {
this._setRuleDataValueDataType(i);
}
}
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="addForm">
<h3>Try the different options and see the JSON output changes.</h3>
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<p>This is the first part which is fine for me</p>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Act</label>
<!-- Here we change the type of `bok.data[0].head` depending on the selected option. -->
<select class="form-control" v-model="bok.name" #change="setRuleDataType(index)">
<option value="Act,1972">Act,1972</option>
<option value="Rule,2012">Rule,2012(CEMR)</option>
<option value="Act,1961">Act,1961</option>
</select>
</div>
</div>
<!--</div>-->
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Section</label>
<input type="text" class="form-control" v-model="bok.section">
</div>
</div>
<!-- Here, `bok.data[0].head` is expected to be a `string`. -->
<div class="row" v-if="bok.name == 'Act,1972'">
<p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms</label>
<input type="text" class="form-control" v-model="bok.data[0].head" #change="setRuleDataType(index, 'value')" required="">
</div>
</div>
</div>
<!-- Here, `bok.data[0].head` is an `object` with 'item' and 'qty'. -->
<div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Item</label>
<input type="text" class="form-control" v-model="bok.data[0].head.item" required="">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Quantity Seized</label>
<input type="text" class="form-control" v-model="bok.data[0].head.qty" required="">
</div>
</div>
</div>
<!-- Here, `bok.data[0].head` would be an array of numbers. -->
<div class="row" v-if="bok.name == 'Act,1961'">
<p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
to do this?</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Select</label>
<select class=" form-control" v-model="bok.data[0].head" #change="removeRuleDataValueProps(index)" multiple="">
<option value="1">life</option>
<option value="2">Enment</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="jQuery.inArray('1', bok.data[0].head) > -1">
<p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area1</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.area_1">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area2</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.area_2">
</div>
</div>
</div>
<div class="row" v-if="jQuery.inArray('2', bok.data[0].head) > -1">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">No.</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.number">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Model</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.model">
</div>
</div>
</div>
<h3>The JSON value of <code>bok</code></h3>
<textarea rows="3" cols="75%" readonly>{{ JSON.stringify(bok) }}</textarea>
</div>
<a #click="addNewRules">Add Another Rule</a>
</div>
My opinion,
Based on the HTML you provied, create one data property=ruleTemplate (it makes sure v-model with related form controls).
When add new rules, push one clone of the template to the rules
When you need the data, just convert the rules to the specific format like
this.getFormattedRules in below demo.
Below is the demo:
addForm = new Vue({
el: "#addForm",
data: {
ruleTemplates: {
name: '',
section: '',
subMenu: {
'Act,1972': '',
'Rule,2012': {'item': '','qty': ''},
'Act,1961': {'head':[], options:{'option1':'', 'option2':''}}
}
},
rules: [{
name: '',
section: '',
subMenu: {
'Act,1972': '',
'Rule,2012': {'item': '','qty': ''},
'Act,1961': {'head':[], options:{'option1':'', 'option2':''}}
}
}
],
},
computed: {
formatedJson: function () {
let handler1972 = function (data) {
return [{'head': 'Arms', 'value': data}]
}
let handler2012 = function (data) {
return [{'head': 'item', 'value': data.item},{'head': 'qty', 'value': data.qty}]
}
let handler1961 = function (data) {
return [{'head': 'option1', 'value': data.options.option1},{'head': 'option1', 'value': data.options.option2}]
}
let handlers = {'Act,1972': handler1972, 'Rule,2012': handler2012, 'Act,1961': handler1961
}
return this.rules.map((rule) => {
let formatedRule = new Object()
// convert the rule to the specific format
formatedRule.name = rule.name
formatedRule.section = rule.section
handler = handlers[rule.name]
formatedRule.data = handler ? handler(rule.subMenu[rule.name]) : []
return formatedRule
})
}
},
methods: {
addNewRules: function() {
this.rules.push(Object.assign({},this.ruleTemplates))
}
}
})
.show-format {
position:absolute;
top:2px;
right -4px;
background-color:gray
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="addForm">
<div class="show-format">Format: {{formatedJson}}</div>
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<p>This is the first part which is fine for me</p>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Act</label>
<select class="form-control" v-model="bok.name">
<option value="Act,1972">Act,1972</option>
<option value="Rule,2012">Rule,2012(CEMR)</option>
<option value="Act,1961">Act,1961</option>
</select>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Section</label>
<input type="text" class="form-control" v-model="bok.section">
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1972'">
<p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms</label>
<input type="text" class="form-control" v-model="bok.subMenu['Act,1972']" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Item</label>
<input type="text" class="form-control" v-model="bok.subMenu['Rule,2012']['item']" required="">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Quantity Seized</label>
<input type="text" class="form-control" v-model="bok.subMenu['Rule,2012']['qty']" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1961'">
<p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
to do this?</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Select</label>
<select class=" form-control" v-model="bok.subMenu['Act,1961'].head" >
<option value="1">life</option>
<option value="2">Enment</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="bok.subMenu['Act,1961'].head == 1">
<p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area1</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option1">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area2</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option2">
</div>
</div>
</div>
<div class="row" v-if="bok.subMenu['Act,1961'].head == 2">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">No.</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option1">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Model</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option2">
</div>
</div>
</div>
</div>
<a #click="addNewRules" style="background-color:green">Add Another Rule</a>
</div>
hey why don't you go with multi-select checkbox drop-down and apply v-model on checkbox. ?
Link: How to use Checkbox inside Select Option

Categories