How to handle an error for validating between two dates? - javascript

I have an jsp page where the user select between two dates. I need validation to ensure that the limit of the range is a month. I need to display message for error handling about that issue.
I tried making a function with return true and false. When the return is false, the message is already appears but system is still running to the next step. Here is my jsp page: (I use netbeans editor)
var fromDate = new Date(document.getElementById("fromTgl").value);
var toDate = new Date(document.getElementById("toTgl").value);
//call the function
var validateDate;
validateDate = rangeWithinDates(toDate,fromDate);
//funtion for validation within two dates
function rangeWithinDates(toDate,fromDate){
var diff = Math.abs(toDate.getTime() - fromDate.getTime());
var daysDiff = diff / (1000 * 60 * 60 * 24);
if (daysDiff>30){
window.alert("Please limit the date range to 1 month!");
return false;
} else {
return true;
}
}
it's my full script
<script>
var officeCode;
var fdsReport;
var rows;
$(document).ready(function() {
esLoadingAnimWindow("wndLoading");
/** Get the userId from session scope **/
var userId = "${sessionScope.UserSession.getUserId()}";
var CurrOfficeCode = "${sessionScope.UserSession.getUserOfficeCode()}";
if ($("#officeCode").data("kendoDropDownList") == null) {
$('#officeCode').kendoDropDownList({
dataTextField: "nameShort",
dataValueField: "officeCode",
dataSource: {
transport: {
read: {
dataType: "json",
url: getFormRestUrl() + "/getListOffice?officeCode=" + CurrOfficeCode
}
}
},
optionLabel: "Select Office Code"
});
}
if($("#fromTgl").data("kendoDatePicker")==null) {
$("#fromTgl").kendoDatePicker({value: new Date(), format: "dd MMMM yyyy"});
}
if($("#toTgl").data("kendoDatePicker")==null) {
$("#toTgl").kendoDatePicker({value: new Date(), format: "dd MMMM yyyy"});
}
$("#wndLoading").kendoWindow({
actions: ["Close"],
modal: true,
width: "350px",
resizable: false,
title: false,
draggable: false,
open: function(e) { $("html, body").css("overflow", "hidden"); },
close: function(e) {
$("html, body").css("overflow", "");
}
}).data("kendoWindow");
// Call the function to stop scrolling main window when scrolling the content of kendo dropdownlist.
stopScroll($("#officeCode").data("kendoDropDownList").ul.parent());
});
$("#btnProcess").click(function(e){
e.preventDefault();
$("#wndLoading").data("kendoWindow").center().open();
var fromDate = new Date(document.getElementById("fromTgl").value);
var toDate = new Date(document.getElementById("toTgl").value);
var validateDate;
validateDate = rangeWithinDates(toDate,fromDate);
fdsReport = new kendo.data.DataSource({
transport: {
read: {
url: getFormRestUrl() + "/getReportFidusia?officeCode=" + $("#officeCode").val().trim()
+ '&beginDate=' + dateToString($("#fromTgl").data("kendoDatePicker").value())
+ '&endDate=' + dateToString($("#toTgl").data("kendoDatePicker").value()),
dataType: "json",
contentType: "application/json"
}
}
});
rows = [{
cells:[
{ value: "TN NY NN" },
{ value: "Pemberi Fidusia" },
{ value: "Pekerjaan" },
{ value: "Kota Lahir" },
{ value: "Tanggal Lahir" }
]
}];
fdsReport.read().then(function(){
var data = fdsReport.data();
for (var i = 0; i < data.length; i++){
rows.push({
cells: [
{ value: data[i].tNnYnN},
{ value: data[i].pemberiFidusia},
{ value: data[i].jobCust},
{ value: data[i].kotaLahir},
{ value: data[i].tglLahir.slice(0,4) + "-" + data[i].tglLahir.slice(5,7) + "-" + data[i].tglLahir.slice(8,10)}
]
});
};
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: [
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true },
{ autoWidth: true }
],
title: "Laporan Fidusia",
rows: rows
}
]
});
$("#wndLoading").data("kendoWindow").close();
// Save the file as Excel file with extension xlsx
kendo.saveAs({
dataURI: workbook.toDataURL(),
fileName: "erpt_laporan_fidusia.xlsx"
});
});
});
//Ajax error listener
$(document).ajaxError(function (event, jqxhr, settings, thrownError){
//Close the loading window if it is opened
$("#wndLoading").data("kendoWindow").close();
//Open the alert window.
var wndAlert = registerAlertModalWindow("wndAlert", jqxhr.responseText);
wndAlert.center().open();
});
function getGLobalRestUrl() {
return "/easy/api";
}
function getFormRestUrl() {
return getGLobalRestUrl() + "/OMTRNF661";
}
function dateToString(pDate) {
return kendo.toString(pDate, 'yyyy-MM-dd').trim();
}
function rangeWithinDates(toDate,fromDate){
var diff = Math.abs(toDate.getTime() - fromDate.getTime());
var daysDiff = diff / (1000 * 60 * 60 * 24);
if (daysDiff>30){
window.alert("Please limit the date range to 1 month!");
document.getElementById("toTgl").value = "";
return false;
}
return true;
}
</script>
the result of this code
I expect if return false will display an error message and stop the running. so, the users must choose the date according to predetermined range. And if return true will be continue to the next step. Please help me to resolve this..

