Yii2-dynamicforms and javascript - javascript

I have wbraganca dynamic forms working in Yii2, but I need to add a little function to multiply 2 fields and put value in a third, and do that in every new dynamic form (suppose field 1 is price, field 2 is amount and field 3 is total).
With the code I have I'm able to do that but only on the first dynamic form.
<?php
$script = <<< JS
$('#itemsfactura-{$i}-cantidad').change(function(){
var cantidad = $(this).val();
var precio = $('#itemsfactura-{$i}-precio').val();
$('#itemsfactura-{$i}-total_item').val(cantidad * precio);
});
JS;
$this->registerJs($script);
?>
This is the code for the dynamic form fields:
...
<div class="row">
<div class="col-sm-4">
<?= $form->field($modelItemFactura, "[{$i}]precio")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelItemFactura, "[{$i}]cantidad")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelItemFactura, "[{$i}]total_item")->textInput(['maxlength' => true]) ?>
</div>
</div>...

Form
<div class="col-sm-4">
<?= $form->field($modelItemFactura, "[{$i}]precio")->textInput(['maxlength' => true, 'onchange' => 'getProduct($(this))', 'onkeyup' => 'getProduct($(this))']) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelItemFactura, "[{$i}]cantidad")->textInput(['maxlength' => true, 'onchange' => 'getProduct($(this))', 'onkeyup' => 'getProduct($(this))']) ?>
</div>
JS
function getProduct(item) {
var index = item.attr("id").replace(/[^0-9.]/g, "");
var total = current = next = 0;
var id = item.attr("id");
var myString = id.split("-").pop();
if(myString == "precio") {
fetch = index.concat("-cantidad");
} else {
fetch = index.concat("-precio");
}
temp = $("#itemsfactura-"+fetch+"").val();
if(!isNaN(temp) && temp.length != 0) {
next = temp;
}
current = item.val();
if(isNaN(current) || current.length == 0) {
current = 0;
}
if(!isNaN(current) && !isNaN(next)) {
total = parseInt(current) * parseInt(next);
}
totalItem = "itemsfactura-".concat(index).concat("-total_item");
$("#"+totalItem+"").val(total);
}

Related

why ajax duplicate content

