I have 5 circles to click. User can select only one. My problem is that I can't deselect previous circle and remove its data-value from variable.
How can I handle it?
HTML
<div class="question">
<h3>' + test + '</h3>
<div class="row" style="padding-top:50px;">
<div class="col-xl-4 col-lg-3 col-md-2 col-sm-2 col-xs-3 text-center"> <span>Całkowicie nietrafnie mnie opisuje</span> </div>
<div class="col-xl-4 col-lg-6 col-md-8 col-sm-8 col-xs-6 text-center">
<div class="circles">
<div class="numberCircle" data-value="1">1</div>
<div class="numberCircle" data-value="2">2</div>
<div class="numberCircle" data-value="3">3</div>
<div class="numberCircle" data-value="4">4</div>
<div class="numberCircle" data-value="5">5</div>
</div>
</div>
<div class="col-xl-4 col-lg-3 col-md-2 col-sm-2 col-xs-3 text-center"><span>całkowicie trafnie mnie opisuje</span></div>
</div>
</div>
JS
pinEventAction = function (e) {
var progressBar = document.querySelector('#progressBar .bar');
var circles = document.querySelectorAll('.question .circles .clicked');
if (e.target.hasAttribute('data-value')) {
values += Number(e.target.getAttribute('data-value'));
e.target.className += ' clicked';
e.target.parentNode.className += ' checked';
width += 2;
progressBar.style.width = width + '%';
}
if (e.target.classList.contains('clicked')) {
e.target.classList.remove('clicked')
}
console.log('score: ' + values);
};
handleClickAndProgressBar = function () {
var progressBar = document.querySelector('#progressBar .bar');
var circles = document.querySelectorAll('.question .circles');
for (var i = 0; i < circles.length; i++) {
circles[i].addEventListener('click', pinEventAction);
}
};
No need to add an eventListener on each circle, you can add an eventListener to an ancestor node instead. By using event.target property, you can determine which node was clicked. Read on Event Delegation for details.
The behavior desired for the circles is like a group of radio buttons that share the same name attribute (only one can be checked). I changed the circles into a radio/label pair then wrapped them into a <fieldset> and a <form>. By doing this, saves you from writing code for the behavior previously mentioned.
This demo does the following:
Allows only one active circle
Allows toggling circles on/off
Updates value according to what is selected/unselected
Displays the value
Demo
var form = document.forms[0];
form.addEventListener('click', circle, false);
function circle(e) {
if (e.target !== e.currentTarget) {
var val = this.elements.view;
var tgt = e.target;
if (tgt.tagName === 'FIELDSET') {
return;
}
if (tgt.classList.contains('act')) {
tgt.classList.remove('act');
val.value = 0;
} else if (!tgt.classList.contains('act')) {
tgt.classList.add('act');
val.value = tgt.value;
}
} else {
if (val.value === undefined) {
val.value = 0;
}
return false;
}
e.stopPropagation();
}
.rad {
display: none
}
.l {
background: black;
color: gold;
border-radius: 50%;
width: 24px;
height: 24px;
cursor: pointer;
margin: 0 auto;
padding-top: 3px;
display: block;
}
.rad:checked+label.l.act {
color: cyan
}
.rad:checked+label.l.act::before {
content: '<'
}
.rad:checked+label.l.act::after {
content: '>'
}
#view {
color: tomato;
font-weight: 900
}
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet'>
<div class="question">
<h3>' + test + '</h3>
<div class="row" style="padding-top:50px;">
<div class="col-xs-3 text-center"> <span>Całkowicie nietrafnie mnie opisuje</span> </div>
<form class="col-xs-6 text-center">
<output id='view'>0</output>
<fieldset class="circles">
<input id='rad1' class='rad' name='rad' type='radio' value="1">
<label class="l" for='rad1'>1</label>
<input id='rad2' class='rad' name='rad' type='radio' value="2">
<label class="l" for='rad2'>2</label>
<input id='rad3' class='rad' name='rad' type='radio' value="3">
<label class="l" for='rad3'>3</label>
<input id='rad4' class='rad' name='rad' type='radio' value="4">
<label class="l" for='rad4'>4</label>
<input id='rad5' class='rad' name='rad' type='radio' value="5">
<label class="l" for='rad5'>5</label>
</fieldset>
</form>
<div class="col-xs-3 text-center"><span>całkowicie trafnie mnie opisuje</span></div>
</div>
</div>
Related
I have a input field that takes numeric inputs. Then i have a button which display the number of divs as per that input. after displaying div there is two radio-box buttons (paired end and single end) if I select paired end then i want two file upload fields in each divs. and if i select single end then i want only one file upload fields in each div.
I have tried but fileupload fields working on only first div.
function CreateText() {
var text = `<div class="row border-top py-3">
<div class="col-md-3">
<label">sample name *</label></br>
<input type="sample" id="sample" name="sample[]">
</div>
<div class="col-md-3" style="display:none" id="showsingle">
<div class="form-group">
<label for="form_upload">Upload file *</label></br>
<input type="file" id="myFile" name="filename1[]">
</div>
</div>
<div class="col-md-3" style="display:none" id="showpair">
<div class="form-group">
<label for="form_upload">Upload file *</label></br>
<input type="file" id="myFile" name="filename2[]">
<label for="form_upload">Upload file *</label></br>
<input type="file" id="myFile" name="filename2[]">
</div>
</div>
<div class="col-md-3 d-grid">
<div class="form-group">
<button class="btn btn-danger remove_add_btn">Remove</button>
</div>
</div>
</div>`;
var textCount = document.getElementById('textInput').value;
var html = '';
for (var i = 0; i < $('#textInput').val(); i++) {
html = document.getElementById('divDynamicTexts').innerHTML;
document.getElementById('divDynamicTexts').innerHTML = html + text.replace('', i);
}
}
function onlyOne() {
let SradioBox = document.getElementById("singleradio"),
Sfileupload = document.getElementById("showsingle"),
PradioBox = document.getElementById("pairedradio"),
Pfileupload = document.getElementById("showpair");
if (SradioBox.checked == true) {
Sfileupload.style.display = "block",
Pfileupload.style.display = "none";
} else if (PradioBox.checked == true) {
Pfileupload.style.display = "block",
Sfileupload.style.display = "none";
} else {
Pfileupload.style.display = "none",
Sfileupload.style.display = "none";
}
};
$(document).ready(function() {
$(document).on('click', '.remove_add_btn', function(e) {
e.preventDefault();
let row_item = $(this).parent().parent().parent();
$(row_item).remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-center">
<input type="text" id="textInput" value="" />
<input type="button" id="" value="Create upload fields" onclick="CreateText();" />
<div class="col-md-4" id="filebutton">
<div class="form-group ">
<label for="form_need">Library Type *</label>
</br>
<div class="px-2">
<label for="myradio">Single end:</label>
<input type="radio" id="singleradio" name="check" onclick="onlyOne();">
<label for="myradio">Paired end:</label>
<input type="radio" id="pairedradio" name="check" onclick="onlyOne();">
</div>
</div>
</div>
</div>
<div id="divDynamicTexts"></div>
ID attributes must be unique. It would be better to remove the IDs altogether ( or change to dataset attributes perhaps ) and use a delegated event listener to process the various clicks related to the task of adding/removing dynamic elements.
In the code below all ID attributes were either removed entirely or changed to data-id type values.
To avoid the need to process different form file input fields at the server the file-input fields are named the same but have an index so can be identified more readily in PHP ( or whatever backend you have )
The delegated listener, because it is bound to the document, will work for all elements whether or not they are static or added dynamically and makes heavy use of the event.target property to help identify the element that invoked the event.
The label element was being used incorrectly previously. If the form-input is within the label then there is no need for the for="ID" syntax ( note that the ID should be the ID of the input element to which the label belongs! ) - as it was the label's appeared to have a for attribute which did not related to an element in the form!
Using querySelector and querySelectorAll you can easily identify nodes of interest within the DOM so button clicks or radio button selection can fire a query to find nodes that are relevant - thus simplifying the hiding/showing of the file input elements.
const strhtml = `
<div data-id="dynrow" class="row border-top py-3">
<div class="col-md-3">
<label>sample name *<input type="text" name="sample[]"></label>
</div>
<div class="col-md-3" style="display:none" data-id="single" data-role="file-field">
<div class="form-group">
<label>Upload file *<input type="file" name="filename[1]" /></label>
</div>
</div>
<div class="col-md-3" style="display:none" data-id="pair" data-role="file-field">
<div class="form-group ">
<label>Upload file *<input type="file" name="filename[1]" /></label>
<label>Upload file *<input type="file" name="filename[2]" /></label>
</div>
</div>
<div class="col-md-3 d-grid">
<div class="form-group">
<button class="btn btn-danger remove_add_btn" data-id='remove'>Remove</button>
</div>
</div>
</div>`;
const _radio = document.querySelectorAll('[type="radio"][data-id]');
const _bttn = document.querySelector('[type="button"][data-id="add"]');
const _div = document.querySelector('#divDynamicTexts');
const _input = document.querySelector('input[type="number"][data-id="textInput"]');
let choice = false;
let qty = false;
/*
Disable radio buttons and the "Create" button initially
and enable when changes are made in the correct sequence.
1: select quantity -> enable radio bttns
2: select single or double -> enable "create" bttn
3: click bttn, create as per radio selection
*/
_input.addEventListener('change', e => {
_radio.forEach(n => {
n.disabled = e.target.value > 0 ? false : true;
});
qty=e.target.value;
});
document.addEventListener('click', e => {
if (e.target instanceof HTMLInputElement && e.target.dataset.id != null) {
/*
set global "choice" variable
and enable "Create" bttn.
*/
if (e.target.type == 'radio') {
choice = e.target.dataset.id;
_bttn.disabled = false;
}
}
/*
If the "choice" has been made the radio
buttons will be enabled. Based on radio
button selected create new HTML and then
unhide the appropriate single/pair DIV
element
*/
if (choice && qty > 0 && e.target.type == 'button') {
_div.innerHTML = '';
for (let i = 0; i < qty; i++) _div.insertAdjacentHTML('afterbegin', strhtml);
let expr = `div[data-id="${choice}"]`;
document.querySelectorAll(expr).forEach(n => n.style.display = 'block');
}
/*
unchanged: delete DIV & contents when "Remove" bttn is clicked.
*/
if (e.target instanceof HTMLButtonElement && e.target.dataset.id != null) {
if (e.target.dataset.id == 'remove') {
_div.removeChild(e.target.closest('[data-id="dynrow"]'));
}
}
});
body {
font-family: arial;
}
label {
display: block;
}
.px-2 {
display: inline-block;
}
.px-2 label {
display: inline-block;
margin: 0.5rem;
}
h2 {
font-size: 1.1rem;
margin: 1rem 0 0 0;
display: inline-block;
width: auto;
}
.inline {
display: inline;
margin: 0 1rem 0 0;
}
#divDynamicTexts {
min-height: 1rem;
margin: 2rem auto
}
div.row {
padding: 0.5rem;
border: 1px dotted grey;
margin: 0.5rem;
}
div[data-id='single'] .form-group label {
background: aliceblue
}
div[data-id='pair'] .form-group label {
background: lightsteelblue
}
div[data-id] .form-group label {
outline: 1px solid grey;
padding: 0.5rem;
margin: 0.5rem 0
}
.bold {
font-weight: bold
}
[disabled]{
border:1px solid red;
outline:2px solid red;
background:rgba(255,0,0,0.25);
}
<div class='text-center'>
<label class='inline bold'>Quantity:<input type='number' data-id='textInput' /></label>
<div class='col-md-4'>
<div class='form-group'>
<h2>Library Type</h2>
<div class='px-2'>
<label>Single end: <input type='radio' data-id='single' name='check' disabled /></label>
<label>Paired end: <input type='radio' data-id='pair' name='check' disabled /></label>
</div>
</div>
</div>
<input type='button' data-id='add' value='Create upload fields' disabled />
</div>
<div id='divDynamicTexts'></div>
I continue to discover JavaScript and again I am faced with a small problem
In my order form, I have about 300 items and each item is wrapped by a div, in which there is a class color1
I would like when the quantity is greater than 0 inside my div that my div turns green.
It works great with a div.
But, if I submit the same class for my second item and the quantity of my item is greater than 0, my div does not turn green unless I add for example the color3 class
To better understand,
here is the extract of my code where I retrieve the quantity of the article and where I test this quantity, in order to give it the green color if quantity greater than 0.
In summary, what I want is that all the div or the whenitee is greater than 0 green silk.
$('.ajouter-panier').click(function(event) {
event.preventDefault();
var nom_option = "";
var prix_option = 0;
var url = $(this).data('url');
var option_checkbox = $(this).data('checkbox');
if (option_checkbox != "") {
var checkboxes = document.getElementsByClassName(option_checkbox);
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked == true) {
var nom_option = nom_option + " (" + $(checkboxes[i]).data('nom') + ")";
var prix_option = prix_option + Number($(checkboxes[i]).data('prix'));
}
}
}
if ($(this).data('select')) {
var nom = $(this).data('nom') + " (" + document.getElementById("" + $(this).data('select') + "").value + ")" + nom_option;
} else var nom = $(this).data('nom');
var prix = Number($(this).data('prix')) + (prix_option);
if ($(this).attr('data-qte')) {
var qte_option = $(this).attr('data-qte');
MonPanier.ajouter_produit_dans_panier(nom, prix, qte_option, url);
} else MonPanier.ajouter_produit_dans_panier(nom, prix, 1, url);
var color = $(this).attr('data-qte');
console.log(color);
if (color > 0) {
const collection1 = document.getElementsByClassName("couleur1");
collection1[0].style.backgroundColor = "green";
const collection2 = document.getElementsByClassName("couleur2");
collection2[0].style.backgroundColor = "green";
} else {
const collection1 = document.getElementsByClassName("couleur1");
collection1[0].style.backgroundColor = "";
const collection2 = document.getElementsByClassName("couleur2");
collection2[0].style.backgroundColor = "";
}
afficherpanier();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-xl-2 col-lg-3 col-md-4 col-sm-6 couleur1" style="margin-bottom: 15px; padding-left: 5px; padding-right: 5px;">
<div class="card">
<div class="">
<h3 class="card-title centrer_titre_texte couleur2">2001</h3>
<div class="card-body stylecardbody" style="padding-top: 0;">
<div class="row mt-12">
<div class="col-md-12">
<select class="form-select styleselect" aria-label="2001" onchange="changeQte(this);">
<option selected value="1.10">1 sachet </option>
<option value="2">2 sachets</option>
<option value="3">3 sachets </option>
</select>
</div>
<a style="cursor: pointer; margin-bottom: 5px;width: 90%;display: block;margin-left: auto;margin-right: auto;" data-nom="2001" data-prix="1.10" data-qte="1" data-checkbox="2001" data-url="https://phil.pecheperle.be/image-perles/perle-verre-peche-gardon-2001.JPG"
class="btn btn-primary ajouter-panier b-items__item__add-to-cart" onclick="setTimeout(() => ouvreMaJolieAlert(event), 1000);"> ajouter au panier </a>
</div>
</div>
</div>
</div>
</div>
You should parse value of attribute to number.
var color = Number($(this).attr('data-qte'));
If you want to change <a> parent to color:green; on event onclick and if is set attribute (data-qte > 0) and apply it to multiple divs with class couleur1. Then the simpliest way to do this is to go to that element using event.currentTarget and parentElement
const collection1 = event.currentTarget.parentElement.parentElement.parentElement.parentElement.parentElement
if (color > 0) {
collection1.style.backgroundColor = "green";
} else {
collection1.style.backgroundColor = "";
}
full code:
$('.ajouter-panier').click(function (event) {
event.preventDefault();
var nom_option = "";
var prix_option = 0;
var url = $(this).data('url');
var option_checkbox = $(this).data('checkbox');
if (option_checkbox != "") {
var checkboxes = document.getElementsByClassName(option_checkbox);
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked == true) {
var nom_option = nom_option + " (" + $(checkboxes[i]).data('nom') + ")";
var prix_option = prix_option + Number($(checkboxes[i]).data('prix'));
}
}
}
if ($(this).data('select')) {
var nom = $(this).data('nom') + " (" + document.getElementById("" + $(this).data('select') + "").value + ")" + nom_option;
} else var nom = $(this).data('nom');
var prix = Number($(this).data('prix')) + (prix_option);
if ($(this).attr('data-qte')) {
var qte_option = $(this).attr('data-qte');
} else MonPanier.ajouter_produit_dans_panier(nom, prix, 1, url);
var color = Number($(this).attr('data-qte'));
const collection1 = event.currentTarget.parentElement.parentElement.parentElement.parentElement.parentElement
const h1 = event.currentTarget.parentElement.parentElement.previousElementSibling
if (color > 0) {
collection1.style.backgroundColor = "green";
h1.style.color = "green";
} else {
collection1.style.backgroundColor = "";
h1.style.color = "";
}
afficherpanier();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/js/bootstrap.bundle.min.js"></script>
<div class="col-xl-2 col-lg-3 col-md-4 col-sm-6 couleur1"
style="margin-bottom: 15px; padding-left: 5px; padding-right: 5px;">
<div class="card">
<div class="">
<h3 class="card-title centrer_titre_texte couleur2">2001</h3>
<div class="card-body stylecardbody" style="padding-top: 0;">
<div class="row mt-12">
<div class="col-md-12">
<select class="form-select styleselect" aria-label="2001" onchange="changeQte(this);">
<option selected value="1.10">1 sachet </option>
<option value="2">2 sachets</option>
<option value="3">3 sachets </option>
</select>
</div>
<a style="cursor: pointer; margin-bottom: 5px;width: 90%;display: block;margin-left: auto;margin-right: auto;"
data-nom="2001" data-prix="1.10" data-qte="1" data-checkbox="2001"
data-url="https://phil.pecheperle.be/image-perles/perle-verre-peche-gardon-2001.JPG"
class="btn btn-primary ajouter-panier b-items__item__add-to-cart"
onclick="setTimeout(() => ouvreMaJolieAlert(event), 1000);"> ajouter au panier </a>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-2 col-lg-3 col-md-4 col-sm-6 couleur1"
style="margin-bottom: 15px; padding-left: 5px; padding-right: 5px;">
<div class="card">
<div class="">
<h3 class="card-title centrer_titre_texte couleur2">2001</h3>
<div class="card-body stylecardbody" style="padding-top: 0;">
<div class="row mt-12">
<div class="col-md-12">
<select class="form-select styleselect" aria-label="2001" onchange="changeQte(this);">
<option selected value="1.10">1 sachet </option>
<option value="2">2 sachets</option>
<option value="3">3 sachets </option>
</select>
</div>
<a style="cursor: pointer; margin-bottom: 5px;width: 90%;display: block;margin-left: auto;margin-right: auto;"
data-nom="2001" data-prix="1.10" data-qte="1" data-checkbox="2001"
data-url="https://phil.pecheperle.be/image-perles/perle-verre-peche-gardon-2001.JPG"
class="btn btn-primary ajouter-panier b-items__item__add-to-cart"
onclick="setTimeout(() => ouvreMaJolieAlert(event), 1000);"> ajouter au panier </a>
</div>
</div>
</div>
</div>
</div>
how can I add the class "disabled" to the second checkbox if the first one is selected and vice versa.
I don't know where I'm wrong, this is my code, in which I imagined two functions to include where I will turn off the secondary checkbox in each. (maybe it can in one function for sure, but I don't know), this is my example, if someone can correct me where I went wrong, thank you.
function disableNewmobileOption(ev) {
ev.preventDefault();
var inputElementLabel = $(ev.currentTarget);
var inputElement = inputElementLabel.siblings("input");
if (inputElement.is(':checked')) {
if (inputElement.attr("id") === "b_mobnr") {
$(".newmobile .circle-buttons").addClass("disabled");
} else {
$(".b_mobnr .circle-buttons").removeClass("disabled");
}
}
}
function disableBMobOption(ev) {
ev.preventDefault();
var inputElementLabel = $(ev.currentTarget);
var inputElement = inputElementLabel.siblings("input");
if (inputElement.attr("id") === "newmobile") {
$(".b_mobnr .circle-buttons").addClass("disabled");
} else {
$(".newmobile .circle-buttons").removeClass("disabled");
}
}
<div class="row">
<div class="col-sm-4 newmobile">
<h4>Optionen</h4>
<span class="circle-buttons">
<input type="checkbox" name="b_mobnr" id="b_mobnr" value="0">
<label for="b_mobnr" onclick="disableNewmobileOption(event)">Mobile Option</label>
<div class="check square-check"></div>
</span>
</div>
<div class="col-sm-12 b_mobnr">
<span class="circle-buttons">
<input type="checkbox" name="newmobile" id="newmobile" value="0">
<label for="newmobile" onclick="disableBMobOption(event)">Newmobile Option </label>
<div class="check square-check"></div>
</span>
</div>
</div>
You can use .not() to add disabled class to other span tag when your checkbox is checked.Other way would be passing this inside your function call then depending on if the checkbox is checked add class to other span.
Demo Code :
/*$(".circle-buttons input[type=checkbox]").on("change", function() {
$(".circle-buttons").removeClass("disabled") //remove from all
if ($(this).is(":checked")) {
$(".circle-buttons").not($(this).closest(".circle-buttons")).addClass("disabled") //other span tag
}
})*/
function disableNewmobileOption(el) {
var inputElement = $(el);
//remove class from all
$(".circle-buttons").removeClass("disabled");
//check if checkbox is checked
if (inputElement.is(':checked')) {
//add class to other
$(".b_mobnr .circle-buttons").addClass("disabled");
}
}
function disableBMobOption(el) {
var inputElement = $(el);
$(".circle-buttons").removeClass("disabled");
if (inputElement.is(':checked')) {
$(".newmobile .circle-buttons").addClass("disabled");
}
}
.disabled {
color: grey;
pointer-events: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-4 newmobile">
<h4>Optionen</h4>
<span class="circle-buttons">
<!--aded click event on checkbox-->
<input type="checkbox" name="b_mobnr" id="b_mobnr" onclick="disableNewmobileOption(this)" value="0">
<label for="b_mobnr" >Mobile Option</label>
<div class="check square-check"></div>
</span>
</div>
<div class="col-sm-12 b_mobnr">
<span class="circle-buttons">
<input type="checkbox" name="newmobile" id="newmobile" onclick="disableBMobOption(this)" value="0">
<label for="newmobile">Newmobile Option </label>
<div class="check square-check"></div>
</span>
</div>
</div>
I'm trying to add an input field when clicking on add, and it should be removed when clicking on delete click.
Here is JS Bin link:
JS issue with deletion
var newTextBoxDiv;
var rowCount = 0;
var counter = 1;
var delCounter = 1;
$(document).ready(function() {
$(document).on('focus', '.txtFocus', function() {
$(this).next('.clearContent').hide()
});
$(document).on('focusout', '.txtFocus', function() {
$('.clearContent').show()
})
});
function addTags(obj) {
var newTextBoxDiv = '<div class="col-md-4 TextBoxMainDiv"><div style=""><div class="input-group" id="" style="width: 40%;margin: 0;padding: 0;padding: 2px;float:left;width:80%;"><input type="text" name="textbox' + counter + '" id="textbox' + counter + '" value="" class="txtFocus" required placeholder="Add Tag" autocomplete="false" style="width: 100%" ><span class="clearContent"><i class="fas fa-times"></i></span> </div><div style="width: 15%;display: inline-block;text-align:right;"><span id="addMore" onClick="addTags(this);"><i class="fas fa-plus-square"></i></span></div></div></div>';
$(obj).hide();
$("#tagElement").append(newTextBoxDiv);
$('.txtFocus').focus();
counter++;
if (counter == 1) {
$(obj).show()
}
}
function deleteTag(obj) {
$(obj).closest('.TextBoxMainDiv').last().find('#addMore').show();
$(obj).closest('.TextBoxMainDiv').last().find('#addMore').css('display', 'block');
$(obj).closest('.TextBoxMainDiv').remove();
counter--;
if (counter == 1) {
$('#addMore').show()
}
}
<div class="row">
<div id="tagElement">
<div> </div>
<div class="col-md-4 TextBoxMainDiv">
<div style="">
<div class="input-group" id="" style="width: 40%;margin: 0;padding: 0;padding: 2px;float:left;width:80%;">
<input type="text" class="txtFocus" required placeholder="Add Tag" id="textBox" autocomplete="false" autofocus="autofocus" style="width: 100%">
<span class="clearContent">
Add
</span>
</div>
<div style="width: 15%;display: inline-block;text-align:right;">
<span id="addMore" onClick="addTags(this);">
cancel
</span>
</div>
</div>
</div>
</div>
</div>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
I manage to add the input fields properly, but have issues deleting them. They seem to be deleted randomly.
I think the add and delete button are mixed up, but I couldn't spend time on analysing the code because it's too much code for something that does very little. The following demo:
has a single button that adds a row of form controls:
a checkbox
a text input
a button that deletes it's own row as well as itself.
Demo
var index = 0;
var template = `
<figure class='frame'><input class='status' type='checkbox'><label class='tag'></label><input class='text' type='text' placeholder='Enter New Task'><button class='del' type='button'>➖</button></figure>`;
$('.set').on('click', 'button', function(e) {
if ($(this).hasClass('add')) {
index++;
$('.set').prepend(template);
$('.status:eq(0)').attr('id', 'chx' + index);
$('.tag:eq(0)').attr('for', 'chx' + index);
} else {
$(this).prevUntil('.del, .add').add(this).remove();
}
});
.set {
position: relative;
padding: 2px 0 1px 2px;
min-height: 28px;
border-radius:7px;
}
.frame {
padding: 0;
margin: 0;
min-width:90vw;
}
.add {
position: absolute;
right: 6px;
top: 3px;
display:block;
}
.status {
display: none
}
.tag {
display: inline-table;
font-size: 28px;
line-height: 1;
vertical-align: middle
}
.tag::before {
content: '\2610';
}
.status:checked+.tag::before {
content: '\2611'
}
.text {
display:inline-table;
width: 75%;
margin: 2px 5px 0
}
<form id='ui'>
<fieldset class='set'>
<figure class='frame'>
<input id='chx0' class='status' type='checkbox'>
<label for='chx0' class='tag'></label>
<input class='text' type='text' placeholder='Enter New Task' style='margin:2.5px 2px 0 0' autofocus>
<button class='del' type='button'>➖</button>
</figure>
<button class='add' type='button'>➕</button>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I think your code's logic is working, however, the icon for addition and deletion of inputs is not being rendered.
You can replace your newTextBoxDiv with this:
var newTextBoxDiv = `
<div class="col-md-4 TextBoxMainDiv">
<div style="">
<div class="input-group" id="" style="width: 40%;margin: 0;padding: 0;padding: 2px; float:left; width:80%;">
<input type="text" name="textbox${counter}" id="textbox${counter}" value="" class="txtFocus" required placeholder="Add Tag" autocomplete="false" style="width: 100%" >
<span class="clearContent">
Delete<i class="fas fa-times"></i>
</span>
</div>
<div style="width: 15%;display: inline-block;text-align:right;">
<span id="addMore" onClick="addTags(this);">
Add
</span>
</div>
</div>`;
Notice that I added the word "Add" and "Delete" between the tags, so that you have something to click on
Also, I think you need to swap the word "Add" and "Cancel" in the initial HTML to convey a clearer message, as they are now doing the opposite thing.
Another fix that's needed is to replace the id="addMore" with class="addMore"
<span class="addMore" onClick="addTags(this);">
Since id is meant to be unique. In your code, however, when you append new element, you added new elements with duplicate id, making jquery's selector not selecting the element you want.
After replacing id with class, you also need to change the deleteTag function to select the last "addMore" span and show it.
function deleteTag(obj) {
$(obj).closest('.TextBoxMainDiv').last().find('.addMore').show();
$(obj).closest('.TextBoxMainDiv').last().find('.addMore').css('display', 'block');
$(obj).closest('.TextBoxMainDiv').remove();
counter--;
$('.addMore').last().show();
}
For the layout, you need to do it with css, removing float and setting the div tag with appropriate width and display: inline-block. I suggest you use a separate css file to style the elements instead of doing it inline.
function deleteTodo() {
$(this).parent().remove();
}
function addTodo() {
var inputTemplate =
'<div class="todo-input-wrapper">' +
'<input class="todo-input" type="text" placeholder="Add Tag" />' +
'<button class="delete-button">Delete</button>' +
'</div>';
$('.todo-wrapper').append(inputTemplate);
$('.delete-button').last().on('click', deleteTodo);
$('.todo-input').last().focus();
}
$(document).ready(function () {
$('.delete-button').on('click', deleteTodo);
$('.add-button').on('click', addTodo);
});
.todo-wrapper {
display: inline-block;
width: max-content;
font-size: 0;
}
.todo-input-wrapper {
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="todo-wrapper">
<div class="todo-input-wrapper">
<input class="todo-input" type="text" placeholder="Add Tag" />
<button class="delete-button">Delete</button>
</div>
</div>
<button class="add-button">Add</button>
why can not my function register a text that is clicked, but must I enter it manually to calculate in total?
Namely, my idea is that by clicking on a product, it is displayed in the input field [284] of the product price, and when clicking on a checkbox option to increase the price and display it at the end of [388], the text menu can now only it is compiled if I enter a number manually in field 285. How can I do it?
function displayAbo(el) {
document.getElementById("contactFormFieldId_284").value = el.querySelector('.product__title').textContent+ " " +el.querySelector('.product__price').textContent;
}
var checkBoxes = document.getElementsByClassName('contactFormClass_checkbox');
var sum = 0,
inputField = document.getElementById('contactFormFieldId_284'),
finalInput = document.getElementById('contactFormFieldId_388');
Array.prototype.slice.call(checkBoxes).forEach( (checkBox) => {
checkBox.addEventListener('change', calculateTotal, false);
})
inputField.addEventListener('blur', calculateSumWithInput, false);
function calculateTotal(e) {
if(e.target.checked) {
sum += parseInt(e.target.value, 10);
} else {
sum -= parseInt(e.target.value, 10);
}
finalInput.value ="CHF "+ sum + ".–";
}
function calculateSumWithInput(e) {
var re = /\d+/;
var value = re.exec(e.target.value);
if(value && !isNaN(value) && Number(value) === parseInt(value, 10)) {
sum = parseInt(value, 10);
finalInput.value = sum;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product__item" onclick="displayAbo(this)" id="product-medium" tabindex="-1" role="radio" aria-checked="false" aria-describedby="medium-desc">
<div class="product__inner" id="medium-desc">
<h3 class="product__title">LEUWIN M</h3>
<ul class="product__features">
<li class="product__features-item">40 Mbit/s</li>
<li class="product__features-item"><img src="themes/zuerich/images/I.png" style="width: 100px; margin-right: 110px;"></li>
</ul>
<h4 class="product__price">CHF 39.–</h4>
</div>
</div>
<div class="contact row">
<label for="contactFormFieldId_284" style="color: #003664; font-size: 16px; font-weight: bold;">[[284_LABEL]]</label>
<input class="contactFormClass_text" id="contactFormFieldId_284" type="text" name="contactFormField_284" value="[[284_VALUE]]" readonly />
</div>
<div class="contact row">
<label for="contactFormFieldId_385">[[385_LABEL]]</label>
<input class="contactFormClass_checkbox" id="contactFormFieldId_385" type="checkbox" name="contactFormField_385" value="5" [[SELECTED_385]] />
</div>
<div class="contact row">
<label for="contactFormFieldId_386">[[386_LABEL]]</label>
<input class="contactFormClass_checkbox" id="contactFormFieldId_386" type="checkbox" name="contactFormField_386" value="15" [[SELECTED_386]] />
</div>
<div class="contact row">
<label for="contactFormFieldId_387">[[387_LABEL]]</label>
<input class="contactFormClass_checkbox" id="contactFormFieldId_387" type="checkbox" name="contactFormField_387" value="20" [[SELECTED_387]] />
</div>
<div class="contact row">
<label for="contactFormFieldId_388" style="color: #003664; font-size: 16px; font-weight: bold;">[[388_LABEL]]</label>
<input class="contactFormClass_text" id="contactFormFieldId_388" type="text" name="contactFormField_388" value="0" />
</div>
I have made 2 changes.
Changed your blur function to click
inputField.addEventListener('click', calculateSumWithInput, false);
Added click triggers in your functions
inputField.click();
function displayAbo(el) {
document.getElementById("contactFormFieldId_284").value = el.querySelector('.product__title').textContent + " " + el.querySelector('.product__price').textContent;
inputField.click();
}
var checkBoxes = document.getElementsByClassName('contactFormClass_checkbox');
var sum = 0,
inputField = document.getElementById('contactFormFieldId_284'),
finalInput = document.getElementById('contactFormFieldId_388');
Array.prototype.slice.call(checkBoxes).forEach((checkBox) => {
checkBox.addEventListener('change', calculateTotal, false);
})
inputField.addEventListener('click', calculateSumWithInput, false);
inputField.click();
function calculateTotal(e) {
if (e.target.checked) {
sum += parseInt(e.target.value, 10);
} else {
sum -= parseInt(e.target.value, 10);
}
finalInput.value = "CHF " + sum + ".–";
}
function calculateSumWithInput(e) {
var re = /\d+/;
var value = re.exec(e.target.value);
if (value && !isNaN(value) && Number(value) === parseInt(value, 10)) {
sum = parseInt(value, 10);
finalInput.value = "CHF " + sum + ".–";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product__item" onclick="displayAbo(this)" id="product-medium" tabindex="-1" role="radio" aria-checked="false" aria-describedby="medium-desc">
<div class="product__inner" id="medium-desc">
<h3 class="product__title">LEUWIN M</h3>
<ul class="product__features">
<li class="product__features-item">40 Mbit/s</li>
<li class="product__features-item"><img src="themes/zuerich/images/I.png" style="width: 100px; margin-right: 110px;"></li>
</ul>
<h4 class="product__price">CHF 39.–</h4>
</div>
</div>
<div class="contact row">
<label for="contactFormFieldId_284" style="color: #003664; font-size: 16px; font-weight: bold;">[[284_LABEL]]</label>
<input class="contactFormClass_text" id="contactFormFieldId_284" type="text" name="contactFormField_284" value="[[284_VALUE]]" readonly />
</div>
<div class="contact row">
<label for="contactFormFieldId_385">[[385_LABEL]]</label>
<input class="contactFormClass_checkbox" id="contactFormFieldId_385" type="checkbox" name="contactFormField_385" value="5" [[SELECTED_385]] />
</div>
<div class="contact row">
<label for="contactFormFieldId_386">[[386_LABEL]]</label>
<input class="contactFormClass_checkbox" id="contactFormFieldId_386" type="checkbox" name="contactFormField_386" value="15" [[SELECTED_386]] />
</div>
<div class="contact row">
<label for="contactFormFieldId_387">[[387_LABEL]]</label>
<input class="contactFormClass_checkbox" id="contactFormFieldId_387" type="checkbox" name="contactFormField_387" value="20" [[SELECTED_387]] />
</div>
<div class="contact row">
<label for="contactFormFieldId_388" style="color: #003664; font-size: 16px; font-weight: bold;">[[388_LABEL]]</label>
<input class="contactFormClass_text" id="contactFormFieldId_388" type="text" name="contactFormField_388" value="0" />
</div>