add callback functionality in a JavaScript class - javascript

I'm trying to create a javascript class which opens a jQuery dialog and allows the user to select an option then returns the selected value in a callback.
...similar to how the jQuery Alert Dialogs do it.
jPrompt(message, [value, title, callback])
jPrompt('Type something:', 'Prefilled value', 'Prompt Dialog', function(r) {
if( r ) alert('You entered ' + r);
});
Here is a DEMO of what i have so far. But if you notice, the value gets set imidiately, and i want it to wait until the user clicks OK. If the user clicks Cancel, then it should return null or empty string.
Here's my Javascript Class:
var namespace = {};
(namespace.myChooser = function () {
var _dialog = null;
/**
* Function : onButtonCancel
*/
function onButtonCancel() {
_dialog.dialog("close");
return null;
}
/**
* Function : onButtonOK
*/
function onButtonOK() {
_dialog.dialog("close");
}
/**
* Function : Initialize
*/
function Init() {
var dialog_options = {
modal: false,
disabled: false,
resizable: false,
autoOpen: false,
//height: 460,
maxHeight: 300,
zIndex: 500,
stack: true,
title: 'My Chooser',
buttons: { "OK": onButtonOK, "Cancel": onButtonCancel }
};
_dialog = $("#myDialog");
// create dialog.
_dialog.dialog(dialog_options);
_dialog.dialog("open");
}
return {
Choose: function Choose() {
Init();
var myChoice = $("#myOptions").val();
return myChoice;
}
}
}());
And i want to be able to do something like this:
namespace.myChooser.Choose(function (myChoice) {
$("span#myChoice").text(myChoice);
});
SOLUTION:
This is what finally did it:
$(document).ready(function () {
$('#myButton').click(function () {
namespace.myChooser.Choose(function (x) {
console.log(x);
});
});
});
var namespace = {};
(namespace.myChooser = function (callback) {
function _show(callback) {
var dialog_options = {
modal: false,
disabled: false,
resizable: false,
autoOpen: false,
//height: 460,
maxHeight: 300,
zIndex: 500,
stack: true,
title: 'My Chooser',
buttons: {
"OK": function () {
if (callback) callback("OK");
},
"Cancel": function () {
if (callback) callback("Cancel");
}
}
};
_dialog = $("#myDialog");
// create dialog.
_dialog.dialog(dialog_options);
_dialog.dialog("open");
}
return {
Choose: function (callback) {
_show(function (result){
if (callback) callback(result);
});
}
}
}());

Choose: function Choose(cb) {
Init();
var myChoice = $("#myOptions").val();
return cb(myChoice);
}
Should do what you want

Add another variable where you have var _dialog, call it something like var _callback. Then in your Choose function, add a parameter to get the callback function and store it, something like:
Choose: function Choose(f) {
_callback = f;
...
}
Then when you're ready to call the callback function (I presume this is in onButtonOK/onButtonCancel), call the callback function using _callback(parameter);

Related

Dialog close does not work second time?

I want to this : If user clicked favorite button I show dialog box
"Report added to favorites"
and user clicked favorite button second time I created dialog box
"Report removed from favorites "
again but dialog boxs has same id.
My code s the following :
$scope.toogleReportToFavorites = function (item) {
if (!item.isInFavorites) {
item.isInFavorites = true;
RepService.AddToDefaultFavourites(item.ReportId, function (reportCat) {
if ($scope.showRemovedDialog) {
$("#denemePicker").dialog("close"); //its works only first time
$scope.showAddedDialog = false;
}
else {
$scope.showAddedDialog = true;
}
WarningDialogs("Report added to favorites");
}, function (ex) {
GlobalErrorHandler(ex);
});
} else {
item.isInFavorites = false;
RepService.RemoveFromFavourites(item.ReportId, function () {
if ($scope.showAddedDialog) {
$("#denemePicker").dialog("close");
$scope.showRemovedDialog = false;
}
else {
$scope.showRemovedDialog = true;
}
WarningDialogs("Report removed from favorites");
}, function (ex) {
GlobalErrorHandler(ex);
});
}
};
and this is my WarningDialogs function code :
function WarningDialogs(text, messageType, dialogWidth, callback, textAlign) {
if (textAlign == null || textAlign.length < 1) {
textAlign = 'center';
}
$('<div>', { title: "deneme", id: 'denemePicker' }).html(text).css('text-align', textAlign).dialog(
{
resizable: true, modal: true, closeOnEscape: true, width: dialogWidth,
create: function () {
isWarningDialogsShown = true;
$(this).css('maxHeight', '300px');
},
close: function (event, ui) {
isWarningDialogsShown = false;
if (callback) {
callback();
}
},
buttons: {
Close: function () {
$(this).dialog("close");
}
}
}).css('overflow', 'auto');
return;
}
I want to always work for this : $("#denemePicker").dialog("close"); but its only work first time. I guess reason same id ?
How can ix this please ?
This code may help You
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<button type="button" class="btn btn-info" style="width:90%;" id="textChanger" status="1" onclick="counter;">D Box</button>
<script>
$(document).on('click','#textChanger',function(){
var status = $(this).attr('status');
if(status ==1){
$(this).attr('status',0);
alert('Report added to favorites');
}else{
$(this).attr('status',1);
alert('Report removed from favorites');
}
})
</script>

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.