Hello I am new here and working on a project that requires this option of "Viewing content in DIV .posts_area, from database using AJAX",
I had a problem that the content I get in .posts_area sometimes duplicate itself.
Can anyone help me with the solution and I would also be happy for more detailed explanation about the subject.
// AJAX in
<script type="text/javascript">
$(document).ready(function() {
var flag = 0;
$.ajax({
type: 'GET',
url: 'getData.php',
data: {
'offset': 0,
'limit': 6
},
async: true,
success: function(data) {
$('.posts_area').append(data);
flag += 3;
}
});
$(window).scroll(function() {
if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
$.ajax({
type: 'GET',
url: 'getData.php',
data: {
'offset': flag,
'limit': 5
},
success: function(data) {
$('.posts_area').append(data);
flag += 3;
}
});
}
});
});
</script>
//getData.php
<?php
include ('config/config.php');
include 'includes/classes/user.php';
include 'includes/classes/post.php';
if(isset($_GET['offset']) && isset($_GET['limit'])){
$limit = $_GET['limit'];
$offset = $_GET['offset'];
$data = mysqli_query($con,"SELECT * FROM posts WHERE deleted='no' ORDER by id DESC LIMIT {$limit} OFFSET {$offset} ");
if(mysqli_num_rows($data ) > 0) {
while($row = mysqli_fetch_array($data) ){
$id = $row['id'];
$comments_check = mysqli_query($con, "SELECT * FROM comments WHERE post_id='$id'");
$comments_check_num = mysqli_num_rows($comments_check);
?>
<script>
function myFunction<?php echo $id; ?>() {
var x = document.getElementById("toggleComment<?php echo $id; ?>");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
</script>
<?php
$added_by_user = $row['added_by_user'];
$post_profile_pic = $row['post_profile_pic'];
$added_by = $row['added_by'];
$body = $row['body'];
$date_time = $row['date_added'];
$user_session = $_SESSION['user'];
if($user_session == $added_by_user)
$delete_button = "<form action = 'delete_post.php?id=$id' method='POST' id = 'delete_post_id_form'>
<input type ='submit' class = 'delete_post_class_input' id = 'delete_post_id_input' value = 'Delete'></input>
</form>";
else
$delete_button = "";
// if($user_session == $added_by_user)
// $update_button = "<form action = 'update_post.php?post_id=$id' method='POST'>
// <input type ='submit' class = 'update_post_class' id = 'update_post_id' value = 'Update'></input>
// </form>";
// else
// $update_button = "";
$str .= "<div class='status_post' >
<div class='on_post_profile_pic_class' id = 'on_post_profile_pic_id'>
<a href='$added_by_user' class='posted_by_on_img'><img src='$post_profile_pic' width='50' id = 'on_post_profile_img_id'></img></a>
</div>
<div class='posted_by1' id='added_by_on_post' style='color:#ACACAC;'>
<a href='$added_by_user' class='posted_by'> $added_by </a>
</div>
<img src='assets/images/icons/more_info_button_black_down.png' onClick='show_hide()'alt='more_info_on_post_button_black_down_button_alt' class='more_info_on_post_button_black_down_btn' id ='more_info_on_post_button_black_down_btn_id' name ='more_info_name'></img>
<img src='assets/images/icons/more_info_button_black_up.png' alt='more_info_on_post_button_black_up_button_alt' class='more_info_on_post_button_black_up_btn' id ='more_info_on_post_button_black_up_btn_id'></img>
<div class = 'date_added_on_post_class' id = 'date_added_on_post_id'>$date_time</div>
<div class = 'update_post_class' id = 'update_post_id'>$update_button</div>
<div class = 'delete_post_class_div' id = 'delete_post_id'>$delete_button</div>
<div id='post_body' dir=auto>
$body
</div>
</div>
</div>
<div class='span_class' id='span_id' onclick='myFunction$id()' >Comments($comments_check_num) </div>
<hr>
<div class='post_comment' id='toggleComment$id' >
<iframe src='comment_frame.php?post_id=$id' class = 'comment_iframe_class' id='comment_iframe' frameborder='0'></iframe>
</div>
<hr class ='hr'>";
}
echo $str;
}
}
?>
$('.posts_area').html(data);
Use this instead of append()

Showing price on click input type="radio"?

[Product listing with clickable inputs][1]
i'm building a webshop system, and i would like to see on the product page that if a user selects a product size, the price will be displayed of the selected size..
Only the last displayed input works when i click on it.
Product listing with size inputs: https://i.stack.imgur.com/Wo6Oq.png
<?php
$count = 0;
foreach($original_array as $order_list){
$count++;
if($order_list['aantal'] == 0 || $order_list['aantal'] == ''){
$disableValue = 'disable';
}
if($count == 2){
$checked = 'checked=""';
}
?>
<div class="sc-item">
<input type="radio" name="variatie_maat[]" value="<?=$order_list['maat'];?>" onclick="myFunction();" id="<?=$order_list['maat'];?>-maat" <?=$disableValue;?> <?=$checked;?>>
<label for="<?=$order_list['maat'];?>-maat"><?=$order_list['maat'];?></label>
<input style="display:none;" value="<?=$order_list['prijs'];?>" id="prijs-<?=$order_list['prijs'];?>" name="variatie_prijs[]">
</div>
<?php
}
?>
<script>
// Here the value is stored in new variable x
function myFunction() {
var x =
document.getElementById("prijs-<?=$order_list['prijs'];?>").value;
document.getElementById(
"price").innerHTML = x;
}
</script>
'''
Try this.
<?php
$count = 0;
foreach($original_array as $order_list){
$count++;
if($order_list['aantal'] == 0 || $order_list['aantal'] == ''){
$disableValue = 'disable';
}
if($count == 2){
$checked = 'checked=""';
}
?>
<div class="sc-item">
<input type="radio" name="variatie_maat[]" value="<?=$order_list['maat'];?>" onclick="myFunction('<?=$order_list['prijs'];?>');" id="<?=$order_list['maat'];?>-maat" <?=$disableValue;?> <?=$checked;?>>
<label for="<?=$order_list['maat'];?>-maat"><?=$order_list['maat'];?></label>
<input style="display:none;" value="<?=$order_list['prijs'];?>" id="prijs-<?=$order_list['prijs'];?>" name="variatie_prijs[]">
</div>
<?php
}
?>
<script>
function myFunction(id) {
var x = document.getElementById("prijs-" + id).value;
document.getElementById("price").innerHTML = x;
}
</script>

How to preview images before upload with php,mysql [duplicate]

This question already has answers here:
Preview an image before it is uploaded
(29 answers)
Closed 3 years ago.
I'm a beginner and still learning to programme.
I want to do something like this:
https://ufile.io/z2w0l
My question is how to preview a few images before uploading in the database with php,mysql?
I have code but it work like this:
When I choose which image i want to upload, the image doesn't display. Image is displaying when i click on submit button. I will take the picture of my layout here: https://prnt.sc/mv1ef0 (this is my form where i can upload image), https://prnt.sc/mv1erl (this is my submit button "Post"). When i click on submit button the page is refreshing and the image is displaying(like this photo): https://prnt.sc/mv1fjg
I want to preview picture first: https://prnt.sc/mv1iiz (in this box)
Here is my php code:
public function create() {
$this->requireSession();
$this->load->model('store_model');
$visible = 0;
if($this->input->post('is_visible') == 'on') {
$visible = 1;
}
$promotion = 0;
if($this->input->post('is_promotion') == 'on') {
$promotion = 1;
}
$internal = 0;
if($this->input->post('is_internal') == 'on') {
$internal = 1;
}
$userId = $this->authorization->getUserId();
$storeId = $this->authorization->getStore();
$price = $this->input->post('price');
$prev_price = $this->input->post('prev_price');
if($promotion == 1) {
$price = $this->input->post('prev_price');
$prev_price = $this->input->post('price');
}
date_default_timezone_set('Europe/Sofia');
$data = array(
'name' => $this->input->post('name'),
'description' => $this->input->post('description'),
'price' => $price,
'currency' => 'BGN',
'is_promotion' => $promotion,
'promotion_price' => $prev_price,
'quantity' => $this->input->post('quantity'),
'status' => $this->input->post('status'),
'main_image' => 0,
'is_internal' => $internal,
'is_visible' => $visible,
'url_address' => $this->input->post('url'),
'total_views' => 0,
'total_likes' => 0,
'total_comments' => 0,
'product_added' => date("Y-m-d H:i:s"),
'is_active' => 1,
'category_id' => $this->input->post('category_id'),
'user_id' => $this->authorization->getUserId(),
'store_id' => $storeId,
'brand_id' => $this->input->post('brand_id')
);
$this->db->insert("products", $data);
$product_id = $this->db->insert_id();
$this->db->query("UPDATE categories SET total_products = total_products + 1 WHERE id = " . $this->input->post('category_id'));
$this->db->query("UPDATE stores SET total_products = total_products + 1 WHERE id = " . $storeId);
$this->db->query("UPDATE users SET total_products = total_products + 1 WHERE id = " . $userId);
$tags = $this->input->post('tags');
$this->load->model('tag_model');
$this->tag_model->updateTags($tags, $product_id);
$this->load->model('category_model');
$this->load->model('attribute_model');
$attributes = $this->category_model->getOnlyAttributes($this->input->post('category_id'));
$values = array();
foreach($attributes as $row) {
$values[] = array('product_id' => $product_id, 'attribute_value_id' => $this->input->post('attribute_id' . $row->attribute_id));
}
if($attributes) {
$this->attribute_model->updateProductAttributes($values, $product_id);
}
if($_FILES["fileToUpload"]["tmp_name"]) {
$uploadOk = 1;
//$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
$uploadOk = 1;
} else {
$uploadOk = 0;
}
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
$uploadOk = 0;
}
// Allow certain file formats
/*if($imageFileType != "jpg") {
$uploadOk = 0;
}*/
// Check if $uploadOk is set to 1
if ($uploadOk == 1) {
$this->db->insert('products_images', array('product_id' => $product_id));
$insert = $this->db->insert_id();
$target_dir = "./" . p_image_path();
$target_file = $target_dir . '/' . $insert . '.jpg';
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file);
$this->db->update("products", array('main_image' => $insert), array('id' => $product_id));
}
}
redirect(site_url('mystore/products/edit/' . $product_id));
}
Here is my HTML code:
<div class="item-card">
<div class="card-section">
<div class="clearfix">
<!---<div class="pull-right">
<input type="file" name="fileToUpload" id="fileToUpload">
</div>---->
<div class="pull-right">
<span class="btn btn-white upload_image" type="file" id="fileToUpload">Upload image</span>
<input class="upload_file" type="file" name="fileToUpload" id="fileToUpload" style="display:none;">
</div>
<h2 class="al">Images</h2>
</div>
<hr />
<div class="item-images clearfix">
<div class="empty-text">
Upload images
</div>
</div>
</div>
</div>
You need to use Jquery onchange event when the file is selected read the file using FileReader
$('#fileToUpload').on('change', function() {
var file = this.files[0];
var imagefile = file.type;
var imageTypes = ["image/jpeg", "image/png", "image/jpg", "image/gif"];
if (imageTypes.indexOf(imagefile) == -1) {
//display error
return false;
$(this).empty();
}
else {
var reader = new FileReader();
reader.onload = function(e) {
$(".empty-text").html('<img src="' + e.target.result + '" />');
};
reader.readAsDataURL(this.files[0]);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="upload_file" type="file" name="fileToUpload" id="fileToUpload">
<div class="item-images clearfix">
<div class="empty-text">
Upload images
</div>
</div>

Chart.js - Multiple generateLegend() functions on same page

So I've been experimenting with Chart.js lately and I'm working on a project where I need to loop three Charts dynamically and I need each of them to have their own Custom Legend generated by the generateLegend() function. The problem is that the functionality of the legends isn't correct. Clicking any of the legends seems to affect only the last iteration of the Chart, which means that the last Chart gets affected only no matter which Chart's legend I click. Here's the code:
jQuery(document).ready(function($) {
if ($(".stats-content__chart__embed").length) {
var chartCount = $(".stats-content__chart__embed").length;
var chartCounter = 1;
window.toggleVisibility = function(element) {
$(element).toggleClass("striken");
}
while (chartCounter <= chartCount) {
var statsChartOptions = {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
stepSize: 1000
}
}]
},
legendCallback: function(chart) {
var legendHtml = [];
for (var i = 0; i < chart.data.datasets.length; i++) {
if (chart.data.datasets[i].label) {
legendHtml.push('<li class="stats-content__chart__legend__item" onclick="toggleVisibility(this); updateDataset(event, ' + '\'' + chart.legend.legendItems[i].datasetIndex + '\'' + ')"><span>' + chart.data.datasets[i].label + '</span></li>');
}
}
return legendHtml.join("");
},
legend: {
display: false
}
};
// You can ignore this
if ($(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__datasets").length) {
var chartDatasets = $(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__datasets");
var datasetsCount = chartDatasets.length;
var datasetsArray = [];
var datasetsLineColors = ["rgb(0,42,72)", "rgb(0,174,239)"];
for (var i = 0; i < datasetsCount; i++) {
var dataEntry = chartDatasets.eq(i).find("span").length;
var datasetLineColor;
var dataArrayString = [];
for (var x = 0; x < dataEntry; x++) {
var dataValue = chartDatasets.eq(i).find("span").eq(x).text();
dataArrayString.push(dataValue);
var dataArrayNumbers = dataArrayString.map(Number);
}
if ($(this).find("h6").length) {
var datasetLabel = chartDatasets.eq(i).find("h6").text();
}
if (i % 2 == 0) {
datasetLineColor = datasetsLineColors[0];
} else {
datasetLineColor = datasetsLineColors[1];
}
datasetsArray.push({
label: datasetLabel,
backgroundColor: "transparent",
lineTension: 0,
pointBackgroundColor: "transparent",
pointBorderColor: "transparent",
borderColor: datasetLineColor,
data: dataArrayNumbers,
borderWidth: 2
});
}
}
if ($(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__labels > span").length) {
var chartDatasetLabels = $(".stats-content").eq(chartCounter - 1).find(".stats-content__chart__labels > span");
var labelCount = chartDatasetLabels.length;
var labelsArray = [];
for (var i = 0; i < labelCount; i++) {
var labelText = chartDatasetLabels.eq(i).text();
labelsArray.push(labelText);
}
}
// Ignore all the way to here
var ctx = document.getElementById("stats-content__chart__embed-" + chartCounter).getContext("2d");
window.statsChart = new Chart(ctx, {
type: 'line',
data: {
labels: labelsArray,
datasets: datasetsArray
},
options: statsChartOptions
});
updateDataset = function(e, datasetIndex) {
var index = datasetIndex;
var ci = e.view.statsChart;
var meta = ci.getDatasetMeta(index);
meta.hidden = meta.hidden === null? !ci.data.datasets[index].hidden : null;
ci.update();
};
document.getElementById("stats-content__chart__legend-" + chartCounter).innerHTML = window.statsChart.generateLegend();
chartCounter++;
}
}
});
You can ignore the code that I've put inside comments since that's not relevant to the issue (I've gotten comments that it's too big of a chunk of code so I try to lessen the strain on you guys haha). Please, offer me any type of help. I really need it. Here's also the HTML for it, in case it helps in any way (the actual content is generated dynamically through Wordpress' Advanced Custom Fields plugin).
<?php if ( have_rows( 'stats_tabs' ) ) : ?>
<div id="statsTabContent" class="tab-content stats-holder">
<?php while ( have_rows( 'stats_tabs' ) ) : the_row();
$index = get_row_index(); ?>
<div class="tab-pane fade <?php echo ( $index == 1 ) ? 'in active' : '' ?> stats-content" id="tab-<?php echo $index; ?>">
<ul id="stats-content__chart__legend-<?php echo $index; ?>" class="stats-content__chart__legend"></ul>
<div class="stats-content__description">
<?php the_sub_field( 'tab_description' ); ?>
</div>
<div class="stats-content__chart__holder">
<?php if ( have_rows( 'tab_dataset' ) ) :
while ( have_rows( 'tab_dataset' ) ) : the_row(); ?>
<div class="stats-content__chart__datasets">
<h6><?php the_sub_field( 'dataset_label' ); ?></h6>
<?php if ( have_rows( 'dataset_data' ) ) :
while ( have_rows( 'dataset_data' ) ) : the_row(); ?>
<span><?php the_sub_field( 'dataset_value' ); ?></span>
<?php endwhile;
endif; ?>
</div>
<?php endwhile;
endif; ?>
<div class="stats-content__chart__labels">
<?php if ( have_rows( 'tab_labels' ) ) :
while ( have_rows( 'tab_labels' ) ) : the_row(); ?>
<span><?php the_sub_field( 'tab_label' ); ?></span>
<?php endwhile;
endif; ?>
</div>
</div>
<div class="stats-content__chart">
<canvas id="stats-content__chart__embed-<?php echo $index; ?>" class="stats-content__chart__embed"></canvas>
</div>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
You are replacing your variable on each iteration, so naturally the variable refers to the last thing assigned (i.e. the last chart created):
while (chartCounter <= chartCount) {
...
window.statsChart = new Chart(ctx, {...});
...
}
Clicking a legend item calls updateDataset wherein you reference back to window.statsChart via the line:
var ci = e.view.statsChart;
Since statsChart is assigned to the last chart iterated your code affects only that chart.
Either make statsChart an array and pass the relevant index via onclick or simply pass the chart object itself to updateDataset (although that won't work via the inline onclick; you'd need to bind to the element).

Function not executing before .forEach

I'm having some problems showing my loading icon, before a function is executing. It seems to be showing at the same time my new elements are being appended to the DOM. I'm expecting to have many elements, so a loading icon is necessary as these new elements are being built.
A breakdown of what I want to happen
Show loading icon
Build new elements and append to DOM
Hide loading icon
Generate Dummy Elements
<div class="loader"></div>
<button>Duplicate Items</button>
<section class="grid">
<?php for ($i = 0; $i < 1000; $i++) :
$randH = rand(1, 10);
$randW = rand(1, 10);
$imgUrl = 'http://placehold.it/' . $randH . 'x' . $randW;
?>
<article class="grid__item">
<img src="<?php echo $imgUrl; ?>" height="<?php echo $randH; ?>" width="<?php echo $randW; ?>">
<p>Hello <?php echo $i; ?></p>
</article>
<?php endfor;?>
</section>
<section class="gallery></section>
Javascript Functions
let createGallery = () => {
let gridItems = document.querySelectorAll('.grid__item'),
gallery = document.querySelector('.gallery'),
gridArray = Array.prototype.slice.call(gridItems, 0);
// create new elements
gridArray.forEach((item, index) => {
let galleryItem = document.createElement('article'),
img = item.querySelector('img').attributes,
markup = {
caption: item.querySelector('p').innerHTML
},
template = `<article class="gallery__item">
<img class="gallery__item__img" src="{{src}}" height="{{height}}" width="{{width}}">
<figcaption>{{caption}}</figcaption>
</article>`;
for (let i = 0; i < img.length; i++) {
markup[img[i].nodeName] = img[i].nodeValue;
}
Object.keys(markup).forEach(function(key) {
let regEx = new RegExp('\{\{' + key + '\}\}', 'g');
template = template.replace(regEx, markup[key]);
});
galleryItem.innerHTML = template;
galleryItem.className = 'gallery__item ' + index;
gallery.appendChild(galleryItem);
})
// after all images have been added > hide loader
$('.loader').removeClass('is-active');
};
let initGallery = () => {
// show loader, before creating gallery
$('.loader').addClass('is-active');
// create new elements
createGallery();
}
let $button = document.querySelector('button');
$button.addEventListener('click', initGallery);

Categories

Resources