Ng-class with condition in AngularJS - html

I have the below popup where the user can encode item information.
My requirement is that, when Foreign Currency and Conversion Rate are both have values, it should multiply Foreign Currency * Conversion Rate to get the Amount. And when both Foreign Currency and Conversion Rate are 0, then Amount field should accept user input.
Currently, I have the below HTML.
<div class="form-group" show-errors>
<label for="foreignCurrency" class="control-label col-md-3 text-muted">Foreign Currency</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-dollar fa-lg"></i> </span>
<input type="number" id="foreignCurrency" name="foreignCurrency" class="form-control" placeholder="Foreign Currency" ng-model="vm.newItem.newItemEnt.ForeignCurrency" value="{{vm.newItem.newItemEnt.ForeignCurrency || 0}}" min="0" />
</div>
<p class="help-block" ng-if="perksFrm.foreignCurrency.$error.min">The minimum foreign currency value is 0</p>
</div>
<div class="form-group" show-errors>
<label for="convRate" class="control-label col-md-3 text-muted">Conversion Rate</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-money"></i></span>
<input type="number" id="convRate" name="convRate" class="form-control" placeholder="Conversion Rate" ng-model="vm.newItem.newItemEnt.ConversionRate" ng-required="vm.newItem.newItemEnt.ForeignCurrency" value="{{vm.newItem.newItemEnt.ConversionRate || 0}}" min="0" />
</div>
<p class="help-block" ng-if="perksFrm.convRate.$error.required">The conversion rate is required</p>
<p class="help-block" ng-if="perksFrm.convRate.$error.min">The minimum conversion rate is 0</p>
</div>
<div class="form-group" show-errors>
<label for="amount" class="control-label col-md-3 text-muted">Amount</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-money"></i></span>
<input type="number" id="amount" name="amount" class="form-control" placeholder="Amount" ng-model="vm.newItem.newItemEnt.Amount" required />
</div>
<p class="help-block" ng-if="perksFrm.amount.$error.required">The first name is required</p>
</div>
In Amount html, I can do it like this {{vm.newItem.newItemEnt.ForeignCurrency * vm.newItem.newItemEnt.ConversionRate}}. But, what if they have a 0 value and my requirement is to accept the user input from Amount textbox.
Any advise to achieve my requirements?
TIA

According to your requirment, I tried to provide you answer.
Please find Code for this, also JS fiddle demo.
HTML
<style>
.error{
border-color:red;
}
</style>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="row">
<div class="col-lg-2">Foreign Currency</div>
<div class="col-lg-2"><input type="number" ng-model="FCurrency" /></div>
</div>
<div class="row">
<div class="col-lg-2">Rate</div>
<div class="col-lg-2"><input type="number" ng-model="Rate" /></div>
</div>
<div class="row">
<div class="col-lg-2">Amount</div>
<div class="col-lg-2"><input ng-class="{error : RateAmount <= 0}" ng-disabled="isAmountDisable"
type="number" ng-model="RateAmount" /></div>
</div>
</div>
JS
var myApp = angular.module("myApp", []);
myApp.controller('myCtrl', function ($scope) {
$scope.RateAmount = 0;
$scope.isAmountDisable = false;
function setRateAmount() {
if ($scope.FCurrency > 0 && $scope.Rate > 0) {
$scope.RateAmount = ($scope.FCurrency * $scope.Rate);
$scope.isAmountDisable = true;
}
else {
$scope.RateAmount = 0;
$scope.isAmountDisable = false;
}
}
$scope.$watch('FCurrency', function (newval, oldval) {
setRateAmount();
});
$scope.$watch('Rate', function (newval, oldval) {
setRateAmount();
});
});
JS Fiddle Demo

Did you tried to use ng-change on foreignCurrency and convRate input.
when those input change you can calcul your amount value and disable it.
if they are both 0, you can enable it.
Something like this :
function change() {
var foreignCurrency = vm.newItem.newItemEnt.ForeignCurrency;
var conversionRate = vm.newItem.newItemEnt.ConversionRate;
if (foreignCurrency === 0 && conversionRate === 0) {
vm.enableAmout = true;
} else {
vm.enableAmout = false;
vm.vm.newItem.newItemEnt.Amount = foreignCurrency * conversionRate;
}
}

