nested arrays in object input manipulation vue - javascript

Good, I have a form which is loaded by 2 iterations, one to load activities and another iteration that is within months, the problem I have is that when entering text in the input text the value in the other text is doubled input The activities come from the database, and the months that will take a start date and an end date, those months should be assigned an amount. So the problem is that these quantities are doubled, making it impossible to enter data correctly.
This is my code in sandbox
https://codesandbox.io/embed/inspiring-proskuriakova-nb0bk?fontsize=14&hidenavigation=1&theme=dark
<template>
<div class="content">
<div v-for="(act, index) in actividades" :key="index">
<div class="row">
<div class="col-12 mt-3">
<b>Actividad {{act.codigo}}</b>
<div class="row" v-for="(pro, index2) in act.programaticas" :key="index2">
<div class="col-4">
<br>
{{pro.mes}}
</div>
<div class="col-8">
Cantidad
<input type="number" required class="form-control" v-model="pro.cantidad">
</div>
</div>
</div>
</div>
<hr>
</div>
export default {
data () {
return {
proyecto:{},
actividades:[],
programaticas:[],
programatica:{mes:'',cantidad:''},
}
},
created() {
this.fetch();
},
methods:{
async fetch()
{
const proyecto = await
Repository.show('proyectos',this.$route.params.proyecto_id);
this.proyecto = proyecto.data;
const actividades=await
Repository.show('actividades',this.$route.params.objetivo_id);
if(actividades.data.length!=0)
{
this.actividades = actividades.data;
}
this.obtenerMeses();
},
obtenerMeses()
{
var monthNames = [ "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" ];
var datFrom = new Date(this.proyecto.fecha_inicio);
var datTo = new Date(this.proyecto.fecha_fin);
var fromYear = datFrom.getFullYear();
var toYear = datTo.getFullYear();
var diffYear = (12 * (toYear - fromYear)) + datTo.getMonth();
for (var i = datFrom.getMonth(); i <= diffYear; i++) {
this.programatica.mes=monthNames[i%12] + " " + Math.floor(fromYear+(i/12));
this.programaticas.push(this.programatica);
this.programatica={mes:'',cantidad:''};
}
for(var i2 = 0; i2 < this.actividades.length; i2++)
{
this.actividades[i2].programaticas=this.programaticas;
}
}
}
}

The problem is:
for(var i2 = 0; i2 < this.actividades.length; i2++)
{
this.actividades[i2].programaticas=this.programaticas;
}
You declare for each item the reference to the same array: this.programaticas. You must create the copy for each item. For example:
for(var i2 = 0; i2 < this.actividades.length; i2++)
{
this.actividades[i2].programaticas=JSON.parse(JSON.strigify(this.programaticas));
}
or better
for(var i2 = 0; i2 < this.actividades.length; i2++)
{
var list = []
for (var i = datFrom.getMonth(); i <= diffYear; i++) {
list.push({
mes: monthNames[i%12] + " " + Math.floor(fromYear+(i/12)),
cantidad:''
});
}
this.actividades[i2].programaticas = list;
}
or change the concept, like one structure for inputs, other for labels

Related

How can I create a secret message app using the square code method?