Can't get value of object's property

Not sure what's going on here. I have a function that is an event handler for a WordPress plugin:
$.fn.almComplete = function(alm){
console.log(alm);
console.log(alm.finished);
}
The first output is this:
e.ajaxloadmore {AjaxLoadMore: Object, page: 0, speed: 300, proceed: false, init: falseā€¦}
AjaxLoadMore: Object
button: m.fn.init[1]
button_label: "Load More"
content: m.fn.init[1]
data: m.fn.init[2]
el: m.fn.init[1]
finished: true
init: false
lang: ""
loading: false
max_pages: 5
offset: 0
page: 0
pause: false
post_type: Array[1]
posts_per_page: 6
prefix: "alm-"
proceed: true
repeater: "default"
scroll: false
speed: 300
transition: "slide"
window: m.fn.init[1]
__proto__: Object
But the second output console.log(alm.finished) always outputs false, but that property is obviously not false so I don't believe I'm referencing this variable correctly.
How do I access the alm object's properties?
EDIT: Here is when this callback is called within the plugin's code:
success: function (data) {
alm.data = $(data); // Convert data to an object
//console.log(alm.data.length);
if (alm.init) {
alm.button.text(alm.button_label);
alm.init = false;
}
if (alm.data.length > 0) {
alm.el = $('<div class="' + alm.prefix + 'reveal"/>');
alm.el.append(alm.data);
alm.el.hide();
alm.content.append(alm.el);
if (alm.transition === 'fade') { // Fade transition
alm.el.fadeIn(alm.speed, 'alm_easeInOutQuad', function () {
alm.loading = false;
alm.button.delay(alm.speed).removeClass('loading');
if (alm.data.length < alm.posts_per_page) {
alm.finished = true;
alm.button.addClass('done');
}
});
} else { // Slide transition
alm.el.slideDown(alm.speed, 'alm_easeInOutQuad', function () {
alm.loading = false;
alm.button.delay(alm.speed).removeClass('loading');
if (alm.data.length < alm.posts_per_page) {
alm.finished = true;
alm.button.addClass('done');
}
});
}
if ($.isFunction($.fn.almComplete)) {
$.fn.almComplete(alm);
}
} else {
alm.button.delay(alm.speed).removeClass('loading').addClass('done');
alm.loading = false;
alm.finished = true;
}
},
Also, the full js source code is here: https://github.com/dcooney/wordpress-ajax-load-more/blob/master/ajax-load-more/core/js/ajax-load-more.js

Images from Backstretch(backstretch.js) in onepage creeping in to other page's backstretch in Durandal.js

