jQuery-ui datepicker not working after extending to add placeholder - jquery-ui

I would like to use the dateFormat property as a placeholder. I have extended the jQuery function but can not get it to work after extending demo in fiddle below. What am I missing?
https://jsfiddle.net/yzk1avan/1/
$(document).ready(function () {
$(".datePicker").datepicker({
dateFormat: 'dd/mm/yy',
placeholder: true
});
});
(function ($) {
$.fn.datepicker = function (options) {
var settings = $.extend({}, $.fn.datepicker, options);
return this.each(function () {
if (settings.placeholder === true) {
var dateFormat = settings.dateFormat;
var placeholder = dateFormat.replace(/y/gi, 'yy');
$(this).attr('placeholder', placeholder);
}
});
}
}(jQuery));
Thanks for your help.

Working fiddle here
https://jsfiddle.net/yzk1avan/3/
Found my answer from here: How can I extend jQueryUI datepicker to accept an additional argument?
was missing these pieces of code:
var __picker = $.fn.datepicker;
__picker.apply(this, [options]);
Here's the working code:
var __picker = $.fn.datepicker;
(function($) {
$.fn.datepicker = function(options) {
__picker.apply(this, [options]);
var settings = $.extend({}, options);
return this.each(function() {
if (settings.placeholder === true) {
var dateFormat = settings.dateFormat;
var placeholder = dateFormat.replace(/y/gi, 'yy');
$(this).attr('placeholder', placeholder);
}
});
}
}(jQuery));
$(document).ready(function() {
$(".datePicker").datepicker({
dateFormat: 'dd/mm/yy',
placeholder: true
});
});

Related

Issue with updating the jQuery UI Slider from Angular directive

I'm trying to get a custom slider up and running using the directives concept.
I have an issue when updating the slider from the input field.
The directive part below and a working example on jsfiddle.
Why is this line $privateScope.sliderElement.slider('value', value); throwing an error and how could I solve it?
app.directive('slider', function ($parse) {
var $privateScope = {};
return {
restrict: 'A',
template: '<div class="slider"></div><div class="input-append"><input class="span1" type="text" ng-model="percentage"><span class="add-on">%</span></div>',
scope: {
slider: '#',
percentage: '='
},
controller: ['$scope', '$element', '$attrs', '$transclude', function ($scope, $element, $attrs, $transclude) {
// Why this doesn't work?
// $attrs.$observe('percentage', function (value) {
// console.log('$attrs.$observe.percentage', value);
// });
// Slider API: http://api.jqueryui.com/slider/
$privateScope.sliderElement = $('.slider', $element).slider({
value: $scope.percentage
});
}],
link: function ($scope, $element, $attrs) {
var changedBySlider = false;
$scope.$watch('percentage', function (value) {
// console.log('$scope.$watch.percentage', value);
if (changedBySlider !== true) {
console.log('change the slider');
// This throws an error
// $privateScope.sliderElement.slider('value', value);
} else {
console.log('don\'t change the slider');
changedBySlider = false;
}
});
$privateScope.sliderElement.on('slidechange', function (event, ui) {
$scope.$apply(function () {
// Why this doesn't work?
// $parse($attrs.percentage).assign($scope, ui.value);
$scope.percentage = ui.value;
changedBySlider = true;
});
});
$scope.$on('$destroy', function (event) {
console.log('on destroy');
});
}
}
});

Multiple ViewModels Knockout with JQuery