Related

How to change name attributes for auto added inputs and textareas?

I'm trying to create a cv creater form and need to let users add more inputs (auto).
I created inputs and they work just fine, but I need to change the name attribute for each auto added block.
For example :
<input type="text" id="fname" name="fname">
<input type="text" id="fname" name="fname2">
<input type="text" id="fname" name="fname3">
I know I can use name="value[]" array, but every new block goes into a different column in the database, so I need to change attributes.
My code :
$(document).ready(function() {
var max_fields = 10;
var wrapper = $("#contant");
var add_button = $("#add_form_field");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) {
x++;
$(wrapper).append('<div id="input-social" class="input-container"><input type="text" id="social" class="col-11 form-control" name="fname" placeholder="fname"> <span id="deleteInput" class="AutoInput" title="Delete"><i class="fas fa-trash-alt"></i></span></div>');
} else {
alert('You Riched limit.')
}
});
$(wrapper).on("click", "#deleteInput", function(e) {
e.preventDefault();
$(this).parent('#input-social').remove();
x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kit.fontawesome.com/e794a0f8b4.js" crossorigin="anonymous"></script>
<div class="form-group">
<div class="row">
<label class="col-3 inputFontSize" for="social">Others</label>
<div id="contant" class="col-7">
<button id="add_form_field" class="btn add_form_field">Add more <i class="fas fa-plus"></i></button>
</div>
<!-- col-9 -->
</div>
<!-- row -->
</div>
<!-- form-group -->
Thanks for all helps
You can use your x variable that is incremented for each added input and append it to the name attribute. We'll use a 'template string'. The adjustment is name="fname${x}" which will substitute ${x} for the value of x.
$(wrapper).append(`
<div id="input-social" class="input-container">
<input type="text" id="social" class="col-11 form-control" name="fname${x}" placeholder="fname">
<span id="deleteInput" class="AutoInput" title="Delete">
<i class="fas fa-trash-alt"></i>
</span>
</div>`
);
$(document).ready(function() {
var max_fields = 10;
var wrapper = $("#contant");
var add_button = $("#add_form_field");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) {
x++;
$(wrapper).append(`<div id="input-social" class="input-container"><input type="text" id="social" class="col-11 form-control" name="fname${x}" placeholder="fname"> <span id="deleteInput" class="AutoInput" title="Delete"><i class="fas fa-trash-alt"></i></span></div>`);
} else {
alert('You Riched limit.')
}
});
$(wrapper).on("click", "#deleteInput", function(e) {
e.preventDefault();
$(this).parent('#input-social').remove();
x--;
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kit.fontawesome.com/e794a0f8b4.js" crossorigin="anonymous"></script>
<div class="form-group">
<div class="row">
<label class="col-3 inputFontSize" for="social">Others</label>
<div id="contant" class="col-7">
<button id="add_form_field" class="btn add_form_field">Add more <i class="fas fa-plus"></i></button>
</div>
<!-- col-9 -->
</div>
<!-- row -->
</div>
<!-- form-group -->

Add CSS Class to Row Elements If Value Equals

Using JQuery I would like to check the value of an input, if it equals Complete I would like to add the Bootstrap class is-valid to that input, and all the other inputs on the same row.
Something like this (pseudo code);
if wb_status_reg = Complete {
// add is-valid to all row inputs / select boxes
}
I should note that sometimes the row will contain a select box, not just text inputs. Also, I'm unable to edit the html as it's being generated by a form builder component (in a CMS).
My code is currently working but I know it's too long and could be improved. In my code i'm showing one form-row but I actually have many more, so I need to duplicate this a few more times.
How can I achieve this in a more efficient way?
jQuery(document).ready(function($) {
var wb_stage_reg = $('#wb_stage_reg');
var wb_status_reg = $('#wb_status_reg');
var wb_date_reg = $('#wb_date_reg');
setIsValid($);
});
function setIsValid($) {
wb_stage_reg = ($(wb_status_reg).val().trim() == "Complete") ? $(wb_stage_reg).addClass("is-valid") : "";
wb_status_reg = ($(wb_status_reg).val().trim() == "Complete") ? $(wb_status_reg).addClass("is-valid") : "";
wb_date_reg = ($(wb_status_reg).val().trim() == "Complete") ? $(wb_date_reg).addClass("is-valid") : "";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-row">
<div class="col-3">
<div class="form-group rsform-block-wb-stage-reg">
<div class="formControls">
<div class="sp-input-wrap">
<input class="form-control" id="wb_stage_reg" name="form[wb_stage_reg]" type="text" value="Registration"><span></span>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="form-group rsform-block-wb-status-reg">
<div class="formControls">
<div class="sp-input-wrap">
<input class="form-control" id="wb_status_reg" name="form[wb_status_reg]" type="text" value="Complete"><span></span>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="form-group rsform-block-wb-date-reg">
<div class="formControls">
<div class="sp-input-wrap">
<input class="form-control" id="wb_date_reg" name="form[wb_date_reg]" type="text" value="2020-06-08 09:41:40"><span></span>
</div>
</div>
</div>
</div>
</div>
Something like this:
You need to change ID to class on all fields
Since you cannot, I use the name instead:
$(function() {
$("[name='form[wb_status_reg]']").each(function() {
const $parent = $(this).closest(".form-row");
const complete = this.value === "Complete";
$parent.find("[name='form[wb_date_reg]'], [name='form[wb_stage_reg]']").toggleClass("is-valid",complete)
})
});
.is-valid { color:green}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-row">
<div class="col-3">
<div class="form-group rsform-block-wb-stage-reg">
<div class="formControls">
<div class="sp-input-wrap">
<input class="form-control wb_stage_reg" name="form[wb_stage_reg]" type="text" value="Registration"><span></span>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="form-group rsform-block-wb-status-reg">
<div class="formControls">
<div class="sp-input-wrap">
<input class="form-control wb_status_reg" name="form[wb_status_reg]" type="text" value="Complete"><span></span>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="form-group rsform-block-wb-date-reg">
<div class="formControls">
<div class="sp-input-wrap">
<input class="form-control wb_date_reg" name="form[wb_date_reg]" type="text" value="2020-06-08 09:41:40"><span></span>
</div>
</div>
</div>
</div>
</div>

property 'name' does not exist on type 'FormComponent'

Here is the error Message:
WARNING in Invalid background value at 160:282. Ignoring.
WARNING in Invalid background value at 184:60084. Ignoring.
ERROR in src/app/form/form.component.html(14,48): : Property 'name' does not exist on type 'FormComponent'.
src/app/form/form.component.html(27,69): : Property 'homePhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(32,67): : Property 'cellPhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(37,71): : Property 'officePhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(168,21): : Property 'homePhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(169,21): : Property 'cellPhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(170,21): : Property 'officePhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(189,11): : Property 'NaN' does not exist on type 'FormComponent'.
src/app/form/form.component.html(14,48): : Property 'name' does not exist on type 'FormComponent'.
src/app/form/form.component.html(27,69): : Property 'homePhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(32,67): : Property 'cellPhone' does not exist on type 'FormComponent'.
src/app/form/form.component.html(37,71): : Property 'officePhone' does not exist on type 'FormComponent'.
Here is my form.component.html
<div [hidden]="submitted" >
<form #calculatingForm="ngForm" (ngSubmit)="onSubmit(calculatingForm)" class="ui big form">
<h2 class="ui dividing header">ProShine Quote Calculator</h2>
<div class="spacer30"></div>
<div class="ui grid">
<div class="row">
<div class="eight wide column">
<div class="required field">
<label for="name">Client Name</label>
<input type="text" name="name" [(ngModel)]="name" #client="ngModel" required autofocus>
<div [hidden]="client.valid || client.pristine" class="ui negative message">
<div class="header">
No Client Name Entered
</div>
<p>Please Enter A Name
</p>
</div>
</div>
<div class="field">
<label for="homePhone">Home Phone</label>
<input type="tel" name="homePhone" id="homePhone" [(ngModel)]="homePhone" placeholder="(123) 456-7890"
[textMask]="{mask: mask}">
</div>
<div class="field">
<label for="cellPhone">Cell Phone</label>
<input type="tel" name="cellPhone" id="cellPhone" [(ngModel)]="cellPhone" placeholder="(123) 456-7890"
[textMask]="{mask: mask}">
</div>
<div class="field">
<label for="officePhone">Office Phone</label>
<input type="tel" name="officePhone" id="officePhone" [(ngModel)]="officePhone" placeholder="(123) 456-7890"
[textMask]="{mask: mask}">
</div>
</div>
<div class="eight wide column">
<div class="required field">
<label for="totalPanes">Total Number of Panes</label>
<input type="number" name="totalPanes" id="totalPanes" [(ngModel)]="totalPanes" #panes="ngModel" required>
<div [hidden]="panes.valid || panes.pristine" class="ui negative message">
<div class="header">
You Didn't Enter A Number
</div>
<p>Please Enter the Number of Panes
</p>
</div>
</div>
<div class="field">
<label for="floorPanes">Number of Floor Panes</label>
<input type="number" name="floorPanes" id="floorPanes" [(ngModel)]="floorPanes">
</div>
<div class="field">
<label for="outsideLadderPanes">Number of Outside Ladder Panes</label>
<input type="number" name="outsideLadderPanes" id="outsideLadderPanes" [(ngModel)]="outsideLadderPanes">
</div>
<div class="field">
<label for="ladderPanesInAndOut">Number of Indoor AND Outdoor Ladder Panes</label>
<input type="number" name="ladderPanesInAndOut" id="ladderPanesInAndOut" [(ngModel)]="ladderPanesInAndOut">
</div>
</div>
</div> <!--End of row-->
<div class="spacer30"></div>
<div class="three column row">
<div class="four wide column"></div>
<div class="eight wide column">
<div class="required field">
<label for="currentUser">Created By</label>
<select name="currentUser" id="currentUser" class="ui fluid dropdown " [(ngModel)]="currentUser" required>
<option value="">-- Select --</option>
<option value="Jason Walle">Jason Walle</option>
<option value="Aubree Walle">Aubree Walle</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="column">
<h2 class="ui dividing header">Additional Options</h2>
<!-- <div class="spacer30"></div> -->
</div>
</div>
<div class="row">
<div class="eight wide column">
<div class="field">
<label for="referral">Referral By</label>
<input type="text" name="referral" id="referral" [(ngModel)]="referral" >
</div>
</div>
<div class="three wide column">
<div class="field">
<label for="clientDiscount">Discount</label>
<input type="text" name="clientDiscount" id="clientDiscount" [(ngModel)]="clientDiscount" >
</div>
</div>
</div>
<div class="row">
<div class="eight wide column"></div>
<div class="three wide column">
<div class="field">
<label for="discountType">Discount Type</label>
<select name="discountType" id="discountType" class="ui fluid dropdown " [(ngModel)]="discountType" required>
<option value="">-- Select --</option>
<option value="Percentage">Percentage(%)</option>
<option value="Dollars">Dollars($)</option>
</select>
</div>
</div>
</div>
</div>
<div class="spacer50"></div>
<button type="submit" class="ui blue button">Calculate</button>
<button type="button" class="ui olive button" (click)="calculatingForm.reset()">New Client</button>
<div class="spacer75"></div>
</form>
</div>
<div [hidden]="!submitted" class="results-div">
<button (click)="goBack()" class="ui blue button"> <i class="arrow alternate circle left outline icon"></i> Go Back</button>
<!-- ============ PDF Generating Section ============= -->
<div id="content">
<div class="ui grid">
<div class="three column row">
<div class="column"></div>
<div class="column">
<img src="./../../assets/proshine-card.jpg" alt="" class="proshine-logo">
</div>
<div class="column"></div>
</div>
</div>
<div class="spacer50"></div>
<div class="ui grid">
<div class="row">
<div class="twelve wide column">
<br>
<h2 class="">Client Name: <span style="margin-left: 50px;font-size: larger">{{ clientName }}</span></h2>
<div class="spacer30"></div>
</div>
<div class="eight wide column">
<h3>Home Phone #: {{homePhone}} </h3>
<h3>Cell Phone #: {{cellPhone}} </h3>
<h3>Office Phone #: {{officePhone}} </h3>
</div>
</div>
</div>
<hr>
<div class="spacer30"></div>
<div class="ui grid">
<div class="row">
<div class="eight wide column">
<h3># of Floor Panes: <h2>{{floorPanes}}</h2> </h3>
<h3># of OUTSIDE Ladder Panes: <h2>{{outsideLadderPanes}}</h2> </h3>
<h3># of Inside AND Outside Ladder Panes: <h2>{{ladderPanesInAndOut}}</h2> </h3>
</div>
</div>
</div>
<hr>
<!-- <h3>Original Quote: ${{clientDiscount - }} </h3> -->
<h3 *ngIf="clientDiscount!= NaN">Client Discount: <span style="color:firebrick">- ${{discountPrice}} </span> </h3>
<h1>Total Quote: <span class="quotePrice" >${{estimatedQuote}}</span> </h1>
<div class="spacer50"></div>
<h3>Created By {{currentUser}} on {{currentDate | date:'fullDate'}} </h3>
</div>
<div class="spacer50"></div>
<button class="ui orange button" (click)="downloadPDF()">Export As PDF</button>
<div class="spacer75"></div>
</div>
Here is my form.component.ts file
import { NavigationComponent } from './../navigation/navigation.component';
import { Estimate } from './../estimate';
import { NgForm, FormsModule } from "#angular/forms";
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit {
constructor(
) { }
// =========== Text Mask ==============
mask: any[] = ['+','1',' ', '(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]
// =========== Variables ===========
submitted = false;
// isOn = false;
costPerPane = 0.00;
costForLadder = 0.00;
costForFloorPanes = 0.00;
estimatedQuote = 0.00;
// quoteDemo = new Estimate("Phil",12,12,0,0,0);
clientName:string = "";
clientHomePhone:string;
clientCellPhone:string;
clientOfficePhone:string;
currentUser:string;
currentDate:string;
referral:string;
totalPanes:number;
floorPanes:number;
outsideLadderPanes:number;
ladderPanesInAndOut:number;
clientDiscount:number;
discountType:string;
discountPrice:any;
onSubmit(calculatingForm :NgForm){
this.submitted = true;
//Getting Form Input Values
this.clientName = calculatingForm.form.get('name').value;
this.clientHomePhone = calculatingForm.form.get('homePhone').value;
this.clientCellPhone = calculatingForm.form.get('cellPhone').value;
this.clientOfficePhone = calculatingForm.form.get('officePhone').value;
this.totalPanes = calculatingForm.form.get('totalPanes').value;
this.floorPanes = calculatingForm.form.get('floorPanes').value;
this.outsideLadderPanes = calculatingForm.form.get('outsideLadderPanes').value;
this.ladderPanesInAndOut = calculatingForm.form.get('ladderPanesInAndOut').value;
this.clientDiscount = calculatingForm.form.get('clientDiscount').value;
this.discountType = calculatingForm.form.get('discountType').value;
this.currentUser = calculatingForm.form.get('currentUser').value;
this.currentDate = Date.now().toString();
// ============ TOTAL QUOTE ==========
this.estimatedQuote = (this.costForFloorPanes + this.costForLadder);
//------ Discount Amount ----------
if (this.discountType == "Percentage") {
this.clientDiscount /= 100;
this.discountPrice = (this.estimatedQuote * this.clientDiscount);
this.estimatedQuote -= (Math.round(this.discountPrice));
this.discountPrice = (Math.round(this.discountPrice)).toString();
// this.estimatedQuote = (Math.ceil(this.estimatedQuote));
}else if(this.discountType == "Dollars"){
this.discountPrice = this.clientDiscount.toString();
this.estimatedQuote -= this.clientDiscount;
}else{
this.estimatedQuote = this.estimatedQuote;
}
}//End of onSubmit
public goBack(){
this.estimatedQuote = 0.00;
this.submitted = false;
}
public downloadPDF(){
return xepOnline.Formatter.Format('content', {render: 'download'});
}
ngOnInit() {
}
}
The error seems to be in the HTML:
[(ngModel)]="stufffffffs"
You have taken the wrong ngModel binding, the variables you have taken in component are not taken in form
In component you have taken,
clientName:string = "";clientHomePhone:string;clientCellPhone:string;
but in form you took,
Name:string = "";HomePhone:string;CellPhone:string;
You forgot to prepend client
Eg;
<input type="text" name="name" [(ngModel)]="name" #client="ngModel" required autofocus>
Should be,
<input type="text" name="name" [(ngModel)]="clientName" #client="ngModel" required autofocus>
so, replace all the occurrences with the same.
Use the same variables with ngModel that are defined in the component. It basically means there is a property in the component, that it is referring to. But as there is no such variable as "homePhone" in component, hence it is giving an error.
[(ngModel)]="clientHomePhone" instead of [(ngModel)]="homePhone"
<input type="tel" name="homePhone" id="homePhone" [(ngModel)]="clientHomePhone" placeholder="(123) 456-7890" [textMask]="{mask: mask}">
Similarly, for all other inputs for which the error is coming.
Read this for how ngModel works.

knockout does not change the radio button view

I have a working panel with radio buttons a label and a textfield. Everything works good except if i click on radio buttons explicitly the radio button does not change the radio button view.
Here the plnkr link to it:
https://embed.plnkr.co/auD0sMEL88EsuaQqvt7E/
As #user3297291 mention that the checked and click binding get in confict.
Add this binding:
ko.bindingHandlers.stopBubble = {
init: function(element) {
ko.utils.registerEventHandler(element, "click", function(event) {
event.cancelBubble = true;
if (event.stopPropagation) {
event.stopPropagation();
}
});
}
};
You have to add in every radio element this binding like this:
<input data-bind="checked: discountValue, stopBubble: true" id="discountArbitrary" name="discount" type="radio" value="arbitrary" />
I created one jsfiddle that works as you expected.
https://jsfiddle.net/astrapi69/s3r60uLu/
I guess the click binding is conflicting with checked binding.
You can use computeds to calculate enabled/focused flags.
You can check modified code (I've omitted focused flags in favor of simplicity):
// Code goes here
var DiscountViewModel = function() {
var self = this;
self.arbitrary = ko.observable();
self.percent = ko.observable();
self.permanent = ko.observable();
self.discountValue = ko.observable('arbitrary');
self.enableArbitrary = ko.computed(() => self.discountValue() === 'arbitrary');
self.enablePercent = ko.computed(() => self.discountValue() === 'percent');
self.enablePermanent = ko.computed(() => self.discountValue() === 'permanent');
self.onArbitrary = onArbitrary;
self.onPercent = onPercent;
self.onPermanent = onPermanent;
function onArbitrary() {
self.discountValue('arbitrary');
}
function onPercent() {
self.discountValue('percent');
}
function onPermanent() {
self.discountValue('permanent');
}
};
var vm = new DiscountViewModel();
ko.applyBindings(vm);
/* Styles go here */
.header-line {
margin-bottom:20px;
margin-top:20px;
margin-left:20px;
}
<script data-require="jquery#2.1.3" data-semver="2.1.3" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.3/js/tether.js"></script>
<link data-require="bootstrap#4.0.0-alpha.2" data-semver="4.0.0-alpha.2" rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css" />
<script data-require="bootstrap#4.0.0-alpha.2" data-semver="4.0.0-alpha.2" src="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js" type="text/javascript" defer="defer"></script>
<h1 class="header-line">
KO binding hasFocus over boolean values
</h1>
<div class="form-group row">
<div class="col-xs-1">
</div>
<div class="col-xs-1">
<input name="discount" type="radio" value="arbitrary" data-bind="checked: discountValue" />
</div>
<div class="col-xs-4">
<label for="arbitrary" data-bind="click: onArbitrary">Discount arbitrary</label>
</div>
<div class="col-xs-5">
<input type="text" class="form-control" id="arbitrary" placeholder="Enter arbitrary discount" data-bind="enable: enableArbitrary, value: arbitrary, hasFocus: enableArbitrary">
</div>
</div>
<div class="form-group row">
<div class="col-xs-1">
</div>
<div class="col-xs-1">
<input name="discount" type="radio" value="percent" data-bind="checked: discountValue" />
</div>
<div class="col-xs-4">
<label for="percent" data-bind="click: onPercent">Discount percent</label>
</div>
<div class="col-xs-5">
<input type="text" class="form-control" id="percent" placeholder="Enter percent of discount" data-bind="enable: enablePercent, value: percent, hasFocus: enablePercent">
</div>
</div>
<div class="form-group row">
<div class="col-xs-1">
</div>
<div class="col-xs-1">
<input name="discount" type="radio" value="permanent" data-bind="checked: discountValue" />
</div>
<div class="col-xs-4">
<label for="permanent" data-bind="click: onPermanent">Discount permanent</label>
</div>
<div class="col-xs-5">
<input type="text" class="form-control" id="permanent" placeholder="Enter permanent discount" data-bind="enable: enablePermanent, value: permanent, hasFocus: enablePermanent">
</div>
</div>
The problem is that by clicking the radio button, two things happen:
The checked binding does its thing
The event bubbles up to the parent element, and the click binding also does its thing.
You'll have to make sure clicking the input element stops the click binding from firing.
There's a great answer by R.P. Niemeyer here: https://stackoverflow.com/a/14321399/3297291

Validate date field

I am trying to disable the save button untill date is not picked. it is disabled but its not able to enbale untill i dont press any key from the keyboard.please tell me what i am doing wrong and thanks in advance.
<div class = "form-group" ng-class="{ 'has-error' : Form.fromTime.$invalid && !Form.fromTime.$pristine }">
<label for = "fromTime"> From Time:
<img src = "images/required.gif" alt = "Required" class = "required-star">
</label>
<div class='input-group date' id='fromTime' >
<input type='text' class="form-control" name="fromTime" ng-model = "fromTime" required />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<p ng-show="Form.fromTime.$invalid && !Form.fromTime.$pristine" class="help-block">From Time is required.</p>
</div>
<button type="button" class="col-sm-2 btn btn-primary" ng-click="scheduleCall()" style="margin-left:10px;" ng-disabled="Form.$invalid"> Save </button>
change:
ng-disabled="Form.$invalid"
to:
ng-disabled="Form.fromTime.$invalid"
You have to use like below
ng-disabled="Form.fromTime.$invalid"
Formname: Form;
Input field name : fromTime;
Input field state: $invalid
If i understand your problem correctly, you need to use a date input.
Now save button will be disabled until a valid date is picked.
function Ctrl($scope) {
$scope.fromTime = '';
$scope.scheduleCall = function() {};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app>
<div ng-controller="Ctrl">
<form name="Form">
<div class="form-group"
ng-class="{ 'has-error' : Form.fromTime.$invalid && !Form.fromTime.$pristine }">
<label for="fromTime">From Time:</label>
<div class='input-group date' id='fromTime'>
<input type='date' class="form-control" name="fromTime" ng-model="fromTime" required />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<p ng-show="Form.fromTime.$invalid && !Form.fromTime.$pristine"
style="font-size: 11px; color: red;">
From Time is required.
</p>
</div>
<button type="button" ng-click="scheduleCall()" ng-disabled="Form.$invalid">Save</button>
</form>
</div>
</div>