Problem with dynamically adding questions via add button on page - javascript

So this is my form creator which will be used to generate forms in django. Basically this is a dynamically generate django "FormView" . So now the problem is when the user will remove a question from the UI the Question's numbering won't reorder automatically. I need those numberings because on the backend those will be used by django to create a form by mapping this data received to actual models.CharField and other corresponding fields. Can someone tell what approach can be used? For who don't know/use django images should explain it well.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Form Builder</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<style>
body{width:90vw;
display:flex;
flex-direction: column;
justify-items: space-between;
align-items: center;
}
.form-choice__dropdown{
display: flex;
justify-items: space-between;
}
</style>
<div class="form__heading">
<h1 class="heading-main">
<input type="text" placeholder="Enter form heading...">
</h1>
</div>
<div class="form-choice__dropdown">
<div class="form-type1">
<label for="form-type1__select">
<select name="form-type1__select" id="">
<option value="Project Request">Project Request</option>
<option value="ToT Request">ToT Request</option>
<option value="NDA Request">NDA Request</option>
<option value="MoU Request">MoU Request</option>
<option value="Tech Service Request">Tech Service Request</option>
</select>
</label>
</div>
<div class="form-type2">
<label for="form-type2__select">
<select name="form-type1__select" id="">
<option value="National">National</option>
<option value="International">International</option>
</select>
</label>
</div>
<div class="form-type3">
<label for="form-type1__select">
<select name="form-type1__select" id="">
<option value="Sponsored">Sponsored</option>
<option value="Collaborative">Collaborative</option>
<option value="Consultancy">Consultancy</option>
</select>
</label>
</div>
</div>
<div id="question-answer-pairs" class="question-answer-pairs">
<button id="add-question">Add Question</button>
</div>
<script>
window.removeQuestion = function (el) {
el.parentNode.parentNode.removeChild(el.parentNode);
}
const putRadioOptions = function () {
this.insertAdjacentElement("afterbegin",
`<input type='text' placeholder="Enter comma separated options(Do not use comma in any option) ">`
)
}
var questionNumber = 1;
var questionList
document.getElementById("add-question").addEventListener('click', function (event) {
let addQuestionButton = event.currentTarget;
let questionAnswerPair = `
<fieldset>
<legend class="question${questionNumber}__question">
Put in the Question${questionNumber}
<input type="text" >
</legend>
<label for="answer${questionNumber}-type">
Choose type of answer field:
<select name="answer${questionNumber}-type" class="question${questionNumber}__answer">
<option value="email">Email </option>
<option value="tel">Telephone</option>
<option value="file">File Upload</option>
<option value="radio" onclick="putRadioOptions()">Radio Buttons</option>
<option value="sex">Sex</option>
<option value="url">Range</option>
<option value="date">Date</option>
</select>
</label>
<button onclick="removeQuestion(this)">Remove</button>
</fieldset>
`
addQuestionButton.insertAdjacentHTML("beforebegin", questionAnswerPair);
++questionNumber;
}
)
</script>
</body>
</html>
This is it
After removing Question2
I don't just need to change the text, that's easy. The problem is that the name= question${questionNumber} should too change to 2 when I remove the 2nd question for question number 3. So I want to see this with numbers in all those classes and names and ids automatically numbered consecutively.
enter image description here
javascript python django

Using the principles of event delegation I added an eventListener to the div with id="question-answer-pairs". Now iterating through all the fieldsets and replacing all numbers with the for loop index variable with regex is what I did.
The regex is bad but works good in my case. For people using h1 tag or other tags with numbers a better regex is needed.
document.getElementById("question-answer-pairs").addEventListener('click', function (event) {
if (event.target.textContent == "Remove") {
event.target.parentNode.remove();
let allFieldset = event.currentTarget.getElementsByTagName("fieldset")
for (let i = 0; i < allFieldset.length; i++) {
allFieldset[i].innerHTML = allFieldset[i].innerHTML.replace(/(.*?)(\d+)(.*)/g, `$1${i + 1}$3`);
}
questionNumber = allFieldset.length + 1;
}
})

Related

How to create a javascript quiz using the select element in html and paste the result in the main

