knockout mvvm binding with metro.js datepicker - javascript

I was trying to hack my way around with the metro.js datepicker and knockout. So far my datepicker binding code looks like:
ko.bindingHandlers.datepicker = {
init: function(el, va, ba, model, ctx) {
var prop = va();
$(el).datepicker({
onSelect: function(txt, date) {
prop(date);
}
});
},
update: function(el, va, ba, model, ctx) {
var prop = va();
var date = ko.unwrap(prop);
if(date) {
applyDate(date);
}
function applyDate(dt) {
var j = $(el);
var dp = j.data('datepicker');
var inp = j.find('input');
var fmt = dp.options.format;
var sDate = format(fmt, dt);
// dp._calendar.calendar.dayClick(sDate, dt);
// inp.value = sDate;
dp._calendar.calendar('setDate', sDate);
j.find('input').val(dp._calendar.calendar('getDate')).trigger('change', sDate);
}
function format(fmt, dt) {
fmt = fmt.replace('yyyy', dt.getFullYear());
fmt = fmt.replace('mm', pad(dt.getMonth() + 1));
fmt = fmt.replace('dd', pad(dt.getDate()));
return fmt;
}
function pad(n) {
return parseInt(n) < 10 ? '0' + n: '' + n;
};
}
}
Issue is that when I issue a model update on the date property its bound to the datepicker doesn't update. I mean, it does it the very first time, but post that, it fails to update the textbox; calendar shows okay however. Ultimately I need to change the logic in the applyDate function...
JSBin: http://jsbin.com/rupaqolexa/1/edit?html,js,output
Update: Another issue just cropped up...it doesn't work in IE 10+. The date appears as NaN in the UI...
Update: Steps for reproduction
type date 2nd text box: 2013/05/13 & click on the Change button. Observe date is updated in the datepicker textbox. This works as expected. (Except in IE).
type another date in the textbox & click the change button. Observe the date is not updated in the datepicker textbox. Expected here that the datepicker textbox updates with latest value.

In the update part of your custom binding you need to make all the changes to the bound elements, which include the calendar widget, and the related input element.
I've modified the code to do so, so that it now works.
function ViewModel(date) {
var model = this;
model.date = ko.observable(date);
model.set = function() {
var val = $('#somedate').val();
var dt = new Date(val);
model.date(dt);
};
}
ko.bindingHandlers.datepicker = {
init: function(el, va, ba, model, ctx) {
var prop = va();
$(el).datepicker({
onSelect: function(txt, date) {
prop(date);
}
});
},
update: function(el, va, ba, model, ctx) {
var newDate = ko.unwrap(va());
if(newDate) {
var $el = $(el);
var datePicker = $el.data('datepicker');
var $input = $el.find('input');
var formattedDate = format(datePicker.options.format, newDate);
datePicker._calendar.calendar('setDate', formattedDate);
$input.val(formattedDate);
//$input.val(dp._calendar.calendar('getDate'))
// .trigger('change', sDate);
}
function format(fmt, dt) {
fmt = fmt.replace('yyyy', dt.getFullYear());
fmt = fmt.replace('mm', pad(dt.getMonth() + 1));
fmt = fmt.replace('dd', pad(dt.getDate()));
return fmt;
}
function pad(n) {
return parseInt(n) < 10 ? '0' + n: '' + n;
}
}
};
var m = new ViewModel();
$(function(){
ko.applyBindings(m);
});
<link href="//metroui.org.ua/css/metro.css" rel="stylesheet">
<link href="//metroui.org.ua/css/metro-icons.css" rel="stylesheet">
<link href="//metroui.org.ua/css/metro-responsive.css" rel="stylesheet">
<link href="http://metroui.org.ua/css/metro-schemes.css" rel="stylesheet">
<script src="http://metroui.org.ua/js/jquery-2.1.3.min.js"></script>
<script src="http://metroui.org.ua/js/metro.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<div>
<div class="input-control text" data-bind="datepicker: date">
<input type="text">
<button class="button"><span class="mif-calendar"></span></button>
</div>
</div>
<div>
<label>Date</label>
<div class="input-control text">
<input type="text" id="somedate"/>
</div>
<input type="button" class="button" value="Change" data-bind="click: set"/>
</div>
<div>
<code data-bind="text: date"></code>
</div>
However there is still a little hiccup: the datepiceker's calendar setdate adss new selected date, instead of replacing selected ones. Please, see the API docs to solve this yourself.

