Angular JS - Using ng-show to show something based on complex requirements - javascript

I just started learning Angular JS, and I need a way to use ng-show to show a line of text by considering the following:
1.) If both number fields have been filled in, display the line of text.
2.) If both number fields have been filled in but both are 0, display the line of text.
3.) If both number fields have been filled in and one is 0 but the other is a different number, display the text.
This is my code so far:
<p ng-show="(firstNumber && secondNumber) || (firstNumber == 0 && secondNumber == 0)">
The product is {{firstNumber * secondNumber}}
</p>
Right now, this line of code fulfills requirements 1 and 2, but when 0 is entered and another number is entered which is not zero, the line of text doesn't show.
Any ideas on how to get this done? I feel like the conditional operation statement will be pretty complex.
I think I should include more of my code since many seem to assume that I have "text" as the input type when I have "number". This is probably why Charlie's solution isn't working:
<p>Enter first number: <input type="number" ng-model="firstNumber"></p>
<p>Enter second number: <input type="number" ng-model="secondNumber" /></p>

The collective logic of all your requirements is to see if both fields are numbers.
<p ng-show="isNumber(firstNumber) && isNumber(secondNumber))">
The product is {{firstNumber * secondNumber}}
</p>
In your controller
$scope.isNumber = function(value) {
return !isNaN(value)
}

It's a good idea to encapsulate every piece of complex logic into a function method of your controller or better yet a model i.e.:
.controller('MyCtrl', function($scope){
$scope.isResultVisible = function(){
return $scope.firstNumber >= 0 && $scope.secondNumber >= 0;
};
$scope.result = function(){
return $scope.firstNumber * $scope.secondNumber;
};
});
And then use it inside of markup:
<p ng-show="isResultVisible()">
The product is {{result()}}
</p>

Related

Partial Password Masking on Input Field

So I need to mask a SSN# input field, lets say the ssn is 123-45-6789, I need to display ***-**-6789 (real time as they enter each digit) but I still need to retain the original value to submit.
I got to the point where I can do that if the user strictly enters the value but it breaks if the user does anything else such as delete, or moving cursor to a random position and adds/deletes a number, copy pasting/deleting, etc. I really don't want to listen to a bunch of events to make this work if thats even possible.
I also tried having a div sit on top of the input field to display the masked ssn while the actual ssn was transparent/hidden behind it but again they lose the functionality of being able to add/delete/select delete/paste in random parts (other then when they start at the end) and also the cursor not totally in sync with the end of the ssn number (asterisk size was the issue). This also broke on some mobile browsers.
I also thought of having two separate input fields, one type password, and one type text sit right next to each other, but again highlighting and deleting/pasting between the two would be an issue.
Ideally if there was something out there to have an input field have two types, part of the value be type password and the rest be type text, that would be fantastic. Btw this is for react js app.
TLDR: Need a fully functional input field that will do password masking on only first 5 digits of ssn and be plaintext for last 4 digits (while having the full plaintext value available for submission).
Thanks!
This might be a little sloppy, but it works as you want it to, is all in one text field, returns the full accurate SSN (despite replacing first 5 values with bullet points), and allows for editing anywhere in the field.
<input type="password" id="ssn" maxlength=9 />
<script>
var ssn = document.getElementById('ssn');
ssn.addEventListener('input', ssnMask, false);
var ssnFirstFive = "";
var secondHalf = "";
var fullSSN = "";
function ssnMask(){
if (ssn.value.length <= 5){
ssn.type = 'password';
}
else{
detectChanges();
secondHalf = ssn.value.substring(5);
ssn.type = 'text';
ssn.value = "•••••";
ssn.value += secondHalf;
fullSSN = ssnFirstFive + secondHalf;
}
}
function detectChanges() {
for (var i = 0; i < 5; i++){
if (ssn.value[i] != "•"){
ssnFirstFive = ssnFirstFive.substring(0, i) + ssn.value[i] + ssnFirstFive.substring(i+1);
}
}
}
</script>
Essentially, every time the input is changed, it checks to see if it matches the first 5 from before, and if it doesn't, it will update the necessary characters.
You can use 3 different fields and make then password fields.
Add a focus handler that changes their type into text and a blur handler that changes them back to password.
You can combine them before submission or on the server.
#ssn1{width:25px;}
#ssn2{width:20px;}
#ssn3{width:35px;}
<input type="password" name="ssn" maxlength=3 id="ssn1" />
<input type="password" name="ssn" maxlength=2 id="ssn2"/>
<input type="password" name="ssn" maxlength=4 id="ssn3"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$('[name="ssn"]').focus(function() {
$(this).attr("type", "text")
});
$('[name="ssn"]').blur(function() {
$(this).attr("type", "password")
});
</script>
You can also write a pass handler to all a full SSN to be pasted in the first field and have all three fields get set.
This is the closest you are going unless you work with a single full text box and give the user the ability to mask and unmask the field.
In production apps, this actually the approach I take:
Masked:
Unmasked:
You can implement you own focus/blur functions to automatically unmask/mask the field as needed.
Achieve this using html data attributes.
i have used the same html tag and store actual value in html tag attribute (data-value) to use later on and store value to display in html tag attribute value.
Function to partial mask input value
function mask_field_value(obj, mask_letters_count=7){
mask_value = $(this).data('mask-value') || '';
unmask_value = $(this).data('unmask-value') || '';
if (obj.value.length <= mask_letters_count){
obj.type = 'password';
mask_value = obj.value;
$(this).data('mask-value', obj.value);
} else {
obj.type = 'text';
unmask_value = obj.value.substring(mask_letters_count);
obj.value = "*".repeat(mask_letters_count) + unmask_value;
$(this).data('unmask-value', unmask_value);
}
$(this).data('value', mask_value + unmask_value);
console.log($(this).data('value'));
}
Add an event on input fields to mask
$(document).ready(function () {
$(document).on('keyup', '.mask_input_display', function () {
mask_field_value(this);
});
});

