Calendar icon not opening the calendar in angularjs - angularjs

I want to open my calendar from both 1. on clicking the textbox and 2. on clicking the calendar Icon
<div class="form-group">
<div class='input-group'>
<input type='text' class="form-control" datepicker-popup
ng-model="model.start" is-open="opened.start" id='start'
ng-click="opened.start = !opened.start" />
<span class="input-group-addon" for='start' ng-click="opened.start = !opened.start">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
And controller code:
app.controller('dateCtrl', ['$scope', function ($scope) {
$scope.model = {
start: new Date('12/31/2014'),
end: new Date()
};
$scope.opened ={
start: false,
end: false
};
}]);
when I am clicking on the textbox it is working, but when I am clicking on calendar icon, nothing happening.
See the plunker.

Use labels instead of spans, they are designed for this purpose. Just make sure to set up correct for and corresponding id attributes:
<div class='input-group'>
<input type='text' class="form-control" datepicker-popup
ng-model="model.start" is-open="opened.start" id='start'
ng-click="opened.start = !opened.start" />
<label class="input-group-addon" for='start'>
<span class="glyphicon glyphicon-calendar"></span>
</label>
</div>
Clicking on HTMLLabelElement generates click event on the related input field, so in this case you get intended behaviour.
Demo: http://plnkr.co/edit/xGPVMPPTOlzOhFIVdhG4?p=preview
UPD. Since you need toggle functionality, then in this case you indeed need javascript solution. Here we go, you need to prevent event bubbling, because Angular listens for events on the document level and closed calendar immediately:
<span class="input-group-addon" ng-click="opened.start = !opened.start; $event.stopPropagation()">
<span class="glyphicon glyphicon-calendar"></span>
</span>
Demo: http://plnkr.co/edit/CmJK1M0icGpKvd38S9mK?p=preview

Related

button onclick using AngularJS

I need to add a button to my Form in which if I click that button it should show me a text area and a Submit button so after typing any text I will click the submit button it should print the checkbox in my form using AngularJS.
Same as in the above pic. I am new to typescript so help me to fix this
Use the ngClick directive:
<button ng-click="yourFunction()">OK</button>
https://docs.angularjs.org/api/ngTouch/directive/ngClick
Also, please read the documentation or a tutorial/example before you ask such a basic question...
<div data-ng-controller="homeController">
<div class="col-lg-1">
<span class="glyphicon glyphicon-plus-sign" style="cursor:hand" aria-hidden="true" title="Add More" ng-click="onEnable()"></span>
</div>
<div class="col-lg-5">
<input type="text" ng-if="isEnableTextBox" ng-model="model.label" name="dynamic" class="form-control">
</div>
<div class="col-lg-5">
<button type="button" class="btn btn-primary" ng-disabled="!model.label" ng-click="onAddCheckBox()">Submit</button>
</div>
<div class="col-lg-12">
<div class="checkbox col-lg-12" ng-repeat="checkBox in checkBoxes track by $index">
<input type="checkbox" name="name_{{$index}}" id="name_{{$index}}" ng-model="checkBox.selectedCheckBox" class="filled-in square chk-col-pink ng-pristine ng-untouched ng-valid ng-empty" checked="checked" aria-invalid="false">
<label for="checkBox.label">{{checkBox.label}}</label>
</div>
</div>
</div>
function init() {
$scope.isEnableTextBox = false;
$scope.checkBoxes = [];
$scope.model = {};
}
$scope.onEnable = function onEnable() {
$scope.isEnableTextBox = true; // Enable text box on Click Plus Icon
};
$scope.onAddCheckBox = function onAddCheckBox() { // On submit button click push the given name into array and empty the text box. Please refer the attached image.
var _checkBoxModel = angular.copy($scope.model.label);
$scope.model.label = "";
$scope.checkBoxes.push({'label': _checkBoxModel, 'selectedCheckBox': true});
};
init();
Sample Image

Angular bootstrap datepickers open when user presses Enter key on unrelated input field