I need to create a secret message app, such that a text:
"If man was meant to stay on the ground, god would have given us roots."
is normalized to:
"ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots"
And the normalised text forms a rectangle (​r x c​) where ​c​ is the number of columns and ​r​ is the number of rows such that ​c >= r​ and ​c - r <= 1​,
So for instance the normalized text is 54 characters long, dictating a rectangle with ​c = 8​ and ​r = 7​:
"ifmanwas"
"meanttos"
"tayonthe"
"groundgo"
"dwouldha"
"vegivenu"
"sroots "
Then the coded message is obtained by reading down the columns going left to right
"imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau"
and further split to
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau"
The resulting cypher text for a non perfect rectangle can only have a single whitespace for the last rows.
"imtgdvs"
"fearwer"
"mayoogo"
"anouuio"
"ntnnlvt"
"wttddes"
"aohghn "
"sseoau "
This what I have done so far, I could only get my normalised text, but I am doing something wrong to convert it to a rectangle and to get a cypher text out of it.
const output = document.querySelector('#encoded_rectangle');
const encodedChunks = document.querySelector('#encoded_chunks');
const text = document.querySelector('#normalized_text');
const string = document.querySelector('#message');
const error = document.querySelector('#alert');
const encodeMessage = () => {
let message = string.value;
function wordCount() {
return message.split(" ").length;
}
if (wordCount < 2 || message.length < 50) {
error.innerHTML = "Invalid message, Input more than one word and at Least 50 characters!";
return false;
}
function normaliseMessage() {
return message.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
}
function rectangleSize() {
return Math.ceil(Math.sqrt(normaliseMessage.length));
}
function splitRegEx() {
return new RegExp(".{1," + rectangleSize + "}", "g");
}
function plaintextSegments() {
return normaliseMessage.match(splitRegEx);
}
function ciphertext() {
var columns = [],
currentLetter, currentSegment;
var i, j;
for (let i = 0; i < rectangleSize; i++) {
columns.push([]);
}
for (i = 0; i < plaintextSegments.length; i++) {
currentSegment = plaintextSegments[i];
for (j = 0; j < columns.length; j++) {
currentLetter = currentSegment[j];
columns[j].push(currentLetter);
}
}
for (i = 0; i < columns.length; i++) {
columns[i] = columns[i].join("");
}
return columns.join("");
}
function normalizeCipherText() {
return ciphertext.match(splitRegEx).join(" ");
}
text.innerHTML = plaintextSegments();
encodedChunks.innerHTML = ciphertext();
output.innerHTML = normalizeCipherText();
}
<form>
<input type="text" placeholder="Type your secret message" id="message">
<p id="alert"></p>
<button type="button" class="button" onclick="encodeMessage()">Encode message</button>
</form>
<div class="box">
<h3>Normalised Text</h3>
<p id="normalized_text"></p>
</div>
<div class="box">
<h3>Encoded Chunks</h3>
<p id="encoded_chunks">
</p>
</div>
<div class="box">
<h3>Encoded Rectangle</h3>
<p id="encoded_rectangle">
</p>
</div>
Most of your code is constructed of very short methods.
Usually I'd consider a good practice, but in this case I think it just made the code less readable.
Additionally, I have to say that the HTML part wasn't necessary in terms of solving the issue - which was clearly Javascript/algorithm related.
This is my solution, which can be modified to match your context:
const input = "If man was meant to stay on the ground, god would have given us roots.";
const normalizedInput = input.replace(/[^\w]/g, "").toLowerCase();
const length = normalizedInput.length;
const cols = Math.ceil(Math.sqrt(length));
const rows = Math.ceil(length / cols);
var cypherText = "";
for (let i = 0; i < cols; i ++) {
for (let j = i; j < normalizedInput.length; j += cols) {
cypherText += normalizedInput[j];
}
cypherText += '\n';
}
console.log(cypherText);
This is what I came up with
const output = document.querySelector('#encoded_rectangle');
const encodedChunks = document.querySelector('#encoded_chunks');
const text = document.querySelector('#normalized_text');
const string = document.querySelector('#message');
const error = document.querySelector('#alert');
const encodeMessage = () => {
let message = string.value;
var normalisedText = message.replace(/[^a-zA-Z0-9]/g, "");
var textCount = normalisedText.length;
if (textCount < 50) {
console.log("Invalid message, Input more than one word and at Least 50 characters!");
return false;
}
var higest = Math.ceil(Math.sqrt(textCount));
var lowest = Math.ceil(textCount/higest);
var rect = [];
var coded = [];
var innerObj = {};
var resulting = "";
rect = rectangleSize(higest,lowest,normalisedText);
//read text from top-down i hotago!!!
coded = readFromTopDown(rect, higest);
coded.forEach(co => {
resulting += co.trim();
});
//nwa idi sharp, nice logic
console.log("Normalized: " + normalisedText);
console.log("Count: " + textCount);
console.log(rect);
console.log(coded);
console.log("Resulting: " + resulting);
function rectangleSize(higest, lowest, normalise) {
var rect = [];
var startIndex = 0;
for(var i = 0; i < lowest; i++){
if(i !== 0)
startIndex += higest;
if(normalise.substring(startIndex, startIndex + higest).length == higest){
rect.push(normalise.substring(startIndex, startIndex + higest))
}else{
//get the remainder as spaces
var spaces = higest - normalise.substring(startIndex, startIndex + higest).length;
var textI = normalise.substring(startIndex, startIndex + higest);
var str = textI + new Array(spaces + 1).join(' ');
rect.push(str);
}
}
return rect;
}
function readFromTopDown(rect, higest) {
var coded = [];
for(var i = 0; i < higest; i++){
var textMain = "";
rect.forEach(re => {
textMain += re.substring(i, i+1);
});
coded.push(textMain);
}
return coded;
}
}
<form>
<input type="text" placeholder="Type your secret message" id="message">
<p id="alert"></p>
<button type="button" class="button" onclick="encodeMessage()">Encode message</button>
</form>
<div class="box">
<h3>Normalised Text</h3>
<p id="normalized_text"></p>
</div>
<div class="box">
<h3>Encoded Chunks</h3>
<p id="encoded_chunks"></p>
</div>
<div class="box">
<h3>Encoded Rectangle</h3>
<p id="encoded_rectangle"></p>
</div>
Try and see