Your validateDate doesn't prevent you from downloading: it's just an unused boolean.
If you want to, you'll have to do something like this:
if (validateDate){<the rest of your download code section>}

You can reset textbox value to empty and ask user to enter the value again. You can reset only last date value or both.
if (daysDiff>30){
window.alert("Please limit the date range to 1 month!");
document.getElementById("toTgl").value = "";
return false;
}
return true;
In file downloading function check the value true or false
if (validateDate == true){
// your code
}

Related

Data is not saved in database but primary key is created Django Fullcalendar

Currently actual data is not save in database but when ever register button is clicked after I input data, an empty data will be saved and primary key will be created. There is no error being posted anywhere but an empty data is saved. I'm using Django Framework for backend and as front-end, I mainly use Javascript and HTML. For database, I use Sqlite. I think the most important part in the data transport is in the Ajax part but since I just used Ajax and Javascript for the first time, I still don't know a lot of thing. Please help me.
script.js
function initializePage() {
$('#calendar').fullCalendar({
height: 550,
lang: "ja",
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
navLinks: true,
timeFormat: 'HH:mm',
selectable: true,
selectHelper: true,
eventSources:[{
url: '/fullcalendar/calendar',
method: 'GET',
failure: function(){
alert("PROBLEM!!!");
},
}
],
select: function(start, end, resource) {
// 日付選択された際のイベント
// ダイアログタイトル設定
$("#dialogTitle").text("スケジュール登録");
// タイトル初期化
$("#inputTitle").val("");
// 備考初期化
$("#inputDescription").val("");
// ボタン制御
$("#registButton").show();
$("#updateButton").hide();
$("#deleteButton").hide();
// ダイアログ表示
$('#inputScheduleForm').on('show.bs.modal', function (event) {
setTimeout(function(){
$('#inputTitle').focus();
}, 500);
}).modal("show");
// 日付ピッカーの設定
$('#inputYmdFrom').datetimepicker({locale: 'ja', format : 'YYYY年MM月DD日', useCurrent: false });
$('#inputYmdTo').datetimepicker({locale: 'ja', format : 'YYYY年MM月DD日', useCurrent: false });
$('.ymdHm').datetimepicker({
locale: 'ja',
format : 'YYYY年MM月DD日 HH時mm分'
});
// 開始終了が逆転しないように制御
$("#inputYmdFrom").on("dp.change", function (e) {
$('#inputYmdTo').data("DateTimePicker").minDate(e.date);
});
$("#inputYmdTo").on("dp.change", function (e) {
$('#inputYmdFrom').data("DateTimePicker").maxDate(e.date);
});
if (this.name == "month") {
$('.ymdHm').hide()
$('.ymd').show()
// 終日チェックボックス
$('#allDayCheck').prop("checked", true);
// 選択された日付をフォームにセット
// FullCalendar の仕様で、終了が翌日の00:00になるため小細工
var startYmd = moment(start);
var endYmd = moment(end);
if (endYmd.diff(startYmd, 'days') > 1) {
endYmd = endYmd.add(-1, "days");
} else {
endYmd = startYmd;
}
$('#inputYmdFrom').val(startYmd.format("YYYY年MM月DD日"));
$('#inputYmdFrom').data("DateTimePicker").date(startYmd.format("YYYY年MM月DD日"));
$('#inputYmdTo').val(endYmd.format("YYYY年MM月DD日"));
$('#inputYmdTo').data("DateTimePicker").date(endYmd.format("YYYY年MM月DD日"));
} else {
$('.ymdHm').show();
$('.ymd').hide();
// 終日チェックボックス
$('#allDayCheck').prop("checked", false);
var startYmd = moment(start);
var endYmd = moment(end);
$('#inputYmdHmFrom').val(startYmd.format("YYYY年MM月DD日 HH時mm分"));
$('#inputYmdHmFrom').data("DateTimePicker").date(startYmd.format("YYYY年MM月DD日 HH時mm分"));
$('#inputYmdHmTo').val(endYmd.format("YYYY年MM月DD日 HH時mm分"));
$('#inputYmdHmTo').data("DateTimePicker").date(endYmd.format("YYYY年MM月DD日 HH時mm分"));
}
},
eventClick: function(event) {
// 予定クリック時のイベント
$("#dialogTitle").text("スケジュール詳細");
// スケジュールID設定
$("#scheduleId").val(event.id);
// タイトル設定
$("#inputTitle").val(event.title);
// ボタン制御
$("#registButton").hide();
$("#updateButton").show();
$("#deleteButton").show();
// ダイアログ表示
$('#inputScheduleForm').on('show.bs.modal', function (event) {
setTimeout(function(){
$('#inputTitle').focus();
}, 500);
}).modal("show");
// 日付ピッカーの設定
$('#inputYmdFrom').datetimepicker({locale: 'ja', format : 'YYYY年MM月DD日', useCurrent: false });
$('#inputYmdTo').datetimepicker({locale: 'ja', format : 'YYYY年MM月DD日', useCurrent: false });
$('.ymdHm').datetimepicker({
locale: 'ja',
format : 'YYYY年MM月DD日 HH時mm分'
});
// 開始終了が逆転しないように制御
$("#inputYmdFrom").on("dp.change", function (e) {
$('#inputYmdTo').data("DateTimePicker").minDate(e.date);
});
$("#inputYmdTo").on("dp.change", function (e) {
$('#inputYmdFrom').data("DateTimePicker").maxDate(e.date);
});
// 終日チェックボックス
$('#allDayCheck').prop("checked", true);
// 選択された日付をフォームにセット
if (this.name == "month") {
$('.ymdHm').hide()
$('.ymd').show()
// 終日チェックボックス
$('#allDayCheck').prop("checked", true);
// 選択された日付をフォームにセット
// FullCalendar の仕様で、終了が翌日の00:00になるため小細工
var startYmd = moment(start);
var endYmd = moment(end);
if (endYmd.diff(startYmd, 'days') > 1) {
endYmd = endYmd.add(-1, "days");
} else {
endYmd = startYmd;
}
$('#inputYmdFrom').val(startYmd.format("YYYY年MM月DD日"));
$('#inputYmdFrom').data("DateTimePicker").date(startYmd.format("YYYY年MM月DD日"));
$('#inputYmdTo').val(endYmd.format("YYYY年MM月DD日"));
$('#inputYmdTo').data("DateTimePicker").date(endYmd.format("YYYY年MM月DD日"));
} else {
$('.ymdHm').show();
$('.ymd').hide();
// 終日チェックボックス
$('#allDayCheck').prop("checked", false);
var startYmd = moment(event.start);
var endYmd = moment(event.end);
$('#inputYmdHmFrom').val(startYmd.format("YYYY年MM月DD日 HH時mm分"));
$('#inputYmdHmFrom').data("DateTimePicker").date(startYmd.format("YYYY年MM月DD日 HH時mm分"));
$('#inputYmdHmTo').val(endYmd.format("YYYY年MM月DD日 HH時mm分"));
$('#inputYmdHmTo').data("DateTimePicker").date(endYmd.format("YYYY年MM月DD日 HH時mm分"));
}
},
});
}
function registSchedule() {
// 開始終了日付の調整
var startYmd = moment(formatNengappi($('#inputYmdFrom').val() + "00時00分00", 1));
var endYmd = moment(formatNengappi($('#inputYmdTo').val() + "00時00分00", 1));
var allDayCheck = $('#allDayCheck').prop("checked");
if (!allDayCheck) {
startYmd = moment(formatNengappi($('#inputYmdHmFrom').val() + "00", 1));
endYmd = moment(formatNengappi($('#inputYmdHmTo').val() + "00", 1));
}
if (endYmd.diff(startYmd, 'days') > 0) {
endYmd = endYmd.add(+1, "days");
}
// 非同期でサーバーにリクエストを送信
var EventData = {
id: $("#scheduleId").val(),
title: $('#inputTitle').val(),
// title: event.title,
start: startYmd.format("YYYY-MM-DDTHH:mm:ss"),
end: endYmd.format("YYYY-MM-DDTHH:mm:ss"),
allDay: allDayCheck,
};
alert("3!");
sendAjaxRequest("add_event", EventData);
}
function sendAjaxRequest(method, EventData) {
var cal = $("#calendar").fullCalendar("getView");
EventData.searchStart = cal.start;
EventData.searchEnd = cal.end;
// 処理名を設定
var methodName = "登録";
if (method == "update") {
methodName = "更新"
} else if (method == "remove") {
methodName = "削除"
}
$.ajax({
url: "/fullcalendar/" + method,
type: "GET",
//JSON data -> string
// data: JSON.stringify(EventData),
// data: {'title': title, 'start': start, 'end': end},
dataType: "json",
success: function() {
// カレンダー再描画
$('#calendar').fullCalendar('refetchEvents');
$('#inputScheduleForm').modal('hide');
alert("予定を" + methodName + "しました。");
},
error: function() {
alert("予定の" + methodName + "に失敗しました。");
}
});
$('#calendar').fullCalendar('unselect');
}
function allDayCheckClick(element) {
if (element && element.checked) {
// 日付に変換して設定
var startYmdHm = formatNengappi($("#inputYmdHmFrom").val() + "00", 1);
var endYmdHm = formatNengappi($("#inputYmdHmTo").val() + "00", 1);
var startYmd = moment(startYmdHm);
var endYmd = moment(endYmdHm);
$("#inputYmdFrom").val(startYmd.format("YYYY年MM月DD日"));
$("#inputYmdTo").val(endYmd.format("YYYY年MM月DD日"));
// 表示切替
$('.ymdHm').hide();
$('.ymd').show();
} else {
// 日時に変換して設定
var startYmd = formatNengappi($("#inputYmdFrom").val(), 0);
var endYmd = formatNengappi($("#inputYmdTo").val(), 0);
var startYmdHm = moment(startYmd + "T" + moment().format("HH") + ":00:00");
var endYmdHm = moment(startYmd + "T" + moment().format("HH") + ":00:00").add(1, "hours");
$("#inputYmdHmFrom").val(startYmdHm.format("YYYY年MM月DD日 HH時mm分"));
$("#inputYmdHmTo").val(endYmdHm.format("YYYY年MM月DD日 HH時mm分"));
// 表示切替
$('.ymdHm').show();
$('.ymd').hide();
}
}
function formatNengappi(nengappi, flg) {
var ret = nengappi.replace("年", "-").replace("月", "-").replace("日", "");
if (flg == 1){
ret = nengappi.replace("年", "-").replace("月", "-").replace("日", "T").replace("時",":").replace("分",":").replace(" ","");
}
return ret;
}
views.py
def add_event(request):
title = request.GET.get("title", None)
start = request.GET.get("start", None)
end = request.GET.get("end", None)
event = Events(title=str(title), start=start, end=end)
event = Events.objects.create(
title = title,
start = start,
end = end,
)
event.save()
data = {}
return JsonResponse(data)
$.ajax({
url: "/fullcalendar/" + method,
type: "GET",
data: {'title': EventData.title, 'start': EventData.start, 'end': EventData.end},
success: function() {
// カレンダー再描画
$('#calendar').fullCalendar('refetchEvents');
$('#inputScheduleForm').modal('hide');
alert("予定を" + methodName + "しました。");
},
error: function() {
alert("予定の" + methodName + "に失敗しました。");
}
});
$('#calendar').fullCalendar('unselect');
}