Number pipe gives string value instead of number

I have the following lines of code. It's basically an input field in my html. I am adding a number pipe to it since it's a currency field. By default it's empty, when the user adds value to it, it should autoformat it as currency. But am getting a rare issue here.
vendor.dll.js:55094 EXCEPTION: Invalid argument '8,888.038' for pipe 'DecimalPipe'
HTML:
<div class="form-input">
<cust-input
[ngModel]="Amnt | number:'.2-2'"
(ngModelChange)="Amnt=$event"
type="tel"
(keyup)="getAmount(RqstdAmnt)"
[ngClass]="{'inValid-requested-amount-class': AmountValid===false}"
placeholder="{{'amount_placeHolder' | translate}}">
</cust-input>
</div>
TS:
RqstdAmnt:number;
getRequestedAmount(amount:number) {
if (amount > somevalue) {
console.log('value higher');
} else {
console.log('value lower');
}
}
May I know what's the right way to do it? We can have another way, when user clicks on the input field no pipe, when the mouseout add the currency pipe. I am not sure how to do that. Can you guys guide me how can I do that? Thanks in advance.
Using a pipe with ngModel is not the best idea, as when user is typing the pipe will run at every keystroke. I have implemented similar scenario using blur and focus. .00 gets added and removed depending on user input and doesn't interfere with the interaction.
Here's the code if you want to use it in yours:
html:
<md-input-container class="example-full-width">
<input mdInput placeholder="Amount"
type="number"
[(ngModel)]="amount"
formControlName="amount"
(blur)="format(amount)"
(focus)="remove(amount)">
</md-input-container>
ts:
format(amt){
// console.log(amt % 1 == 0);
if(amt % 1 == 0){
amt = amt + '.00';
this.amount = amt;
}
}
remove(amt){
// console.log(amt % 1 == 0);
if(amt % 1 == 0){
this.amount = amt * 1;;
}
}
submit(form){
alert(JSON.stringify(form));
}
Plunker demo

Simple Guess my Number Game in Javascript

