Doing calculation in Yii is only taking manually inserted values - php

I am writing a small invoice application in Yii. I have the database for the model item. The item database is something like this
+++++++++++++++++
| InvoiceItems |
+++++++++++++++++
+ id +
+ name +
+ description +
+ unit_cost +
+ quantity +
+ tax +
+ total +
+++++++++++++++++
Now, in item model I have made a dropdown list where I am fetching all the item name with its unit_cost, quantity, tax etc in Ajax. In order to do the total, I have the business logic as:
unit_cost will be multiplied by quantity
Tax will then be added to the total.
The total should finally pop up in the total field in the _form.php file.
For the calculation, I have written this jQuery script:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#InvoiceItems_unit_cost, #InvoiceItems_quantity, #InvoiceItems_tax").on('keyup',function(event){
var subtotal = jQuery("#InvoiceItems_quantity").val() * jQuery("#InvoiceItems_unit_cost").val();
var total = subtotal + (subtotal * jQuery("#InvoiceItems_tax").val() / 100);
jQuery("#InvoiceItems_total").val(total);
});
});
</script>
This is working fine when I am manually inserting the values but it's not working when the values are coming from the database. I am totally stuck.
UPDATE
When I am trying to see the value after fetching from the database through ajax in console tab of firefox just like console.log("#InvoiceItems_quantity").val(), it is showing an empty string.
Ajax code to fetch data from the database in form of json
<?php echo $form->dropDownList($customers,'customer_name',CMap::mergeArray(CHtml::listData(Customers::model()->findAll(), 'customer_name', 'customer_name'
),
array(
'empty'=>array('Select'=>'- - Choose One - -'),
'id'=>'Customers_name',
'ajax'=> array(
'type'=>'GET',
'id'=>'abc',
'url'=>$this->createUrl('Invoices/customerdetails'),// action that will generate the data
'data'=>'js:"customer_name="+$(this).val()',// this is the data that we are sending to the action in the controller
'dataType'=>'json',// type of data we expect back from the server
'success'=>'js:updateFieldsCustomers',// a javascript function that will execute when the request completes
'beforeSend'=>'js:function(){
if($("#Customers_name").val() == "create_customer_link") {
addCustomers();
$("#dialogCustomers").dialog("open");
return false;
}
}',
),
'options'=>array(
'create_customer_link' => array('class'=>'create-link'),
)
)
);?>
<?php
Yii::app()->clientScript->registerScript('update','
function updateFieldsCustomers(data, textStatus, jqXHR){
// select each input field by id, and update its value
$("#InvoiceItems_unit_cost").val(data.unit_cost);
$("#InvoiceItems_quantity").val(data.quantity);
$("#InvoiceItems_discount").val(data.discount);
// similarly update the fields for the other inputs
}
');
?>
Recent Update
When I tried for console.log("#InvoiceItems_quantity").val() I saw that it is showing the actual value of that field after change. Means when one value is selected it is showing the value of previous entered value in console panel. I think all this is working as I have used on change function but when I am using .select its not working at all.Not any value is showing in console panel.

I got the solution for this question. It should be like this
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#Product_name").ajaxComplete(function(event,request,settings){
var subtotal = jQuery("#InvoiceItems_quantity").val() * jQuery("#InvoiceItems_unit_cost").val();
var total = subtotal + (subtotal * jQuery("#InvoiceItems_tax").val() / 100);
jQuery("#InvoiceItems_total").val(total);
});
});
</script>

Try this
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#Items_unit_cost, #Items_quantity, #Items_discount").on('keyup',calculate_total);
function calculate_total(){
var subtotal = jQuery("#Items_quantity").val() * jQuery("#Items_unit_cost").val();
var total = subtotal + (subtotal * jQuery("#Items_discount").val() / 100);
jQuery("#Items_total").val(total);
}
calculate_total();
});
</script>

Related

Woocommerce allow one variation to be selected

