How to access refreshView() in Twitter Bootstrap Datepicker for Angular? - javascript

EDIT It actually does it right out of the box.
I leave the plunker here just in case someone drops in via search: http://plnkr.co/edit/maArVIu6iWuWZbkvLI4j?p=preview
I need to disable disable specific dates in a datepicker based on user input.
The datepicker offers isDisabled(date) but that only gets fired once. It does however have a refreshView() as per: https://github.com/angular-ui/bootstrap/issues/779
What I can't figure out is how to trigger it after a change.
<!doctype html>
<html ng-app="plunker">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="DatepickerDemoCtrl" >
<h4>Inline</h4>
<div style="display:inline-block; min-height:290px;">
<div class="well well-sm" ng-model="dt" ng-change="change()">
<datepicker></datepicker>
</div>
</div>
</div>
</body>
</html>
and the js
angular.module('plunker', ['ui.bootstrap']);
var DatepickerDemoCtrl = function ($scope) {
$scope.change = function(){
console.log('changed to ' + $scope.dt);
// Get array of disabled dates
// call refreshView(); <--- My problem, right here
};
};
I've ommitted the part where I define an array of disabled dates and the isDisabled function that checks against that. What I only need to know is how to trigger the refreshView()
EDIT:
This is what I want to call/trigger in ui-bootstrap-tpls.js
this.refreshView = function() {
if ( this.element ) {
this._refreshView();
var date = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null;
ngModelCtrl.$setValidity('date-disabled', !date || (this.element && !this.isDisabled(date)));
}
};

Related

angular js close on outside click

I am trying to implement close on out side click, just like in this example : http://plnkr.co/edit/ybYmHtFavHnN1oD8vsuw?p=preview
But I keep missing something, It is not working in my code.
HTML Directive
<div class='multiDate'>
<div class="dropdown">
<button data-ng-click="show = !show" class="dropbtn">Press</button>
<div id="myDropdown" ng-show="show" class="dropdown-content">
<multiple-date-picker></multiple-date-picker>
</div>
</div>
</div>
HTML Main
<html>
<head>
<script data-require="angularjs#1.6.2" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></script>
<script data-require="moment.js#*" data-semver="2.14.1" src="https://npmcdn.com/moment#2.14.1"></script>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://arca-computing.github.io/MultipleDatePicker/stylesheets/multipleDatePicker.css" />
<script src="https://arca-computing.github.io/MultipleDatePicker/javascripts/multipleDatePicker.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="cntrl">
<multi-date></multi-date>
</body>
</html>
JS
var app = angular.module("app", ['multipleDatePicker']);
app.controller("cntrl", function($scope) {
});
app.directive('multiDate', function($document) {
return {
templateUrl: 'multi.html',
replace: true,
link: function(scope, element) {
$document.bind('click', function(event) {
var isClickedElementChildOfPopup = element
.find(event.target)
.length > 0;
if (isClickedElementChildOfPopup)
return;
scope.show = false;
scope.$apply();
});
}
}
});
PLNKR
Your plunker code is pretty much working, except the jquery library is not referenced. Add it before the angular library will do.
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script data-require="angularjs#1.6.2" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></script>
<script data-require="moment.js#*" data-semver="2.14.1" src="https://npmcdn.com/moment#2.14.1"></script>
If jquery is not included before angular, angular will use its built in jqLite, which element.find function doesn't work exactly like the one in jquery.
First of all angularjs by default use jquery which was included into page before angularjs or jqLite in other cases.
Secondly jqLite has not all methods, even more, some method's behavior can be different from jquery. See documentation for angular.element
Your example doesn't work due find() - Limited to lookups by tag name. To fix it you have to change condition for isClickedElementChildOfPopup one of possible solutions
var isClickedElementChildOfPopup = event.target.closest(".dropdown") !== null;
but be careful Browser support closest method and polyfill.

How can I close a bootstrap alert after a specific time using angular.js?