I have 2 datepickers, 'from' date and 'to' date in a search from. Also a few input fields for different search criteria, and a submit button.
When focus is on a text field and the user presses Enter, instead of sending the form the focus moves to the first of the datepickers and opens the calendar view of it.
Markup for the form (partial for relevance):
<div class="form-group">
<label class="col-xs-3 control-label" for="txtSupplierList" translate>Supplier</label>
<div class="col-xs-4">
<input class="form-control"
id="txtSupplierList"
type="text"
ng-model="vm.supplierName"
placeholder="{{'name or ID'| translate}}"
ng-keyup="vm.searchAppls()" />
</div>
</div><!-- #form-group -->
<div class="form-group value">
<label class="col-xs-3 control-label" for="dateFrom" translate>Created date from</label>
<div class="col-xs-3">
<p class="input-group p-group-format">
<input class="form-control"
type="text"
ng-click="open1($event,'opened1')"
is-open="opened1"
max-date="maxDate"
placeholder="{{'dd/mm/yyyy' | translate}}"
datepicker-options="dateOptions"
ng-required="true"
datepicker-popup="{{format}}"
ng-model="vm.from"
current-text="{{'Today'| translate}}"
toggle-weeks-text="{{'Weeks'| translate}}"
clear-text="{{'Clear'| translate}}"
close-text="{{'Close'| translate}}"
ng-change="vm.logicalDates(vm.from, vm.to)" />
<span class="input-group-btn">
<button class="btn btn-standard" ng-click="open1($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
<div class="value form-group pull-right" ng-if="!vm.logicalDatesBool">
<div class="note note-error" translate>'From' date should preceed 'to' date</div>
</div>
</p>
</div>
<label class="col-xs-1 middleLabel" for="dateUntil" translate>to</label>
<div class="col-xs-3">
<p class="input-group p-group-format">
<input class="form-control"
type="text"
ng-click="open2($event, 'opened2')"
is-open="opened2"
max-date="maxDate"
placeholder="{{'dd/mm/yyyy' | translate}}"
datepicker-options="dateOptions"
ng-required="true"
datepicker-popup="{{format}}"
ng-model="vm.to"
current-text="{{'Today'| translate}}"
toggle-weeks-text="{{'Weeks'| translate}}"
clear-text="{{'Clear'| translate}}"
close-text="{{'Close'| translate}}"
ng-change="vm.logicalDates(vm.from, vm.to)" />
<span class="input-group-btn">
<button class="btn btn-standard" ng-click="open2($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</div>
</div><!-- form group -->
To divide behavior between the 2 datepickers I have a in my controller this code (options etc omitted for brevity):
vm.open = open;
$scope.open1 = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened1 = true;
};
$scope.open2 = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened2 = true;
};
There is more to the form, 6 standard input fields in total, nothing special about them, then a submit button at the end.
So, to reiterate: the issue is that when the user has focus on the Supplier text input or any other, and then presses Enter, instead of the form being sent (ie a search returns results) the first of the datepickers opens to display the calendar. What's binding the calendar to the Enter key?
Why is this happening and how can I fix it?
Answering my own question because there are answers here on SO, but they have titles that make them hard to find, and Google's results show the UI-Datepicker Github where they claim to have fixed this bug on multiple occasions but clearly have not done so.
So, answer is here by user rahil-wazir
For each of my input elements I added the attribute:
ng-keypress="keyPress($event)"
The whole element looks like this:
<input class="form-control"
id="fooID"
ng-model="vm.foobar"
maxlength="100"
placeholder="{{'Foo name'|translate}}"
ng-keyup="vm.searchFunction()"
ng-keypress="keyPress($event)" />
and then in my Controller function I added a new function like this:
$scope.keyPress = function(e) {
// console.log(e);
if (e.charCode == 13) {
e.stopPropagation();
e.preventDefault();
e.bubbles = false;
searchFunction();
return false;
}
}
As you can see, I also wanted to perform a search when the Enter key is pressed, so the keyPress function calls that. Nothing to do with the datepicker.

Angular directive open date picker

I have an Angular directive that includes a form with a datepicker. I am trying to create a function to keep the button click from calling submit on the form. I can not determine where to find the .opened attribute. When I was performing the open with ng-click everything worked. Below is sample code.
HTML:
<form ng-submit="editAlert.$valid && vm.handleSubmit()" name="editAlert" id="editAlert" class="buffer-bottom" novalidate>
<div class="form-group">
<label class="control-label" for="effectiveDate">Effective Date</label>
<div class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="MM-dd-yyyy" is-open="dpEffectiveDate.opened" ng-model="alertMsg.effectiveDateFmt" name="effectiveDate" id="effectiveDate">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="vm.openDateHandler($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
<p class="help-block" ng-show="editAlert.effectiveDate.$error.endBeforeStart">Effective date must be before expire date.</p>
</div>
</form>
I also tried passing dpEffectiveDate into the openDateHandler function.
Below is my Typescript function
openDateHandler = ($event) => {
$event.preventDefault();
//dpDate.opened = !dpDate.opened;
}
How do I access the .opened attribute?
If all you are trying to do is prevent the submit behaviour, simply add 'type="button"' to your button element.
<button type="button" class="btn btn-default" ng-click="vm.openDateHandler($event)">
By default, a button inside a form will act as a submit button unless it's given a different type.
You shouldnt need to mess with the opened state of a date picker to prevent a form submitting.

