Simple Maths with jQuery - division - javascript

I've got two inputs in a div that I want to divide one by the other.
<div>
<input type="number" id="a"> / <input type="number" id="b">
<input type="submit">
<p class="result">RESULT HERE</p>
</div>
How can the maths of this be done with jquery?

It really depends when you want the calculation to take place, but the maths itself is incredibly simple. Just use the standard division operator, /:
var num1 = $("input[label='a']").val(),
num2 = $("input[label='b']").val(),
result = parseInt(num1, 10) / parseInt(num2, 10);
$(".result").text(result);
I guess it also depends if you only want to support integer division (that's why I've used parseInt - you could use parseFloat if necessary).
Also, as mentioned in the comments on your question, label is not a valid attribute. A better option would be to use id, or if you need to use an arbitrarily named attribute, use HTML5 data-* attributes.
Update based on comments
As you have stated that you want the code to run when a button is clicked, all you need to do is bind to the click event:
$("#someButton").click(function() {
//Do stuff when the button is clicked.
});

You're mixing your markup with your logic. You can't divide HTML elements with each other they are for structural presentation only. Instead, you have to pull their values with javascript, apply the math, and update the HTML with the resulting value.

Related

Any way to do "real-time" unit conversion in web application

I want to build a website that allows the user to convert Hz to bpm (note however that my question concerns all sort of unit conversion). I am using PHP and am hosting my website on Apache.
So, I was wondering if it was possible to "bind" an input field to an HTML element, like we do in WPF developement where you can bind an input area to a WPF element, and apply some sort of data conversion so if the user types 12 bpm, the bound element will automaticly and immediately display 0.2 Hz. If the user then adds a "0" so 120 bpm will be automaticly and immediately converted to 2 Hz.
The effect I am trying to describe can also be noted on this very forum : as I type my question, I can see a "real-time" final version of my text.
How is this achieved? Is there any way to do it with PHP? I know of AJAX but I would really prefer to avoid using Javascript to hold my math functions. Correct me if I am wrong but I think this could be accomplished with Node.js? Should I consider migrating to Node?
With just the DOM and JavaScript, you can use the input event on a text field to receive an immediate callback when its value changes as the result of user action:
document.querySelector("selector-for-the-field").addEventListener("input", function() {
// Code here to do and display conversion
}, false);
Example (centigrade/Celsuis to Fahrenheit):
var f = document.getElementById("f");
document.querySelector("#c").addEventListener("input", function() {
var value = +this.value;
if (!isNaN(value)) {
value = (value * 9) / 5 + 32;
f.innerHTML = value;
}
}, false);
<div>
<label>
Enter centigrade:
<input type="text" id="c">
</label>
</div>
<div>
Fahrenheit: <span id="f"></span>
</div>
Stepping back, yes, there are dozens of libraries and frameworks that provide MVC/MVVM/MVM/whatever-the-acronym-is-this-week in the browser. A short list of current popular ones: React, Angular, Vue, Knockout, ... Note that these are not magic, they're just code written in JavaScript (or something like TypeScript or Dart or CoffeeScript that compiles to JavaScript) that use the DOM the covers.
I will give you an example of real-time "inches to cm" conversion.
Note for this example to work, you will need to include jQuery.
HTML:
<div>
<label>Inches</label>
<input type="text" id="user_input" />
</div>
<div>
<label>Centimeters</label>
<input type="text" id="result" readonly />
</div>
JAVASCRIPT:
$(document).ready(function(){
$('#user_input').on('propertychange input keyup', function(){
var thisVal = $(this).val();
$('#result').val(thisVal * 2.54);
});
});
Fiddle: https://jsfiddle.net/captain_theo/t10z01cm/
You can expand that for any type of conversion.
Check my updated fiddle that includes Hz to bpm also:
https://jsfiddle.net/captain_theo/t10z01cm/1/
Cheers, Theo

Input field limit 9 char and after 3 char automaticly ads "-"