I Have this Fiddle
It is working perfectly in the fiddle, but as soon as i put everything in a ASP.NET MVC4 Application the second ViewModel is not loaded!
This normally is only when i add the following Script Tag to my Project
<script src="../../Scripts/jquery.mobile-1.2.0.js" type="text/javascript"></script>
Do i need some JQuery Functions to load the second ViewModel or what did i wrong? ;)
Here is my code:
<form action="" data-bind=" template:{ 'if': loginVM, data: loginVM }">
//SomeCode
</form>
<form action="" data-bind=" template:{ 'if': startVM, data: startVM}">
//Some Code
</form>
<script type="text/javascript">
var masterViewModel = {
loginVM: ko.observable(),
startVM: ko.observable(),
projektUnterbrechen: ko.observable(),
logout : ko.observable(),
projectStartVM: ko.observable()
};
var LoginVM = function () {
var self = this;
self.mandant = ko.observable();
self.user = ko.observable();
self.password = ko.observable();
self.showDetails = function () {
if ((self.user() == "Gregor") && (self.password() == "gregrech")) {
masterViewModel.loginVM(null);
masterViewModel.startVM(new StartVM());
**//alert(masterViewModel.startVM()!=null) //==True**
}
else {
alert("Username oder Passwort falsch");
}
};
};
var StartVM = function () {
self = this;
**//alert(masterViewModel.startVM()!=null) //==False**
//Um weiterzumachen muss man eingeloggt sein
self.favoriten = ko.observableArray([
{
projectName: "Favorit1"
},
{
projectName: "Favorit2"
},
{
projectName: "Favorit3"
}
]);
//Die zuletzt verwendeten Projekte
self.zuletzt = ko.observableArray([
{
lastProjName: "Zuletzt1"
},
{
lastProjName: "Zuletzt2"
},
{
lastProjName: "Zuletzt3"
}
]);
self.showStart = function (projectName, data, event) {
masterViewModel.projectStartVM(new ProjectStartVM(projectName));
masterViewModel.startVM(null);
};
};
masterViewModel.loginVM(new LoginVM());
$(document).on('pageinit', function () {
ko.applyBindings(masterViewModel);
});
</script>
Thank you for your answers
EDIT:
I found out, that i get different Values if i compare my masterViewModel.startVM()!= null even if it has to be the same!
Maybe this helps you!
Please look at the comments with "**" in my Code to understand what i mean
Try to load viewmodel in ready event not pageinit event.
$(document).ready(function () {
ko.applyBindings(masterViewModel);
});

AngularJS - jQuery UI - binding issue