When the users choose a selection from the quiz. I want an image of a beanie to generate on the main. Code Below of my html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>BEANIE GENIE</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div class="grid-container">
<header class="headerimg">
<img src="Images/bigger thing.png" align="left">
</header>
<header class="headertxt">
<h1>BEANIE GENIE</h1>
</header>
<nav class="nav">
<div class="topnav">
HOME
WISH
BEANIE BUDDY
CONTACT US
</div>
</nav>
<aside class="aside" id=BeanieQuiz>
<h2>WELCOME TO THE BEANIE QUIZ</h2>
<label for="beanie">Select a color:</label>
<select id="Question1">
<option value="Blank"></option>
<option value="color1">Blue</option>
<option value="color2">Purple</option>
<option value="color3">Red</option>
<option value="color4">White</option>
<option value="color5">Black</option>
<br>
</select><br>
<label for="beanie">Select a style:</label>
<select id="Question2">
<option value="Blank"></option>
<option value="style1">Design</option>
<option value="style2">Solid Color</option><br>
</select><br>
<label for="beanie">Select a material:</label>
<select id="Question3">
<option value="Blank"></option>
<option value="material1">Wool</option>
<option value="material2">Cotton</option>
<option value="material3">Polyster</option><br>
</select><br>
<button type="button" onclick="quizResults()">Submit</button></aside>
<main class="main" id="quizBeanie">
<!-- this is where the images show based off what the user selects-->
</main>
<footer class="footer">
Here is the javascript I tried to create for if the user only selects the first option on each question and I tried to have the image paste in the main just to test it out to see how it works, but it doesn't work.
Code below of javascript:
//Hidden page for the beanie quiz. When the user takes the quiz it will generate an image of a beanie based off the user selection
function quizResults{
let name = document.querySelectorAll("#Question1, #Question2, #Question3").value;
if (name == "color1, style1, material1")
"Images/Beanie11_ccexpress.png"
//supposed to post the image inside the main
document.getElementById("quizBeanie").innerHTML
}
querySelectorAll returns a NodeList not a string, so the following line is incorrect:
if (name == "color1, style1, material1")
Check out this documentation https://www.w3schools.com/js/js_htmldom_nodelist.asp
Your code is not entirely understandable. But your problem probably lies in checking whether the selected one is one of the following haystacks. I have tapped it once.
let vals = []
const haystack = "color1, style1, material1";
selects.forEach(s => {
if (haystack.includes(s.value)) {
vals.push(s.value);
}
})
if (vals.length > 0) {
// do something
}
//Hidden page for the beanie quiz. When the user takes the quiz it will generate an image of a beanie based off the user selection
function quizResults() {
let selects = document.querySelectorAll("[id^=Question]");
let vals = []
const haystack = "color1, style1, material1";
selects.forEach(s => {
if (haystack.includes(s.value)) {
vals.push(s.value);
}
})
if (vals.length > 0) {
// do something
}
/* code which i dont undertood ;-) */
"Images/Beanie11_ccexpress.png"
//supposed to post the image inside the main
document.getElementById("quizBeanie").innerHTML
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<body>
<div class="grid-container">
<header class="headerimg">
<img src="Images/bigger thing.png" align="left">
</header>
<header class="headertxt">
<h1>BEANIE GENIE</h1>
</header>
<nav class="nav">
<div class="topnav">
HOME
WISH
BEANIE BUDDY
CONTACT US
</div>
</nav>
<aside class="aside" id=BeanieQuiz>
<h2>WELCOME TO THE BEANIE QUIZ</h2>
<label for="beanie">Select a color:</label>
<select id="Question1">
<option value="Blank"></option>
<option value="color1">Blue</option>
<option value="color2">Purple</option>
<option value="color3">Red</option>
<option value="color4">White</option>
<option value="color5">Black</option>
<br>
</select><br>
<label for="beanie">Select a style:</label>
<select id="Question2">
<option value="Blank"></option>
<option value="style1">Design</option>
<option value="style2">Solid Color</option><br>
</select><br>
<label for="beanie">Select a material:</label>
<select id="Question3">
<option value="Blank"></option>
<option value="material1">Wool</option>
<option value="material2">Cotton</option>
<option value="material3">Polyster</option><br>
</select><br>
<button type="button" onclick="quizResults()">Submit</button></aside>
<main class="main" id="quizBeanie">
<!-- this is where the images show based off what the user selects-->
</main>

How to validate dynamic select DropDown using html and javascript?

I have a form having education details in which there is a dropdown which gives 4 option
schooling
graduation
post graduation
others
now what I am doing is allowing user to fill those details but what I want is user can not select one education type more than once which means user can select schooling once,graduation once and so on and this validation i want on client end which is js/jquery
image for reference
function checkUserEducation() {
const userSelectedEducationArray = $("select[name='educationType[]']").map(function() {
return $(this).val();
}).get();
//checks if any education type is empty
if (userSelectedEducationArray.includes("")) {
$('#educationErrorMsg').show();
} else {
$('#educationErrorMsg').hide();
}
if (countElement('schooling', userSelectedEducationArray) > 1) {
// $('#educationErrorMsg').show();
$('#educationErrorMsg').after("*schooling can be chosen only one time");
} else {
}
if (countElement('graduation', userSelectedEducationArray) > 1) {
$('#educationErrorMsg').after("</br>*graduation can be chosen only one time");
} else {
}
if (countElement('post_graduation', userSelectedEducationArray) > 1) {
$('#educationErrorMsg').after("</br>*post graduation can be chosen only one time");
} else {
}
if (countElement('others', userSelectedEducationArray) > 1) {
$('#educationErrorMsg').html("</br>*others can be chosen only one time");
} else {
}
}
function countElement(item, array) {
var count = 0;
$.each(array, function(i, v) { if (v === item) count++; });
return count;
}
this validation i am trying to do but i am not getting appropriate outcome
so any help regarding this
<select class="form-control" id="educationType" name="educationType[]" aria-label="Select Education Type">
<option selected value="">Select type</option>
<option value="schooling">Schooling</option>
<option value="graduation">Graduation</option>
<option value="post_graduation">Post Graduation</option>
<option value="others">Others</option>
</select>
this is my select dropdown on which i want validation
so any hints or validation tips would be very helpful
THANK YOU !!
English is not my primary language but i'll try my best to explain.
Give same class to all selects that you want to check
then on change function loop through all element with given class
if you're using form-repeater then compare name of the elements to avoid comparing with the same element. if you are not using form-repeater add a "data-counter" element add increase its value on every new add,
after that just compare value of the element, if same then show alert
var count = 1;
$(document).on("click", ".add-btn", function () {
$("#clone")
.find(".gg").addClass('test-select')
.attr("data-counter", count++);
$("#Main").append($("#clone").html());
$("#clone")
.find(".gg").removeClass('test-select');
});
$(document).on("change", ".test-select", function () {
const This = $(this);
$(".test-select").map(function() {
if(this.getAttribute('data-counter') !== $(This).attr('data-counter')){
if($(this).val() == $(This).val()){
alert('repeat');
$(This).css('background-color','red')
}
}
});
});
<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.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>stack question</title>
</head>
<body>
<div id="Main" class="row p-1">
<div class="col-md-8">
<select class="form-select test-select" data-counter="0" name="test[]" aria-label="Default select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-primary add-btn">Add</button>
</div>
</div>
<div class="d-none" id="clone">
<div class="mt-2"></div>
<div class="col-md-8">
<select class="form-select gg test-select" data-counter="" name="test[]" aria-label="Default select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
<div class="col-md-4">
<button type="button" class="btn btn-primary add-btn">Add</button>
</div>
</div>
</body>
</html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$("#educationType").change(function(){
if($(this).val() && !$(this).find('option:selected').attr("data-clicked")){
$(this).find('option:selected').attr("data-clicked","true")
}else if($(this).find('option:selected').attr("data-clicked")){
alert(`"${$(this).val().toUpperCase()}" can be chosen only one time`);
$(this).val("")
}
})
</script>

How do I change the select option value contents using js

I'm not good at javascript but I tried this...
I'm trying to make an option for a user to switch to another page after searching for an item.
The user for example will searches for a Mercedes under cars section then the options value can change to the Mercedes links page as well as can change to GMC links page is the user searches for gmc. This code seems not to work.
Below is the code:
<div class="all" id="note">
Some content will be posted here...
</div>
<select id="marketing" onChange="window.open(this.value)" multiple>
<option value="1">cars</option>
<option value="2">houses</option>
<option value="3">Promotion</option>
</select>
<script type="text/javascript">
var cars = ['mercedes']
$('#marketing').change(function(){
if($(this).val() == '1'){
if cars[0] ==='mercedes';{
$(this).val() == "http://www.cars.com/mercedes";
}
}
});
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script>
var cars = ['mercedes']
function myFunction() {
var x = document.getElementById("marketing").value;
var companey = document.getElementById('companies').value;
console.log(x + companey);
if (x == 1 && companey == "mercedes") {
var url =
window.open("http://www.cars.com/mercedes" , '_blank');//for new tab
//for same tab
//window.open('http://www.cars.com/mercedes');
}
}
</script>
</head>
<body>
<!this is a working sample hope this will help>
<div class="all" id="note">
Some content will be posted here... <br />
<input type="text" id="companies">mercedes</input>
</div>
<select id="marketing" onchange="myFunction()">
<option value="0"></option>
<option value="1">cars</option>
<option value="2">houses</option>
<option value="3">Promotion</option>
</select>
</body>
</html>

Session storage value not showing in second page

I am trying to get user input data in index.html. Then once user clicks on next, it should show the input data in the getapart.html page(second page). I am trying to use session storage for same. There are no errors, but it doesn't show the value. Not sure what I am doing wrong.
HTML
<html>
<head>
<script src = "showdata.js">
</script>
</head>
<body>
<fieldset style="width: fit-content; margin: 0 auto; font-size: 30px;">
<form action="getapart.html">
<legend>Check for your part!</legend><br>
<label>Year:<br />
<select id="Year" onchange="show_yeardata()">
<option> - Select Year - </option>
<option value="2019">2019</option>
<option value="2018">2018</option>
<option value="2017">2017</option>
<option value="2016">2016</option>
<option value="2015">2015</option>
</select>
<br>
<label>Make:<br />
<select id="Make" onchange= show_makedata()">
<option> - Select Make - </option>
<option value="Chevrolet">Chevrolet</option>
<option value="Ford">Ford</option>
<option value="BMW">BMW</option>
<option value="Audi">Audi</option>
<option value="Toyota">Toyota</option>
</select>
<br>
<br><br>
<input type="text" id="showyear"><br>
<input type="text" id="showmake"> <br>
<input type="Submit"; value="Next" />
</form>
</fieldset>
</body>
</html>
getapart.html (second page to retrieve the user input and display the data)
<html>
<head>
<script src = "showdata.js">
</script>
</head>
<body>
Home
<br><br><br>
<div onload= "show_yeardata()" >
Year: <span id="ss_showyear"> </span><br>
Make: <span id="ss_showmake"> </span><br>
</div>
</body>
</html>
JS script (showdata.js)
function show_yeardata()
{
var year = document.getElementById("Year");
var year1 = year.options[year.selectedIndex].text;
document.getElementById("showyear").value=year1;
sessionStorage.setItem("key_showyear",year1);
document.getElementById("ss_showyear").innerHTML = sessionStorage.getItem("key_showyear");
}
function show_makedata()
{
var make = document.getElementById("Make");
var make1 = make.options[make.selectedIndex].text;
document.getElementById("showmake").value=make1;
sessionStorage.setItem("key_showmake",make1);
document.getElementById("ss_showmake").innerHTML = sessionStorage.getItem("key_showmake");
}
Looks like you are using same function for setting and getting the data. This increases complexity in many cases and brokes the system in your case.
Edit: Placement of the onload event is also invalid. You should put that to the body tag. See: How to add onload event to a div element
In the first page you successfully get data from selection and set to the session storage. However, when you trigger the same function again in the second page, year1 becomes undefined since there is no element with id "Year".
Then with these line you first put undefined to session storage then get it back immediately.
sessionStorage.setItem("key_showyear",year1);
document.getElementById("ss_showyear").innerHTML = sessionStorage.getItem("key_showyear");
Solution is simple. You split setter and getter functions like this.
function set_year_data() {
var year = document.getElementById("Year");
var year1 = year.options[year.selectedIndex].text;
document.getElementById("showyear").value=year1;
sessionStorage.setItem("key_showyear",year1);
}
function get_year_data() {
document.getElementById("ss_showyear").innerHTML = sessionStorage.getItem("key_showyear");
}
And in the first html:
...
<select id="Year" onchange="set_year_data()">
...
And in the secondhtml:
...
<body onload="get_year_data()" >
...

How can I build multiple step selectors in HTML page?

I have a problem with HTML contact form.
For example I have that schema with element dependencies:
Where are many selectors and inputs depends on what is selected in previous steps.
How can I build that logic in HTML and Javascript (Jquery)?
For result I need to return one input hidden field, where are placed all selected values, for example:
Cash - at Compensa partners - Outside Riga - Serviss from selected option
Maybe there are some Jquery solutions for that purpose?
P.S. I can only use HTML pages
Minimal example: write out all the different selects and only show the relevant one. You can add all the other dependencies in a similar way. Building the selects dynamically will be less, but more complicated code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example</title>
<style>
.hide {
display: none;
}
.show {
display: block;
}
</style>
</head>
<body>
<div id="claim">
<select>
<option value="default" disabled="disabled" selected="selected">Select a claim type</option>
<option value="cash">Cash</option>
<option value="repair">Repair</option>
<option value="glazing">Glazing</option>
</select>
</div>
<div id="cash" class="hide">
<select>
<option value="partners">At Compensa partners</option>
<option value="office">Compensa Office</option>
<option value="broken">Verhicle is broken</option>
</select>
</div>
<div id="repair" class="hide">
<select>
<option value="age">Car age</option>
<option value="place">Serviss place</option>
</select>
</div>
<script>
var dependencies = {
'claim' : {
'cash' : 'nextDep',
'repair' : 'nextDep',
'glazing' : 'nextDep'
}
};
document.querySelector('#claim select').addEventListener('change', function ( event ) {
var parentID = event.target.parentNode.id,
value = event.target.value;
Object.keys(dependencies[parentID]).forEach(function ( key ) {
var select = document.querySelector('#' + key),
currentClass = select.className;
if (select.id === value && currentClass === 'hide') select.className = 'show';
else if (currentClass !== 'hide') select.className = 'hide';
});
});
</script>
</body>
</html>

Categories

Resources