Issue with ng-model and ng-repeat, duplicate forms

I have a page where multiple forms are created based on ng-repeat. Everything works fine until write something into the input and everything gets duplicated on all the other repeated forms input elements. I have used ng-model="Notify.message" which is nothing but object which takes the value from the input and sends to control on button submit and hence rest of the logic.
I am looking for when if one form is been filled, other forms should keep quite and shouldn't duplicate the values written in input text of form 1.
Here is the code:
<div data-ng-show="alluserposts.length > 0">
<div id="b{{userpost.id}}" data-ng-repeat="userpost in alluserposts" >
<div class="row" style="margin-left: -5px">
<form class="text-center" role="form" id=f1{{userpost.id}} name="userForm"
ng-submit="notify(userForm.$valid, userpost, apiMe)" novalidate>
<div class="row">
<div class="col-xs-8 col-md-4">
<div class="form-group">
<input data-container="body" data-toggle="popover" data-placement="top"
data-content="Any message which you would like to convey to post owner"
type="text" ng-model="Notify.message" data-ng-init="Notify.message=''"
id="u{{userpost.id}}"
placeholder="Enter a Message or Phone number" class="form-control"
required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">It is
required.</p>
<script>$(function () {
$("[data-toggle='popover']").popover();
});
</script>
<input type="hidden" ng-model="Notify.loggedInEmail"
ng-init="Notify.loggedInEmail = result.email"/>
<input type="hidden" ng-model="Notify.postId" ng-init="Notify.postId = userpost.id"/>
<input type="hidden" ng-model="Notify.destEmail"
ng-init="Notify.destEmail = userpost.userEmail"/>
</div>
</div>
<div ng-show="loginStatus.status == 'connected'" class="col-xs-4 col-md-2">
<button class="btn btn-primary" ng-disabled="userForm.$invalid || !userForm.$dirty"
type="submit">
Notify Post Owner
</button>
</div>
</div>
</form>
</p>
</div>
</div>
</div>
</div>
Issue fiddle - jsfiddle
Here you can when something is written in one input, other gets filled too :( . Also Notify is a Java mapped object and message is a variable inside it. Pls let me know how can this can be segragated!
You bind all of your inputs to same variable on $scope.
You must bind every text box to a distinct variable on $scope:
View:
<ul ng-repeat="post in posts">
<li>{{$index}}
<input type="text" ng-model="emails[$index]"/>
</li>
</ul>
Controller:
$scope.emails = [];
I am also at the starting phase of angularjs.
I have faced the same issue few days ago and resolved it by providing dynamic model name in ng-model like
<input type="text" ng-model="Notify[post.userEmail]" ng-init="Notify[post.userEmail] = post.userEmail" />
Working fiddle: Fiddle

Angular.js What is the best way to determine which button caused submit?

I have two buttons on a simple login form in a dropdown on a header bar that is outside of the view/content part of my single page app. There are two buttons on the form:
EDIT: both buttons need to submit the form, but I have two different outcomes; one does new member sign-up, the other login existing members. I do not want to handle this on multiple partials.
My Website
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">
Home
</li>
<li class="divider-vertical"></li>
<li>
<div class="btn-group btn-group-xs navbar-btn btn-pad">
NL
FR
EN
</div>
</li>
<li class="divider-vertical"></li>
<!-- Begin Login Section -->
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown">Signup/Login <strong class="caret"></strong></a>
<div class="dropdown-menu">
<div class="accountForm">
<!--form action="#" method="post" role="form"-->
<form name="loginForm" ng-submit="login()" ng-controller="homeController">
<div class="form-group">
<label class="control-label" for="username">Username</label>
<input type="text" ng-model="credentials.username" name="username" class="form-control input-sm" placeholder="username" required/>
</div>
<div class="form-group">
<label class="control-label" for="password">Password</label>
<input type="password" ng-model="credentials.password" name="password" class="form-control input-sm" placeholder="password" required/>
</div>
<div class="form-group">
<label class="control-label" for="remember">
<input type="checkbox" class"form-control" name="remember" value="1"/>Remember me</label>
</div>
<div class="form-group btn-group-justified">
<div class="btn-group">
<button button-id="join" type="submit" class="btn btn-default">New? Join us</button>
<input type="hidden" class="btn" />
</div>
<div class="btn-group inline">
<input type="hidden" class="btn" />
<button button-id="login" type="submit" class="btn btn-primary active">Log in</button>
</div>
</div>
</form>
</div>
</div>
</li>
<!-- End Login Section -->
</ul>
</div>
<!--/.nav-collapse -->
</div>
</div>
<div id="page" ng-view>
The first button is intended to send the user to the login process (if they are already registered) and the second button is for new users to register.
The problem I have is that if I use the <form ng-submit="myFunction()"> directive, I haven't yet found a way to determine the button that was pressed.
I can alternatively create my own directive, where I can determine the button that was pressed, but this seems to be a lot of coding effort by comparison, and is this really the Angular way?
app.directive('buttonId', function() {
return {
restrict: "A",
link: function(scope, element, attributes) {
element.bind("click", function(){
// when attributes.buttonId = 'join'
//call the create script
// when attributes.buttonId = 'login'
//call the authenticate script
});
}
}
});
So my question is simply using ng-submit="myfunction()"can i determine which button was pressed?
I know I am answering my own question, but this seems to be the "correct" way to do this:
<form name="loginForm" ng-submit="login()" ng-controller="homeController">
<div class="form-group btn-group-justified">
<div class="btn-group">
<button type="submit" class="btn btn-default" button-id="join">New?Joinus</button>
<input type="hidden" class="btn" />
</div>
<div class="btn-group inline">
<input type="hidden" class="btn" />
<button type="submit" class="btn btn-primary active" button-id="login">Log in</button>
</div>
</div>
</form≥
The above is the section of the form that I'm interested in. Note that both buttons have type="submit"and not type="button" . This is important for two reasons:
1) you can use the standard HTML5 form validation options when you click the buttons
2) it forces the ng-submithandler.
First the controller
app.controller('homeController', function($scope){
$scope.buttons = { chosen: "" };
$scope.login = function (){
// can get the button that was clicked as it is now added to the scope
// by the directive
alert($scope.buttons.chosen);
};
});
... and now the directive.
Next I handle the click on either button using a directive. This has the purpose of allowing me to identify the button, and pass it to the $scope. This was actually the main purpose of the excercise, but I realised that I could now bind this to anything where I suspected a click and pass some data to the scope.
app.directive('buttonId', function() {
return {
restrict: "A",
link: function(scope, element, attributes) {
element.bind("click", function(){
// able to get the name of the button and pass it to the $scope
// this is executed on every click
scope.buttons.chosen = attributes.buttonId;
// alert(attributes.buttonId + scope.buttons.chosen);
});
}
}
});
I am not sure if i have understood your problem correct but you can differential based on
Calling different function for each ng-submit such as ng-submit="myFunction1()" and ng-submit="myFunction2()"
You can also do the same passing in context using a parameter ng-submit="myFunction(from)"
You can also pass in special $event object as parameter ng-submit="myFunction($event)". This object contains the target information.
You can get a handle to the $event in your ng-click, and get its target, and then get its id, but I wouldn't recommend that it is not the angular way of doing things:
<input type="submit" id="test" data-ng-click="showAlert($event)">
Click Me
</button>
$scope.showAlert = function(event){
alert(event.target.id);
}
Another way is to set property dirty for this button and then to check which of the buttons is dirty.
For example if you have a form named "myForm" you can write something like this:
<form name="myForm" id="myForm" ng-submit="save()" ng-model="myForm" novalidate>
<input type="submit" name="save" ng-model="btnSave" ng-click="(frmForm.save.$setDirty())" />
<input type="submit" name="saveOut" ng-model="btnSaveOut" ng-click="(frmForm.saveOut.$setDirty())" />
</form>
In Javascript file you can handle it by:
if ($scope.btnSave.$dirty){
alert("First was clicked)}
else{
alert("First was clicked)}
}

Resources