I am setting up a shop for a photographer and have his different product options setup as variations. I want to allow the user to successfully add the product to cart without having to select all available variations.
here is an example of attribute/terms I have setup as variations:
so the customer should be allowed to select one option (variation) and add to cart. Currently it fails and says I need to select a variation from each attribute
So my question is simple: How do I make it where all variation selections are not required?
My Approach: there are a few things I think may work. First I think there is probably an action or hook I can plug in to to make this not required. OR I could possibly use jquery to modify the add to cart url so when a user clicks the add to cart button that the product id and variation id get passed to the url which I imagine would add that variation only to cart.
Any thoughts?
UPDATE:
I have attempted to manage this through some jQuery. I have it where it will only allow one input to be selected and a class is added or removed depending on selection. When user hits the add to cart button it will get all .not-active input name attributes into an array. I know the following url will work: http://my-url.com/?add-to-cart=976&variation_id=1186&attribute_pa_downloads=print-300dpi&attribute_pa_high-definition-aluminum=0&attribute_pa_photo-tiles=0&attribute_pa_canvas-gallery-wraps=0&attribute_pa_custom-prints=0 so I needed a way to make this dynamic. Currently Im stuck on how to build my url to include all the POST parameters so it passes validation and will add to cart. With that said, given the code below how can I build out my url so it redirects with all parameters and adds to cart (building out the url is the only thing I dont think I have working.)
var selectedName;
var selectedValue;
//Shop only allow one radio to be checked
$('input.selectOne').on('change', function(){
$('input.selectOne').not(this).prop('checked', false).removeClass('active').addClass('not-active');
$(this).addClass('active').removeClass('not-active');
selectedName = $(this).attr('name');
selectedValue = $(this).val();
});
$('.single_add_to_cart_button').click(function(e){
e.preventDefault();
console.log(selectedName);
console.log(selectedValue);
//Works :http://my-url.com/?add-to-cart=976&variation_id=1186&attribute_pa_downloads=print-300dpi&attribute_pa_high-definition-aluminum=0&attribute_pa_photo-tiles=0&attribute_pa_canvas-gallery-wraps=0&attribute_pa_custom-prints=0
var productID = $('input[name="product_id"]').val();
var variationID = $('input[name="variation_id"]').val();
var location = window.location.href; //Get URL to redirect to cart
var emptyOptions = [];
$('.not-active').map(function() {
return this.name;
}).each(function(i, str) {
if (!~$.inArray(str, emptyOptions) && str != selectedName) emptyOptions.push(str: '0&');
});
console.log(emptyOptions);
alert(location + 'add-to-cart=' + productID + '&variation_id=' + variationID + '&' + $.each(emptyOptions));
});
JSFiddle
For anyone else looking I ended up solving this issue with jQuery and the Woocommerce Radio Buttons Plugin.
In my local JS file I added this and it will handle allow for one selection and then create the add to cart url.
var selectedName;
var selectedValue;
//Shop only allow one radio to be checked
$('input.selectOne').on('change', function(){
$('input.selectOne').not(this).prop('checked', false).removeClass('active').addClass('not-active');
$(this).addClass('active').removeClass('not-active');
selectedName = $(this).attr('name');
selectedValue = $(this).val();
});
$('.single_add_to_cart_button').click(function(e){
e.preventDefault();
//console.log(selectedName);
//console.log(selectedValue);
//Works :http://my-url.com/?add-to-cart=976&variation_id=1186&attribute_pa_downloads=print-300dpi&attribute_pa_high-definition-aluminum=0&attribute_pa_photo-tiles=0&attribute_pa_canvas-gallery-wraps=0&attribute_pa_custom-prints=0
var productID = $('input[name="product_id"]').val();
var variationID = $('input[name="variation_id"]').val();
var location = window.location.href; //Get URL to redirect to cart
var emptyOptions = {};
$('.not-active').map(function() {
return this.name;
}).each(function(i, str) {
if (!~$.inArray(str, emptyOptions) && str != selectedName) emptyOptions[str] = 0;
});
//console.log(emptyOptions);
window.location = location + '?add-to-cart=' + productID + '&variation_id=' + variationID + '&' + selectedName + '=' + selectedValue + '&' + $.param(emptyOptions);
});

Add price to unit price when checked, minus price when unchcked

So i have a 'total' field at the bottom of this column.
Above this field are checkboxes, when ticked, the 'total' should update by adding the price of that checkbox, and when unticked, the price should be removed.
So something similar to http://www.tepilo.com/#packages-anc
the below code updates the price when checkbox is clicked
it does nothing when unclicked
when clicked again, it adds to the new current price
$('.col-2 input[type="checkbox"]').on('click', function() {
var attribute_name = $(this).val();
var attribute_price = settings.wsapo_custom[0][attribute_name].price;
var current_price_total = $(".col-2 #update-price").text();
var new_price = parseInt(current_price_total) + parseInt(attribute_price);
console.log(new_price);
$(".col-2 #update-price").text(new_price);
});
thanks in advance
Using the onchange or change function in jquery will suffice here. Check if the checkbox is checked and then just change the data accordingly.
Demo on JSFIDDLE: http://jsfiddle.net/lrojas94/t9d04oeb/
Code:
$('input[type="checkbox"]').change(function(){
var actual = parseInt($('p').text());
if($(this).is(':checked'))
actual+= 100;
else
actual-=100;
$('p').text(actual);
});
And feel free to read the docs about this function: http://api.jquery.com/change/