Datatables server side processing with mongodb and javascript

Hi I'm having some major issues trying to understand how to datatables to work with server side processing. For some background I'm using a service call Gamesparks to create the backend for a videogame and inside this service they have an implementation of mongodb.
I have an endpoint that fetchs all my users and I can see them in my table but the issue is that I fetch all of them, how can I achieve a pagination?. In the documentation they state that we must put serverSide to true but is not working. I really have no idea on how to proceed I need help.
Gamesparks event to fetch all users
require("LeaderboardMethods");
var playerList = Spark.runtimeCollection("playerList").find({},{"_id":0});
var finalData = [];
while(playerList.hasNext()){
var current = playerList.next();
var playerStats = Spark.runtimeCollection("playerStatistics").findOne({
"playerId":current.playerId
});
var loadedPlayer = Spark.loadPlayer(current.playerId);
var score = getScore(current.playerId);
if(loadedPlayer === null){
var toReturn = {
"playerId": current.playerId,
"displayName": current.displayName,
"email": "DELETED",
"rank": current.rank,
"coins": "DELETED",
"ban": "DELETED",
"score": score
}
finalData.push(toReturn);
} else{
var coins = loadedPlayer.getBalance("COIN");
var toReturn = {
"playerId": current.playerId,
"displayName": current.displayName,
"email": current.email,
"rank":playerStats.rank,
"coins": coins,
"ban": playerStats.isBlocked,
"score":score
}
finalData.push(toReturn);
}
}
Spark.setScriptData("playerList",finalData);
Datatables call
App.getUsers = function(){
var bodyData = {
"#class": ".LogEventRequest",
"eventKey": "GET_PLAYER_DATA",
"playerId": "MY_ID"
}
var table = $('#table1').DataTable({
"dom": "<'row be-datatable-header'<'col-sm-4'l><'col-sm-4'B><'col-sm-4'f>>" +
"<'row be-datatable-body'<'col-sm-12'tr>>" +
"<'row be-datatable-footer'<'col-sm-5'i><'col-sm-7'p>>",
"buttons": [
{
text: 'Edit',
action: function (e, dt, node, config) {
var sel_row = table.rows({
selected: true
}).data();
if (sel_row.length != 0) {
window.location.href = "edit-user.html";
localStorage.setItem("editUser", JSON.stringify(sel_row[0]));
}
}
},
{
text: 'Create',
action: function (e, dt, node, config) {
window.location.href = "create-user.html";
}
},
{
text: 'Delete',
className: 'delete-btn',
action: function (e, dt, node, config) {
var filtered = table.rows({
filter: 'applied',
selected: true
}).data();
// Only open modal when are users selected
if(filtered.length != 0){
$("#proceed-delete").prop('disabled', true)
$("#mod-danger-delete").modal();
if(filtered.length != 1) {
$('#length-users').append(document.createTextNode(filtered.length + " users"));
} else {
$('#length-users').append(document.createTextNode(filtered.length + " user"));
}
$("#delete-confirmation").change(function () {
if ($("#delete-confirmation").val() === "DELETE"){
$("#proceed-delete").prop('disabled', false)
$('#proceed-delete').on('click', function () {
if (filtered.length === 1) {
deleteUserRequest(filtered[0]);
} else {
for (let index = 0; index < filtered.length; index++) {
deleteUserRequest(filtered[index])
}
}
});
}
});
}
}
}, 'selectAll', 'selectNone'
],
"paging":true,
"pageLength":50,
"serverSide":true,
"ajax": {
"data": function (d) {
return JSON.stringify(bodyData);
},
"contentType": "application/json; charset=utf-8",
"url": config.REQUEST_API + '/rs/' + config.API_CREDENTIAL_SERVER + '/' + config.API_SERVER_SECRET + '/LogEventRequest',
"type":"POST",
"dataSrc":function(json){
console.log(json);
$('#loading-row').removeClass('be-loading-active');
return json.scriptData.playerList
},
},
"columns": [
{
data: null,
defaultContent: "<td></td>",
className: 'select-checkbox'
},
{ data: "playerId"},
{ data: "displayName" },
{ data: "email" },
{ data: "score"},
{ data: "rank" },
{ data: "isBlocked" },
{ data: "coins" },
{
"data": null,
"defaultContent": "<button class='btn btn-space btn-primary' onclick='App.click()'>View more</button>"
}
],
"select": {
style: 'multi',
selector: 'td:first-child'
},
}).on('error.dt', function(e, settings, techNote, message){
var err = settings.jqXHR.responseJSON.error;
// GS err
if(err === "UNAUTHORIZED"){
location.href = "pages-login.html";
return true;
} else{
$('#error-container-dt').show();
console.log(message);
return true;
}
});
}
Quick peek into Gamesparks SDK and found this for example:
ListTransactionsRequest
dateFrom Optional date constraint to list transactions from
dateTo Optional date constraint to list transactions to
entryCount The number of items to return in a page (default=50)
include An optional filter that limits the transaction types returned
offset The offset (page number) to start from (default=0)
Now, for paging you need entryCount and offset. First is size of one page, default 50, you can change it. Server returns 'entryCount' no of records.
Offset is the starting record. For example, initial list (1st page) does have 50 records, clicking "Next" button will send request "offset: 51" to the server. And server reply records from 50 (offset) to 100 (offset + entryCount).
var bodyData = {
"#class": ".LogEventRequest",
"eventKey": "GET_PLAYER_DATA",
"playerId": "MY_ID",
"entryCount": entryCount, // you have to send it if you dont like the default value
"offset": offset // gets his value from "NEXT" or "PREV" button
}
Thats how paging works. I'm not able to give more detailed answer as I dont use Gamesparks myself. Hope it gives you least some directon.

