How to generate same elements in multiple divs? - javascript

I have been trying to create onlick function in multiple divs by using shot codes in javascript but I end up creating multiple javascript codes with different ids and onclick function.
I tried for loop function but it didn't work as well.
function copy() {
document.getElementById("label").innerHTML = document.getElementById("mySelect").value;
}
function copy2() {
document.getElementById("label2").innerHTML = document.getElementById("mySelect2").value;
}
function copy3() {
document.getElementById("label3").innerHTML = document.getElementById("mySelect3").value;
}
function copy4() {
document.getElementById("label4").innerHTML = document.getElementById("mySelect4").value;
}
function copy5() {
document.getElementById("label5").innerHTML = document.getElementById("mySelect5").value;
}
function copy6() {
document.getElementById("label6").innerHTML = document.getElementById("mySelect6").value;
}
function copy7() {
document.getElementById("label7").innerHTML = document.getElementById("mySelect7").value;
}
function copy8() {
document.getElementById("label8").innerHTML = document.getElementById("mySelect8").value;
}
function copy9() {
document.getElementById("label9").innerHTML = document.getElementById("mySelect9").value;
}
function copy10() {
document.getElementById("label10").innerHTML = document.getElementById("mySelect10").value;
}

try this concept and adjust your code.
for(var i = 1; i < 3; i++) {
document.getElementById("label"+i).innerHTML = document.getElementById("mySelect"+i).innerHTML;
}
<div id="mySelect1">Up above the world so high</div>
<div id="mySelect2">like a diamond in the sky</div>
<div id="label1"></div>
<div id="label2"></div>

It is really hard to understand this question but can you not just make one function with a parameter? And loop the function with a for-loop if necessary.
function copy(id) {
id = id || ""; //empty string if id is undefined
document.getElementById("label" + id).innerHTML = document.getElementById("mySelect" + id).value;
}
function copyClick() {
for(var i = 0; i < 10; i++){
copy(i);
}
}
<button onclick="copyClick">Copy!</button>
Or if you have multiple buttons the copyClick function is not necessary.
<button onclick="function(){ copy(0) }">Copy 0!</button>
<button onclick="function(){ copy(1) }">Copy 1!</button>
...

Related

How do I combine 2 onclick functions in javascript?

Hi there I am trying to combine 2 javascript onClick function so that they only fire once both have been clicked, this is what I have currently attempted.
Javascript
click.onclick = function() {
for (let i = 0; i < 1; i++) {
console.log("Clicks counted " + I);
}
}
click2.onclick = function() {
for (let i = 0; i < 1; i++) {
console.log("Clicks counted " + I);
}
}
if (click.onclick && click2.onclick === true) {
console.log("You have clicked on both onClicks");
}
HTML
<section>
<button id="button-click">Nice</button>
<button id="button-click-2">Even nicer</button>
</section>
Super simple I know, but I just wanted to figure out how to do this as it's for an API call so requires both buttons to be clicked and then send a statement.
You could use a function which checks a value. This value is made up by using bitwise or with 1 or 2, for more buttons double the value for each one.
In the checking function, check the value which is 2n - 1, for two check against 3.
let clickButtons = 0;
function check() {
if (clickButtons === 3) console.log("You have clicked on both onClicks");
}
document.getElementById("button-click").addEventListener('click', function() {
clickButtons |= 1;
check();
});
document.getElementById("button-click-2").addEventListener('click', function() {
clickButtons |= 2;
check();
});
<section>
<button id="button-click">Nice</button>
<button id="button-click-2">Even nicer</button>
</section>

How to update created elements?

