Attempting to grab data from Dynamic Element before submission of form to calculate duration of time.
As shown in the picture, I have
Day 1 works perfectly, However Day 2 does not calculate the duration of hours. Not sure why that is. Also Unable to edit day 1 once I click to add another day but interested in how to go about fixing the first issue.
var template;
var numOfSegments = 1;
window.addEventListener('load', function() {
template = document.querySelector("#wrapper").innerHTML;
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault(); // tell the browser to not send the form
document.getElementById('wrapper').insertAdjacentHTML('beforeend', template); // add next segment
numOfSegments = document.querySelectorAll("div.segment").length;
document.querySelector("div.segment:last-of-type > label").innerHTML = "Day " + (numOfSegments) + ":"; //Updates Segment #
});
})
function deleteMe() {
if (numOfSegments > 1) {
var btn = document.querySelector("#wrapper > div.segment:last-of-type");
btn.remove();
event.preventDefault();
}
}
function addNumSeg() {
var elem = document.getElementById("segments_num");
elem.value = ++numOfSegments;
}
function subtractNumSeg() {
var elem = document.getElementById("segments_num");
if (numOfSegments > 1) {
elem.value = --numOfSegments;
}
}
<div id='segments_num' value=1 >
<form id="seg" oninput="z.value=parseInt(segout.value)-parseInt(segin.value)">
<div id="room_fileds">
<div class="content" id="wrapper">
<div class="segment">
<label id="seg[]" style="margin:0 0 10px 60px;display: inline;">Day 1:</label>
<div class="form-group" style="display: inline;">
<label id=seg-in[] style="margin:0 0 10px 35px;display: inline;">IN:</label>
<input class="form-control seg_in" id="segin" type="text" style="margin:0 0 10px 5px;Width:15%;display: inline;">
</div>
<div class="form-group" style="display: inline;">
<label id=seg-out[] style="margin:0 0 10px 35px;display: inline;">OUT:</label>
<input class="form-control seg_out" id="segout" type="text" style="margin:0 0 10px 5px;Width:15%;display: inline;">
</div>
<div class="form-group" style="display: inline;">
<label id="seg-dur[]" style="margin:0 0 10px 35px;display: inline;">Duration:</label>
<output class="form-control seg_out" form="seg" name="z" for="segin segout" style="margin:0 0 10px 5px;Width:15%;display:inline"; readonly></output>
</div>
</div>
</div>
</div>
</div>
<div style="text-align:right;">
<div style="display:inline;text-align: right;">
<button onclick="deleteMe(); subtractNumSeg();" type="button" style="height: 25px;width:14px;" id="less_fields">-</button>
</div>
<div style="display:inline;text-align: right;">
<button onclick="addNumSeg();" type="button" style="height: 25px;width:14px;" id="more_fields">+</button>
</div>
</div>
<br><br>
<button type="button" class="btn btn-default" id="formSubmit">Submit</button>
Related
I want to hide the divi when I click the button and open it when I click it again. But I couldn't run the normally working code, what could be the reason?
The js code works when there is only one div, but it does not work due to this code I wrote, but I can't solve the problem.
Razor Page
#for (int i = 0; i < Model.quest.Count; i++)
{
<div class="row mt-12" >
<div class="col-md-1">
<input type="checkbox" id="questcb" asp-for="#Model.quest[i].check">
<span>#(i + 1) Soru</span>
</div>
<div class="col-md-9">
<textarea class="form-control" asp-for=#Model.quest[i].Question rows="3" id="question" hidden></textarea>
<label>#Model.quest[i].Question</label>
</div>
</div>
<div class="row mt-12">
<div class="col-md-1" hidden>
<button class="btn btn-outline-secondary" type="button" id="A" onclick="clickFunc(this.id)">A</button>
</div>
<div class="col-md-1" >
A)
</div>
<div class="col-md-11" hidden="hidden">
<input type="text" asp-for=#Model.quest[i].Answer1 class="form-control" placeholder="" id="answer"
aria-label="Example text with button addon" aria-describedby="button-addon1">
</div>
<div class="col-md-11" id="Amod_#i" style="display:inline-block">
#Model.quest[i].Answer1
</div>
<div class="col-md-2">
<button class="btn btn-primary" type="button" id="mod_#i" onclick="question(this.id)">Cevapları Görüntüle</button>
</div>
</div>
}
js code
let question = button => {
let element = document.getElementById(`A${button}`);
let buttonDOM = document.getElementById(`${button}`)
let hidden = element.getAttribute("hidden");
if (hidden) {
element.removeAttribute("hidden");
buttonDOM.innerText = "Cevapları Gizle";
}
else {
element.setAttribute("hidden", "hidden");
buttonDOM.innerText = "Cevapları Görüntüle";
}
}
</script>
If the id of div is unique in your code,your js should work.If it still doesn't work,you can try to find the div with the position of the button:
let question = button => {
let element = $("#" + button).parent().siblings(".col-md-11")[1];
let buttonDOM = document.getElementById(`${button}`);
if (element.hidden) {
element.removeAttribute("hidden");
buttonDOM.innerText = "Cevapları Gizle";
}
else {
element.setAttribute("hidden", "hidden");
buttonDOM.innerText = "Cevapları Görüntüle";
}
}
result:
I followed this thread Set number input max based on the sum of 4 inputs using jquery and the code below works as expected:
$("input[type='number'].wapo-product-qty").val(0);
$("input[type='number'].wapo-product-qty").change(function () {
$.each($("input[type='number'].wapo-product-qty"), function (index, element) {
var total = 0;
$.each($("input[type='number'].wapo-product-qty").not($(element)), function
(innerIndex, innerElement) {
total += parseInt($(innerElement).val());
});
if ($(element).val() > 6 - total) {
alert("The total value for all inputs can not exceed 6");
$(element).val(0);
return false;
} else {
$(element).attr("max", 6 - total);
}
});
});
Here full HTML --> https://pastebin.com/DjX8Kkt1
But I need the quantity selector to start from 0 and not from 1.
I added this for that, but I don't know is the best approach:
$("input[type='number'].wapo-product-qty").val(0);
Once the condition of the maximum number of quantities is reached, the fields for which the quantity has not been selected with the selector are reset to 0.
For example in my case:
4 input fields:
0 -> change to 2
0 -> change to 2
0 -> change to 2
0 -> change to 1 -> we are over 6, condition reached
But the last input it remains 1, so I would like to reset to 0 for this reason.
Thanks
try this code with an updated javascript function.
call function onchange of input and get sum of all input and check condition
$("input[type='number'].wapo-product-qty").val(0);
function getQtyTotal(event) {
var total = 0;
// total += parseInt(event.target.value);
$.each($("input[type='number'].wapo-product-qty"), function(index, element) {
total += parseInt($(this).val());
});
//console.log(total);
if (total > 6) {
alert("The total value for all inputs can not exceed 6");
event.target.value = 0;
return false;
} else {
if (event.target.value > 6) {
event.target.setAttribute("max", 6 - total);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="options default-closed per-row-5 grid">
<p class="wapo-addon-description">Choose product</p>
<div id="yith-wapo-option-1-0" class="yith-wapo-option selection-multiple " data-replace-image="">
<input type="checkbox" id="yith-wapo-1-0" class="yith-proteo-standard-checkbox" name="yith_wapo[][1-0]" value="product-8061-1" data-price="0" data-price-sale="0" data-price-type="fixed" data-price-method="free" data-first-free-enabled="no" data-first-free-options="5"
data-addon-id="1" style="display: none;">
<label for="yith-wapo-1-0" style="width: 33%;">
<img src="#" data-id="8061">
<div>
<!-- PRODUCT NAME -->
Product 1
<br>
<div class="option-add-to-cart">
<input type="number" class="wapo-product-qty" data-product-id="8061" name="yith_wapo_product_qty[1-0]" value="1" min="1" max="1254" style="min-width: 50px; width: 5em; margin-right: 10px; float: left;" onChange="getQtyTotal(event);">
</div>
</div>
<div class="clear"></div>
</label>
</div>
<div id="yith-wapo-option-1-1" class="yith-wapo-option selection-multiple " data-replace-image="">
<input type="checkbox" id="yith-wapo-1-1" class="yith-proteo-standard-checkbox" name="yith_wapo[][1-1]" value="product-8028-1" data-price="0" data-price-sale="0" data-price-type="fixed" data-price-method="free" data-first-free-enabled="no" data-first-free-options="5"
data-addon-id="1" style="display: none;">
<label for="yith-wapo-1-1" style="width: 33%;">
<img src="#" data-id="8028">
<div>
<!-- PRODUCT NAME -->
Product 2
<br>
<div class="option-add-to-cart">
<input type="number" class="wapo-product-qty" data-product-id="8028" name="yith_wapo_product_qty[1-1]" value="1" min="1" max="1180" style="min-width: 50px; width: 5em; margin-right: 10px; float: left;" onChange="getQtyTotal(event);">
</div>
</div>
<div class="clear"></div>
</label>
</div>
<div id="yith-wapo-option-1-2" class="yith-wapo-option selection-multiple " data-replace-image="">
<input type="checkbox" id="yith-wapo-1-2" class="yith-proteo-standard-checkbox" name="yith_wapo[][1-2]" value="product-8026-1" data-price="0" data-price-sale="0" data-price-type="fixed" data-price-method="free" data-first-free-enabled="no" data-first-free-options="5"
data-addon-id="1" style="display: none;">
<label for="yith-wapo-1-2" style="width: 33%;">
<img src="#" data-id="8026">
<div>
<!-- PRODUCT NAME -->
Product 3
<br>
<div class="option-add-to-cart">
<input type="number" class="wapo-product-qty" data-product-id="8026" name="yith_wapo_product_qty[1-2]" value="1" min="1" max="991" style="min-width: 50px; width: 5em; margin-right: 10px; float: left;" onChange="getQtyTotal(event);">
</div>
</div>
<div class="clear"></div>
</label>
</div>
<div id="yith-wapo-option-1-3" class="yith-wapo-option selection-multiple " data-replace-image="">
<input type="checkbox" id="yith-wapo-1-3" class="yith-proteo-standard-checkbox" name="yith_wapo[][1-3]" value="product-7943-1" data-price="0" data-price-sale="0" data-price-type="fixed" data-price-method="free" data-first-free-enabled="no" data-first-free-options="5"
data-addon-id="1" style="display: none;">
<label for="yith-wapo-1-3" style="width: 33%;">
<img src="#" data-id="7943">
<div>
<!-- PRODUCT NAME -->
Product 4
<br>
<div class="option-add-to-cart">
<input type="number" class="wapo-product-qty" data-product-id="7943" name="yith_wapo_product_qty[1-3]" value="1" min="1" max="955" style="min-width: 50px; width: 5em; margin-right: 10px; float: left;" onChange="getQtyTotal(event);">
</div>
</div>
<div class="clear"></div>
</label>
</div>
i would like help for some improvement i would like to change the structure of my html this is the image below
I would like that when user press the plus a new input box however the right side there is a minus instead and if press minus the input box be gone
Example of image below
currently what i have is on my code is just like this
So how can i change it to be like the example of the image?
$('.add').on('click', add);
$('.remove').on('click', remove);
function add() {
var new_chq_no = parseInt($('#total_chq').val()) + 1;
var new_input = "<div style='margin-bottom:5px;'><input type='text' id='new_" + new_chq_no + "'pattern='^[0-9]{8}$' class='form-control col-9' required><div class='invalid-feedback'>Enter a correct PhoneNumber!</div></div>";
$('#new_chq').append(new_input);
$('#total_chq').val(new_chq_no);
}
function remove() {
var last_chq_no = $('#total_chq').val();
if (last_chq_no > 1) {
$('#new_' + last_chq_no).remove();
$('#total_chq').val(last_chq_no - 1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="form-group row">
<label for="validationNumber" class="col-2 col-form-label">Contact:</label>
<div class="col-4">
<div class="flex" style="margin-bottom:5px;">
<input style="margin-right: 19px;" id="validationNumber" name="phonenumber" type="text" class="form-control" pattern="\b\d{8}\b" required>
<a onclick="add()"><label style="cursor: pointer; padding-top: 5px;"><i data-feather="plus">+</i></label></a>
<a onclick="remove()"><label style="cursor: pointer; padding-top: 5px;"><i data-feather="minus">-</i></label></a>
</div>
<div id="new_chq"> </div>
<input type="hidden" value="1" id="total_chq">
<div class="invalid-feedback">
Enter a correct PhoneNumber!
</div>
</div>
</div>
Here is a version that is using clone and delegation
Wrap the set in a container of their own
Wrap the containers in a container
Check that the user cannot delete the last row
Clone the number including the possible error message
No need for ID, you can navigate using closest and the name
const $container = $('#contactContainer')
$(".remove").eq(0).hide()
$container.on('click', ".ar", function(e) {
const add = $(this).is(".add");
const $phones = $container.find(".phone");
const len = $phones.length;
if (add) {
const $newPhone = $phones.eq(0).clone(true)
$newPhone.find("[name=phonenumber]")
.attr("id", `new_${$phones.length}`)
.val("");
$container.append($newPhone);
$newPhone.find(".add").hide(); // if you only want one plus
$newPhone.find(".remove").show()
} else {
$(this).closest(".phone").remove()
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="form-group row">
<label class="col-2 col-form-label">Contact:</label>
<div class="col-4" id="contactContainer">
<div class="flex phone" style="margin-bottom:5px;">
<input style="margin-right: 19px;" name="phonenumber" type="text" class="form-control" pattern="\b\d{8}\b" required>
<span class="ar add"><label style="cursor: pointer; padding-top: 5px;"><i data-feather="plus">+</i></label></span>
<span class="ar remove"><label style="cursor: pointer; padding-top: 5px;"><i data-feather="minus">-</i></label></span>
<div class="invalid-feedback">
Enter a correct PhoneNumber!
</div>
</div>
</div>
</div>
I'm creating a comment and reply system, but I can't get the reply button to display the input field for only the comment.
When the any reply button is clicked, all the input fields displays instead of just the one clicked
This is my javascript:
function reply() {
var doc;
doc=document.getElementsByClassName("sho") ;
for (var i = 0 ; i < doc.length; i++){
doc[i].style.display="block ";
}
}
$('.btn-reply').on("click", function () {
var parent_dom = $(this).parent();
var _input_child_dom = $(parent_dom).children("input");
var find_allInput = $('.reply-container').find("input");
if(find_allInput.length > 0 ){
for (var i = 0; i < find_allInput.length; i++) {
$(find_allInput[i]).css("display" , "none");
}
}
$(_input_child_dom).css("display" , "block");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="reply-container">
<div class="reply">
<p>First reply</p>
<button class="btn btn-primary btn-reply">reply</button>
<input type="text" class="InputReply" style="display: none;">
</div>
<br>
<div class="reply">
<p>Second reply</p>
<button class="btn btn-primary btn-reply">reply</button>
<input type="text" class="InputReply" style="display: none;">
</div>
<br>
<div class="reply">
<p>Third reply</p>
<button class="btn btn-primary btn-reply">reply</button>
<input type="text" class="InputReply" style="display: none;">
</div>
</div>
Note: This is the idea of how you can achieve your requirement.
Creating Dynamic new fields seems to clear the already existing fields
Also not trying to have multiple elements with the same id hence why i don't believe appendChild will work. Perhaps you can find a way to do that while creating different IDs?
Any help welcomed =)
var template;
var a = 1;
window.onload = function() {
template = document.querySelector("#wrapper").innerHTML;
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault(); // tell the browser to not send the form
document.getElementById('wrapper').innerHTML += template; // add next segment
document.querySelector("#wrapper > label:last-of-type").innerHTML = "Segment " + (++a) + ":";
});
}
.form-group {
display: inline
}
#wrapper > label {
margin: 0 0 10px 210px;
}
.segment {
display: inline-block;
margin: 0 0 1em
}
.form-group > label {
margin: 0 0 10px 20px;
}
.form-group > input {
width: 15%
}
<div class="container">
<h2>Form</h2>
<form>
<div id="room_fields">
<div class="content" id="wrapper">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
</div>
<br><br>
<div style="text-align: right;">
<button id="more_fields">+</button>
</div>
<br>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
innerHTML will not include the current value entered IIRC but it's still strange that doing += operation will remove the existing value.
However, insertAdjacentHTML() should work as expected.
var template;
var a = 1;
window.onload = function() {
template = document.querySelector("#wrapper").innerHTML;
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault(); // tell the browser to not send the form
document.getElementById('wrapper').insertAdjacentHTML('beforeend', template); // add next segment
document.querySelector("#wrapper > label:last-of-type").innerHTML = "Segment " + (++a) + ":";
});
}
.form-group {
display: inline
}
#wrapper > label {
margin: 0 0 10px 210px;
}
.segment {
display: inline-block;
margin: 0 0 1em
}
.form-group > label {
margin: 0 0 10px 20px;
}
.form-group > input {
width: 15%
}
<div class="container">
<h2>Form</h2>
<form>
<div id="room_fields">
<div class="content" id="wrapper">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
</div>
<br><br>
<div style="text-align: right;">
<button id="more_fields">+</button>
</div>
<br>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
Basically, my below code is not 100% correct, you should alter it by yourself following mine.
In the HTML, you can define a hidden div which is your wrapper. In its and nested element ids, you can set a pattern like '$$$'.
<div class="content" id="wrapper$$$" sytle="visibility: hidden;">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
In your javascript, declare a global variable named index and replace index value with '$$$'. It will be increased 1 when you add your template dynamically.
template = document.querySelector("#wrapper").innerHTML;
template = template.replace('$$$', index);
index ++;
...
Problem:
The problem here is with using innerHTML, because innerHTML will always override the HTML of your elements so previously typed values will be cleared, that's why you should use .appendChild().
And your logic for dynamic is correct, you just need to chnage the way you add new fields.
Solution:
I tried to rewrite your code so it uses appendChild() in a smart way using the #wrapper innerHTML as template and updating the id dynamically in the new appended fields.
var template = document.querySelector("#wrapper").innerHTML;
function addFields() {
var wrapper = document.createElement("div");
wrapper.innerHTML = template;
wrapper.querySelector("label:last-of-type").innerHTML = "Segment " + (++a) + ":";
document.getElementById('wrapper').appendChild(wrapper);
}
This code will create a new div everytime, wher we put the template HTML inside it, update the label dynamically referring the label inside our current wrapper div using wrapper.querySelector("label:last-of-type"), then finally append this new div to our element.
Demo:
Here's a working Demo snippet:
var template = document.querySelector("#wrapper").innerHTML;
var a = 1;
function addFields() {
var wrapper = document.createElement("div");
wrapper.innerHTML = template;
wrapper.querySelector("label:last-of-type").innerHTML = "Segment " + (++a) + ":";
document.getElementById('wrapper').appendChild(wrapper);
}
window.onload = function() {
document.querySelector("#more_fields").addEventListener("click", function(e) {
e.preventDefault();
addFields();
});
}
<div class="container">
<h2>Form</h2>
<form>
<div id="room_fields">
<div class="content" id="wrapper">
<label style:>Segment 1:</label>
<div class="segment">
<div class="form-group">
<label>IN:</label>
<input name="seg-in[]" type="text">
</div>
<div class="form-group">
<label>OUT:</label>
<input name="seg-out[]" type="text">
</div>
<div class="form-group">
<label>Duration:</label>
<input name="seg-dur[]" type="text">
</div>
</div>
</div>
</div>
<br><br>
<div style="text-align: right;">
<button id="more_fields">+</button>
</div>
<br>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>