Change default figures in textbox via dropdown - html

I'm working on this page - http://www.medilogicuk.com/v1/products/calculate-savings/
It's a simple calculator that calculates savings. At the moment the default values in the "Pharmacist" & "Dispenser/Technician" inputs are per annum figures, when the user clicks on the drop down and selects "per hour" I want the figures to automatically change to per hour (via a simple calculation)... and vice versa. The input needs to (re)calculate whatever number the user enters, so if they enter 50.00 and change to per annum then the per annum figure needs to reflect that.
How could I implement this?
Here's my code to create that table:
<table border="0">
<tr>
<td colspan="3"><h3>Current service costs</h3></td>
</tr>
<tr>
<td width="440"><p>Pharmacist</p></td>
<td><p style="padding-left:5px!IMPORTANT;">£
<input value="42500" type="text" name="pharmacist" />
</p></td>
<td width="5" rowspan="2"><select>
<option value="perannum">per annum</option>
<option value="perhour">per hour</option>
</select></td>
</tr>
<tr>
<td><p>Dispenser / Technician</p></td>
<td><p style="padding-left:5px!IMPORTANT;">£
<input value="17500" type="text" name="dispenser" />
</p></td>
</tr>
<tr>
<td colspan="3"> </td>
</tr>
</table>

You need to do something like below.
assuming that the "select" has got and id "ddlDuration"
using JQuery
$('#ddlDuration').change(function(){
if($(this.val) == 'perhour'{
pharmacist = $('input[name="pharmacist"]');
pharmacist.val( calculateHourlyFromAnnual( pharmacist.val() ) );
}
});
function calculateHourlyFromAnnual( annumRate )
{
return 100; // calculate the value of the hourly rate based on the per-annum rate
}

Worked out a solution for you: http://jsfiddle.net/tive/Gya43/
javascript
$(function() {
$('#ddlDuration').change(function() {
var pharmacist = $('#pharmacist');
var dispenser = $('#dispenser');
if ($(this).val() == 'perhour') {
pharmacist.val(toHour(pharmacist.val()));
dispenser.val(toHour(dispenser.val()));
} else {
pharmacist.val(toAnnual(pharmacist.val()));
dispenser.val(toAnnual(dispenser.val()));
}
});
function toHour(annumRate) {
var num = (annumRate / 8760);
return num.toPrecision(annumRate.length);
}
function toAnnual(hourRate) {
var num = (hourRate * 8760);
return num.toFixed(0);
}
});
If you run into troubles with num.toFixed(2) try num.toPrecision(2) since that will be more precise.
EDIT:
I noticed when using the length of your number in the .toPrecision method, you will always return the original value. It's not so well rounded down but at least you won't get any mistakes. If you want to tweak this behaviour for rounded numbers I suggest to use a placeholder field/attribute/something to store value.

Okay, I'll break it down.
Firstly, this solution uses the jQuery library so you need to reference this in the <HEAD> section. You will so want to reference the javascript file where you will be placing your code:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!-- You need to define the file name and path as appropriate for yourself. -->
<script type="text/javascript" src="http://path-to-your-url.com/scripts/script.js"></script>
</head>
...
</html>
Next you need to make some small changes to your markup.
<input value="42500" type="text" name="pharmacist" />
<select>
<input value="17500" type="text" name="dispenser" />
becomes:
<input value="42500" type="text" name="pharmacist" id="pharmacist" />
<select id="rate">
<input value="17500" type="text" name="dispenser" id="dispenser" />
The key change being the new id attributes. These will be used by your javascript to identify the key elements in the code (you could use the name attributes for this, as JQone suggests - I prefer using id from a style point of view and because the jQuery/CSS selector code is smaller).
Finally, you create a javascript file (I'm calling it "script.js" here) and place it in the correct folder in the website (in keeping with the path used in the HEAD section of the HTML doc, this will be a sub-folder of the website's root folder called "scripts"). The file will have the following contents:
// This code sets up the javascript. It is saying: 'when the document is ready, register the "changeRate" function with the "change" event of the select box'. So whenever the select box's value is changed, the function will be called.
$( document ).ready( function() {
$( 'select#rate' ).change( changeRate );
} );
// This sets the values of the text values based upon the selected rate and the existing value.
var changeRate = function() {
var rate = $( this );
var pharmacist = $( 'input#pharmacist' );
var dispenser = $( 'input#dispenser' );
if ( rate.val() == 'perhour' ) {
pharmacist.val( calculateHourlyFromAnnual( pharmacist.val() ) );
dispenser.val( calculateHourlyFromAnnual( dispenser.val() ) );
}
else if ( rate.val() == 'perannum' ) {
pharmacist.val( calculateAnnualFromHourly( pharmacist.val() ) );
dispenser.val( calculateAnnualFromHourly( dispenser.val() ) );
}
};
// Calculates an hourly rate based upon the supplied per annum rate. At the moment this doesn't take into account scenarios where the provided value is empty or is not a number so you will need to adjust appropriately.
function calculateHourlyFromAnnual( annumRate )
{
-- Making the assumption that a per-annum rate of $50,000 translates to an hourly rate of $50
return annumRate / 1000;
}
// Calculates a per-annum rate based upon the supplied hourly rate. At the moment this doesn't take into account scenarios where the provided value is empty or is not a number so you will need to adjust appropriately.
function calculateAnnualFromHourly( hourlyRate )
{
-- Making the assumption that an hourly rate of $50 translates to a per-annum rate of $50,000
return hourlyRate * 1000;
}
More than likely, the formula I've used for calculating the rate change is overly simplistic but I don't know the business requirements in your situation. You'll have to figure out the correct formula yourself.
Basically, if you follow these steps the values should be changed as you switch the select list between per annum and per hour.

You have to use JavaScript to solve this.
With jQuery e.g. register a change event listener on your dropdown element and update the value of the two input fields when the selected value of the dropdown element changes.

Related

html5 onclick update table data

I have a table that has js to allow me to sort the data. But I need to be able to change the data and have js still sort it when I click the header. I have a input box off to the side with a button. I am looking for a onclick way to change the table data from X to what is ever in that input box.
<td id="tabledata1">
1
</td>
I need to be able to change the "1" in that table data. I can not find the function code to effect that specific number. I am guessing it is something like this document.getElementById("tabledata1").style.color but instead of style.color there is something to reference table data.
It would look something like this
var cell = document.getElementById("tabledata1");
var button = document.getElementById("my-button");
var input = document.getElementById("my-input");
var par = document.getElementById("result");
button.addEventListener("click", function() {
cell.textContent = input.value;
});
<input id="my-input" type="text" />
<button id="my-button">Change Table Data</button>
<table>
<tr>
<td id="tabledata1">1</td>
</tr>
</table>
<p id="result"></p>
Breakdown
First query the document for the ids you want and store them into variables. You can then listen for the click event with the addEventListener function.
You can change the text of the table cell, by using the textContent property and setting it equal to the value of the input element.

Using angularjs, how to perform math operations on textboxes and see result as the values are being typed in?

I have an HTML file with 2 textboxes, one for value and the other for quantity. The result text at the bottom multiplies value with quantity and show the result.
The intention is to show the sum of all the rows of pairs of textboxes on the screen. To that end, I have an "add new" button which keeps adding additional pairs of textboxes.
The first set of textboxes that appear on the HTML, reflect the size of the "numbers" array of objects containing properties "val" and "qty". The same values are bound to the textboxes.
However, only the first set of values are added on screen. As I keep adding new textboxes and entering new values, the value of the result should change accordingly, but it simply doesn't.
HTML Code
<div ng-app="adder" ng-controller="addcontrol">
<table>
<tr>
<th>Value</th><th>Quantity</th>
</tr>
<tr ng-repeat="number in numbers">
<td><input type="text" ng-model="number.val"></td>
<td><input type="text" ng-model="number.qty"></td>
<td><input type="button" ng-click="deleteNumber($index)" value= "Delete"></td>pp',[]);
</tr>
</table>
<input type="button" ng-click="add()" value="Add new">Result : {{sum}}
</div>
</body>
</html>
Javascript
var myapp = angular.module('adder', []);
myapp.controller('addcontrol',function($scope){
$scope.numbers = [
{val:100,
qty:200,
}
];
$scope.add = function()
{
$scope.numbers.push({val:0,qty:0});
};
$scope.deleteNumber = function(val)
{
numbers.splice(val, 1);
};
var result=0;
angular.forEach($scope.numbers, function(num){
result+=(num.val * num.qty);
});
$scope.sum = result;
});
What am I doing wrong here?
In your code, the calculation of the sum would only be executed once.
You need to add a watch of the scope or bind a function to ng-change event in order to keep the sum updated while you change the numbers.
For example, you can do:
<div ng-app="adder" ng-controller="addcontrol">
<table>
<tr>
<th>Value</th><th>Quantity</th>
</tr>
<tr ng-repeat="number in numbers">
<td><input type="text" ng-change="update()" ng-model="number.val"></td>
<td><input type="text" ng-change="update()" ng-model="number.qty"></td>
<td><input type="button" ng-click="deleteNumber($index)" value= "Delete"></td>pp',[]);
</tr>
</table>
<input type="button" ng-click="add()" value="Add new">Result : {{sum}}
</div>
And:
var myapp = angular.module('adder', []);
myapp.controller('addcontrol', function($scope) {
$scope.numbers = [{
val: 100,
qty: 200,
}
];
$scope.add = function() {
$scope.numbers.push({
val: 0,
qty: 0
});
};
$scope.deleteNumber = function(val) {
numbers.splice(val, 1);
$scope.update();
};
$scope.update = function() {
var result = 0;
angular.forEach($scope.numbers, function(num) {
result += (num.val * num.qty);
});
$scope.sum = result;
};
});
I know this a little bit besides the question but you can do arbitrary arithmetic operations inside a single input field:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="">
<input ng-model="expression"/>
<p>{{$eval(expression)}}</p>
</body>
Based on Pylinux's answer: it may seem obvious, however here it is. If you want to add 2 expressions, use the following:
{{$eval(expression1)+ $eval(expression2) }}
The code in your controller is only activated once (when the view is rendered). Therefore, your sum is only computed once, before you even get a chance to add any rows. What you need to do is put your calculation into a function so that it can be called repeatedly as needed.
Tong's answer is basically correct, but I think this is a nicer way to do it:
<div ng-controller="addcontrol">
<table>
<tr>
<th>Value</th><th>Quantity</th>
</tr>
<tr ng-repeat="number in numbers">
<td><input type="text" ng-model="number.val"></td>
<td><input type="text" ng-model="number.qty"></td>
<td><input type="button" ng-click="deleteNumber($index)" value= "Delete"></td>
</tr>
</table>
<input type="button" ng-click="add()" value="Add new">Result : {{total()}}
</div>
and
var app = angular.module('app', [])
.controller('addcontrol', function($scope) {
$scope.numbers = [{
val: 100,
qty: 200,
}];
$scope.add = function() {
$scope.numbers.push({
val: 0,
qty: 0
});
};
$scope.deleteNumber = function(val) {
$scope.numbers.splice(val, 1);
};
$scope.total = function(){
var total = 0;
angular.forEach($scope.numbers, function(num) {
total += (num.val * num.qty);
});
return total;
}
})
Define a total function that loops through the array and returns the appropriate sum. Then you can bind that function to the result field in the view. The benefit of doing it this way is that you don't have to remember to call update() everywhere that might cause the total to change (like ng-change on the textboxes, and in the deleteNumber function). The total just updates automatically.
Here's a demo.
Php
Create a database named as students(using cmd)
Create a table named as tbl_students_info with column:
id, data type is int with size of 11, auto increment and set as primary key
Firstname, data type is varchar with size of 30
Middlename, data type is varchar with size of 30
Lastname, data type is varchar with size of 30
Contact, data type is int with size of 11
House_address, data type is int with size of 50
Create a webpage that contains 5 textbox and 1 button. 1st textbox is for firstname, 2nd textbox is for middlename, 3rd textbox is for lastname, 4th textbox is for contact, last textbox is for house_address and button for saving the input data in those texboxes to database
Angular
Create a calculator that computes the sum of 2 numbers, product of 2 numbers, difference of 2 numbers and quotient of 2 numbers. The web page must contain 2 textbox and 4 buttons for the operations.
Create a wepage that computes the area of a triangle. Must have 2 textbox and a button for calculate area.
Create a website that calculate the age of the user. Must have a textbox and a button, textbox is for input birth year and button for compute age. Note: no need for exact months.
Help TT

AngularJS, checkboxes, and generating dynamic html

I am wanting to generate a table dynamically using Angular JS, based on what is checked on some checkboxes. The problem is that there are a few fields, we will call them relation/column, that I want to display ALWAYS, and the remaining fields only if their box is checked. The relation is searched for via a search box (relations can have multiple columns), and I want to display only the properties of that relation that are relevant to a user.
So
Update Time [X]
Update Status [ ]
Time Zone [ ]
Would display some html along the lines of
<table>
<tr>
<th> Relation </th>
<th> Column </th>
<th> Update Time </th>
</tr>
<tr ng-repeat= "result in results">
<td> {{result.relation}} </td>
<td> {{result.column}} </td>
<td> {{result.update_time}}</td>
</tr>
If no boxes were checked, only the relation and column fields would be populated. The documentation for Angular JS is taking me all over the place, so would anyone have an idea on how to do this?
edit : controller isn't working quite yet, I still need to filter the search results, but basically it goes
$scope.search = function(){
//validate form input
//create url with the input recieved
$http.get(url).success(function(data){
$scope.results = angular.fromJson(data);
});
}
I use mojolicious backend to grab the data I want. Again, the problem isn't that I can't get any data, or that I can't filter the results based on the relation. I want to be able to search based on relation, and only display the attributes of that relation that I want to, based on what is checked. THAT part, I can't figure out.
edit again : the firewall where I'm at prevents me from writing comments/upvoting. You shall be rewarded for your help when I get home tonight. Thank you thank you!
I think the best way to do this would be using ng-show expressions tied to a variable in the model.
For example.
<input type="checkbox" ng-model="updateTime">
makes a checkbox and ties the result to $scope.updateTime. You can then use this variable later on via the ng-show directive like so...
<th ng-show="updateTime"> Update Time </th>
...
<td ng-show="updateTime"> {{result.update_time}}</td>
this means that these elements will only show when updateTime is set to true (i.e the checkbox is checked.)
You can see an example here, I've only implemented the one field but it should be possible to extend it pretty easily!
http://plnkr.co/edit/W6Ht6dnGw4fBplI83fB1?p=preview
I would suggest using a custom filter with the checkbox scope variables passed in. Something like this:
html
<input type="checkbox" ng-model="checkbox1" />
<input type="checkbox" ng-model="checkbox2" />
<input type="checkbox" ng-model="checkbox3" />
... ng-repeat= "result in results|checkboxFilter:{checkbox1,checkbox2,checkbox3}"
filter.js
.filter('checkboxFilter', function() {
return function (results, checkbox1, checkbox2, checkbox3) {
var filtered_objects = angular.copy(results);
for (var i = 0, len = filtered_objects.length; i < len; i++) {
**modify your filtered_objects based on your checkboxes**
if (checkbox1) ...
if (checkbox2) ...
if (checkbox3) ...
}
return filtered_objects;
}
});
Maybe something like that.

Make an html number input always display 2 decimal places

I'm making a form where the user can enter a dollar amount using an html number input tag. Is there a way to have the input box always display 2 decimal places?
So if someone else stumbles upon this here is a JavaScript solution to this problem:
Step 1: Hook your HTML number input box to an onchange event
myHTMLNumberInput.onchange = setTwoNumberDecimal;
or in the html code if you so prefer
<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />
Step 2: Write the setTwoDecimalPlace method
function setTwoNumberDecimal(event) {
this.value = parseFloat(this.value).toFixed(2);
}
By changing the '2' in toFixed you can get more or less decimal places if you so prefer.
an inline solution combines Groot and Ivaylo suggestions in the format below:
onchange="(function(el){el.value=parseFloat(el.value).toFixed(2);})(this)"
An even simpler solution would be this (IF you are targeting ALL number inputs in a particular form):
//limit number input decimal places to two
$(':input[type="number"]').change(function(){
this.value = parseFloat(this.value).toFixed(2);
});
What other folks posted here mainly worked, but using onchange doesn't work when I change the number using arrows in the same direction more than once. What did work was oninput. My code (mainly borrowing from MC9000):
HTML
<input class="form-control" oninput="setTwoNumberDecimal(this)" step="0.01" value="0.00" type="number" name="item[amount]" id="item_amount">
JS
function setTwoNumberDecimal(el) {
el.value = parseFloat(el.value).toFixed(2);
};
The accepted solution here is incorrect.
Try this in the HTML:
onchange="setTwoNumberDecimal(this)"
and the function to look like:
function setTwoNumberDecimal(el) {
el.value = parseFloat(el.value).toFixed(2);
};
Pure html is not able to do what you want. My suggestion would be to write a simple javascript function to do the roudning for you.
You can use Telerik's numerictextbox for a lot of functionality:
<input id="account_rate" data-role="numerictextbox" data-format="#.00" data-min="0.01" data-max="100" data-decimals="2" data-spinners="false" data-bind="value: account_rate_value" onchange="APP.models.rates.buttons_state(true);" />
The core code is free to download
I used #carpetofgreenness's answer in which you listen for input event instead of change as in the accepted one, but discovered that in any case deleting characters isn't handled properly.
Let's say we've got an input with the value of "0.25". The user hits "Backspace", the value turns into "0.20", and it appears impossible to delete any more characters, because "0" is always added at the end by the function.
To take care of that, I added a guard clause for when the user deletes a character:
if (e.inputType == "deleteContentBackward") {
return;
}
This fixes the bug, but there's still one extra thing to cover - now when the user hits "Backspace" the value "0.25" changes to "0.2", but we still need the two digits to be present in the input when we leave it. To do that we can listen for the blur event and attach the same callback to it.
I ended up with this solution:
const setTwoNumberDecimal = (el) => {
el.value = parseFloat(el.value).toFixed(2);
};
const handleInput = (e) => {
if (e.inputType == "deleteContentBackward") {
return;
}
setTwoNumberDecimal(e.target);
};
const handleBlur = (e) => {
if (e.target.value !== "") {
setTwoNumberDecimal(e.target);
}
};
myHTMLNumberInput.addEventListener("input", handleInput);
myHTMLNumberInput.addEventListener("blur", handleBlur);
Look into toFixed for Javascript numbers. You could write an onChange function for your number field that calls toFixed on the input and sets the new value.
What I didn't like about all these solutions, is that they only work when a form is submitted or input field is blurred. I wanted Javascript to just prevent me from even typing more than two decimal places.
I've found the perfect solution for this:
<!DOCTYPE html>
<html>
<head>
<script>
var validate = function(e) {
var t = e.value;
e.value = (t.indexOf(".") >= 0) ? (t.substr(0, t.indexOf(".")) + t.substr(t.indexOf("."), 3)) : t;
}
</script>
</head>
<body>
<p> Enter the number</p>
<input type="text" id="resultText" oninput="validate(this)" />
</body>
https://tutorial.eyehunts.com/js/javascript-limit-input-to-2-decimal-places-restrict-input-example/
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" integrity="sha512-pHVGpX7F/27yZ0ISY+VVjyULApbDlD0/X0rgGbTqCE7WFW5MezNTWG/dnhtbBuICzsd0WQPgpE4REBLv+UqChw==" crossorigin="anonymous"></script>
<input type="text" class = 'item_price' name="price" min="1.00" placeholder="Enter Price" value="{{ old('price') }}" step="">
<script>
$(document).ready(function() {
$('.item_price').mask('00000.00', { reverse: true });
});
</script>
give out is 99999.99

jQuery event bound to dynamically created DOM elements fires erronously

I have this markup.
<form action='xxx.php' method='post'>
<table>
<tr>
<th>Branch Id</th>
<td><input id="branchId" type="text" size="15%" name="branchId"></input></td>
<th>Branch Name</th>
<td colspan="3"><input id="branchName" type="text" size="75%" name="branchName"></input></td>
<td>
<div id="button">
<input type="button" id="btnAdd" value="Add" name="submit"/>
</div>
</td>
</table>
</form>
<!------- Something here--------------->
<table class="divTable" id="exisBranch">
<tr><th id="thBranchId">Branch Id</th>
<th id="thBranchName">Branch Name</th>
<th class="btn" id="tcEdit">Edit</th>
<th class="btn" id="tcDelete">Delete</th>
</tr>
</table>
What basically happens is I populate the second table records retrieved through AJAX. Each row has a 'branchId','branchName' and two buttons of class 'bt'. When I click the edit button, I need the corresponding 'branchId' and 'branchName' values inserted into input elements in the first table, so that I can edit them and later, when I click the "btnAdd", I can save them.
This is the jQuery I have.
function fun(){
var branchId=$(this).closest("tr").find("td").eq(0).html();
$("#btnAdd").click(function () {
if($("#btnAdd").val()=='Save')
{
alert(branchId);
//ajax call
}
});
}
$(document).ready(function(){
$("#exisBranch").on('click','.bt',fun);
$("input[type='button']").click(function(e){
e.preventDefault();
});
});
Everything works fine when I click the 'btnAdd' for the first time. The problem starts with the second and successive clicks on this button.Consider that there are 6 rows in the dynamically populated content, and that 'branchId' of each row is the corresponding row number.
When I first click on 'EDIT' button on the 2nd row, and then the 'btnAdd', an alert correctly pops up showing 2.
Problem is , if I then go on to click 'EDIT' on the 6th row, and then the 'btnAdd' , I get two alerts. The first one shows 2, then 6.I just want 6.
For the third round, it goes like 2,6, and what ever is clicked next. This is making my AJAX fire as many no. of times as the no. of clicks.
This is really infuriating.I just can't seem to figure out why. I am a jQuery novice, so please bear with me if this is something fundamental and I messed it up.Please let me know how to make it fire only once with the latest value, instead of it stacking up on my history of calls?
You shouldn't keep binding your Add button w/ each Edit click--move it out to your document ready.
<script>
var branchId; //keep track of which branch is under edit
function fun(){
branchId = $(this).closest("tr").find("td").eq(0).html();
var branchName = $(this).closest("tr").find("td").eq(1).html();
$('#branchId').val(branchId);
$('#branchName').val(branchName);
}
$(document).ready(function(){
$("#exisBranch").on('click','.btn',fun);
$("#btnAdd").click(function () {
if($("#btnAdd").val()=='Save') {
alert(branchId);
//ajax call
}
});
$("input[type='button']").click(function(e){
e.preventDefault();
});
});
<script>
*you have a number of typos in your stack post.
The problem is that you are attaching a new click handler each time that fun is called. These handlers are not unbound after they fire, so the handlers are building up. You could use jquery's one to ensure that each event fires only once.
Really though, your entire approach is not ideal. Off the top of my head, one possible improvement which wouldn't take too much re-engineering would be to store the IDs in an array, then when add is clicked, process the array and clear it. This would let you only have one handler on add as well as allow for batch ajax calls instead of one per id.