I have this simple function that will create a paragraph.
function appendElements() {
const input = document.getElementById("myInput");
const createDiv = document.createElement("div");
createDiv.classList.add("myDiv");
const createP = document.createElement("P");
createP.classList.add("myParagraph");
createP.innerHTML = input.value;
createDiv.appendChild(createP);
const div = document.getElementById("examplediv");
div.appendChild(createDiv);
}
And another function that will sum the innerHTML of the divs, and create a div element for the result.
function calculateSum() {
let div = document.getElementsByClassName("myParagraph");
let array = new Array;
for (var i = 0; i <div.length; i++) {
array.push(div[i].innerHTML);
}
let numberedArray = array.map((i) => Number(i));
const sumArray = numberedArray.reduce(function(a, b){
return a + b;
}, 0);
const createElement = document.createElement("div");
createElement.innerHTML = sumArray;
document.getElementById("divForAvg").appendChild(createElement);
}
And the last function that will change the innerHTML of the paragraph element when clicked.
function editELement() {
const input2 = document.getElementById("myInput2")
let items = document.getElementsByClassName("myParagraph");
for(var i = 0; i < items.length; i++){
items[i].onclick = function(){
items[i].innerHTML = input2.value;
}
}
}
So basically when I create some paragraphs and execute the second function, the second function will calculate the sum of the paragraphs and create a div with the sum inside.
What I want is when I remove one of the paragraph elements or edit them, I want the previously created divs to update(recalculate the sum), I have literally no idea on how to do this.
Let's try this using event delegation. I have interpreted what I think you are looking for (note: it's exemplary, but it may give you an idea for your code) and reduced your code a bit for the example. Note the 2 different ways to create new elements (insertAdjacentHTML and Object.assign).
You can play with the code #Stackblitz.com.
document.addEventListener("click", handle);
function handle(evt) {
if (evt.target.id === "create") {
return appendInputValueElement();
}
if (evt.target.classList.contains("remove")) {
return removeThis(evt.target);
}
if (evt.target.id === "clear") {
document.querySelector("#accumulated ul").innerHTML = "";
return true;
}
}
function appendInputValueElement() {
const input = document.querySelector(".myInput");
const div = document.querySelector("#exampleDiv");
exampleDiv.insertAdjacentHTML("beforeEnd", `
<div class="myDiv">
<button class="remove">remove</button>
<span class="myParagraph">${input.value || 0}</span>
</div>
`);
calculateSum();
}
function removeThis(elem) {
elem.closest(".myDiv").remove();
calculateSum();
}
function calculateSum() {
const allParas = [...document.querySelectorAll(".myParagraph")];
const sum = allParas.reduce( (acc, val) => acc + +val.textContent, 0);
document.querySelector("#accumulated ul")
.append(Object.assign(document.createElement("li"), {textContent: sum}));
document.querySelector(".currentSum").dataset.currentSum = sum;
if (sum < 1) {
document.querySelector("#accumulated ul").innerHTML = "";
}
}
.currentSum::after {
content: ' 'attr(data-current-sum);
color: green;
font-weight: bold;
}
.myParagraph {
color: red;
}
.accSums, .currentSum, .myDiv {
margin-top: 0.3rem;
}
<div>
A number please: <input class="myInput" type="number" value="12">
<button id="create">create value</button>
</div>
<div class="currentSum" data-current-sum="0">*Current sum</div>
<p id="exampleDiv"></p>
<div id="accumulated">
<div class="accSums">*Accumulated sums</div>
<ul></ul>
<button id="clear">Clear accumulated</button>
</div>
i've changed calculateSum you can call it when you edited paragraph. If summParagraph doesn't exists then we create it.
function calculateSum() {
let div = document.getElementsByClassName("myParagraph");
let array = new Array;
for (var i = 0; i <div.length; i++) {
array.push(div[i].innerHTML);
}
let numberedArray = array.map((i) => Number(i));
const sumArray = numberedArray.reduce(function(a, b){
return a + b;
}, 0);
if (!document.getElementById("summParagraph")) {
const createElement = document.createElement("div");
createElement.setAttribute("id", "summParagraph");
document.getElementById("divForAvg").appendChild(createElement);
}
document.getElementById("summParagraph").innerHTML = summArray;
}

Stop taking input in text-field (tag input)