Related

How to check when input value is changed?

How can i check when a value on input is changed.
I have a calendar and when i click on calendar it changes the value on input , but when im trying to see if it has changed its not working. i have tried AddEventListener, also jquery on change, also i sent a function on change to call it but none of them is working.
<input type="text" id="date" class="date" onchange="changed()" name="" >
function changed(){
alert("hello world");
}
Main js file for creating the calendar :
This function creates the calendar on my php file .
And then when on click it gets the value on the input with id #date
But When im trying to see if value has changed it is not working .
// Initialize the calendar by appending the HTML dates
function init_calendar(date) {
$(".tbody").empty();
$(".events-container").empty();
var calendar_days = $(".tbody");
var month = date.getMonth();
var year = date.getFullYear();
var day_count = days_in_month(month, year);
var row = $("<tr class='table-row'></tr>");
var today = date.getDate();
// Set date to 1 to find the first day of the month
date.setDate(1);
var first_day = date.getDay();
// 35+firstDay is the number of date elements to be added to the dates table
// 35 is from (7 days in a week) * (up to 5 rows of dates in a month)
for(var i=0; i<35+first_day; i++) {
// Since some of the elements will be blank,
// need to calculate actual date from index
var day = i-first_day+1;
// If it is a sunday, make a new row
if(i%7===0) {
calendar_days.append(row);
row = $("<tr class='table-row'></tr>");
}
// if current index isn't a day in this month, make it blank
if(i < first_day || day > day_count) {
var curr_date = $("<td class='table-date nil'>"+"</td>");
row.append(curr_date);
}
else {
var monthplusone = months[month];
var curr_date = $("<td class='table-date' id='"+day+"-"+monthplusone+"-"+year+"'>"+day+"</td>");
var events = check_events(day, month+1, year);
if(today===day && $(".active-date").length===0) {
curr_date.addClass("active-date");
let x = document.getElementById('date').value=day+"-"+monthplusone+"-"+year;
$('.table-date').ready(function () {
x.value;
});
show_events(events, months[month], day);
}
// If this date has any events, style it with .event-date
if(events.length!==0) {
curr_date.addClass("event-date");
}
// Set onClick handler for clicking a date
$('.table-date').on('click', function () {
document.getElementById('date').value = $(this).attr('id');
});
curr_date.click({events: events, month: months[month], day:day}, date_click);
row.append(curr_date);
}
}
// Append the last row and set the current year
calendar_days.append(row);
$(".year").text(year);
}
Notice that change is actually triggered when the input is not focused anymore.
document.getElementById("date").addEventListener("change", function () {
alert("hello world");
});
<input type="text" id="date" class="date" name="">
This works. Not sure where you're running into an issue.
function changed(){
console.log("hello world");
}
<input type="text" id="date" class="date" onchange="changed()" name="" >
EDIT: Shortened version of init_calender() for others interested in answering:
function setDate() {
document.getElementById("date").value = '19-Dec-2021'
}
I basically agree with #Spankied in that you should try and shorten your code to the point where you are having the issue. However, after looking at your code it seems to me that you want the following function
$('.table-date').on('click', function () {
document.getElementById('date').value = $(this).attr('id');
});
to not only change the value in your #date input but also trigger its change event-handler function. You can do that by changing it to something like
$('.table-date').on('click', function () {
document.getElementById('date').value = $(this).attr('id');
$("#date" ).change();
});
jQuery.change() without any arguments will trigger a predefined "change"-event on the DOM-object that is selected by the jQuery-object.
You can use js to do that:
let x = $(...) //select the input box
let val = x.value;
function repeat() {
if (val !== x.value) {
change()
}
}
setInterval(repeat, 100)
This checks if the result is the same.
This might make your site a bit slow and it might look odd but this will work in just every case
<script>
let Oldvalue = $('.date')[0].val();
setInterval(() => {
let currentValue = $('.data')[0].val()
if (Oldvalue != currentValue){
//do whatever but in end write this
Oldvalue = currentValue;
}
}, 10);
</script>

JQuery Datatables and Bootstrap 3 datepicker