I am currently porting a large application over to a HTML5 based web app - I have started building the app in AngularJS and enjoying the power of the AngularJS framework - I have one issue standing in my way currently:
I have a directive that gives me a jQuery Datepicker however the binding to the model does not seem to be working.
http://jsfiddle.net/9BRNf/
I am probably misunderstanding the way directives work and would like to see if I can patch this part of my understanding of the framework. I have gone through loads of examples (including the angularui project on github but still not making sense of why the binding is not happening)
any assistance will be greatly appreciated.
For those Googling this issue (as I was), a simpler way of tying in the jQuery UI datepicker with Angular is to do this...
$.datepicker.setDefaults({
// When a date is selected from the picker
onSelect: function(newValue) {
if (window.angular && angular.element)
// Update the angular model
angular.element(this).controller("ngModel").$setViewValue(newValue);
}
});
Just place it prior to your .datepicker() initialisation code.
(Taken from another answer I posted here: https://stackoverflow.com/a/17206242/195835)
First off, it's great that you are using angularjs, its a sweet framework. An offshoot project was started awhile back to deal with things like wrapping jquery-ui and creating ui modules.
Below is link to Peter Bacon Darwin's implementation.
https://github.com/angular-ui/angular-ui/tree/master/modules/directives/date
--dan
The angular-ui datepicker wasn't working with Angular 1.0.0, so I rewrote it. My fork gives you the ability to set how the date is formatted inside the input and how it gets saved back to the model.
Code: https://gist.github.com/2967979
jsFiddle: http://jsfiddle.net/m8L8Y/8/ (It's missing jquery-ui styles but works just the same)
// Code inspired by angular-ui https://github.com/angular-ui/angular-ui/blob/master/modules/directives/date/src/date.js
/*
Features:
* via the ui-date attribute:
* Ability to say how model is parsed into a date object
* Ability to say how input's value is parsed into a date object
* Ability to say how a date object is saved to the model
* Ability to say how a date object is displayed in the input
* via the ui-date-picker attribute
* Ability to directly configure the jQuery-ui datepicker
*/
angular.module('ui.directives', [])
.directive('uiDate', function () {
return {
require: '?ngModel',
//scope: {},
link: function ($scope, element, attrs, ngModel) {
// Date Handling Functions
var dateHandler = $.extend({ model: {}, view: {} }, $scope.$eval(attrs.uiDate));
// This will attempt to use preferredParser to parse a date.
function defaultDateParse(date, preferredParser) {
if (!preferredParser)
return new Date(date);
return preferredParser(date);
}
// This will attempt to use preferredFormatter to format a date, otherwise use 'mm/dd/yy'.
function defaultDateFormatter(date, preferredFormatter) {
if (!preferredFormatter)
preferredFormatter = "mm/dd/yy";
if (typeof preferredFormatter == 'string')
return $.datepicker.formatDate(preferredFormatter, date);
else
return preferredFormatter(date);
}
// Functions for Parsing & Formatting on the Model & View
function parseDateFromModel(date) {
return defaultDateParse(date, dateHandler.model.parse)
}
function parseDateFromView(date) {
return defaultDateParse(date, dateHandler.view.parse)
}
function formatDateForModel(date) {
return defaultDateFormatter(date, dateHandler.model.format)
}
function formatDateForView(date) {
return defaultDateFormatter(date, dateHandler.view.format)
}
var defaultDateViewFormat = (
typeof dateHandler.view.format == 'string'
? dateHandler.view.format
: 'mm/dd/yy'
)
// Initialize the jQuery-ui datePicker
var datePickerSettings = $.extend({ dateFormat: defaultDateViewFormat }, $scope.$eval(attrs.uiDatePicker))
var oldOnSelect = datePickerSettings.onSelect;
datePickerSettings.onSelect = function (dateVal) {
$scope.$apply(function () {
element.focus().val(dateVal);
updateModel();
})
if (oldOnSelect)
oldOnSelect.apply(this, arguments)
}
element.datepicker(datePickerSettings);
if (ngModel) {
// Specify how UI should be updated
ngModel.$render = function () {
element.val(ngModel.$viewValue || '');
};
// Listen for change events to enable binding
element.bind('blur keyup change', function () {
$scope.$apply(updateModel);
});
// Write data to the model
function updateModel() {
ngModel.$setViewValue(element.val());
}
// Convert the model into a string value
ngModel.$formatters.push(function (v) {
if (v != "" && v != null)
return formatDateForView(parseDateFromModel(v));
return null;
});
// Convert the string value into the model
ngModel.$parsers.push(function (v) {
if (v != "" && v != null)
return formatDateForModel(parseDateFromView(v))
return null;
});
}
}
};
})
Similar to praveepd (using their's as a base), but this will include deep model selection.
http://jsfiddle.net/c8PMa/
var myApp = angular.module('myApp', ['myApp.directives']);
function MainCtrl($scope) {
$scope.deepValue = {
fromDate: null,
toDate: null
}
}
angular.module('myApp.directives', [])
.directive('myDatepicker', function() {
return function(scope, element, attrs) {
element.datepicker({
changeYear : true,
changeMonth : true,
appendText : '(yyyy-mm-dd)',
dateFormat : 'yy-mm-dd',
onSelect: function(dateText) {
var mdlAttr = $(this).attr('ng-model').split(".");
if (mdlAttr.length > 1) {
var objAttr = mdlAttr[mdlAttr.length-1];
var s = scope[mdlAttr[0]];
for (var i=0; i < mdlAttr.length-2; i++) {
s = s[mdlAttr[i]];
}
s[objAttr] = dateText;
} else {
scope[mdlAttr[0]] = dateText;
}
scope.$apply();
}
});
}
});​
http://jsfiddle.net/9BRNf/74/ here is the solution :)
code:
var myApp = angular.module('myApp', ['myApp.directives']);
function MainCtrl() {
}
angular.module('myApp.directives', [])
.directive('myDatepicker', function() {
return {
require: '?ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datepicker({
changeYear : true,
changeMonth : true,
appendText : '(yyyy-mm-dd)',
dateFormat : 'yy-mm-dd',
onSelect: function(date) {
ngModelCtrl.$setViewValue(date);
scope.$apply();
}
});
}
}
});
Old question, but this was the first hit for me in google search for this. Anyways, I used dual datepickers working together using jquery and angular directives, so I thought I'd share to help anyone else trying to do this.
Here's the plunker for it:
http://plnkr.co/edit/veEmtCM3ZnQAhGTn5EGy?p=preview
Basically it initializes the form using json. The datepickers have their own conditions like mindate's, etc. The first select box if true = disables sundays on the calendars, else enables them.
The viewmodel get's updates when 'done' is clicked. Here's a bit of the code for one of the datepickers:
Html:
<input id="StartDate" data-ng-model="viewModel.startdate" date-from />
Directive:
app.directive('dateFrom', function() {
return function (scope, element, attrs) {
var doDate = $('#EndDate');
element.datepicker({
dateFormat: 'dd-M-yy', showOtherMonths: true,
selectOtherMonths: true, minDate: '0',
beforeShowDay: function (date) {
var day = date.getDay();
console.log(scope.nosunday);
if (scope.nosunday === 'true') return [(day !== 0), '']; // disable sundays
else return [true, ''];
},
onSelect: function (selectedDate) {
var toDate = new Date(element.datepicker("getDate"));
toDate.setDate(toDate.getDate() + 1);
doDate.datepicker('option', 'minDate', toDate);
scope.viewModel.startdate = selectedDate;
scope.viewModel.enddate = doDate.val();
}
});
}
})
Feel free to optimize it further. Post a comment with a forked plunk if you do :)
I had just trimmed the code, have a look at this: http://jsfiddle.net/YU5mV/
HTML
<input id="date1" value="1/1/1980" ng-model="fromDate" my-datepicker />
<input id="date2" value="1/1/1980" ng-model="toDate" my-datepicker />
JavaScript
angular.module('myApp.directives', [])
.directive('myDatepicker', function() {
return function(scope, element, attrs) {
element.datepicker({
changeYear : true,
changeMonth : true,
appendText : '(yyyy-mm-dd)',
dateFormat : 'yy-mm-dd',
onSelect: function(dateText) {
var mdlAttr = $(this).attr('ng-model');
scope[mdlAttr] = dateText;
scope.$apply();
}
});
}
});