I am taking some tags name like "study","reading" something like that in the textfield with the help of Bootstrap 4 Tag Input Plugin With jQuery - Tagsinput.js and I have also some predefine tags name contain by buttons. If I click the button then the count of the tag's will increase (count++) and again click this button count will decrease(count--). Same rules for the text-field tags and the total count of the tags in both fields (text and buttons)<=5.
I can count the total tags of the both field but can't stop taking input in text-field when it is greater than 5.
html
<button class="btnr btnr-tags-optional" id="1" onclick="tagSelect(this.id)" >1</button>
<button class="btnr btnr-tags-optional" id="2" onclick="tagSelect(this.id)" >2</button>
<button class="btnr btnr-tags-optional" id="3" onclick="tagSelect(this.id)" >3</button>
My Js
var tagsCount = 0;
var store = 0;
var total_tags = 0;
function tagSelect(clicked_id) {
if (total_tags < 5) {
var tags = document.getElementById(clicked_id);
if (tags.style.borderColor == "rgb(255, 72, 20)") {
tags.style.borderColor = "";
tagsCount--;
} else if (tags.style.borderColor == "") {
tags.style.borderColor = 'rgb(255, 72, 20)';
tagsCount++;
}
total_tags = store + tagsCount;
}
console.log(total_tags);
}
$('#tags_text').on('change', function() {
if (total_tags >= 5) {
$("#tags_text").attr('readonly');
console.log('condition')
} else {
$("#tags_text").removeAttr('readonly');
var items = $("#tags_text").tagsinput('items').length;
store = items;
total_tags = store + tagsCount;
console.log(total_tags);
}
});
Here is the example in jsfiddle
This problem is solved.
I have changed the maxTags value of the plugin with the change of the tags click.
window.tagsCount = 0;
var store = 0;
var total_tags = 0;
function tagSelect(clicked_id) {
var r = ("#" + clicked_id).toString();
if (total_tags < 5) {
if ($(r).hasClass("classActiveIssue")) {
$(r).removeClass("classActiveIssue");
window.tagsCount--;
} else {
$(r).addClass("classActiveIssue");
window.tagsCount++;
}
} else {
if ($(r).hasClass("classActiveIssue")) {
$(r).removeClass("classActiveIssue");
window.tagsCount--;
}
}
total_tags = store + tagsCount;
$("#optionsleft").text(total_tags + "/5 selected");
//console.log("total",total_tags);
}
$('#tags_text').on('change', function() {
var items = $("#tags_text").tagsinput('items').length;
store = items;
total_tags = store + tagsCount;
});
and add the line in add:
self.options.maxTags = 5 - window.tagsCount;
Here is the fiddle

innerHTML does not dynamically update nor display on PHP page - JavaScript