Jquery to iterate through multiple sections and fields of table

Here is what I'm doing.
I have a set of divs. Each set of divs can contain a section header and a list of items. Each item has a price associated with it. So item 1 under section Demolition has a price of 150.00. Item 2 under section Demolition has a price of 200.00. Next to each item is an input field that the user can type in a numeric value. That value is then multiplied by the item price. So next to item 1(150.00) is a field where I enter 2. In the next div I then display the total. So 150.00 x 2 = 300.00.
I can do this for each item under the section. I then sum the entire items into one global price next to the sections.
Here is a sample of what I'm doing:
$(document).ready(function() {
$(".demolition_num").each(function() {
$(this).keyup(function(){
calculateDemSum();
});
});
});
function calculateDemSum() {
var sum = 0;
$(".demolition_num").each(function(){
if(!isNaN(this.value) && this.value.lenth != 0){
var unitCost = $(".unit_cost1").text();
var _parent = $(this).parent();
var total = _parent.prev().html();
sum += parseFloat(this.value * total);
var subtotal = this.value * total;
$(_parent).next().html(this.value * total);
}
else if (this.value.length !=0){
}
});
$(".cost1").text(sum.toFixed(2));
$("#cost1").val(sum.toFixed(2));
}
You can view all the code here: http://jsfiddle.net/pmetzger/Xeu2T/3/
As you can see in the jquery that right now I have to call each section independently
of the others since I do not want to calculate all of the fields, just the one I'm modifying.
So the question is, can I avoid having to add each sections input type id as the key up to trigger the calculations and make sure the totals get placed correctly?
Note: This code could be duplicated, but the data associated is going to be different. So on the next clients list it might not be Demolition, but Demo and so forth.
Any help will be greatly appreciated.
First of all a couple of pointers:
You don't need to bind events within an each() loop, simply
binding it to a standard selector will bind to all elements that fit
that selector.
You also have multiple <tr> elements with the same id.
You don't need a size attribute on hidden tags
New working fiddle here and the code:
$(document).ready(function()
{
// Bind the event
$("#calc").on("keyup", "input[type='text']", function()
{
calculateSum(this);
});
});
function calculateSum(element)
{
var sum = 0;
var $this = $(element);
var targetClass = $this.attr("class");
// Process each element with the same class
$("." + targetClass).each(function()
{
var thisVal = $(this).val();
// Count invalid entries as 0
if(isNaN(thisVal) || thisVal.length === 0)
{
thisVal = 0;
}
else
{
thisVal = parseFloat(thisVal);
}
// Get the unit cost and calculate sub-total
var unitCost = parseFloat($(this).parent().prev("td.unit_cost").text());
var subTotal = thisVal * unitCost;
sum += subTotal;
$(this).parent().next("td").text(subTotal);
});
var $item = $this.closest("tr").prevAll(".item").first();
$item.find("input.section_cost").val(sum.toFixed(2));
$item.find("td.section_cost").text(sum.toFixed(2));
}
Note that I have modified your HTML slightly - I changed the multiple <tr id="item"> to use classes, I moved where these rows were to better target your subsection totals, I added classes to the subsection totals (both hidden inputs and displayed values), I added a class to your unit value fields and I added an id to the table.

Dynamically change dropdowns via SQL and calculate sums?

I've got a row in a table with 3 fields laid out as so:
Job Pay Grade Cost
<Select> <Select> <Calculation>
I've got an SQL table with the information above in it, for example:
Job Pay Grade Cost
Techie 1 100
Techie 2 200
Engi 2 300
Engi 3 400
Engi 4 500
What I need to do is to be able to select a Job from the dropdown and then the Pay Grade select box will change depending on what matches that job in the SQL database. It will then show the cost which relates to the to selected.
How can I go about this as I am a little stuck
First create ajax request when a job title is selected. WIthin the success callback of the request will generate html for the options for pay grade select from JSON response from server
jQuery
$('select.jobTitle').change(function(){
var $titleSelect=$(this);
$.getJSON('processJobGrades.php', { jobTitle : $(this).val() }, function(response){
var gradesOptionsHtml='';
/* create options html from json response */
$.each( response, function(i, item){
gradesOptionsHtml+='<option value="'+item.grade+' data-cost="'+item.cost+'">'+item.grade+'</option>';
});
$titleSelect.parent().find('select.jobGrade').html(gradesOptionsHtml);
});
});
IN processJobGrades.php receive $_GET['jobTitle'] . Do DB lookup and create json to send back.
PHP
$outputArray=array();
/*in loop over DB data:*/
$outputArray[]= array( 'grade'=>$row['grade'], 'cost'=>$row['cost']);
/*Output final array as JSON*/
echo json_encode( $outputArray);
jQuery change handler for paygrade select to get cost
$('select.jobGrade').change(function(){
var cost=$(this).find(':selected').data('cost')
$(this).parent().find('input.jobCost').val( cost);
})
You need to post the select job via $.ajax and then in success function populate the dropdown list like this:
function selectHandler (event, ui)
{
var id = event.target.id;
$.ajax({
type: "POST",
url: "/php/get_quantity_type.php",
dataType:"json",
data: { ingridient : ui.item.value},
success: function(data){$("#"+id+"_t").empty(); $.each(data,function(index,value) {$("#"+id+"_t").append('<option value="' + value + '">' + value + '</option>');})}
});
}
This example takes a name of a material from select list posts it via $ajax() to a php script and writes it down to a new dropdown list which id is based on id that triggered the event. If you need the php code just ask:)
You bind your job list to the event handler above:
("#job_list").bind("select",selectHandler);
This code posts data to "/php/get_quantity_type.php", and passess the result to function declared in success attribute;