Adding generated values from inputs

I have a site where I can enter the amount of an item, it will then take that input value and return the result on the page. I am then trying to get the results of all the items and return a grand total.
The issue is when I a loop to do this it will only add the first one.
I created a fiddle: https://jsfiddle.net/rc1mgLj5/4/
I am using querySelectorAll and using the length of all the classNames for the result of the first return.
Then looping them after parsing them to a number from text.
But at the moment it is only doing the first calculation. If I delete the for loop the first part works correctly again.
So since its only doing the first calculation for the first item, I get NaN for the second because it does not have a number to parse.
const total = document.querySelectorAll(".tot");
const price = document.querySelectorAll(".cost");
let textval = document.querySelectorAll(".qty-item");
const cal = document.getElementById("calc");
const errorMessage = document.querySelectorAll(".error");
cal.addEventListener("mouseover", function(e) {
console.log(total);
for (var i = 0; i < price.length; i++) {
let xPrice = price[i].innerHTML.split("$");
let parsePrice = parseFloat(xPrice[1]);
if (textval[i].value === "" || isNaN(textval[i].value)) {
setMessage("Please enter a number", "red");
} else {
let x = parseFloat(textval[i].value);
let y = parsePrice;
let z = x * y;
total[i].innerText = z.toFixed(2);
total[i].innerText = z;
for (i = 0; i < total.length; i++) {
let j = parseFloat(total[i].innerHTML);
console.log(j);
}
}
}
});
HTML:
<body>
<div class="main">
<span class="title">A Title</span>
</div>
<div class="content">
<div class="item">
<span>Item 1</span>
</div>
<div>
<span class="cost">$100.00</span>
</div>
<div id="qty">
<label>QTY:</label><input placeholder="0" class="qty-item">
<p class="error"></p>
</div>
<div class="tot">
<span><label>TOTAL</label> $0.0</span>
</div>
</div>
<br><br>
<div class="main">
<span class="title">A Title</span>
</div>
<div class="content">
<div class="item">
<span>Item 2</span>
</div>
<div>
<span class="cost">$50.00</span>
</div>
<div class="qty">
<label>QTY:</label><input placeholder="0" class="qty-item">
<p class="error"></p>
</div>
<div class="tot">
<span><label>TOTAL</label> $0.0</span>
</div>
</div>
<div class="calc-button">
<button id="calc">Calculate Prices</button>
</div>
</body>
You are nesting two fors using the same i variable as index:
cal.addEventListener('mouseover', function(e) {
console.log('total', total);
for (var i = 0; i < price.length; i++) {
//...
for (i = 0; i < total.length; i++) { // <== uses "i" again
let j = parseFloat(total[ii].innerHTML);
console.log(j);
}
}
}
});
Just replace that second for's variable with another name. Example:
for (let k = 0; k < total.length; k++) {
let j = parseFloat(total[k].innerHTML);
console.log(j);
}
Demo: https://jsfiddle.net/acdcjunior/gpLvszx3/
It seems you are using the same variable "i" for both loops and i is being reset in the second loop to 3 and hence the main loop runs only once. So i removed the following code and calculated the total outside main loop. seems to be working fine now. https://jsfiddle.net/uxr7ac9k/7/
total[i].innerText = z;
for (i=0;i < total.length; i++){
let j = parseFloat(total[i].innerHTML);
console.log(j);
}