I have used Durandal.js for my SPA. I need to have slideshow of Images as background in certain pages, for which I am using jquery-backstretch. I am fetching images from my web back-end. Everything works fine while navigating between pages in normal speed. But, when I navigate from one of the pages which has backstretch to another one with backstretch very rapidly, Images from backstretch in first page also creeps in second page. When I debugged, only the correct Images were being passed to second page. And also the slideshow is not running in a proper interval. So it must be both the backstretches being invoked.
Please tell me how I can stop the previous backstretch from appearing again. Here are the relevant code snippets.
This is my first page's(with backstretch) viewmodel code.
var id = 0;
var backstetcharray;
function loadbackstretchb() {
backstetcharray = new Array();
$.each(that.products, function (i, item)
{
if(item.ProductBackImage != "")
{
backstetcharray.push("xxxxxxxxxx" + item.ProductBackImage);
}
}
);
$.backstretch(backstetcharray, { duration: 5000, fade: 1500 });
}
var that;
define(['plugins/http', 'durandal/app', 'knockout'], function (http, app, ko) {
var location;
function callback() {
window.location.href = "#individual/"+id;
// this.deactivate();
};
return {
products: ko.observableArray([]),
activate: function () {
currentpage = "products";
that = this;
return http.get('yyyyyyyyyyyyyyy').then(function (response) {
that.products = response;
loadbackstretchb();
});
},
attached: function () {
$(document).ready(function () {
$('.contacticon').on({
'mouseenter': function () {
$(this).animate({ right: 0 }, { queue: false, duration: 400 });
},
'mouseleave': function () {
$(this).animate({ right: -156 }, { queue: false, duration: 400 });
}
});
});
$(document).ready(function () {
$(".mainmenucont").effect("slide", null, 1000);
});
//setTimeout($(".mainmenucont").effect("slide", null, 1000), 1000);
$(document).on("click", ".ind1", function (e) {
// alert("ind1");
id = e.target.id;
// $(".mainmenucont").effect("drop", null, 2000, callback(e.target.id));
$('.mainmenucont').hide('slide', { direction: 'left' }, 1000, callback);
});
}
}
});
This is my second page's(with backstretch) viewmodel code.(To where I am navigating)
var recs;
var open;
var i, count;
var backstetcharray;
function loadbackstretchc() {
backstetcharray = new Array();
$.each(recs, function (i, item) {
if (item.BackgroundImage != "") {
backstetcharray.push("xxxxxxxxxx" + item.BackgroundImage);
}
}
);
$.backstretch(backstetcharray, { duration: 5000, fade: 1500 });
}
var that;
define(['plugins/http', 'durandal/app', 'knockout'], function (http, app, ko) {
var system = require('durandal/system');
var location;
function menucallback() {
window.location.href = location;
// this.deactivate();
};
return {
activate: function (val) {
currentpage = "recipes";
open = val;
that = this;
var pdts;
recs;
var recipeJson = [];
http.get('yyyyyyyyyyyyyy').then(function (response) {
pdts = response;
http.get('yyyyyyyyyyyy').then(function (response1) {
recs = response1;
loadbackstretchc();
$.each(pdts, function (i, item) {
var json = [];
$.each(recs, function (j, jtem) {
if (item.DocumentTypeId == jtem.BelongstoProduct) {
json.push(jtem);
}
});
jsonitem = {}
jsonitem["product"] = item.ProductName;
jsonitem["link"] = "#" + item.UmbracoUrl;
jsonitem["target"] = item.UmbracoUrl;
jsonitem["recipes"] = json;
recipeJson.push(jsonitem);
});
// that.products = recipeJson;
count = recipeJson.length;
i = 0;
return that.products(recipeJson);
});
});
},
attached: function(view) {
$(document).ready(function () {
$('.contacticon').on({
'mouseenter': function () {
$(this).animate({ right: 0 }, { queue: false, duration: 400 });
},
'mouseleave': function () {
$(this).animate({ right: -156 }, { queue: false, duration: 400 });
}
});
});
$(document).ready(function () {
$(".mainmenucont").effect("slide", null, 1000);
});
$(document).on("click", ".recipeclick", function (e) {
console.log(e);
location = "#recipe/" + e.target.id;
$('.mainmenucont').hide('slide', { direction: 'left' }, 1000, menucallback);
});
$(document).on("click", ".locclick", function (e) {
if (e.handled != true) {
if (false == $(this).next().is(':visible')) {
$('#accordion ul').slideUp(300);
}
$(this).next().slideToggle(300);
e.handled = true;
}
});
},
products: ko.observableArray([]),
expand: function() {
++i;
if (i == count) {
$("#" + open).addClass("in");
}
}
};
});

What is the difference between plug-in-type methods and methods in a global variable

In terms of efficiency,
what's the fastest and most standard way to tweak a function in javascript?
Plugin-style coding would be like this.
; (function ($, window, document, undefined) {
var pluginName = "SoketManager",
dataPlugin = "plugin_" + pluginName,
settings = {
target: this,
width: 350,
height: 150,
theme: 'default'
}
var Plugin = {
// instance...
}
Plugin.prototype = {
connect: function() {
//something.
},
disconnect: function() {
//something.
},
sendmessage: function() {
//something...
},
etc: function() {
}
//etc2: function() .......
}
$.fn[pluginName] = function (arg, contents) {
var args, instance;
if (typeof arg === 'string' && typeof instance[arg] === 'function') {
args = Array.prototype.slice.call(arguments, 1);
return instance[arg].apply(instance, args);
}
And using global variable would be like this..
var SocketManager = {
sock: '',
connect: function () {
var stdInfo = new JSONClientParameters();
var socket = io.connect('http://192.168.1.39:3000', {
query: stdInfo.toGetString()
//'reconnect': true,
// 'reconnection delay': 500,//default 500
//'max reconnection attempts': 10
});
kdbSocketManager.ksock = socket;
socket.on('connect', function () {
alert('successfully connected to the database!!');
});
},
disconnect: function () {
this.ksock.disconnect();
},
sendMessage: function (pMsg, pTargetId) {
this.ksock.emit('sendMessage', { msg: pMsg, targetId: pTargetId });
},
I see no point in coding like the plugin-way. Is it much more simple and easy to read to code like the latter one? could somebody explain this in detail?

Categories