Entering a variable amount of data into a database with the best normalization possible

ok, so I have a database comprising of two tables, products and suppliers.
All suppliers fill in a form and their data is then stored in the suppliers table, and the products table contains a list of all of the products, so when the supplier fills in the form, he can choose as many products as he wishes as I use jQuery JSON and AJAX to get the list of all of the products and then populate a drop down list with all of them in it, which can then be cloned as many times as is needed.
The problem I am sitting with now is, how do I insert all of the different products the supplier chooses into the supplier table, or should I rather just relate all of the products he chooses to the one supplier for better normalization since all the products are already there?
I will be using jQuery $.ajax to POST the form data in JSON format to a waiting PHP file, which will then parse it and insert the data into the database.
So basically, I need to figure out how to relate the data in the database to achieve the best normalization possible, and I need to figure out a way of inserting a variable amount of products into the suppliers table or find a way to relate the many products he chooses to the one supplier.
I am very new to relational databases, so any advice on how to proceed would be a great help, so would any other advice you guys may have!
The jQuery code I use to populate clone and POST the products the supplier chooses:
$(document).ready(function() {
var count = 0;
//when clicked it will remove the closest div with a class of 'container'
$("span.remove").live('click', function(){
$(this).closest("div.container").fadeOut(400, function(){
$(this).remove();
$('#button').attr('disabled','');
});
});
//initialize the button
$('#button').attr('disabled','');
$('#button').click(function(){
var count = $("#systems_wrapper > .container").size();
var lastID = $("#systems_wrapper > .container:last").attr('id');
var exploded = lastID.split("_");
var increment = Number(exploded[1])+1;
//if the user has selected 5 products, disable the 'add' button
if(count >= 5){
$('#button').attr('disabled','disabled');
}else {
$('#button').attr('disabled','');
}
//clone the first drop down and give it a different ID, as well as it's child elements
var test = $('#systems_0.container').clone().attr('id', 'system_' + increment).appendTo('#systems_wrapper');
test.children(':nth-child(2)').append('<span class="remove"></span>');
test.children(':nth-child(2)').children(':first').attr('id', 'mail_' + increment).attr('class','dropDowns').attr('onchange','test();');
});
//get the products JSON object returned from test_post.php and run the necessary functions on the returned data
$.getJSON("test_post.php", function(data){
//clean out the select list
$('#box').html('');
//run the loop to populate the drop down list
$.each(data, function(i, products) {
$('#box').append(
$('<option></option>').html(products.products)
);
});
});
});
//this gets all of the products chosen and then gets each ones value and ID, and then posts it to the qwer.php file
function test(){
var sections = $('#systems_wrapper').find('.dropDowns');
var newArray = new Array();
sections.each(function(){
var id = $(this).attr('id');
var val = $(this).val();
var o = { 'id': id, 'value': val };
newArray.push(o);
});
alert(newArray);
$.ajax({
type: "POST",
url: "qwer.php",
dataType: 'json',
data: { json: JSON.stringify(newArray) }
});
}
Thanx in advance!
If i understand the problem correctly from a database level, should you be using an intermediate table called something like ProductSupplier containing a Product_ID and Supplier_ID column.
Then when a supplier selects a product, add both the supplier and product id to a new column in this table.
This will allow multiple suppliers to pick the same product and multiple products to be picked by the same supplier.
EDIT: I meant to say "add both the supplier and product id to a new ROW in this table"

Categories