I'm working on a javascript program that is a simple guessing game. It comes up with a random number between 1 and 10 and provides an input field and a button for the user to make their guess. The program tells after each guess whether the user guessed too high or too low, and it keeps up with the number of guess it took the user to get the correct answer which it displays along with a "congratulations" message when they get it right.
I'm having some trouble getting it to work properly. The page displays properly, but when I enter a guess and click my submit button, nothing happens.
Here is my code:
<html>
<head>
<title>Guess My Number</title>
<script type="text/javascript">
var game = {
num : 0,
turns : 1,
reset : function() {
this.turns = 1;
this.newNum();
},
newNum() : function() {
this.num = parseInt(Math.random() * 10) +1;
},
checkNum() : function(guess) {
try {
guess = parseInt(guess);
}
catch(e) {
alert("Enter a guess!");
this.turns++;
return false;
}
if (guess == this.num) {
alert("Correct! It took you " + this.turns + "turns to guess my number.");
return true;
}
else if(guess > this.num) {
alert("Your guess is too high. Try again.");
this.turns++;
return false;
}
else (guess < this.num) {
alert("Your guess is too low. Try again.");
this.turns++;
return false;
}
}
};
function guessNumber() {
var guess = document.getElementById("guess").value;
game.checkGuess(guess);
}
function resetGame() {
game.reset();
}
resetGame();
</script>
</head>
<body>
<h1>Would You Like To Play A Game?</h1>
<h2>Thank you for checking out my game. Good luck!</h2>
<h3>Created by Beth Tanner</h3>
<h2>Directions:</h2>
<p>
The game is very simple. I am thinking of a number between 1
and 10. It is your job to guess that number. If you do not guess
correctly on your first attempt, don't worry, you can keep guessing
until you guess the correct number.
</p>
<p>
Your Guess: <input type="text" id="guess" size="10" />
<br />
<input type="button" value="Sumbit Guess" onclick="guessNumber()" />
<input type="button" value="Reset Game" onclick="resetGame()" />
</p>
</body>
</html>
I've never actually worked with Javascript before so I know this is probably a very basic thing that I'm overlooking. Any ideas as to why this isn't working correctly?
You variable guess is undefined.
Just initialize it with :
var guess = 0;
However be careful there's a possibility that num is initialize to 0. So, the user guessed immediatly without doing nothing.
var num = Math.random() *10 + 1;
BR
You should call your function in first place, one possible thing you can do is:
<input type = "button" value = "Submit Guess" onclick="guessNumber()">
now that your function is called you need to get the value entered by the user into your guess variable, which I don't see in your code, you can do it as:
Your guess:<input type = "text" name = "guess" size = "10" id="guess" /> <br />
and then in your java script initialize the variable guess as:
guess=document.getElementById("guess").value;
This should do the thing!
EDIT:
Also make sure that Math.random() returns an Integer,as others have suggested use Math.ceil() !
Several other answers have pointed out some issues in the test code:
type="submit" but no <form> tags.
Misspelled variable name tunrs instead of turns.
Use of the while loop
No event connections between the buttons and the JavaScript
This is a simple code example, and there are so, SO many ways to tackle it in JavaScript. Here is my method.
When creating a simple game board where the page does not need to be reloaded, I like to create a game object. In JavaScript you can create objects in a variety of ways. But one of the simplest is this:
var game = {};
This creates an empty object with no properties or methods. To create a couple of properties:
var game = {
num: 0,
turns: -1
};
Each of these properties can be referenced globally like var x = game.num;. To create the object with a function:
var game = {
num: 0,
turns: 0,
reset: function() {
this.turns = 0;
//get a random integer between 1 and 10
this.num = parseInt(Math.random() * 10) + 1;
//Note: "this" lets you refer to the current object context. "game" in this case.
//There are a couple of ways to force the value to an Int, I chose parseInt
}
};
Game now has a game.reset() function that will set game.turns back to 0 and get a new game.num. Here is the full javascript code for my example (slightly different than the above examples):
<script type="text/javascript">
//Create an object to hold the game info
var game = {
num : 0,
turns : 0,
reset : function() {
//function to reset
this.turns = 0;
this.newNum();
},
newNum : function() {
//get a random integer between 1 and 10
this.num = parseInt(Math.random() * 10) + 1;
},
checkGuess : function(guess) {
//try to convert the guess into a integer
try {
guess = parseInt(guess);
} catch(e) {
alert("Enter a guess!");
this.turns++;
return false;
}
//perform strict check of equality
if (guess === this.num) {
alert("Correct! It took you " + this.turns + " turn(s) to guess my number");
return true;
} else if (guess > this.num) {
alert("Your guess is too high. Try again.");
this.turns++;
return false;
} else {
alert("Your guess is too low. Try again.");
this.turns++;
return false;
}
}
};
function guessNumber() {
var guess = document.getElementById("guess").value;
game.checkGuess(guess);
}
function resetGame() {
game.reset();
}
resetGame();
</script>
Note: I didn't do a window.onload event here because those are only needed when the code will be interacting with elements on the document, or DOM elements. If you try to execute JS code in the head of the document, it gets executed instantly before the rest of the document gets loaded. This is bad if your JS code is trying to get, set, or manipulate elements in the page because you're still in the head and the body hasn't been loaded yet.
So in the case where your code needs to get access to elements of the page, often a window.onload = someInitFunction(); will be used so that the JS code will be executed after the document has completed it's load.
Below is my HTML code. It is mostly similar to your code except that I change the name attribute to id on the "guess" input to make it easier to access with document.getElementById(). Using name is helpful when you are in a form and will be submitting values to a server. Only fields with the name attribute set get submitted in that case. Often on forms you will have something like <input type="text" id="textfield" name="textfield" />. The id is used in JavaScript for easy of access, and name is used when submitting the form back to the server.
I also added onclick attributes to the buttons, and changed the input type="submit" to input type="button".
<h1>Would You Like To Play A Game?</h2>
<h2>Thank you for checking out my game. Good luck!</h2>
<h3>Created by Beth Tanner</h3>
<h2>Instructions</h2>
<p>
The game is very simple, I am thinking of a non-decimal number between 1 and 10
and it is your job to guess what that number is. If you do not guess my number
correctly on your first attempt, that's ok, you can keep guessing until you are correct.
</p>
<p>
Your guess:<input type="text" id="guess" size = "10" />
<br />
<input type="button" value = "Submit Guess" onclick="guessNumber()" />
<input type="button" value = "Reset Game" onclick="resetGame()" />
</p>
Here is a JSFiddle example that operates, I believe, the way you want it to.
update
As I was saying there are so many ways to do this. Here is an alternate way to give number selections.
A few issues with your code:
Math.random()*10 will return something that looks like 8.523525235, so you'll have a hard time matching that to any guesses. Instead, use Math.ceil(Math.random()*10). This generates a random number and then rounds up to the nearest integer.
In your JavaScript code, you're calling guessNumber() on the last line, which will execute the function as soon as the browser gets to that line. This will mean the function being executed before the user puts in any guesses. Instead you need to attach an event listener to the button, so that when the button is clicked, guessNumber() is called. Something like:
document.getElementById('button').addEventListener('click', guessNumber).
Right now you're not setting the variable guess in any way. You need to grab the value of the text box and assign that to guess. Something like:
guess = document.getElementById('textbox').value
Using a while loop is not appropriate here, since the user is using the textbox and the button to submit guesses each time. There are ways of doing this with a while loop, but let's stick with your current setup.
You want something that resembles this:
HTML:
<p>Your guess:
<input type="text" id="textbox" />
<input type="button" id="button" value="Guess" />
</p>
JS:
var rand = Math.ceil(Math.random()*10);
var turns = 0;
var guess;
document.getElementById('button').addEventListener('click', guess);
function guess() {
guess = document.getElementById('textbox').value;
if (guess == rand) {
alert('Correct! It took you ' + turns + ' turns to guess the number!');
} else if (guess < rand) {
alert('Your guess is too low. Try again.');
turns++;
} else if (guess > rand) {
alert('Your guess is too high. Try again.');
turns++;
} else {
alert('You didn\'t enter a number. Try again.');
}
}
Here's a fiddle. I added some for the reset functionality.