I have managed to dynamically display the sum of 6 line-cost DOM elements from a php file. Unfortunately, when trying to calculate the delivery charge, my JavaScript methods regarding to the deliveryCharge implementation fails to display anything on the page. With the sub-total methods working and displaying perfectly, I tried to troubleshoot the problem by providing innerHTML with a constant value of both a string and an int- both times yielded nothing to be displayed on screen.
I have displayed both the working part of the sub-total calculation method as well as the non-working part of the delivery-charge calculation. Would the problem lie within an incorrect way of using innerHTML, be a calculation error or a different error entirely?
function calcST(){
var i;
var sum = 0; // initialize the sum
let p = document.getElementsByTagName("line_cost");
for (i = 0; i < p.length; i++) {
if (!isNaN(Number(p[i].innerHTML))) {
sum = Number(sum + Number(p[i].innerHTML)); // p[i].innerHTML gives you the value
}
}
setST(sum, "sub_total");
}
function setST(sum, item_id){
let i = document.getElementById(item_id);
i.innerHTML = sum;
calcDelivCharge();
}
function getST() {
let i = document.getElementById("sub_total");
let v = i.innerHTML;
return v;
}
function calcDelivCharge(){
var delCharge;
var e = getST();
if(e < 100){
delcharge = e*0.10
}else{
delcharge = 0;
}
setDelivCharge("delivery_charge", delCharge);
}
function setDelivCharge(item_id, delCharge){
let i = document.getElementById(item_id);
i.innerHTML = delCharge;
calculateTAX();
}
function getDelivCharge() {
let i = document.getElementById("delivery_charge");
let v = i.innerHTML;
return v;
}
I managed to find that the DOM was not ready loading before the getST() method was called. This can be fixed with the following code:
if(document.getElementById("sub_total") != null){
let i = document.getElementById("sub_total");
let v = i.innerHTML;
return v;
}
Unfortunately, delivery-charge is seen as 'unidentified'. Why does this appear when the getST() method is altered?
Well, if you're HTML is like
<line_cost>
<div>30</div>
<div>40</div>
...
</line_cost>
You can do this:
function calcSubtotal() {
const costs = document.querySelector("line_cost").children;
let sum = 0;
for( let i = 0 ; i < costs.length ; i ++) {
sum += parseInt(costs[i].innerHTML);
}
setST(sum, "sub_total");
}
// Subtotal getter and setter
function setST(sum, item_id) {
document.getElementById(item_id).innerHTML = sum.toFixed(2);
calcDeliveryCharge();
}
function getSubTotal() {
return document.getElementById("sub_total").innerHTML;
}
function calcDeliveryCharge() {
const subTotal = getSubTotal();
setDeliveryCharge("delivery_charge", subTotal < 100 ? subTotal * 0.10 : 0);
}
function setDeliveryCharge(item_id, deliveryCharge){
document.getElementById(item_id).innerHTML = deliveryCharge.toFixed(2);
//calculateTAX();
}
function getDeliveryCharge() {
return document.getElementById("delivery_charge").innerHTML;
}
calcSubtotal();
calcDeliveryCharge();
<line_cost>
<div>5</div>
<div>4</div>
<div>3</div>
<div>20</div>
</line_cost>
<br/>
<div>
<span>Sub Total: $
<span id="sub_total"></span>
</span>
<br/>
<span>Delivery Charge: $
<span id="delivery_charge"></span>
</span>
</div>
Otherwise, if you have:
<div>
<line_cost>30</line_cost>
<line_cost>40</line_cost>
...
</div>
Then do this:
function calcSubtotal() {
const costs = document.querySelectorAll("line_cost");
let sum = 0
for( let i = 0 ; i < costs.length ; i ++) {
sum += parseFloat(costs[i].innerHTML);
}
setST(sum, "sub_total");
}
// Subtotal getter and setter
function setST(sum, item_id) {
document.getElementById(item_id).innerHTML = sum.toFixed(2);
calcDeliveryCharge();
}
function getSubTotal() {
return document.getElementById("sub_total").innerHTML;
}
function calcDeliveryCharge() {
const subTotal = getSubTotal();
setDeliveryCharge("delivery_charge", subTotal < 100 ? subTotal * 0.10 : 0);
}
function setDeliveryCharge(item_id, deliveryCharge){
document.getElementById(item_id).innerHTML = deliveryCharge.toFixed(2);
//calculateTAX();
}
function getDeliveryCharge() {
return document.getElementById("delivery_charge").innerHTML;
}
calcSubtotal();
calcDeliveryCharge();
line_cost {
display: block;
}
<div>
<line_cost>25</line_cost>
<line_cost>34</line_cost>
<line_cost>43</line_cost>
<line_cost>250</line_cost>
</div>
<br/>
<div>
<span>Sub Total: $
<span id="sub_total"></span>
</span>
<br/>
<span>Delivery Charge: $
<span id="delivery_charge"></span>
</span>
</div>

Add space after dot

Good day. I've got some problem.
I've got input where I wrote some information.
Example:
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
And I've got my controller.
Example:
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
How I can add space after dot? Who knows?
Here is link to jsfiddle with my example.
We achieve it by adding space to each splitted string other than first one and an empty string
function someCtrl($scope) {
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
var addSpace='';
if(i>0 && strt[i].trim().length>0){
addSpace=' ';
}
strt[i] = addSpace+strt[i].trim().charAt(0).toUpperCase() + strt[i].trim().substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
</div>
You can do this simply by changing strt.join('.') to strt.join('. ').
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].trim();
if(strt[i].length > 0) {
strt[i] = ' '+strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
This is working fiddle
I suggest creating a directive so that you can plugin this behaviour whenever required., rather than writing your ng-change in every controller.
In directive simple line element.val(event.target.value.split(".").join(". ")); will work for you., with help of directive controller parameter.
See example fiddle

Categories

Resources