<input id="myText" type="text" placeholder="XXX-XXX-XXX" /></input>
<script type="text/javascript">
document.getElementById("myText").value.substr(0, 9).match(/.{1,3}/g).join("-");
</script>
There are a few problems with your current JavaScript. First, your script will only run once when the page is loaded, meaning any input you enter into myText after that will never be processed. Consider binding to an event of myText - for example, the onkeyup event.
Another problem is that your JavaScript doesn't take into account existing dashes when splitting the value of myText into 3-character parts - this results in undesirable behaviour, where more and more dashes will be added to the value, at seemingly random positions.
Lastly, as mentioned by Tushar in the comments, you need to set the value of myText to the new, processed value you create. Otherwise this value ends up being unused and discarded, and your code appears to do nothing.
Putting this all together, the fixed code might look like:
var textInput = document.getElementById("myText");
textInput.onkeyup = function()
{
var dashlessInput = textInput.value.replace(/-/g, "");
textInput.value = dashlessInput.substr(0, 9).match(/.{1,3}/g).join("-");
};
<input id="myText" type="text" placeholder="XXX-XXX-XXX" /></input>
Hope this helps! Let me know if you have any questions.
For future reference - try to clearly state what your question by explaining what you want to achieve, and specifically indicating what problems you're facing. This way, you're more likely to attract good answers rather than downvotes.

Another jquery dynamic selector