jquery ui autocomplete inside jQuery Ui Dialog

Hi I have a JQuery Ui (jquery-ui-1.8.13.custom.min.js) inside a Dialog. When I start typing on the box I get the dropdown of items but it hides right away? Does anyone know why? Here is my code:
$(".openDialog").live("click", function (e) {
e.preventDefault();
var itemId = $(this).attr("data-item-id");
var ajaxurl = $(this).attr('data-ajax-refresh-url');
var dialogId = $(this).attr("data-dialog-id");
$('<div><img src="Content/images/spinner.gif" /> Loading...</div>')
.addClass("dialog")
.attr("id", $(this).attr("data-dialog-id"))
.appendTo("body")
.dialog({
width: 'auto',
title: $(this).attr("data-dialog-title"),
buttons: {
"Save": function () {
$(this).find('form').submit();
},
close: function () {
if (typeof itemId != "undefined") {
$.get(ajaxurl, { id: itemId },
function (data) {
// The data returned is a table <tr>
$("#Row" + itemId).replaceWith(data);
});
bindConfirm();
}
$(this).remove();
}
},
modal: true
}).load(this.href, function () {
$(this).find("input[data-autocomplete]").autocomplete({ source: $(this).find("input[data-autocomplete]").attr("data-autocomplete") });
});
});
They also had problems in early 1.8 releases. I remember applying a custom CSS selector to increase zIndex manually.
See also: http://forum.jquery.com/topic/autocomplete-inside-a-dialog-1-8rc2

jquery close datepicker when input lose focus