I'm using JQuery datatables to sort some table with data.
I'm using custom items to sort, in my case I have a select element which sorts one of the columns. And this works.
I also have 2 inputs that serve as datepickers.
These pickers have data formatted as same as on the table, so filtering works well, but my question is:
Is possible to filter column based on the range of pickers? So for example:
from 1 sep 2017 to 10 sep 2017?
I'm was looking for some custom function in datatables docs but I found nothing so it's why I'm asking StackOverflow community.
I think I need to check when second date one was selected and then get data of first datepicker and filter column based on this. But to make things easier, when the first picker is selected I will just show the second picker, so the user may know that selecting the first picker will trigger need of selecting the second one also....
$(document).ready(function() {
var table = $('#scroll-wrc-changes-table table').DataTable({
"paging": false,
});
var picker1 = $('#datetimepicker1').datetimepicker({
format: 'DD MMM YYYY',
defaultDate: new Date(),
});
var picker2 = $('#datetimepicker2').datetimepicker({
format: 'DD MMM YYYY',
defaultDate: new Date(),
});
picker1.on('dp.change',function() {
table.columns([3] ).search( this.value ).draw();
});
picker2.on('dp.change',function() {
table.columns([3] ).search( this.value ).draw();
});
// This is just select element
$('#table-select').change(function() {
table.columns([2] ).search( this.value ).draw();
})
});
Maybe this link can help you.
Range Filtering
The idea is to make function for custom filtering.
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var date1 = new Date( $('#datetimepicker1').val() );
var date2 = new Date( $('#datetimepicker2').val() );
var dateData = new Date( data[3] ); // use data from the date column
if ( dateData >= date1 && dateData <= date2 )
{
return true;
}
return false;
});
Hope this help..
Asuming you are using ajax datatable . If not draw idea from this example
Add a row where you can set range for filter as:
<div class="col-md-3"> <label>From:</label> <input readonly="readonly" type="text" id="mindate" class="srchdp"> <i class="fa fa-times-circle-o" id="clear-mindate"></i></div>
<div class="col-md-3"> <label>To:</label> <input readonly="readonly" type="text" id="maxdate" class="srchdp"> <i class="fa fa-times-circle-o" id="clear-maxdate" ></i></div>
<div class="col-md-2"><button class="btn btn-primary" id="filter-record">Filter</button></div>
//initialize datepicker as
$("input:text.srchdp").datetimepicker({
changeMonth: true,
changeYear: true,
yearRange: "-100:+0",
dateFormat: 'mm/dd/yy',
controlType: 'select',
timeFormat: 'hh:mm:ss TT',
})
// now keep a event on filter button click
$(document).on("click", "#filter-record", function () {
assetListVM.search("").draw();
});
// now on ajax request
public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel, string mindate,string maxdate, string searchbase)
{
DataBaseEntities db = new DataBaseEntities();
IQueryable<Wishlist> query = db.Wishlists;
var totalCount = query.Count();
#region Filtering
// Apply filters for searching
var value = requestModel.Search.Value.Trim();
if (!string.IsNullOrEmpty(searchbase))
{
if (!string.IsNullOrEmpty(mindate) && !string.IsNullOrEmpty(maxdate))
{
DateTime datevaluemin;
DateTime datevaluemax;
var mindateval = DateTime.TryParse(mindate, out datevaluemin);
var maxdateval = DateTime.TryParse(mindate, out datevaluemax);
if (mindateval && maxdateval)
{
var minvalue = Convert.ToDateTime(mindate);
var maxvalue = Convert.ToDateTime(maxdate);
if (searchbase == "CreatedDate")
{
query = query.Where(p =>
p.CreatedDate >= minvalue
&& p.CreatedDate <= maxvalue);
}
}
}
else if (!string.IsNullOrEmpty(mindate))
{
DateTime datevalue;
var mindateval = DateTime.TryParse(mindate, out datevalue);
if (mindateval)
{
var minvalue = Convert.ToDateTime(mindate);
if (searchbase == "CreatedDate")
{
query = query.Where(p =>
p.CreatedDate >= minvalue
);
}
}
}
}
if (requestModel.Search.Value != string.Empty)
{
query = query.Where(p => p.Id.ToString().Equals(value) ||
p.ProductId.ToString().Equals(value) ||
p.MemberId.ToString().Contains(value)
);
}
var filteredCount = query.Count();
#endregion Filtering
#region Sorting
// Sorting
var sortedColumns = requestModel.Columns.GetSortedColumns();
var orderByString = String.Empty;
foreach (var column in sortedColumns)
{
orderByString += orderByString != String.Empty ? "," : "";
orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc");
}
query = query.OrderBy(orderByString == string.Empty ? " asc" : orderByString);
#endregion Sorting
// Paging
query = query.Skip(requestModel.Start).Take(requestModel.Length);
var data = query.Select(asset => new
{
Id = asset.Id,
ProductId = asset.ProductId,
ProductName = asset.Product.ProductName,
MemberId=asset.MemberId,
CreatedDate = asset.CreatedDate.ToString(),
}).ToList();
return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}
}
}
this code is not complete hence it doesn't work alone.