Bad Javascript Coding and Drop Down Boxes

here is a jsfiddle I made to show you what I'd like help with.
Need help with updating select box values
I've tried using 3 for loop constructs to update my drop down box, but my bad Javascript skills don't let me achieve this.
var units = [
['Volts', 1],
['Millivolts', .001],
['Microvolts', 0.000001]
];
var selectors = document.querySelectorAll('.Voltage');
for (var i = 0; i < units.length; i++) {
for (var j = 0; j < selectors.length; j++) {
var option = document.createElement('option');
option.value = units[i][1];
option.textContent = units[i][0];
selectors[j].add(option);
}
}
var units = [
['Amps', 1],
['Milliamperes', .001],
['Microamperes', 0.000001]
];
var selectors = document.querySelectorAll('.Current');
for (var i = 0; i < units.length; i++) {
for (var j = 0; j < selectors.length; j++) {
var option = document.createElement('option');
option.value = units[i][1];
option.textContent = units[i][0];
selectors[j].add(option);
}
}
var units = [
['Ohms', 1],
['Milliohms', .001],
['Microohms', 0.000001]
];
var selectors = document.querySelectorAll('.Resistance');
for (var i = 0; i < units.length; i++) {
for (var j = 0; j < selectors.length; j++) {
var option = document.createElement('option');
option.value = units[i][1];
option.textContent = units[i][0];
selectors[j].add(option);
}
}
function EqualsVoltage() {
var Voltage = document.getElementById("inputVoltage").value;
var Current = document.getElementById("inputCurrent").value;
var Resistance = document.getElementById("inputResistance").value;
if (Resistance != "0" && Current != "0") {
document.getElementById("inputVoltage").value = parseFloat(Current * Resistance).toExponential();
}
}
function EqualsCurrent() {
var Voltage = document.getElementById("inputVoltage").value;
var Current = document.getElementById("inputCurrent").value;
var Resistance = document.getElementById("inputResistance").value;
if (Voltage != "0" && Resistance != "0") {
document.getElementById("inputCurrent").value = parseFloat(Voltage / Resistance).toExponential();
}
}
function EqualsResistance() {
var Voltage = document.getElementById("inputVoltage").value;
var Current = document.getElementById("inputCurrent").value;
var Resistance = document.getElementById("inputResistance").value;
if (Voltage != "0" && Current != "0") {
document.getElementById("inputResistance").value = parseFloat(Voltage / Current).toExponential();
}
}
<!DOCTYPE html>
<html>
<body>
<br>
<select style="float:left" id="EANDM1" class="js-example-basic-single select2-container Voltage" oninput="EqualsResistance(); EqualsCurrent()" onchange="EqualsResistance(); EqualsCurrent()">
</select>
<label>Voltage:</label>
<input style="height:50%;font-size:15pt;width:1000px; border: 1px solid #000;" id="inputVoltage" type="number" oninput="EqualsResistance(); EqualsCurrent()" value="0"> </p>
<select style="float:left" id="EANDM2" class="js-example-basic-single select2-container Current" oninput="EqualsVoltage(); EqualsResistance()" onchange="EqualsVoltage(); EqualsResistance()">
</select>
<p>
<label>Current:</label>
<input style="height:50%;font-size:15pt;width:1000px; border: 1px solid #000;" id="inputCurrent" type="number" oninput="EqualsVoltage(); EqualsResistance()" value="0"> </p>
<select style="float:left" id="EANDM3" class="js-example-basic-single select2-container Resistance" oninput="EqualsCurrent();EqualsVoltage()" onchange="EqualsCurrent();EqualsVoltage()">
</select>
<p>
<label>Resistance:</label>
<input style="height:50%;font-size:15pt;width:1000px; border: 1px solid #000;" id="inputResistance" type="number" oninput="EqualsCurrent();EqualsVoltage()" value="0"> </p>
</body>
</html>
When I switch to millivolts in the drop down box, the values for Current and Resistance should change after I've filled in 2 values in their respective drop down boxes. Please help me get the drop down box to change the values for the input fields. Thank you.
There's a couple problems.
parseFloat(Current * Resistance)
This doesn't work because Current and Resistance are strings, but you're multiplying them before you parse them. Instead, parse them before you multiply them:
parseFloat(Current) * parseFloat(Resistance)
Another problem, related to the recalculation when selecting something from one of the drop-down boxes, is that you aren't pulling out or using the factors. So the units never change.
Here is a quick tidying up I did of the calculation code that takes into account the selected units and converts values before doing the calculation. (I also removed the toExponential calls to see what was happening a bit more easily.)
Extracted the code that gets the values from the controls to its own function. This could still be improved further.
function GetValues() {
const voltageText = document.getElementById("inputVoltage").value;
const currentText = document.getElementById("inputCurrent").value;
const resistanceText = document.getElementById("inputResistance").value;
const voltageFactorText = document.getElementById("EANDM1").value;
const currentFactorText = document.getElementById("EANDM2").value;
const resistanceFactorText = document.getElementById("EANDM3").value;
const voltageValue = parseFloat(voltageText);
const currentValue = parseFloat(currentText);
const resistanceValue = parseFloat(resistanceText);
const voltageFactor = parseFloat(voltageFactorText);
const currentFactor = parseFloat(currentFactorText);
const resistanceFactor = parseFloat(resistanceFactorText);
const voltage = voltageValue / voltageFactor;
const current = currentValue / currentFactor;
const resistance = resistanceValue / resistanceFactor;
return [voltage, current, resistance];
}
And then the three recalculation functions:
function EqualsVoltage() {
const [voltage, current, resistance] = GetValues();
if (!resistance || !current)
return;
document.getElementById("inputVoltage").value = current * resistance;
}
function EqualsCurrent() {
const [voltage, current, resistance] = GetValues();
if (!voltage || !resistance)
return;
document.getElementById("inputCurrent").value = voltage / resistance;
}
function EqualsResistance() {
const [voltage, current, resistance] = GetValues();
if (!voltage || !current)
return;
document.getElementById("inputResistance").value = voltage / current;
}