how to call a typescript function inside a jquery function?

I don't know if it is possible to call a typescript inside a jquery function. if it is possible, what is the right method to do it?
this my component.ts
getCalendar(){
calendarOptions:Object = {
height: 'parent',
fixedWeekCount : false,
defaultDate: '2017-03-01',
editable: true,
eventLimit: true, // allow "more" link when too many
dayclick function
dayClick: function(date, jsEvent, view) {
this.addModal(); **this function is not working**
//console.log(jsEvent);
// alert('Clicked on: ' + date.format());
// alert('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY);
// alert('Current view: ' + view.name);
},
success: function(doc) {
var events = [];
$(doc).find('event').each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start') // will be parsed
});
});
},
eventAllow: function(dropLocation, draggedEvent) {
if (draggedEvent.id === '999') {
return dropLocation.isAfter('2017-03-22'); // a boolean
}
else {
return true;
}
}
};
ngOnInit() {
this.getTotalEmployee();
this.getComputeAbsent();
this.getTotalAttendance();
// this.showEvent();
this.calendarOptions['events'] = this.events;
}
public catchError(error: any) {
let response_body = error._body;
let response_status = error.status;
if( response_status == 500 ){
this.error_title = 'Error 500';
this.error_message = 'The given data failed to pass validation.';
} else if( response_status == 200 ) {
this.error_title = '';
this.error_message = '';
}
}
showEvent(){
this._event_service.getEventList()
.subscribe(
data => {
this.events = Array.from(data);
this.calendarOptions['events'] = this.events;
console.log(this.calendarOptions['events']);
},
err => this.catchError(err)
);
}
getEvents() {
this._event_service.getEvents().subscribe(
data => {
this.eventsList = Array.from(data);
this.calendarOptions['events'] = this.eventsList;
},
err =>{}
);
}
this is my modal function that im trying to call in jquery function above
addModal() {
let disposable = this.modalService.addDialog(EventComponent, {
title:'Add Event'
}).subscribe((isConfirmed)=>{
});
}
getTotalAttendance() {
let pre;
this._attend_service.getTotalPresent().subscribe(
data => {
pre = Array.from(data);
this.present = pre[0].total_present;
},
err =>{}
);
}
getTotalEmployee() {
let totalEmp;
let filter = "Active";
this._attend_service.getTotalEmp(filter).subscribe(
data => {
totalEmp = data; // fetced record
this.total_emp = totalEmp[0].total_employee;
},
err =>{}
);
}
getComputeAbsent(){
let employee = parseInt(this.employee);
let attendance = parseInt(this.attendance);
this.totalAbsent = employee - attendance;
}
If you don't need the enclosed this
You can use the arrow function:
dayClick: (date, jsEvent, view)=> {
this.addModal();
}
Or you can store the outer this in a variable and use it later
var self = this; // store here
dayClick: function(date, jsEvent, view) {
self.addModal(); // use here
}
Edit:
getCalendar(){
var self = this; // ******
calendarOptions:Object = {
height: 'parent',
fixedWeekCount : false,
defaultDate: '2017-03-01',
editable: true,
eventLimit: true, // allow "more" link when too many
dayClick: function(date, jsEvent, view) {
self.addModal(); // *********
},
success: function(doc) {
var events = [];
$(doc).find('event').each(function() {
events.push({
title: $(this).attr('title'),
start: $(this).attr('start') // will be parsed
});
});
},
eventAllow: function(dropLocation, draggedEvent) {
if (draggedEvent.id === '999') {
return dropLocation.isAfter('2017-03-22'); // a boolean
}
else {
return true;
}
}
};

Create session timeout warning for durandal single page application

I have a durandal/requirejs single page application. When a user sits idle, I need to display a warning to the user indicating that the session is about to time out. I have looked at several examples on the internet for asp.net apps, but can't find any examples for a single page application.
My application is similar to John Papa's code camper (MVC application).
How can I get a session timeout warning to the user if their session is 2 minutes away from timing out?
--EDIT
In my main.js file I have-
app.setRoot('viewmodels/shell', 'entrance');
router.guardRoute = function (instance, instruction) {
var sess_pollInterval = 60000;
//How many minutes the session is valid for
var sess_expirationMinutes = 2;
//How many minutes before the warning prompt
var sess_warningMinutes = 1;
var sess_intervalID;
var sess_lastActivity;
initSessionMonitor();
function initSessionMonitor() {
sess_lastActivity = new Date();
sessSetInterval();
$(document).bind('keypress.session', function (ed, e) { sessKeyPressed(ed, e); });
}
function sessSetInterval() {
sess_intervalID = setInterval('sessInterval()', sess_pollInterval);
}
function sessClearInterval() {
clearInterval(sess_intervalID);
}
function sessKeyPressed(ed, e) {
sess_lastActivity = new Date();
}
function sessPingServer() {
//Call an AJAX function to keep-alive your session.
alert('someAJAXFunction();');
}
function sessLogOut() {
alert('here');
//window.location.href = '/Account/LogOff';
}
function sessInterval() {
var now = new Date();
var diff = now - sess_lastActivity;
var diffMins = (diff / 1000 / 60);
if (diffMins >= sess_warningMinutes) {
//wran before expiring
//stop the timer
sessClearInterval();
//promt for attention
if (confirm('Your session will expire in ' + (sess_expirationMinutes - sess_warningMinutes) +
' minutes (as of ' + now.toTimeString() + '), press OK to remain logged in ' +
'or press Cancel to log off. \nIf you are logged off any changes will be lost.')) {
now = new Date();
diff = now - sess_lastActivity;
diffMins = (diff / 1000 / 60);
if (diffMins > sess_expirationMinutes) {
//timed out
sessLogOut();
}
else {
//reset inactivity timer
sessPingServer();
sessSetInterval();
sess_lastActivity = new Date();
}
} else {
sessLogOut();
}
} else {
sessPingServer();
}
}
return true;
};
}
now getting "Uncaught ReferenceError: sessInterval is not defined." Ideas?
Here's how I do it in my idle service. It uses some other services, but you should get the idea. Basically, I start tracking user activity in observable when he sings in and reset the timeout for idle handler everytime observable changes.
//idle.js
define(function (require) {
var ko = require('knockout'),
$ = require('jquery'),
router = require('lib/router'),
config = require('lib/config'),
dialog = require('lib/dialog'),
auth = require('auth/auth'),
lastActionDate = ko.observable(),
signoutHandle = null,
onIdle = function () {
console.log('user has been idle, signing out');
return auth.signOut()
.then(function () {
router.navigate('');
dialog.show('auth/idle');
});
},
init = function () {
var userActionHandler = function () {
lastActionDate(new Date());
};
auth.on('signin:success').then(function (user) {
$(document).on('click keydown scroll', userActionHandler);
userActionHandler();
});
auth.on('signout:success').then(function (using) {
$(document).off('click keydown scroll', userActionHandler);
});
lastActionDate.subscribe(function () {
if (signoutHandle) {
clearTimeout(signoutHandle);
}
signoutHandle = setTimeout(onIdle, config.get('idleTimeout') * 1000);
});
};
return {
init: init
};
});
Then I just call idle.init() my main.js file before app.start()
The approach I used was different than my post above. I used timeout-dialog.js and altered that script to use with durandal's router and any other service I needed within my application. I also used idle js. Here is the code-
main.js in app.start()-
var timeout = 100;
$(document).bind("idle.idleTimer", function () {
controls.timeoutDialog.setupDialogTimer();
});
$(document).bind("active.idleTimer", function () {
var sess = Security.GetKeepSessionAlive();
});
$.idleTimer(timeout);
timeout-dialog.js code-
String.prototype.format = function () {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
define(['durandal/system', 'plugins/router', 'services/logger', 'services/SecurityDataService'],
function (system, router, logger, Security){
timeoutDialog = {
settings: {
timeout: 50,
countdown: 15,
title: 'Your session is about to expire!',
message: 'You will be logged out in {0} seconds.',
question: 'Do you want to stay signed in?',
keep_alive_button_text: 'Yes, Keep me signed in',
sign_out_button_text: 'No, Sign me out',
keep_alive_url: '',
keep_alive_function: function () {
},
logout_url: function () {
router.map([
{ route: 'ErrorPage', moduleId: 'ErrorPage', title: 'ErrorPage', title: 'ErrorPage', nav: false }
]).activate
router.navigate('ErrorPage');
},
logout_redirect_url: function () {
router.map([
{ route: 'ErrorPage', moduleId: 'ErrorPage', title: 'ErrorPage', title: 'ErrorPage', nav: false }
]).activate
router.navigate('ErrorPage');
},
logout_function: function () {
amplify.store("ErrorDetails", "Session Timed Out!");
router.map([
{ route: 'ErrorPage', moduleId: 'ErrorPage', title: 'ErrorPage', title: 'ErrorPage', nav: false }
]).activate
router.navigate('ErrorPage');
},
restart_on_yes: true,
dialog_width: 350
},
alertSetTimeoutHandle: 0,
setupDialogTimer: function (options) {
if (options !== undefined) {
$.extend(this.settings, options);
}
var self = this;
if (self.alertSetTimeoutHandle !== 0) {
clearTimeout(self.alertSetTimeoutHandle);
}
self.alertSetTimeoutHandle = window.setTimeout(function () {
self.setupDialog();
}, (this.settings.timeout - this.settings.countdown) * 1000);
},
setupDialog: function () {
//check for other modal forms on view
//$.element.modal('hide');
$('.modal').modal('hide');
var self = this;
self.destroyDialog();
$('<div id="timeout-dialog">' +
'<p id="timeout-message">' + this.settings.message.format('<span id="timeout-countdown">' + this.settings.countdown + '</span>') + '</p>' +
'<p id="timeout-question">' + this.settings.question + '</p>' +
'</div>')
.appendTo('body')
.dialog({
modal: true,
width: this.settings.dialog_width,
minHeight: 'auto',
zIndex: 10000,
closeOnEscape: false,
draggable: false,
resizable: false,
dialogClass: 'timeout-dialog',
title: this.settings.title,
buttons: {
'keep-alive-button': {
text: this.settings.keep_alive_button_text,
id: "timeout-keep-signin-btn",
click: function () {
self.keepAlive();
}
},
'sign-out-button': {
text: this.settings.sign_out_button_text,
id: "timeout-sign-out-button",
click: function () {
self.signOut(true);
}
}
}
});
self.startCountdown();
},
destroyDialog: function () {
if ($("#timeout-dialog").length) {
$("#timeout-dialog").dialog("close");
$('#timeout-dialog').remove();
}
},
startCountdown: function () {
var self = this,
counter = this.settings.countdown;
this.countdown = window.setInterval(function () {
counter -= 1;
$("#timeout-countdown").html(counter);
if (counter <= 0) {
window.clearInterval(self.countdown);
self.signOut(false);
}
}, 1000);
},
keepAlive: function () {
var self = this;
this.destroyDialog();
window.clearInterval(this.countdown);
this.settings.keep_alive_function();
if (this.settings.keep_alive_url !== '') {
$.get(this.settings.keep_alive_url, function (data) {
if (data === "OK") {
if (this.settings.restart_on_yes) {
self.setupDialogTimer();
}
}
else {
self.signOut(false);
}
});
}
},
signOut: function (is_forced) {
var self = this;
this.destroyDialog();
this.settings.logout_function(is_forced);
if (this.settings.logout_url !== null) {
$.post(this.settings.logout_url, function (data) {
self.redirectLogout(is_forced);
});
}
else {
self.redirectLogout(is_forced);
}
},
redirectLogout: function (is_forced) {
var target = this.settings.logout_redirect_url + '?next=' + encodeURIComponent(window.location.pathname + window.location.search);
if (!is_forced)
target += '&timeout=t';
window.location = target;
},
};
var dataservice = {
timeoutDialog: timeoutDialog
};
return dataservice;
});
I put the timeout-dialog.js in my own folder under the apps folder to bring in durandal and other services i needed. The idle-timer.js was left in the scripts folder and registered via bundle.config.

YUI3 - DataTable Datasource Polling

Im new to YUI3; Im trying to poll a datasource every 10 seconds to refresh a datatable. But with the code below it says there is 'No Data To Display'... Sorry for the large amount of code...
YUI().use("datatable", "datasource-get", "datasource-jsonschema", "datatable-datasource", "datasource-polling", "datasource-function", function (Y) {
var url = "http://query.yahooapis.com/v1/public/yql?format=json" +
"&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys",
query = "&q=" + encodeURIComponent(
'select * from local.search ' +
'where zip = "94089" and query = "pizza"'),
dataSource,
table;
dataSource = new Y.DataSource.Get({ source: url });
dataSource.plug(Y.Plugin.DataSourceJSONSchema, {
schema: {
resultListLocator: "query.results.Result",
resultFields: [
"Title",
"Phone",
{
key: "Rating",
locator: "Rating.AverageRating",
parser: function (val) {
// YQL is returning "NaN" for unrated restaurants
return isNaN(val) ? -1 : +val;
}
}
]
}
});
intervalId = dataSource.setInterval(10000, {
request : query,
callback: {
success: function (e) {
table.datasource.load(e.response);
},
failure: function (e) {
}
}
});
table = new Y.DataTable({
columns: [
"Title",
"Phone",
{
key: "Rating",
formatter: function (o) {
if (o.value === -1) {
o.value = '(none)';
}
}
}
],
summary: "Pizza places near 98089",
caption: "Table with JSON data from YQL"
});
table.plug(Y.Plugin.DataTableDataSource, { datasource: dataSource });
// This line works (but it doesnt poll)
//table.datasource.load({ request: query });
table.render("#pizza");
});
The line I am not sure about is...
success: function (e) {
table.datasource.load(e.response);
},
The following should fit your needs: http://developer.yahoo.com/yui/examples/datatable/dt_polling.html

Categories