In MVC, how do I return items in and Entity database using a range of dates from Javascript Calendar

I want to get a range of items between dates from two JQuery calendars and then update the view when I press a submit button so that I only see the items between the selected dates. I'm not sure I'm going about things the best way.
My plan was to:
Get the user to select the dates in the calendars.
Use Javascript to return the dates as variables.
Send the variables to a controller which would then return a new view.
My code is below and my question is really in two parts.
Is there a better way to do this?
If this is ok, how can I get the javascript variables into the ActionLink to pass back to the controller?
Thanks in advance!
Controller:
// GET: Home
public ActionResult IndexDateRange(string sortOrder, DateTime startDateFromJS, DateTime endDateFromJS)
{
var sortedByDates = from pay in db.DailyPayments
select pay;
sortedByDates = sortedByDates.OrderByDescending(pay => pay.Date);
var first = sortedByDates.Select(pay => pay.Date).First();
var lastDate = sortedByDates.Select(pay => pay.Date).Last();
if (startDateFromJS > first.Date || (endDateFromJS < lastDate))
{
var dateRange = sortedByDates.Where(pay => pay.Date >= startDateFromJS && pay.Date <= endDateFromJS);
return View(dateRange.ToList());
}
return View(sortedByDates.ToList());
}
Javascript in the Index:
#Html.ActionLink("Get Dates", "IndexDateRange", routeValues: new { startDateFromJS = startDate, endDateFromJS = endDate })
<script>
$(function () {
var startDate = getStartDate();
var endDate = getEndDate();
function getStartDate() {
$('#startDate').datepicker();
$('#calendarSubmitButton').click(function () {
//var startDate = $('#startDate').datepicker('getDate');
var startDate = $('#startDate').datepicker('getDate');
console.log(startDate);
return startDate;
})
};
function getEndDate() {
$('#endDate').datepicker();
$('#calendarSubmitButton').click(function () {
var endDate = $('#endDate').datepicker('getDate');
console.log(endDate);
return endDate;
})
};
Temporary Test JS to try and wire up the href. When I click on it, it just adds the pound symbol to the home/index Url and in the browser developer tools it says illegal character.
Get Dates
<script type="text/javascript">
$('#calendarSubmitButton').click(function() {
var tempStartDate = #DateTime.Now.AddMonths(-1).ToString("yyyyMMdd");
var tempEndDate = #DateTime.Now.ToString("yyyyMMdd");
location.href='#Url.Action("IndexDateRange")+'?startDateFrom‌​JS='+$('tempStartDate')+'&endDateFromJS='+$('tempEndDate')';
});
</script>
Screen Grab:
Screenshot of the setup
Try this
Get Dates
<script type="text/javascript">
$('#calendarSubmitButton').click(function() {
var tempStartDate = '#DateTime.Now.AddMonths(-1).ToString("yyyyMMdd")';
var tempEndDate = '#DateTime.Now.ToString("yyyyMMdd")';
location.href='#Url.Action("IndexDateRange")?startDateFrom‌​JS='+tempStartDate +'&endDateFromJS='+tempEndDate;
});
</script>
Thanks to the help of #StephenMuecke and #Tanmay, I was finally able to get this to work. I'm posting the functioning code here.
Controller
// GET: Home
public ActionResult Index(string sortOrder, string startDate, string endDateFromJS)
{
var sortedByDates = from pay in db.DailyPayments
select pay;
sortedByDates = sortedByDates.OrderByDescending(pay => pay.Date);
if (startDate != null && endDateFromJS != null)
{
DateTime convertedStartDateFromJS = DateTime.ParseExact(startDate, "yyyyMMdd", new CultureInfo("en-US"));
DateTime convertedEndDateFromJS = DateTime.ParseExact(endDateFromJS, "yyyyMMdd", new CultureInfo("en-US"));
var dateRange = sortedByDates.Where(pay => pay.Date >= convertedStartDateFromJS && pay.Date <= convertedEndDateFromJS);
return View(dateRange.ToList());
}
return View(sortedByDates.ToList());
}
Javascript and HTML in the index.cshtml
<div class="form-group">
#Html.Label("Total payment:", new { id = "totalTextbox" }) <br />
#Html.TextBox("Total", Math.Floor(totalPayment) + " yen" , new { #class = "alert alert-danger", #readonly = "readonly" })
</div>
<div class="form-group">
#Html.Label("Starting Date:")
#Html.TextBox("Starting Date:", "", new { #class = "date-picker", id = "startDate" })
#Html.Label("Ending Date:")
#Html.TextBox("Ending Date:", "", new { #class = "date-picker", id = "endDate" })
#*<input type="submit" href="#" id="calendarSubmitButton" class="btn btn-primary" />*#
Get Dates
<script type="text/javascript">
$(document).ready(function () {
$('#calendarSubmitButton').click(function () {
//TODO: Figure this out.
var tempStartDate = $("#startDate").val($.datepicker.formatDate('yymmdd', new Date($('#startDate').datepicker('getDate'))));
var tempEndDate = $("#endDate").val($.datepicker.formatDate('yymmdd', new Date($('#startDate').datepicker('getDate'))));
location.href = '#Url.Action("Index")?startDate=' + tempStartDate.val() + '&endDateFromJS=' + tempEndDate.val();
})
});
</script>
</div>

How to Increase Date after the time in Timepicker passes midnight?

I have a startDate model which I have bound to a bootstrap date picker and timepicker. When I increase the time in the Time picker and it passes midnight, I need to have the model increase its date as well. Following is my existing code.
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('DatepickerDemoCtrl', function($scope) {
$scope.hstep = 1;
$scope.mstep = 15;
$scope.ismeridian = true;
$scope.toggleMode = function() {
$scope.ismeridian = !$scope.ismeridian;
};
$scope.today = function() {
$scope.startDate = new Date();
};
$scope.startDateState = {
opened: false
}; /* Model to keep track if Popup is open */
$scope.today(); /* Sets Date as Today Initially */
$scope.showWeeks = false; /* Hides Week Numbers */
$scope.minDate = new Date(); /* Disables past dates */
$scope.format = 'dd MMM, yyyy'; /* Date Format Setting */
$scope.dateOptions = {
startingDay: 1,
showWeeks: false,
}; /* to be passed in the date-options directive */
$scope.open = function() {
$scope.startDateState.opened = true;
}; /* Button Click Event to open Popup */
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.3.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="DatepickerDemoCtrl">
<pre>Start date is: <em>{{startDate| date:"MM/dd/yyyy 'at' h:mma"}}</em></pre>
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="startDate" is-open="startDateState.opened" on-open-focus="false" min-date="minDate" show-button-bar="false" datepicker-options="dateOptions" ng-required="true" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
<uib-timepicker ng-model="startDate" hour-step="hstep" minute-step="mstep" show-meridian="ismeridian"></uib-timepicker>
</div>
</div>
</div>
</body>
</html>
How to approach this problem?
Akash,
The way I approached the problem was to use the ng-change directive on the date input field.
HTML
<input ... ng-change="startDateChanged({{startDateTime}})"></input>
You will notice that the parameter being passed to the controllers scope function is a literal expression. The reason for this is so that we can compare what the original value of the ng-model date object was before it was modified by the up or down arrows from the time picker.
Controller
var app = angular.module('plunker', ['ui.bootstrap']);
app.controller('MainCtrl', function($scope) {
var twelveAm = 0;
var oneAm = 1;
var elevenPm = 23;
$scope.hStep = 1;
$scope.mStep = 15;
$scope.startDateTime = new Date();
$scope.today = new Date();
$scope.datePickerState = {
startDateOpened: false
};
$scope.datePickerOptions = {
"show-weeks": false
};
$scope.open = () => {
$scope.datePickerState.startDateOpened = true;
};
$scope.startDateChanged = (originalModel) => {
var nd = _.clone($scope.startDateTime);
var od = new Date(originalModel);
if (nd.getHours() === twelveAm) {
if (od.getHours() === elevenPm) {
nd.setDate(nd.getDate() + 1);
$scope.startDateTime = nd;
} else if (od.getHours() === oneAm) {
nd.setDate(nd.getDate() - 1);
$scope.startDateTime = nd;
}
}
};
});
Inside the method $scope.startDateChanged(), I first create two new date objects, one holding the value of the original datetime (the expression that was passed in) and another with the new datetime. Then I check to see if the new datetime (nd) has a value of 12 AM. If it does, I then check to see if the original datetime (od) has a value of 11 PM or 1 AM and act accordingly (if its 11 PM, it means the button we pushed was to increase the time and therefore the day, otherwise, we are lowering the time and henceforth the day)
I've included a Plunker to illustrate the example.
https://plnkr.co/edit/dDMfpXmy3JBEjXzOca9v

moment datapicker: subcription to KO property

Working with moment datepicker in my project i can't see where my error is.
Basically what i want to do is make a suscription to source property in order to know when th property change (the time to load to service method). So follwoing some urls i was able to build this basic example:
var model = {
test_date: ko.observable(new Date('2012/12/12'))
};
ko.applyBindings(model, $("#target")[0]);
model.test_date.subscribe(function (newValue) {
alert("new selection :" + newValue);
});
http://jsfiddle.net/rolandomartinezg/x7Zt3/5/
The code above is simple and works, my trouble begin in my production code where for some strange reason the code realted to suscription is not fired.
short example (in production code I am typescript):
export var fromDate = ko.observable(new Date('2012/12/12'));
fromDate.subscribe(function (newValue) {
alert("new selection of date");
});
I tried find some missing reference from my jsfiddle example and my production code and both are using the same libraries (moment.js, moment-datepicker.js, moment-datepicker-ko.js,/knockout.js.
what i am doing wrong? any tip?
UPDATE 1: My production code converted from typescript to js:
define(["require", "exports", 'services/logger', '../../services/Assessment/datacontext'], function(require, exports, __logger__, __datacontext__) {
var logger = __logger__;
var datacontext = __datacontext__;
exports.title = 'AssessmentListing';
exports.fromDate = ko.observable(new Date('2012/12/12'));
exports.toDate = ko.observable(new Date('2012/12/12'));
function activate() {
loadInitData();
}
exports.activate = activate;
function loadInitData() {
var focusDate = ko.observable(new Date('2013/07/06'));
exports.fromDate = ko.observable(firstDayOfMonth(focusDate));
exports.toDate = ko.observable(getLastDayOfMonth(focusDate));
// calls to services
}
function getLastDayOfMonth(focusDate) {
var d = new Date(Date.apply(null, focusDate));
d.setMonth(d.getMonth() + 1);
d.setDate(0);
return d;
}
function firstDayOfMonth(focusDate) {
var d = new Date(Date.apply(null, arguments));
d.setDate(1);
return d;
}
exports.toDate.subscribe(function (newValue) {
alert("new selection :");
});
exports.fromDate.subscribe(function (newValue) {
alert("new selection");
});
function viewAttached() {
}
exports.viewAttached = viewAttached;
})
UPDATE 2: My VIEW
<div class="span4">
<span><small>From Date:</small> </span>
<div class="input-append date" id="fromDate" >
<input id="fromDatePicker" type="text" data-bind="datepicker: fromDate()" class="input-small">
<span class="add-on"><i class="icon-calendar"></i></span>
</div>
<span><small>To Date: </small></span>
<div class="input-append date" id="ToDate" >
<input id="toDatePicker" type="text" data-bind="datepicker: toDate()" class="input-small">
<span class="add-on"><i class="icon-calendar"></i></span>
</div>
</div>
Update 3
Trying use changeDate doesn't work because ev.date is not available.
export function viewAttached() {
$('#fromDatePicker').datepicker()
.on('changeDate', function (ev) {
/*ev.date doesn't work*/
alert('fromdate has changed');
});
}
In your data binding, you have:
datepicker: toDate()
Since toDate is an observable, calling toDate() gets you the value of the observable, so you're passing that instead of passing the observable itself.
Try changing your binding to:
datepicker: toDate
That will enable the datepicker binding handler to update your observable.
Update:
I think this is your second problem. In this function:
function loadInitData() {
var focusDate = ko.observable(new Date('2013/07/06'));
exports.fromDate = ko.observable(firstDayOfMonth(focusDate));
exports.toDate = ko.observable(getLastDayOfMonth(focusDate));
// calls to services
}
...you are replacing the toDate and fromDate properties with new observables which do not have the subscriptions applied that the original observables do. Try attaching the subscriptions after creating these observables, or perhaps instead of creating new observables, just populate them:
function loadInitData() {
var focusDate = ko.observable(new Date('2013/07/06'));
exports.fromDate(firstDayOfMonth(focusDate));
exports.toDate(getLastDayOfMonth(focusDate));
// calls to services
}

Categories

Resources