append method is not working in for loop

I have multiple json object and each object have multiple same, For example:
A->
- A1
-A1A
-A1A
- A2
-A2A
-A2A
- A3
-A3A
-A3A
I have tired to execute in below code but it's not working. Can you please suggest me what is the issue in my code?
subscriptionbarMyData = JSON.parse(window.localStorage.getItem('subscriptionBarJson'));
$('.total-month-cost-product-header-names').text('').addClass('hidden');
for (var key in subscriptionbarMyData) {
if (subscriptionbarMyData.hasOwnProperty(key)) {
var val = subscriptionbarMyData[key];
$('.total-month-cost-product-header')
.find('.total-month-cost-product-header-names')
.removeClass('hidden')
.addClass('show')
.text(val.Name + val.ProductPrice);
var addonvalue = subscriptionbarMyData[key]["Add-on"];
for (var keyval in addonvalue) {
if (addonvalue != undefined) {
var TotalOneCostProduct = $('.total-month-cost-product-items').text('');
for (var keyval in addonvalue) {
// var dataValues = addonvalue[keyval].Name;
$('.total-month-cost-product-header-names')
.text(addonvalue[keyval].Name)
.appendTo(TotalOneCostProduct);
}
}
}
}
}
<div class="summary-block">
<div class="total-month-cost-summary">
<div class="total-month-cost-product-header">
<div class="total-month-cost-product-header-names"></div>
<div class="total-month-cost-product-header-price"></div>
</div>
<div class="total-month-cost-product-items">
<div class="total-month-cost-product-item-names"></div>
<div class="total-month-cost-product-item-price"></div>
</div>
</div>
</div>