I've a bootstrap alert that appears after some operation is completed,but I want it to close after two or more seconds,how can I achieve this effect?I'm using Angular.js and I've only found solutions in jQuery.
Thanks.
Angular bootstrap provides an option for alert directive dismiss-on-timeout. It accepts timeout in milliseconds. This attribute requires the presence of the close attribute.
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('AlertDemoCtrl', function($scope) {
$scope.show = true;
$scope.closeAlert = function(index) {
$scope.show = false;
};
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.3.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="AlertDemoCtrl">
<uib-alert type="danger" close="closeAlert()" ng-if="show" dismiss-on-timeout="4000">Oh snap! Change a few things up and try submitting again.</uib-alert>
</div>
</body>
</html>

Knockout JS `hasFocus` within template that is called twice

I have a template, which is using hasFocus similar to example in docs: http://knockoutjs.com/documentation/hasfocus-binding.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>field test</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/bootstrap/3.3.6/css/bootstrap.min.css">
<style>
body {
margin-top: 1em;
}
</style>
<script src="https://cdn.jsdelivr.net/g/jquery#2.2.2,bootstrap#3.3.6,knockout#3.4.0"></script>
<script>
$(function() {
var VM = function() {
var model = {};
model = {
one: ko.observable(false),
two: ko.observable(false)
};
this.model = model;
};
ko.applyBindings(new VM());
});
</script>
</head>
<body>
<script type="text/template" id="first-template">
<input type="text" class='form-control' data-bind="hasFocus: model.one">
<p>one has<span data-bind="visible: !model.one()"> not got</span> focus now</p>
<input type="text" class='form-control' data-bind="hasFocus: model.two">
<p>two has<span data-bind="visible: !model.two()"> not got</span> focus now</p>
</script>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div data-bind="template: { name: 'first-template' }"></div>
<!-- if I uncomment the next line, it stops working... -->
<!-- <div data-bind="template: { name: 'first-template' }"></div> -->
</div>
</div>
</div>
</body>
</html>
It all works as expected, updating the focus state on the model correctly when entering and leaving the field. However, if I apply the template a second time, the template appears to work ok with the exception of the focus state. Is this unsupported, or am I implementing wrong? How can I use template multiple times, and still use focus state?
The browser cannot have two <input> elements with focus. The hasFocus bind will try to give both elements a focused state. You can circumvent this behavior by using event bindings for both focus and blur events:
data-bind="event: {
focus: function() {
model.one(true)
},
blur: function() {
model.one(false)
}
}"
Check out this fiddle for a working example of your code: https://jsfiddle.net/77meefmf/
You need to make sure each copy of the template has its own viewmodel. The hasFocus binding is meant to represent the focus status a single field. If you bind it to more then one field, the results will be wrong.

How can you selectively run ngBlur code

I have a textarea and a span. The textarea has an ngBlur which calls a function. I only want that function to run its code when the cause of the blur wasn't a click on the span. How can I do that?
http://plnkr.co/edit/ENvuujbychxYum1EMmkf?p=preview
HTML
<!DOCTYPE html>
<html ng-app='app'>
<head>
<script data-require="angular.js#1.4.7" data-semver="1.4.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller='MainController as vm'>
<textarea ng-blur='vm.selective()'></textarea>
<span>span</span>
</body>
</html>
JS
angular
.module('app', [])
.controller('MainController', MainController)
;
function MainController() {
vm.focus = true;
vm.onBlur = function() {
// HOW DO I DO THIS?
// if (spanIsClicked) {
// return;
// }
vm.focus = false;
};
}
I believe you can pass in the DOM element as an argument in angular, looking like :
vm.onBlur = function($event){}
You could then access the event by using event.target. I know this works with ng-click so I'm not totally positive if the same rules apply for ng-blur.

addEventListner working only at app creation

For some reason my eventHandling code stopped working.
I was working on some functions to handle the indexedDB stuff, when i went back to work on the interface, i noticed that the eventHandlers only worked at app creation, even when i didnt performed any action on them, they just go off.
Heres my default.js
(function () {
"use strict";
WinJS.Binding.optimizeBindingReferences = true;
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var _swAlarm;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
} else {
}
args.setPromise(WinJS.UI.processAll());
}
};
app.oncheckpoint = function (args) {
};
function testSelection(value) {
console.log("from event listner "+value)
}
function getDomElements() {
_swAlarm = document.getElementById("swAlarm");
}
function registerHandlers() {
_swAlarm.addEventListener("onchange", console.log("ola"));
}
app.onready = function () {
getDomElements();
registerHandlers();
}
app.start();
And this is my default.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>MyApp</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!-- my references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/default.js"></script>
<script src="/js/database.js"></script>
<!-- jquery references -->
<script src="js/jquery-1.8.2-win8-1.0.js"></script>
<script src="js/visualize.jQuery.js"></script>
<script type="text/javascript"> jQuery.isUnsafe = true;</script>
<link href="/css/default.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="content">
<div id="settings">
<h2 id="lAlarm">Alarm</h2>
<div id="swAlarm" data-win-control="WinJS.UI.ToggleSwitch" ></div>
<input id="iMaxval" type="number">
<input id="iMinval" type="number">
<button id="bSave">Save</button>
</div>
<div id="graph">
<h2 id="hGraph" class="graph">Graph</h2>
</div>
<div id="stats">
<h2 id="hStats" class="stats">Stats</h2>
</div>
</div>
</body>
</html>
When you run this code:
_swAlarm.addEventListener("onchange", console.log("ola"));
you are:
running console.log("ola")
affecting the result as a callback for the event onchange of _swAlarm.
This is wrong on many levels.
console.log("ola") does not return a call back. I think I understand what you meant, and the correct code could be: function() { console.log("ola"); }
When using addEventListener you have to use dom lexique with event denomination. In your case, onchange needs to be instead change. If you had to affect this event directly in html, you indeed would have to use onchange="console.log("ola");". But not with addEventListener.
The final result is:
_swAlarm.addEventListener("change", function() { console.log("ola"); }, false);
As for why was it working on app creation, I think it is simply because on app creation console.log("ola") was called right away at event affectation, but since no event was actually affected later on you would not get any result for the onchange event.
On a side note, and since I guess you're sort of migrating from "old" syntaxis (onchange... etc.) to the addEventListener api, I'll add an important difference between the 2 modes: when an event is executed the old way, this referers to window. But affecting the callback through addEventListener makes the domElement itself (_swAlarm in your case) be the target of this during the callback execution.

Categories

Resources