I just asked a question here about selecting all id's of the form id_* where * is any string and id is the id of the element. I got a great working solution:
$("*[id^=" + id + "_]").each(function() {... // id is the element name
I need to take this one step further now:
All of my ids will be of the form: a_b_c ... where a b and c are arbitrarity strings (that do NOT contain a ''). So, now rather than selecting all the elems of the form id_* where * could be a_b_c ... I need only to select 1 level deep: i.e. all elems of the form id_a. So in other words it stops at the next ''. Is this possible?
As an example:
If my id is: first
And there exist id's: first_second, first_second_third
It will select only first_second
Sounds like you are storing too many values in the id of the field. With HTML5 we now have data- attributes.
Perhaps, you should be making use of data- attributes something like this to link them?
<div id="a">
</div>
<div id="b0" data-parentId='a'>
</div>
<div id="b1" data-parentId='a'>
</div>
<div id="b2" data-parentId='a'>
</div>
<div id="c" data-parentId='b1'>
</div>
It will still validate, as any non-standard attribute starting with data- will be considered valid.
See: http://ejohn.org/blog/html-5-data-attributes/
Your jQuery selectors can then make use of this new attribute, rather than trying to parse strings
Something like this would select all of a's children
var childrenOfA = $("div[data-parentId='a']);
What I ended up doing (and I'm open to faster implementations) is:
$("*[id^=" + id + "_]").each(function() {
//here I simply split the id and test the size of the array
//if its too large (i.e. too deep in the tree), I return true (to continue
// to the next iteration):
var row = $(this);
var split = row.attr('id').split("_");
if(split.length > SOME_PREDETERMINED_VAL)
return true;
//code here
});
I am not totally happy with this since it still traverses all elements (or would it do this anyway regardless of the filter in the each() function??).
This doesn't give you the whole solution, but you could try the attribute prefix selector or the attribute starts with selector
That will allow you to select any descendant of an element:
$("[id^='a_b_']").each(....
Will think how to remove the grandchildren etc, but this might get you started.
EDIT
I have just found that a similar question was asked about jQuery wildcards - this looks as if it will do what you need.
It seems like you are seriously overcomplicating this task. Let's say your structure is currently like this:
<div id="a">
<div id="a_b">
<div id="a_b_c">
</div>
</div>
</div>
Why don't you just do something along these lines...
<div id="a">
<div class="b">
<div class="c">
</div>
</div>
</div>
So, if I JUST wanted #a .b I would do:
$("#a .b").not("#a .c").show();
Makes it a bit more semantic and readable as well. Am I understanding what you're trying to do? Might need to shed a bit more light on what exactly you're doing
The obvious solution is changing your document, for example instead of
<div id="a"></div>
<div id="a_b"></div>
<div id="a_b_c"></div>
you could write
<div id="a" class="l1"></div>
<div id="a_b" class="l2"></div>
<div id="a_b_c" class="l3"></div>
and then select $('.l2[id^=a_]'). If that is not an option, you could try some sort of sieve scheme:
var set = $('[id^='+id+'_]'), i = 0;
while (i < set.length) {
var e = set.eq(i);
if (e.attr('id').substr(id.length+1).match('_')) {
set = set.not(e);
} else {
i++;
}
set = set.not($('[id^='+e.attr('id')+'_]'));
}
(I haven't tested, so there might be errors, and I'm not sure not is the one that subtracts from a result set, but you get the idea.)
It depends on the document structure and browser whether this will be actually faster than the naive implmentation of simply walking through the while set and skipping everything with two _ in the id. (High number of branches per node helps, and it will be probably faster on browsers which have a native implementation of the CSS3 prefix selector which jQuery can call on.)
update: fixed some mistakes. The logic might change depending on your structure, e.g. the innermost if branch is unnecessery if foo_bar always precedes foo_bar_baz.

dynamically add elements from jquery or javascript

if a user types in an input say 3 into a text box three small text boxes should be shown below or in a popup through javascript or jquery .How can this be done...
<input type="text" name="order">3</input>
Thanks..
Give the <input/> an id of "order", then it's as simple as:
var order = $('#order'),
container = $('<div/>').insertAfter(order);
order.keyup(function(){
container.html(
Array(Math.abs(~~this.value) + 1).join('<input/>')
);
});
FYI, ~~ (double-bitwise-not) has the effect of getting the number representation of any type (using the internal toInt32 operation) and then flooring it. E.g:
~~'2'; // => 2
~~'2.333'; // => 2
~~null; // => 0
And Math.abs is to protect against negative values, that will throw an error if passed to Array().
DEMO: http://jsbin.com/azexa4
Keep in mind you should probably mask the textbox to allow only numerical entries...Or maybe use a drop down list with a list of numbers to prevent error. But here is a great jquery mask plugin to prevent non-numerical entries.
<input type="text" name="Order" onKeyDown="checkVal(this)">3</input>
<div id="myDiv">
</div>
function checkVal(ctrl){
var val = ctrl.value;
$('myDiv').html(''); // remove existing elements
for (i=0;i<parseInt(val,10);i++){
$('#myDiv').append('<input type="text" />');
}
}

Is it possible to set the width of an element to that of the preceding element?

My input elements are followed by a div. I would like to set the width of that div to be that of the preceding input element.
<input type="text" class="input" size="100" name="data"/>
<div class="inputHelp"> enter data above </div>
<input type="text" class="input" size="80" name="moredata"/>
<div class="inputHelp"> enter more data above </div>
In each instance, the class .inputHelp should have the same width as the input element before it.
Using the next selector, I was able to grab the width of input elements followed by the inputHelp div.
However, when attempting to set the width of the following inputHelp div, it instead set the width of ALL inputHelp divs on the page. How can I limit it to only set the width of the next inputHelp, and then iterate through all the other input + inputHelp combinations on the page?
Here's my current JQuery code:
$('.input + .inputHelp').width( $('.inputHelp').prev('.input').width() );
$('.input + .inputHelp').each(function() {
$(this).width($(this).prev('.input').width();
});
The key to the solution is using $(this), rather than $('.inputHelp'). The latter grabs all .inputHelps globally, rather than the specific one you are looping on.
I wonder, is the .each solution needed - I'm just going to fire up my dev environment and test - more just a curiousity of mine as you've already marked Stuart B's answer correct (which it is).
Would the following not be equivalent:
$('.input + .inputHelp').width( $(this).prev('.input').width() );
I'll update this with a comment when I've tinkered, but as someone learning jQuery myselft, I'd love to hear if they're equivalent and if not why.
Thanks,
Terry

Categories

Resources