I want to change the value of a public variables with a function and use this new values from an other function.
My use case: I want to set a default public variable for a countdown timer, and if the user wants to change the target date he could put a new date. To do so, I've created another function to change the public variables, but it doesn't seem to work perfectly.
Here is my code:
<table id="global" border="3">
<tr>
<td align="center">
<form name="formInput" action="#">
<label>Choose new Date: </label>
<input type="date" name="field1" Id="txtvarInput" />
<br />
<br />
</label>
<div class="form-actions" "span3">
<input name="submit" type="submit" class="btn" value="Select" onclick="alertVal()" />
</div>
</form>
</td>
</tr>
<tr id="countdownTimer">
<td>
<script type="application/javascript">
var current = "Has been launched!"; //-->enter what you want the script to display when the target date and time are reached, limit to 20 characters
var year;
var month;
var day;
var hour = 0;
var minute = 0;
var second = 0;
var ampm = "pm";
var timezone = -5;
function alertVal() {
var theInput = document.getElementById('txtvarInput').value;
var date_array = new Array();
date_array = theInput.split("-");
month = date_array[1];
year = date_array[0];
day = date_array[2];
}
var Countdown_Ignition = new Countdown({
width: 300,
height: 60,
year,
month,
day,
hour,
ampm,
minute,
second,
timezone,
rangeHi: "day",
style: "flip" // <- no comma on last item!!
});
</script>
</td>
The issue is that when I change the date, my second function doesn't take the new values.
this doesn't work because you're passing a value on the object literal (pointing to undefined at first), so when your alertVal function "updates" the value, it's making an assignment pointing to the new value (i.e. 22).
If you want to keep track of the change inside the Countdown object, you have to pass a variable which points to an actual object (a reference, not a value). So, your global function updates a property of the very same object and you win!
var publicObject = {
year: null,
day: null,
etc: null
};
function setData(){
publicObject.day = 'new value';
publicObject.year = 'new value';
publicObject.etc = 'and so on';
};
var Countdown_Ignition = new Countdown({
width:300,
height:60,
publicObject,
rangeHi:"day",
style:"flip" // <- no comma on last item!!
});
Related
I have a watcher on a $scope variable which sets off a function to change the $scope variable to the beginning of the week of the date chosen. The function is returning the correct date but when I try to set the $scope variable to that date the view does not update. But checking it inside the inspector the $scope variable is changed but the view never updates. Here is the $watch function:
angular.module('hansenApp', ['ngAnimate', 'ui.bootstrap']);
angular.module('hansenApp').controller('DatepickerCtrl', function ($scope) {
$scope.startDate = new Date();
$scope.endDate = new Date();
$scope.status = {
startOpened: false,
endOpened: false,
};
$scope.openStart = function ($event) {
$scope.status.startOpened = true;
};
$scope.openEnd = function ($event) {
$scope.status.endOpened = true;
};
$scope.$watch('startDate', function (dateVal) {
var oldDate = new Date(dateVal);
var tempDate = getStartDateOfWeek(dateVal);
if (oldDate.getTime() != tempDate.getTime()) {
$scope.startDate = tempDate;
}
});
$scope.$watch('endDate', function (dateVal) {
var oldDate = new Date(dateVal);
var tempDate = getEndDateOfWeek(dateVal);
if ($scope.endDate.getTime() != tempDate.getTime()) {
$scope.endDate = tempDate;
}
});
function getStartDateOfWeek(date) {
var ISOweekStart = date;
ISOweekStart.setDate(date.getDate() - date.getDay());
return ISOweekStart;
}
function getEndDateOfWeek(date) {
var ISOweekEnd = date;
ISOweekEnd.setDate(date.getDate() + (6 - date.getDay()));
return ISOweekEnd;
}
});
Edit 1: Here's the view:
<p class="input-group">
<input type="text" id="endDate" class="form-control" uib-datepicker-popup="MM/dd/yyyy" ng-model="endDate" is-open="status.endOpened" close-text="Close" placeholder="End Date:" runat="server" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openEnd($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
You do not change the reference of the date, but just the value of it.
A Date is an object in javascript, hence if you do not change the reference (replace it by a new Date() object) the angular change detector will not trigger again.
So you will have to replace the startDate by a completely new instance of a javascript date with the given properties.
So replace
var ISOweekEnd = date;
by
var ISOweekEnd = new Date();
I have an input field that asks user to pick a date and if the date is less than 30 days form today it will display some other contents. I am using jQueryUI datapicker and knockout.js for data binding and here is what I have so far JSFiddle but it's not working. What am I missing?
$(document).ready(function() {
$("#datepicker").datepicker();
});
$(document).ready(function() {
var viewModel = function() {
var self = this;
self.request_due_date = ko.observable();
self.request_due_date_rush = ko.observable(false);
self.request_due_date_rush_reason = ko.observable();
self.request_due_date.subscribe(function(dd) {
var cur = new Date(),
rush_date = cur.setDate(cur.getDate() + 30);
if (dd < rush_date) {
self.request_due_date_rush(true);
}
});
};
ko.applyBindings(new viewModel());
});
<div>Due Date:
<input id="datepicker" data-bind="text: request_due_date" type="text" />
</div>
<div data-bind="visible: request_due_date_rush">Reason For Rush:
<input data-bind="text: request_due_date_rush_reason" />
</div>
it's because when you create the datepicker object, the underlying input element gets moved around in the DOM, breaking the binding. Consider writing your own binding handler, like seen here:
jQuery UI datepicker change event not caught by KnockoutJS
You need to bind value, not text.
<input id="datepicker" data-bind="value: request_due_date" type="text" />
Also the value dd is a string and must be parsed to date, for example using moment.js
var days = moment().diff(moment(dd, "MM/DD/YYYY"), "days");
See updated fiddle
Thanks to #MaxBrodin for the insight (to bind value, not text) and this post I found the following solution to be working. Here is also the updated Fiddle
$(document).ready(function() {
$("#datepicker").datepicker();
});
$(document).ready(function() {
var viewModel = function() {
var self = this;
self.request_due_date = ko.observable();
self.request_due_date_rush = ko.observable(false);
self.request_due_date_rush_reason = ko.observable();
self.request_due_date.subscribe(function(dd) {
var date1 = new Date(dd);
var date2 = new Date();
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var days = Math.ceil(timeDiff / (1000 * 3600 * 24));
self.request_due_date_rush(days < 30);
});
};
ko.applyBindings(new viewModel());
});
<div>Due Date:
<input id="datepicker" data-bind="value: request_due_date" type="text" />
</div>
<div data-bind="visible: request_due_date_rush">Reason For Rush:
<input data-bind="text: request_due_date_rush_reason" />
</div>
I am having a problem with an HTML5 form field, I need the field (time) to update each second to the current time, the update code is called every second via a setInterval, the HTML5 form element :
<form name="process">
<input name="p_time" type="time" value="<?php echo date("H:i:s");?>" />
//...
</form>
when I try to update : document.forms.process.p_time.value = current.time.slice(17,25); the display remains at the setting made by PHP, the type of string data is the same format of 00:00:00 but it refuses to budge from that original time. the variable current.time is a string of the UTC format corresponding to : ddd, dd mmm, yyyy hh:mm:ss +00:00 GMT variety.
The javascript is a simple routine, it updates a element in the full version
current = {
now:function(){ return new Date(); },
time:0,
tick:function(){
current.time = current.now().toUTCString();
document.forms.process.p_time.value = current.time.slice(17,25);
current.clock();
},
clock:function(){
current.target.innerHTML = current.time.slice(0,25);
},
auto:setInterval(current.tick,1000)
}
What I don't want to have to do is to have the page refreshed by a page refresh.
This should work!: http://jsfiddle.net/d9vg5yhL/1/
<form name="process">
<input name="p_time" id='time' type="time" value="" />
</form>
Javascript:
function startTime() {
var today=new Date();
var h=today.getHours();
var m=today.getMinutes();
var s=today.getSeconds();
h = checkTime(h);
m = checkTime(m);
s= checkTime(s);
document.getElementById('time').value = h+":"+m+":"+s;
var t = setTimeout(function(){startTime()},1000);
}
function checkTime(i) {
if (i<10) {i = "0" + i} // add zero in front of numbers < 10
return i;
}
startTime();
I have two timepicker in my view
#Html.Kendo().TimePickerFor(m=>m.AttendeeStartTime).Format("HH:mm")
#Html.Kendo().TimePickerFor(m=>m.AttendeeEndTime).Format("HH:mm")
This is how it looks
and here is rendered HTML for From Timepicker,
<input data-val="true" data-val-required="The AttendeeStartTime field is required."
id="AttendeeStartTime" name="AttendeeStartTime" type="text" value="09:00" data-role="timepicker"
class="k-input valid" role="textbox" aria-haspopup="true" aria-expanded="false" aria-
owns="AttendeeStartTime_timeview" aria-disabled="false" aria-readonly="false" style="width: 100%;">
Whenever there is change in From timepicker, how can I add one hour to its value and set to to To timepicker?
This is what I have done,
$('##Html.IdFor(m=>m.AttendeeStartTime)').on('change', function () {
//var date = new Date();
endTime.value($(this).val());
alert(endTime.value());
This only sets the To value to the same as From when there is change, but I want to add an hour or some timespan to it.
How should i do that?
Use this:
$('##Html.IdFor(m=>m.AttendeeStartTime)').on('change', function () {
//try getting the date from the date picker
var date = $("##Html.IdFor(m=>m.AttendeeStartTime)").data("kendoTimePicker").value();
if (date) {
//convert the string to a date
date = new Date(date); //you can probably skip this step since the Kendo DatePicker returns a Date object
//increase the "hours"
date.setHours(date.getHours() + 1);
//set it back in the "to" date picker
$("##Html.IdFor(m=>m.AttendeeEndTime)").data("kendoTimePicker").value(date);
//alert(endTime.value());
}
}
You can write a custom function like this,
function addMinutes(time, minsToAdd) {
function z(n){ return (n<10? '0':'') + n;};
var bits = time.split(':');
var mins = bits[0]*60 + +bits[1] + +minsToAdd;
return z(mins%(24*60)/60 | 0) + ':' + z(mins%60);
}
addMinutes('05:40', '20'); // '06:00'
addMinutes('23:50', 20);
Your scenario should be,
$('##Html.IdFor(m=>m.AttendeeStartTime)').on('change', function () {
//var date = new Date();
endTime.value($(this).val());
addMinutes($(this).val(), '60');
alert(endTime.value());
I am trying to validate date based on date entered in first textbox. If second textbox exceeds one year from the date entered in first textbox, then it should display an alert and blank the second date field textbox. Both the textboxes are readonly and gets the values from calender. I tried the below code but the alert is popping up even if the year is not more than a year. Also ,is it possible to pass 'name3' and 'name4' IDs as parameters. I need to apply this code to 10 rows.
<script>
function fixup()
{
var parts = document.getElementById('name3').value.split("-");
parts[2] = Number(parts[2]) + 1;
var pj = parts.join("-");
var x=document.getElementById('name4').value;
if(x>pj)
{
alert("Expiration date should not be greater than one year from start date");
document.getElementById('name4').value = "";
return false;
}
return true;
}
</script>
</head>
<body>
<form onsubmit="return fixup()">
<table>
<tr>
<td><input type="text" name="soname3" id="name3" size="15" readonly="readonly">
<img src="../Image/cal.gif" id="" style="cursor: pointer;" onclick="javascript:NewCssCal('name3','MMddyyyy','dropdown',false,'12')" /></td>
<td><input type="text" name="soname4" id="name4" size="15" readonly="readonly">
<img src="../Image/cal.gif" id="" style="cursor: pointer;" onclick="javascript:NewCssCal('name4','MMddyyyy','dropdown',false,'12'); " /> </td>
</tr>
</table>
<input type="submit" value="Submit">
</form>
I did Below code after suggestions by dm03514. but validation is not working..
function test()
{
start = document.getElementById('name3').value;
end = document.getElementById('name4').value;
compare(start, end);
}
function compare(sDate, eDate)
{
function parseDate(input) {
var parts = input.match(/(\d+)/g);
return new Date(parts[2], parts[0]-1, parts[1]); //parts[2] is year, parts[0] is month and parts[1] is date.
}
var parse_sDate = parseDate(sDate);
var parse_eDate = parseDate(eDate);
parse_sDate.setDate(parse_sDate.setFullYear(parse_sDate.getMonth() + 12));
if(parse_sDate>parse_eDate)
{
alert("End date should not be greater than one year from start date");
}
}
I would strongly recommend using a library like moment.js for handling dates. It has extensive date formatting and parsing features as well as comparison helpers:
var d1 = moment(document.getElementById('name3').value, 'YYYY-MM-DD');
var d2 = moment(document.getElementById('name4').value, 'YYYY-MM-DD');
var diff = d2.diff(d1, 'years');
if (diff > 0) {
alert("Expiration date should not be greater than one year from start date");
}
See also:Compare two dates in JS