How to properly distribute js code for php foreach? - javascript

Have php foreach in file
<?php
foreach($_SESSION['cart'] as $item):
$sqlcartprod = mysqli_query(db(),"SELECT * FROM products WHERE id='".$item['product']."' ");
$rowcartprod = mysqli_fetch_array($sqlcartprod);
?>
<tr>
<td class="shoping__cart__item">
<img src="<?=$rowcartprod['ikonka']?>" width="101" alt="">
<h5><?=$rowcartprod['name_'.$lang]?></h5>
</td>
<td class="shoping__cart__price" >
<span id="priceprod"><?=$rowcartprod['price']?></span> azn
</td>
<td class="shoping__cart__quantity">
<div class="quantity">
<div class="pro-qty">
<input type="text" style="cursor: default" readonly value="<?=$item['qty']?>">
</div>
</div>
</td>
<td class="shoping__cart__total" id="totalprice">
<?=$item['price']*$item['qty']?> azn
</td>
</tr>
<?php endforeach; ?>
for this piece of code:
<div class="quantity">
<div class="pro-qty">
<input type="text" style="cursor: default" readonly value="<?=$item['qty']?>">
</div>
</div>
have JS code:
var proQty = $('.pro-qty');
proQty.prepend('<span class="dec qtybtn">-</span>');
proQty.append('<span class="inc qtybtn">+</span>');
proQty.on('click', '.qtybtn', function () {
var $button = $(this);
var oldValue = $button.parent().find('input').val();
if ($button.hasClass('inc')) {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below zero
if (oldValue > 0) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 0;
}
}
$button.parent().find('input').val(newVal);
var Price = document.getElementById('priceprod').innerText;
var Tprice = document.getElementById('totalprice');
if (Price[i] > 0) {
Tprice.textContent = (Price[i] * newVal) + ' azn';
}
});
The issue is that when I click on qtybtn + or qtybtn -, the js code works only for the first product in the shopping list, even if there are 2,3 or more products in the list. I tried to separate inside the js code with loops, but then the js code somehow stops working at all. How to distribute correctly so that the js code works for each product separately?

Related

Skill stats are changing in a weird way