I'm using datepicker inside my input , my last field is the datepicker input , after validating it i want to set focus on another input inside my form , but the problem is the datepicker is not closed even taht it does not have the focus..
how can I close the datepicker when i set the focus on another input field?
(I tried .datepicker("hide"); but it did not worked for me).
UPDATE:
this is my code:
$(function()
{ $( "#test_date" ).datepicker({
dateFormat: "dd/mm/yy"
});
});
//when i call my function:
$( "#test_date" ).datepicker("hide"); //---> this does not work!
Thank's In Advance.
Question Edited to work with the latest version of jqueryUI
JqueryUi auto-closes the datepicker when an element loses focus by user interaction, but not when changing focus with JS.
Where you are calling your function which removes focus from the input assigned a datepicker you also need to call:
$("#test_date ~ .ui-datepicker").hide();
This code is hiding the datepicker which is a sibling (~) of #test_date.
To be dynamic, and using the class assigned by jQueryui you can do:
$(".hasDatepicker").on("blur", function(e) { $(this).off("focus").datepicker("hide"); });
;(function() {
function eventOnFocusDP(e, par) {
if (par.ver == $.fn.jquery) {
if (this.tmr) clearTimeout(this.tmr);
par.lbl1.text(par.msgs[1]);
this.tmr = setTimeout(function() { par.inpNP.focus(); }, par.secs*1e3);
}
}
function eventOnFocusNP(e, par) {
if (par.ver == $.fn.jquery) {
par.lbl1.text(par.msgs[0]);
par.lbl2.text(par.msgs[2]);
}
}
function eventOnBlurNP(e, par) {
if (par.ver == $.fn.jquery) par.lbl2.text("");
}
function eventOnBlurHDP(e, par) {
if (par.ver == $.fn.jquery) {
$(this).off("focus").datepicker("hide");
}
}
function test(secs) {
this.ver = $.fn.jquery;
this.secs = (typeof secs)=='number'?secs:2;
this.msgs = [
'This will lose focus to box below '+this.secs+' seconds after it gains focus.',
'Losing focus in '+this.secs+' seconds!',
'Focus now on bottom box.'
];
this.inpDP = $('[name=datePicker]');
this.inpNP = $('[name=nextPicker]');
this.lbl1 = $('#dPMsg').text(this.msgs[0]);
this.lbl2 = $('#dPMsg2');
var par = this;
this.inpDP.datepicker({ dateFormat: "dd/mm/yy" })
.on('focus', function(e) { eventOnFocusDP.apply(this, [e, par]) });
this.inpNP.on('focus', function(e) { eventOnFocusNP.apply(this, [e, par]) });
this.inpNP.on('blur', function(e) { eventOnBlurNP.apply(this, [e, par]) });
$(document).on('blur', '.hasDatepicker', function(e) { eventOnBlurHDP.apply(this, [e, par]) });
return this;
}
function init() {
window.Test = test;
setTimeout(function() {
$(document).on('change', '.switcher, .switcher-ui', function(e) { if (window.Test) new Test(); });
$(jQueryUISwitcher).trigger('change');
}, 1e3);
}
if (document.readyState == "complete") init();
else jQuery(window).on('load', init);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/JDMcKinstry/cfc32292cbbfa548fb9584db05b2b2fc/raw/4f16f7ee441dfb98aa166a2e84193b14574a46d1/jquery.switcher.js"></script>
<form action="javascript: void 0">
<input type="text" name="datePicker" id="dP" placeholder="mm/dd/yyyy" />
<label for="dP" id="dPMsg"></label>
<hr />
<input type="text" name="nextPicker" placeholder="tab to here" />
<label for="dP" id="dPMsg2"></label>
</form>
<hr />
<hr />
<hr />
Here's a modified solution that worked for me:
$(".hasDatepicker").each(function (index, element) {
var context = $(this);
context.on("blur", function (e) {
// The setTimeout is the key here.
setTimeout(function () {
if (!context.is(':focus')) {
$(context).datepicker("hide");
}
}, 250);
});
});
My version of js:
<script type="text/javascript"> $(function () {
$("#dtp1").on("dp.change", function (e) {
$('#dtp1').data("DateTimePicker").hide();
});
});
I hope it's help you
This worked for me:
$("#datepickerTo").datepicker({
onSelect: function () {
$(this).off( "focus" );
}
});

Resources