How do I execute a JavaScript function from clicking an HTML button?

I am trying to write a short piece of html code that, given two initial amounts, attempts to find the number greater than or equal to the first that wholly divides the second given amount. The code tries to divide the numbers, and if it is unsuccessful, adds 1 to the first number and tries to divide again, etc...
I want the code to return the value that does wholly divide the second number AND the answer to the division (with some plain text appearing around it).
Added to this, or at least I'd like there to be, is that upon clicking one of 5 different buttons a multiplication operation is performed on the first given number, it is rounded up to the nearest whole number, and THEN the function attempts to divide this into the second given number.
It's difficult to explain exactly what I want without showing you the code I have so far, so here it is:
<html>
<head>
<b>Rounded Commodity Pricing:</b><br>
<script language="Javascript">
function finddivid(marketprice,tradevalue) {
var KWDex = 0.281955
var GBPex = 0.625907
var USDex = 1
var CADex = 0.998727
var EURex = 0.784594
if
(currency == "KWD")
var currencyMarketprice = Math.ceil(marketprice*KWDex)
else if
(currency == "GBP")
var currencyMarketprice = Math.ceil(marketprice*GBPex)
else if
(currency == "USD")
var currencyMarketprice = Math.ceil(marketprice*USDex)
else if
(currency == "CAD")
var currencyMarketprice = Math.ceil(marketprice*CADex)
else if
(currency == "EUR")
var currencyMarketprice = Math.ceil(marketprice*EURex)
if (tradevalue % currencyMarketprice == 0)
return ("tonnage = " + tradevalue / currencyMarketprice + " mt, and price = " + currencyMarketprice +" " +currency +" per mt");
else
{for (var counter = currencyMarketprice+1; counter<(currencyMarketprice*2); counter++) {
if (tradevalue % counter == 0)
return ("tonnage = " + tradevalue / counter + " mt, and price = " + counter +" " +currency +" per mt");}}};
</script>
</head>
<p>Select currency:
<input type="button" value="KWD" OnClick="var currency = KWD">
<input type="button" value="USD" OnClick="var currency = USD">
<input type="button" value="GBP" OnClick="var currency = GBP">
<input type="button" value="EUR" OnClick="var currency = EUR">
<input type="button" value="CAD" OnClick="var currency = CAD">
<P>Enter today's price of commodity in USD: <input name="mktprc" input type="number"><br><p>
<P>Enter value of trade: <input name="trdval" input type="number">
<input type="button" value="Calculate" OnClick="showMeArea.value=finddivid(mktprc,trdval);">
<p>
<br><br>
<input name="showMeArea" readonly="true" size="30">
</html>
If you run this html in your browser you should see what I am trying to achieve.
It is far from complete but here are the main problems/features that I need help with:
I would like to be able to click on one of the 'currency' buttons so that upon clicking, the variable 'currency' is assigned and then used in the function finddivid.
(2. This isn't as important right now, but eventually, once this is working, I'd like it so that upon clicking one of the currency buttons, it changes colour, or is highlighted or something so that the user knows which currency rate they are using.)
Upon entering the numbers into the two boxes I would like to click 'Calculate' and have it return what I've written in the function into the 'showMeArea' read-only box at the end of the code.
I know I'm probably missing loads of stuff and I might be miles away from success but I am very new to programming (started 4 days ago!) so would like any like of help that can be offered.
Thanks in advance of your comments.
The first request requires that you put the currency into the actual script, and I would recommend using a setter function:
<script language="Javascript">
var currency; // you might want to set this at a default just in case
function setCurrency(val) { currency = val; } // Setter function
function finddivid(marketprice,tradevalue) {
Then call it in your button click:
<input type="button" value="KWD" onClick="setCurrency('KWD');">
As for the second request, I'd say you have the concept down well enough, but you don't have the method exactly right. First your inputs will need an id attribute:
<input name="mktprc" id="mktprc" input type="number">
<input name="trdval" id="trdval" input type="number">
The name attribute is used for posting values, the id attribute is used by javascript to find elements within a page. Using jQuery would make retrieving these elements easy, but I'll show both the jQuery and the standard JavaScript method of doing this:
jQuery:
<input type="button" value="Calculate" OnClick="$('#showMeArea').val(finddivid($('#mktprc'),$(#'trdval')));">
The $('#id') selects an element. The method .val() sets the value.
Note for the jQuery purists: Yes, there are much better/sophisticated ways to accomplish this with jQuery, but this answer is targeted to my perception of OP's JavaScript capability.
Standard Javascript:
<input type="button" value="Calculate" OnClick="document.getElementById('showMeArea').value = finddivid(document.getElementById('mktprc'),document.getElementById('trdval'));">

javascript calculator to decimal places and images as button

i have a small javascript form
<div id="calculator-text"><h2>Tape calculator - based on cable size 1 mm to 28 mm, with 15% overlap</h2></div>
<form name="form1" method="post" action="">
<div id="calcformlabel"><label for="val2">Enter your cable size</label> (in mm)</div>
<div id="calcformtext1"><input type="text" name="val2" id="val2"></div>
<div id="calcformbutton"><input type="button" name="calculate" id="calculate" value="Calculate"></div>
<div id="calcformresult">The tape size you require is:- <span id="result1" class="maintext1"></span> (mm)</div>
</form>
<script type="text/javascript">
var btn = document.getElementById('calculate');
btn.onclick = function() {
// get the input values
var val2 = parseInt(document.getElementById('val2').value);
// get the elements to hold the results
var result1 = document.getElementById('result1');
// create an empty array to hold error messages
var msg = [];
// check each input value, and add an error message
// to the array if it's not a number
if (isNaN(val2)) {
msg.push('<span class="maintext1">Enter your cable size</span>');
}
// if the array contains any values, display the error message(s)
// as a comma-separated string in the first <span> element
if (msg.length > 0) {
result1.innerHTML = msg.join(', ');
} else {
// otherwise display the results in the <span> elements
result1.innerHTML = val2 * 3.142 * 1.15;
}
};
</script>
basically this is a simple calculation
a) how can i get this to output to 2 decimal places (and obviously round up or down depending on -.5 = round down and +.5 = round up)
b) replace the input type button for an image ( i have tried the obvious code and >input type = image>, basically these do actually work but instead of displaying the actual result, they display the result in a split second then reload the page with the blank form again...
any help on this would be much appreaciated
thanks in advance
for a part of your question
you can round javascript to specific precision by
Link :Number rounding in JavaScript
var original=28.453
1) //round "original" to two decimals
var result=Math.round(original*100)/100 //returns 28.45
2) // round "original" to 1 decimal
var result=Math.round(original*10)/10 //returns 28.5
3) //round 8.111111 to 3 decimals
var result=Math.round(8.111111*1000)/1000 //returns 8.111
The .toFixed() method lets you round off to n decimal places, so:
result1.innerHTML = (val2 * 3.142 * 1.15).toFixed(2);
I think the problem you're having with the image is that <input type="image"> defines the image as a submit button. Perhaps just include a standard image with an <img> tag rather than <input type="image">. If you give it an id='calculate' it should still work with your existing JS.
Or you could use a button element containing an img element so that you can specify the type (as not being submit):
<button type="button" id="calculate"><img src="yourimage"></button>
(I'm not sure that you need a form at all for this functionality since you don't seem to want to submit anything back to the server.)
To swap the button for an image, replace the button <input> with this code:
<img src="http://www.raiseakitten.com/wp-content/uploads/2012/03/kitten.jpg" name="calculate" id="calculate" value="Calculate" onclick="document.forms['form1'].submit();" />
It adds the image and a submit function for your form.
To round to two decimal places, use this function:
function twoDP(x){
return Math.round(x*100)/100
}
use it like this:
twoDP(100/3) //returns 33.33
it might also be relevant for you to use Math.PI
var result = val2 * Math.PI * 1.15 ;

Categories

Resources