My problem: skill stats are changing in a weird way
They are changing in all fields not one.
The numbers are weird.Output is 1, 111112 and 1.111121111121111e+35, instead of 1, 2, 3, ...
My js code:
var skillcount = 15;
// Dodawanie umiejętności
$('.skill-plus div img').click(function() {
if (skillcount > 0) {
var new_skillstat = parseInt($('td.skill-plus').closest('.skill-stat').text(),0) + 1;
$('td.skill-plus').closest('.skill-stat').text(new_skillstat);
$('.skill-item').val(new_skillstat);
skillcount--;
$('.abilities').text(skillcount);
$('.register-abilities').val(skillcount);
}
});
HTML:
<?php
$showSkills = $databasecon->getSome('*', 'skills', 'skill_cat', 0);
while($showSkill = mysqli_fetch_array($showSkills)) {
?>
<tr class="ability-record">
<td><?php echo $showSkill['skill_name']; ?></td>
<td class="skill-stat">0</td>
<td class="skill-plus">
<div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>
<td class="skill-minus">
<div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
<input type="hidden" name="skill-<?php echo $showSkill['id']; ?>" class="skill-item" value="0">
</td>
</td>
</tr>
<?php
}
?>
It is a bit more complex than you thought
I delegate from the ability record
I do not allow to go negative on skill
Your HTML is invalid
var skillcount = 15;
// Dodawanie umiejętności
$('.ability-record img').on('click', function() {
const $row = $(this).closest('tr');
const skillValue = $(this).closest('div').is('.stat-plus') ? 1 : -1
let new_skillstat = +$row.find('.skill-stat').text() + skillValue;
if (new_skillstat < 0) return; // negative
$row.find('.skill-stat').text(new_skillstat);
$row.find('.skill-item').val(new_skillstat);
skillcount += skillValue * -1; // invert
$('.abilities').text(skillcount);
// $('.register-abilities').val(skillcount);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr class="ability-record">
<td>
Skill 1
</td>
<td class="skill-stat">0</td>
<td class="skill-plus">
<div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>
<div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
<input type="hidden" name="skill-skill-1" class="skill-item" value="0" />
</td>
</tr>
<tr class="ability-record">
<td>
Skill 2
</td>
<td class="skill-stat">0</td>
<td class="skill-plus">
<div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>
<div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
<input type="hidden" name="skill-skill-1" class="skill-item" value="0">
</td>
</tr>
</tbody>
</table>
<span class="abilities"></span>
I wanted to stop when using too much skillCount but this did not work as I thought
const sum = $('.skill-stat')
.map(function() { return +this.textContent})
.get()
.reduce((a,b)=>a+b)
if (skillcount-sum <= 0) return; // negative

How I get values updating/refreshing related input areas in Javascript?

I have a form and when I press the Try button it returns values for the 3rd and 6th input fields of the form according to the values entered in 1,2 and 5.6. Also, the 7th input field combines the 3rd and 6th results.
My question is how can I get the result values from input fields 3 and 6 without clicking the Try It button and also update the input field 7 without refreshing the page?
My code is in JSFiddle UPDATED !!
My Javascript are:
<script type="text/javascript">
function concatenate(/*String*/string_one, /*String*/string_two, /*boolean*/with_space) {
if (with_space===true) {
return string_one+'/'+string_two;
}
else {
return string_one+string_two;
}
}
function join_names() {
var input_name_first = document.getElementsByName('ht')[0].value;
var input_name_last = document.getElementsByName('ft')[0].value;
var input_name_full = document.getElementsByName('htft')[0];
var var_name_full = concatenate(input_name_first, input_name_last, true);
input_name_full.value = var_name_full;
}
</script>
<script type="text/javascript">
function myFunctionFt() {
var home = document.getElementById("home_score").value;
var away = document.getElementById("away_score").value;
var results;
if (home > away) {
results = "1";
} else if (home < away) {
results = "2";
} else if (home = away) {
results = "X";
}
document.getElementById("ft").value = results;
}
</script>
<script type="text/javascript">
function myFunctionHt() {
var home = document.getElementById("home_ht_score").value;
var away = document.getElementById("away_ht_score").value;
var results;
if (home > away) {
results = "1";
} else if (home < away) {
results = "2";
} else if (home = away) {
results = "X";
}
document.getElementById("ht").value = results;
}
</script>
I have removed all the previous answers from this answer and added a new answer in place. I have read your last comment and you said that my code was not working for the Home Team HT Score and Away Team HT Score. Well, I had made the logic to behave this way because it makes more sense to put the result in HT Result once both of the teams have played or in other words when we have both of the inputs. In sports, it rarely happens that only one team plays. Right. So outputting the result in HT result based on one of the inputs makes no sense. But if this is what you want, you simply have to change the logic from if (!input_home || !input_away) return; to if (!input_home && !input_away) return; and it will start working the way you want. Basically in the first logic statement with "||" we are saying unless both of the inputs are available don't out into HT result and in the second statement with && we are saying id doesn't matter if one of them is not present, just take whatever is present and output it in HT result. The same thing is happening for FT. You just have to change || to &&.
Here is the final working code:
//FT and HT Result//
let name_first = document.getElementById('ht');
let name_last = document.getElementById('ft');
let input_name_first = name_first.value;
let input_name_last = name_last.value;
//HT Home//
let home = document.getElementById("home_ht_score");
let away = document.getElementById("away_ht_score");
home_ht_score.addEventListener("input", myFunctionHt);
away_ht_score.addEventListener("input", myFunctionHt);
let input_away = away.value;
let input_home = home.value;
//FT Home//
let home_ft = document.getElementById("home_score");
let away_ft = document.getElementById("away_score");
home_score.addEventListener("input", myFunctionFt);
away_score.addEventListener("input", myFunctionFt);
let input_ft_away = away_ft.value;
let input_ft_home = home_ft.value;
function myFunctionHt() {
input_away = away.value;
input_home = home.value;
input_name_first = name_first.value;
input_name_last = name_last.value;
if (!input_home && !input_away) return;
var results = "";
if (input_home > input_away) {
results = "1";
} else if (input_home < input_away) {
results = "2";
} else if (input_home = input_away) {
results = "X";
}
document.getElementById("ht").value = results;
join_names();
}
function myFunctionFt() {
input_ft_away = away_ft.value;
input_ft_home = home_ft.value;
input_name_first = name_first.value;
input_name_last = name_last.value;
if (!input_ft_home && !input_ft_away) return;
var results = "";
if (input_ft_home > input_ft_away) {
results = "1";
} else if (input_ft_home < input_ft_away) {
results = "2";
} else if (input_ft_home = input_ft_away) {
results = "X";
}
document.getElementById("ft").value = results;
join_names();
}
function join_names() {
if (!input_name_first && !input_name_last) return;
let input_name_full = document.getElementsByName('htft')[0];
var var_name_full = concatenate(name_first.value, name_last.value, true);
input_name_full.value = var_name_full;
}
function concatenate(/*String*/string_one, /*String*/string_two, /*boolean*/with_space) {
if (with_space===true) {
return string_one+'/'+string_two;
}
else {
return string_one+string_two;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<form class="form-group" action="addemp" method="post" onsubmit="return true" onClick="return false">
<table border="0" cellpadding="1">
<tbody>
<tr>
<td> <label class="form-label" style="color:blue" for="name">Home Team HT Score</label> </td>
<td> <input id="home_ht_score" name="home_ht_score" type="text" class="form-control mb-3" style="width: 200px;"></td>
</tr>
<tr>
<td> <label class="form-label" style="color:red" for="name">Away Team HT Score</label> </td>
<td> <input id="away_ht_score" name="away_ht_score" type="text" class="form-control mb-3" style="width: 200px;"></td>
</tr>
<tr>
<td><label class="form-label" style="color:green" for="name">HT Result</label> </td>
<td> <input id="ht" name="ht" type="text" class="form-control mb-3" oninput="join_names();" onpaste="join_names();" style="width: 200px;"></td>
</tr>
<tr>
<td><label class="form-label" style="color:blue" for="name">Home FT Score</label> </td>
<td> <input id="home_score" name="home_score" type="number" class="form-control mb-3" style="width: 200px;"></td>
</tr>
<tr>
<td><label class="form-label" style="color:red" for="name">Away FT Score</label> </td>
<td> <input id="away_score" name="away_score" type="number" class="form-control mb-3" style="width: 200px;"></td>
</tr>
<tr>
<td> <label class="form-label" style="color:green" for="name">FT Result</label> </td>
<td> <input id="ft" name="ft" type="text" class="form-control mb-3" onchange="join_names();" onpaste="join_names();" style="width: 200px;"></td>
</tr>
<tr>
<td><label class="form-label" style="color:green" for="name">HT/FT</label> </td>
<td> <input name="htft" type="text" class="form-control mb-3" style="width: 200px;"> </td>
</tr>
<tr>
<td> </td>
<td><button class="btn btn-primary mb-4" type="submit">Save Match Result</button> </td>
</tr>
</tbody>
</table>
</form>
</body>
</html>

JavaScript Total Cost after deleting Item

I have foreached some items that I sell :
<?php foreach ($selectedItems as $item): ?>
<tr class="product" data-price="<?= $item->price ?>">
<th class="items"><?= $item->name ?></th>
<th id="price" class="items middle-th "> <!-- the 3rd column -->
<div >
<button type="button" class="sub" title="If u want less quantity">-</button>
<input class="quantityTxt quantity " id="quantity" name="quantity[]" type="text" value="1" onchange="quantityChange(this)" >
<button type="button" class="add" title="If u want more quantity" >+</button>
</div>
</th>
<th>
<span class="productTotal"></span>
</th>
<th id="price" class="items">
<button class="remove_field" data-value="<?= $item->price ?>" title="Click to delete product" >
<div class="glyphicon glyphicon-trash" ></div>
</button>
</th>
</tr>
<?php endforeach; ?>
</table>
<div class="row-fluid well">
<strong id="total"> Total: € <span id="sum"> </span> </strong></div>
<div class="payment">
I set onClick to delete the row after the button is pressed so to delete the rows so I need when I delete the row , to minus the total cost of the product form the total sum . Later is my Script Code where I have all of the things ,but I left only to minus from Total the Cost of the deleted row .
$('table').on('click', 'button.remove_field', function () {
$(this).closest('tr').remove();
var id = $(this).attr('data-value');
console.log(id);
});
$('.add').click(function () {
var target = $('.quantity', this.parentNode)[0];
target.value = +target.value + 1;
updateTotal();
});
$('.sub').click(function () {
var target = $('.quantity', this.parentNode)[0];
if (target.value > 1) {
target.value = +target.value - 1;
}
updateTotal();
});
var updateTotal = function () {
var sum = 0;
//Add each product price to total
$(".product").each(function () {
var price = $(this).data('price');
var quantity = $('.quantityTxt', this).val();
//Total for one product
var subtotal = price * quantity;
//Round to 2 decimal places.
subtotal = subtotal.toFixed(2);
//Display subtotal in HTML element
$('.productTotal', this).html(subtotal);
});
// total
$('.productTotal').each(function () {
sum += Number($(this).html());
});
$('#sum').html(sum.toFixed(2));
};
//Update total when quantity changes
$(".product").keyup(function () {
updateTotal();
});
//Update totals when page first loads
updateTotal();
// set this from local
$('span.productTotal').each(function () {
$(this).before("€");
});
// unit price
$('.product').each(function () {
var $price = $(this).parents("div").data('price');
$(this).before($price);
});

quantity and remove item in shopping cart

I made the "items" from the shop to be stored in unique array in session and to be passed on the shopping cart , and I want to put quantity for each item and if I want to delete item from the shopping cart to be deleted from the array . I made the html form and quantity buttons for "plus" and "minus" , but I cant figure out how to catch the value in the input when its changed with the buttons and then to multiply it with the cost of each item so later I can get total cost ( In the code it can be seen that I set value="1" for each item , so the base value for each item is 1 ) . I made also with JS to remove the row from deleted item that I want but also didnt figure out how to delete the item from the array
This is my shopping cart :
<div class="container">
<div class="jumbotron">
<div class="container text-center">
<h3>Shopping Cart</h3>
<table class="table table-striped" >
<tr>
<th class="items" > Product </th>
<th class="items"> Quantity </th>
<th class="items"> Unit Price </th>
<th>Total Cost</th>
<th></th>
</tr>
<?php foreach ($selectedItems as $item): ?>
<tr>
<th class="items"><?= $item->name ?></th>
<th class="items ">
<div>
<button type="button" class="sub" title="If u want less quantity">-</button>
<input type="text" value="1" id="quantity" class="quantity" name="quantity[]" onchange="quantityChange(this)" >
<button type="button" class="add" title="If u want more quantity" >+</button>
</div>
</th>
<th id="price" class="items"> <?= $item->price ?></th>
<th><span class="allcost"> </span></th>
<th class="items">
<button class="remove_field " title="Click to delete product" >
<div class="glyphicon glyphicon-trash" ></div>
</button>
</th>
</tr>
<?php endforeach; ?>
</table>
<?= Html::a('Return to Shop', ['/stock/shop'], ['class' => 'btn btn-default']) ?>
<?= Html::a('Checkout', ['/stock/checkout'], ['class' => 'btn btn-default']) ?>
</div>
</div>
<script type="text/javascript">
$(document).on('click', 'button.remove_field', function () {
$(this).closest('tr').remove();
});
$('.add').click(function () {
var target = $('.quantity', this.parentNode)[0];
target.value = +target.value + 1;
target.onchange();
});
$('.sub').click(function () {
var target = $('.quantity', this.parentNode)[0];
if (target.value > 1) {
target.value = +target.value - 1;
}
target.onchange();
});
function quantityChange(sender) {
var quantity = $(sender).val();
console.log(quantity);
};
My ActionCart :
public function actionCart() {
Yii::$app->session->open();
Yii::$app->session->open();
$selectedItems = Yii::$app->session['selectedItems'];
$stockItems = Stock::find()->where(['id' => $selectedItems])->all();
$data = [
'selectedItems' => $stockItems,
];
return $this->render('cart', $data);
}
Quantity and Cost solution :
In the HTML code :
<?php foreach ($selectedItems as $item): ?>
<tr class="product" data-price="<?= $item->price ?>">
<th class="items"><?= $item->name ?></th>
<th id="price" class="items middle-th "> <!-- the 3rd column -->
<div >
<button type="button" class="sub" title="If u want less quantity">-</button>
<input class="quantityTxt quantity " id="quantity" name="quantity[]" type="text" value="1" onchange="quantityChange(this)" >
<button type="button" class="add" title="If u want more quantity" >+</button>
</div>
</th>
<th>
<span class="productTotal"></span>
</th>
<th id="price" class="items ">
<button class="remove_field " data-value="<?= $item->id ?>" title="Click to delete product" >
<div class="glyphicon glyphicon-trash" ></div>
</button>
</th>
</tr>
<?php endforeach; ?>
JavaScript Code :
$('.add').click(function () {
var target = $('.quantity', this.parentNode)[0];
target.value = +target.value + 1;
updateTotal();
});
$('.sub').click(function () {
var target = $('.quantity', this.parentNode)[0];
if (target.value > 1) {
target.value = +target.value - 1;
}
updateTotal();
});
function quantityChange(sender) {
var quantity = $(sender).val();
console.log(quantity);
}
;
var updateTotal = function () {
var sum = 0;
//Add each product price to total
$(".product").each(function () {
var price = $(this).data('price');
var quantity = $('.quantityTxt', this).val();
//Total for one product
var subtotal = price * quantity;
//Round to 2 decimal places.
subtotal = subtotal.toFixed(2);
//Display subtotal in HTML element
$('.productTotal', this).html(subtotal);
});
// total
$('.productTotal').each(function () {
sum += Number($(this).html());
});
$('#sum').html(sum.toFixed(2));
};
//Update total when quantity changes
$(".product").keyup(function () {
updateTotal();
});
//Update totals when page first loads
updateTotal();
// set this from local
$('span.productTotal').each(function () {
$(this).before("€");
});
// unit price
$('.product').each(function () {
var $price = $(this).parents("div").data('price');
$(this).before($price);
});

php codeigniter - managing values in multi select box

I am working on a multibox as a part of my codeigniter based project, here I am trying to move the values across the boxes using custom js code shared below
The values shown in first box are fetched from db when page loads and used to move the required values to second box using javascript. My goal it that the values already moved to second box should not be visible in the first box after saving the data and at the same time source data for the first box should not be altered.
Right now I am able to select the values to second box and save successfully but when I load the page again after saving I am seeing the moved values in the fist box and this is visually creating duplication of values and would confuse the user. On the other hand if I try to move back the values to the first box which is creating a conflict while saving the data.
Is there any way I could change my code so that moved values will not be available in the first box again
HTML version of multibox
<fieldset class="emp_contact">
<legend>Area Allocation</legend>
<div class="form-group input-group">
<table width="100%" border="0" cellpadding="10" cellspacing="10" style="border:1px solid #ccc">
<tr>
<td width="40%">
<p>Available Areas</p>
</td>
<td width="12%"> </td>
<td width="40%">
<p>Selected Areas</p>
</td>
</tr>
<tr>
<td valign="top" id="myarea_list">
<?php echo $aval_area_list ?>
</td>
<select name="aval_id_temp" id="aval_id_temp" multiple style="display:none"></select>
<td>
<table width="100%" border="0">
<tr>
<td align="center">
<input type="Button" value=">>" onClick="SelectMoveRows_all(document.form.avail_area, document.form.selec_area)">
<br>
<br />
<input type="Button" value=">" onClick="SelectMoveRows(document.form.avail_area, document.form.selec_area)">
<br>
<br>
<input type="Button" value="<<" onClick="SelectMoveRows_all(document.form.selec_area, document.form.avail_area)">
<br>
<br>
<input type="Button" value="<" onClick="SelectMoveRows(document.form.selec_area, document.form.avail_area)">
</td>
</tr>
<tr>
<td align="center"> </td>
</tr>
</table>
</td>
<td valign="top">
<?php echo $sel_area_list ?>
<select name="sel_id_temp" id="sel_id_temp" multiple style="display:none"></select>
</td>
</tr>
</table>
</div>
</fieldset>
Javascript functions used
function SelectMoveRows_all(SS1, SS2) {
var SelID = '';
var SelText = '';
// Move rows from SS1 to SS2 from bottom to top
for (i = SS1.options.length - 1; i >= 0; i--) {
//if (SS1.options[i].selected == true)
{
SelID = SS1.options[i].value;
SelText = SS1.options[i].text;
var newRow = new Option(SelText, SelID);
SS2.options[SS2.length] = newRow;
SS1.options[i] = null;
for (j = SS2.options.length - 1; j >= 0; j--) {
SS2.options[j].selected = true;
}
}
}
SelectSort(SS2);
}
function SelectMoveRows(SS1, SS2) {
var SelID = '';
var SelText = '';
// Move rows from SS1 to SS2 from bottom to top
for (i = SS1.options.length - 1; i >= 0; i--) {
if (SS1.options[i].selected == true) {
SelID = SS1.options[i].value;
SelText = SS1.options[i].text;
var newRow = new Option(SelText, SelID);
SS2.options[SS2.length] = newRow;
SS1.options[i] = null;
for (j = SS2.options.length - 1; j >= 0; j--) {
SS2.options[j].selected = true;
}
}
}
SelectSort(SS2);
}
function SelectSort(SelList) {
var ID = '';
var Text = '';
for (x = 0; x < SelList.length - 1; x++) {
for (y = x + 1; y < SelList.length; y++) {
if (SelList[x].text > SelList[y].text) {
// Swap rows
ID = SelList[x].value;
Text = SelList[x].text;
SelList[x].value = SelList[y].value;
SelList[x].text = SelList[y].text;
SelList[y].value = ID;
SelList[y].text = Text;
}
}
}
}

Categories

Resources