code that displays words, JS Jquery

Code Link: http://jsbin.com/lozifokuzi/1/edit?html,js,output should display 16 words but it displays only 15 words (The words written in Hebrew).
The code is written in languages ​​JavaScript and jQuery.
$(document).ready(function () {
// creat array of objects, DetermineIDs
var words = new Array(16);
for (var i = 0; i < words.length; i++) {
words[i] = new Object();
words[i].id = i + 1;
}
//insert into objects words
words[0].word = "קוף";
words[1].word = "קוף";
words[2].word = "אריה";
words[3].word = "אריה";
words[4].word = "נמר";
words[5].word = "נמר";
words[6].word = "טלפון";
words[7].word = "טלפון";
words[8].word = "מחשב";
words[9].word = "מחשב";
words[10].word = "מקלדת";
words[11].word = "מקלדת";
words[12].word = "אוגר";
words[13].word = "אוגר";
words[14].word = "עכבר";
words[15].word = "עכבר";
//Determine locations
var ret=Random(loc);
var random = 0;
for (var i = 0; i < words.length; i++) {
words[i].loca=ret[0];
loc=ret[1];
ret = Random(loc);
}
//write the words
for (var i = 0; i < 16; i++) {
$("#c" + (words[i].loca)).html(words[i].word);
}
});
function RandomC(ezer, random) {
for (var i = 0; i <= 16; i++) {
if (ezer[i] == random) {
return true;
}
}
return false;
}
function Random(lq) {
var ezer = new Array(16);
for (var i = 0; i < 16; i++) {
ezer[i] = lq[i];
}
var random = 0;
while ((random < 1 || random > 17) || RandomC(ezer, random)) {
random = parseInt(Math.random() * 100);
}
for (var i = 0; i < lq.length; i++) {
if (lq[i] == null) {
ezer[i] = random;
break;
}
}
var arr = new Array(2);
arr[0] = random;
arr[1] = ezer;
return arr;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<title></title>
</head>
<body>
<article>
<div id="l1">
<p id="c1"></p>
<p id ="c2"></p>
<p id="c3"></p>
<p id="c4"></p>
</div>
<div id="l2">
<p id="c5"></p>
<p id="c6"></p>
<p id="c7"></p>
<p id="c8"></p>
</div>
<div id="l3">
<p id="c9"></p>
<p id="c10"></p>
<p id="c11"></p>
<p id="c12"></p>
</div>
<div id="l4">
<p id="c13"></p>
<p id="c14"></p>
<p id="c15"></p>
<p id="c16"></p>
</div>
</article>
</body>
</html>
Can anyone help?
You have 17 in funciton Random() while loop:
while ((random < 1 || random > 17) || RandomC(ezer, random))
{
random = parseInt(Math.random() * 100);
}
make it 16:
while ((random < 1 || random > 16) || RandomC(ezer, random))
{
random = parseInt(Math.random() * 100);
}
You problem is that you have 16 element from 1 to 16, and your random function gives 16 random numbers from 1 to 17, in case returned range has number 17 it lacks something from 1 to 16, which means your p element of that nubmer doesn't get filled with content.

Categories

Resources