Alertify.js notification's callback not fired - alertifyjs

I've got some issues making a callback to be invoked. I prefix that I've followed this link but it won't work right now.
What I need to do is that at the notification click a new page is opened. At the current time, even a simple alert is not shown.
My code is the following
switch (obj.Status) {
//case "OK":
// {
// alertify.message(obj.Message, timeout);
// break;
// }
case "KO":
{
alertify.message(obj.Message, timeout);
alertify.callback = function () {
//if(isClicked)
// alert('notification dismissed by user');
//else
alert('notification auto-dismissed');
};
break;
"Warn":
// {
// alertify.warning(obj.Message, timeout);
// break;
// }
}
What am I doing wrong?
Thanks
UPDATE #1
I'm still facing issue passing a value "downstair"
Consider this snippet
chat.client.updateNotifications = function (message) {
var obj = JSON.parse(message);
var guid = obj.RequestId;
var notify = function(level, msg) {
var func;
switch (level) {
case "success":
func = alertify.success;
break;
case "error":
func = alertify.error;
break;
case "warn":
func = alertify.warn;
break;
}
var m = func(msg, timeout);
m.id = guid;
m.callback = function(isClicked) {
if (isClicked) {
var url = '<%=Url.Action("Index","Import",new {id = -1})%>';
url.replace("-1", this.id);
// alert(url);
window.open(url, "target=_blank");
}
}
}
I got null as id, outside the callback it's ok, what am I doing wrong?
Thanks again

In reference to the provided link, the callback is a property of the returned notification object (not alertify)
//this call returns a notification object.
var msg = alertify.message('Open up your web console', 10);
//set the callback on the notification object.
msg.callback = function (isClicked) {
if(isClicked)
console.log('notification dismissed by user');
else
console.log('notification auto-dismissed');
};

Related

Xamarin-IOS BTLE WroteCharacteristicValue not fired

I have the following code for my IOS implementation, the problem is that the WroteCharacteristicValue event is never fired. Is is being fired on the android side when I connect to the same module. Any ideas what to do?
public void StartUpdates ()
{
// TODO: should be bool RequestValue? compare iOS API for commonality
bool successful = false;
if(CanRead) {
Console.WriteLine ("** Characteristic.RequestValue, PropertyType = Read, requesting read");
_parentDevice.UpdatedCharacterteristicValue += UpdatedRead;
_parentDevice.ReadValue (_nativeCharacteristic);
successful = true;
}
if (CanUpdate) {
Console.WriteLine ("** Characteristic.RequestValue, PropertyType = Notify, requesting updates");
_parentDevice.UpdatedCharacterteristicValue += UpdatedNotify;
_parentDevice.WroteCharacteristicValue += Wrote; // -DP here??
_parentDevice.SetNotifyValue (true, _nativeCharacteristic);
successful = true;
}
Console.WriteLine ("** RequestValue, Succesful: " + successful.ToString());
}
void Wrote(object sender, CBCharacteristicEventArgs e) {
System.Diagnostics.Debug.WriteLine("Characteristic Write Complete!");
this.WriteComplete (this, new CharacteristicReadEventArgs () {
Characteristic = new Characteristic(e.Characteristic, _parentDevice)
});
}
The WroteCharacteristic will only fire if the characteristic writes with response.
You can check it with:
var prop = _nativeCharacteristic.Properties;
if(prop.HasFlag(CBCharacteristicProperties.Write))
{
// Event can be used
}
else if(prop.HasFlag(CBCharacteristicProperties.WriteWithoutResponse))
{
// Event will not fire if WriteWithoutResponse
}
Btw: we provide a plugin for BLE, so you don't have to care about platform sepcific stuff ;) http://smstuebe.de/2016/05/13/blev1.0/

breeze observableArray binding - are properties observable?

I have a viewmodel which consists of a list(foreach loop) of DoctorPrices and when clicking on an item in the list it open up a CRUD form on the side. However when i update the values on the CRUD the observableArray that is bound to the foreach is not refreshing? (although the values are updates in the DB correctly)
From my data access module i call the following query.
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
return manager.executeQueryLocally(query);
}
In my viewmodel i have the following code:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
services is bound using a foreach loop (not posting here as the code is simple and works)
When i click on a one of the DoctorPrices it gets the data as follows and places it in an observable:
this.selectedPrice = function (data, event) {
self.currentService(data);
self.showEdit(true);
};
I then bind selectPrice to a simple form that has the properties on it to be modified by the user. I then call manager.SaveChanges().
This results in the following problem: the value is being updated correctly but the GUI / Original List that is bound in the foreach is not being updated? Are the properties in breeze not observables? What is the best way to work with something like this.
I thought of a workaround and changing the code with something like this:
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
});
But i feel that clearing the array in that way is sloppy and not the right way of doing things specially with long lists.
Can someone please point me in the right direction on how to bind observableArray properties properly so they are updated?
Additional code my VM Component:
function services() {
var self = this;
this.showForm = ko.observable(false);
this.currentService = ko.observable();
this.services = ko.observableArray(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
this.title = ko.observable();
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
self.showDetails(false);
});
this.show = function (value) {
self.showForm(value);
};
this.showDetails = ko.observable(false);
this.addNewService = function() {
self.currentService(doctorServices.createService(doctorList.viewModel.instance.currentDoctorID()));
console.log(self.currentService().entityAspect.entityState);
self.showDetails(true);
};
this.showDelete = ko.computed(function() {
if (self.currentService() == null)
return false;
else if (self.currentService().entityAspect.entityState.isDetached()) {
self.title('Add new service');
return false;
} else {
self.title('Edit service');
return true;
}
});
this.deleteService = function() {
self.currentService().entityAspect.setDeleted();
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
};
this.closeDetails = function () {
doctorServices.manager.rejectChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.showDetails(false);
};
this.selectService = function (data, event) {
self.currentService(data);
self.showDetails(true);
};
this.saveChanges = function () {
console.log(self.currentService().entityAspect.entityState);
if (self.currentService().entityAspect.entityState.isDetached()) {
doctorServices.attachEntity(self.currentService());
}
console.log(self.currentService().entityAspect.entityState);
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.currentService.notifySubscribers();
self.showDetails(true);
};
}
return {
viewModel: {
instance: new services()
},
template: servicesTemplate,
};
Below is my Breeze Data Class:
define('data/doctorServices', ['jquery', 'data/dataManager', 'knockout','mod/medappBase', 'breeze', 'breeze.savequeuing'], function ($, manager, ko,base, breeze, savequeuing) {
var services = ko.observableArray([]);
return {
attachEntity:attachEntity,
getServices: getServices,
services: services,
manager:manager,
getDoctorServices: getDoctorServices,
getServiceById: getServiceById,
createService:createService,
hasChanges: hasChanges,
saveChanges: saveChanges
};
function getServices() {
var query = breeze.EntityQuery.from("DoctorPrices");
return manager.executeQuery(query).then(function (data) {
services(data.results);
}).fail(function (data) {
console.log('fetch failed...');
console.log(data);
});;
}
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
var set = manager.executeQueryLocally(query);
return set;
}
function getServiceById(serviceId) {
return manager.createEntity('DoctorPrice', serviceId);
//return manager.getEntityByKey('DoctorPrice', serviceId);
}
function handleSaveValidationError(error) {
var message = "Not saved due to validation error";
try { // fish out the first error
var firstErr = error.innerError.entityErrors[0];
message += ": " + firstErr.errorMessage;
base.addNotify('error', 'Could not save.', message);
} catch (e) { /* eat it for now */ }
return message;
}
function hasChanges() {
return manager.hasChanges();
}
function attachEntity(entity) {
manager.addEntity(entity);
}
function createService(doctorId) {
return manager.createEntity('DoctorPrice', { DoctorPricingID: breeze.core.getUuid(), DoctorID:doctorId }, breeze.EntityState.Detached);
};
function saveChanges() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
function saveSucceeded(saveResult) {
base.addNotify('success', 'Saved.', 'Your updates have been saved.');
}
function saveFailed(error) {
var reason = error.message;
var detail = error.detail;
if (error.innerError.entityErrors) {
reason = handleSaveValidationError(error);
} else if (detail && detail.ExceptionType &&
detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
// Concurrency error
reason =
"Another user, perhaps the server, " +
"may have deleted one or all of the settings." +
" You may have to restart the app.";
} else {
reason = "Failed to save changes: " + reason +
" You may have to restart the app.";
}
console.log(error);
console.log(reason);
}
}
});
Please note this is my frist attempt at both a data class and VM. At the moment i am relying heavily on clearing the array ([]) and using notifySubscribers to make the array refresh :(
I bet you're missing an observable somewhere. I can't tell because you keep hopping from property to property whose definition is not shown.
For example, I don't know how you defined this.currentService.
I'm confused by this:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
Why is it a ko.computed? Why not just make it an observable array.
self.service = ko.observableArray();
// ... later replace the inner array in one step ...
self.service(doctorServices.getDoctorServices(
doctorList.viewModel.instance.currentDoctorID()));
I urge you to follow the observability trail, confident that your Breeze entity properties are indeed observable.
vm.selectedPrice = ko.dependentObservable(function () {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
}, vm);
vm is ur model on which u applied bindings , try this it will work.

Dartlang server call my function more than once

I'm sending a data to the server like this:
save(){
var el = this.parent.nodes;
print(el);print(el.length);
request = new HttpRequest();
if(el.length == 1) print('No lines to save!');
else
{
var opt = el[i].shadowRoot.nodes[0].options[el[i].shadowRoot.nodes[0].selectedIndex].text;
print(this.parent.nodes.length);
for(var i=1; i < el.length; i++)
{
orderLines.add({
'poid': orderHeader[0]['OrderID'],
'ponum': orderHeader[0]['onum'],
'lnum' : i.toString(),
'itmid' :el[i].shadowRoot.nodes[0].value,
'icode' : opt,
'qty': el[i].shadowRoot.nodes[1].value,
'rqty': 0,
'bqty': el[i].shadowRoot.nodes[1].value,
'iqty': 0,
'biqty': el[i].shadowRoot.nodes[1].value,
'price': el[i].shadowRoot.nodes[2].value,
'rdd': orderHeader[0]['rdd'],
'eta': '',
'flag': 0
});
print(orderLines);
request.onReadyStateChange.listen(onData_save);
request.open('POST', host+'/sPO');
request.send(JSON.encode(orderLines));
}
}
}
and my server side function is:
void main() {
connections = new List<WebSocket>();
HttpServer.bind(HOST, PORT).then((HttpServer server) {
print('Server listening on port ${PORT}.');
server.listen((HttpRequest request) {
if (WebSocketTransformer.isUpgradeRequest(request)) {
WebSocketTransformer.upgrade(request).then(handleWS);
} else gotMSG(request);
});
});
}
handleWS(WebSocket ws){
connections.add(ws);
print('Client connected, there are now ${connections.length} client(s) connected.');
ws.listen((String message) {
for (WebSocket connection in connections) {
connection.add(message);
}
},
onDone: () {
connections.remove(ws);
print('Client disconnected, there are now ${connections.length} client(s) connected.');
});
}
void gotMSG(HttpRequest request) {
switch (request.method) {
case 'POST':
handlePost(request);
break;
case 'OPTIONS':
handleOptions(request);
break;
default:
defaultHandler(request);
}
}
void serveRequest(HttpRequest request){
print('Listening for GET and POST on http://$HOST:$PORT');
request.response.statusCode = HttpStatus.FORBIDDEN;
request.response.reasonPhrase = "WebSocket connections only";
request.response.close();
}
void handlePost(HttpRequest req) {
HttpResponse res = req.response;
switch (req.uri.path) {
case '/login': login(req); break;
...
case '/sPO': savePO(req); break;
default: break;
}
}
The /sPO => savePO is executed once if the order sent is of one line only, but if n lines in the order, the function is executed more than once, could not find a pattern for that,
In the SavePO I used oracledart pub, so thought something wrong in it, and tried postgresql pub, but got same results, the savePO function is:
void savePO(HttpRequest req){
HttpResponse res = req.response;
addCorsHeaders(res);
print('${req.method}: ${req.uri.path}');
Future future() => new Future.value(true);
req.listen((List<int> buffer) {
var theDataLines = JSON.decode(new String.fromCharCodes(buffer));
print(theDataLines);
connect(db).then((conn) {
for (var theData in theDataLines)
conn.execute("""
insert into pol
(poid,ponum,lnum,itmid,icode,qty,rqty,bqty,iqty,biqty,price,rdd, eta, flag)
values (#poid,#ponum,#lnum,#itmid,#icode,#qty,#rqty,#bqty,#iqty,#biqty,#price,
to_timestamp(#rdd,'YYYY-MM-DD'), to_timestamp(#eta,'YYYY-MM-DD'), #flag)
""",
{
'poid': theData['poid'],
'ponum': theData['ponum'],
'lnum' : theData['lnum'],
'itmid' : theData['itmid'],
'icode' : theData['icode'],
'qty': theData['qty'],
'rqty': theData['rqty'],
'bqty': theData['bqty'],
'iqty': theData['iqty'],
'biqty': theData['biqty'],
'price': theData['price'],
'rdd': theData['rdd'].toString(),
'eta': theData['eta'].toString(),
'flag': theData['flag']
})
.then((_)=>conn.query('commit').toList().then((rows) {print('committed');}))
.then((_){
res.write('done');
res.close();
});
}); // END of SQL
}, onError: printError); // End of server listen
} // END of function
I even tried to change the:
case '/sPO': savePO(req); break;
to be
case '/sPO': print(1); break;
the it printed the 1, 4 times after sending an order of 6 lines!!
It's hard to see for me what you actually try to accomplish.
The problem is very probably your save() method. You wrote how it behaves but not much about what you try to accomplish?
Why don't you put more lines into one JSON string and post them together in one request?
You create one request instance and call send repeatedly on this one request instance.
You also register the onReadyStateChange handler more than once on the same request object which results in onData_save being called several times when the event occurs just once.
I think you should either move request = new HttpRequest(); down just before
request.open('POST', host+'/sPO');
request.send(JSON.encode(orderLines));
or better move request.onReadyStateChange.listen(onData_save); up to request = new HttpRequest();,
add all orderlines into one JSON and call
request.open('POST', host+'/sPO');
request.send(JSON.encode(orderLines));
after the for loop.
Another problem I see is that you do a fire and forget. What if the send request fails for some reason?
I would create a sendJSON method that returns a future (with a Completer which completes on onDone and completeError when something goes wrong.
When you want to create more than one request in your save() you can use something like
// create your JSON
var futures = [];
for(i = 0; i < 5; i++) {
futures.add(sendData(myJson)); // collects the futures returned from sendData
}
// executes all futures and waits for all to respond and then returns another future
return Future.wait()
.then((results) {
results.forEach((r) {
// check result
});
});

Firefox SDK: How to make trigger for certain domain

I need to catch requests on sites with URLs *.net and take some actions (stop request and put HTML code from disk, but this I can do). How do I catch these requests?
I tried to use progress listeners, but something is wrong:
const STATE_START = Ci.nsIWebProgressListener.STATE_START;
var myListener = {
QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
"nsISupportsWeakReference"]),
onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) {
if (aFlag & STATE_START) {
// actions
}
}
use nsIHTTPChannel and observer service. copy paste it. however .net can be included in resources like javascript things, if you want to test if its specfically a window you have to check for some load flags of LOAD_INITIAL_DOCUMENT_URI, also will want to chec
Cu.import('resource://gre/modules/Services.jsm');
var httpRequestObserver = {
observe: function (subject, topic, data) {
var httpChannel, requestURL;
if (topic == "http-on-modify-request") {
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
var newRequestURL, i;
if (httpChannel.loadFlags & httpChannel.LOAD_INITIAL_DOCUMENT_URI) {
//ok continue because loadFlags is a document
} else {
//its not a document, probably a resource like a js file image or css or something, but maybe could be ajax call
return;
}
if (requestURL.indexOf('.net')) {
var goodies = loadContextGoodies(httpChannel);
if (goodies) {
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
goodies.contentWindow.location = self.data.url('pages/test.html');
} else {
//dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
}
}
return;
}
}
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
//httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
//start loadContext stuff
var loadContext;
try {
var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
//var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
try {
loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
} catch (ex) {
try {
loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
} catch (ex2) {}
}
} catch (ex0) {}
if (!loadContext) {
//no load context so dont do anything although you can run this, which is your old code
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var contentWindow = loadContext.associatedWindow;
if (!contentWindow) {
//this channel does not have a window, its probably loading a resource
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var gBrowser = aDOMWindow.gBrowser;
var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
if (aTab == null) {
return null;
}
else {
var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
return {
aDOMWindow: aDOMWindow,
gBrowser: gBrowser,
aTab: aTab,
browser: browser,
contentWindow: contentWindow
};
}
}
//end loadContext stuff
}

Notification does not pop up when blocking an HTTP request

Introduction
I'm trying to intercept certain HTTP requests and then notify the user and cancel these requests:
UPDATE: reproducible code
const {Cc, Ci, Cr} = require("chrome");
const self = require("sdk/self");
const data = self.data;
const notif = require("notifications");
const REGEX = {
'lookup.bluecava.com': "1",
'ds.bluecava.com/v50/AC/BCAC': "2"
};
// ------------------------------------------------------------------
// Initialize observer service
var observerService = Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
function TracingListener() {
this.originalListener = null;
}
// Request observer
var httpRequestObserver = {
observe: function (aSubject, aTopic, aData) {
var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
if ("http-on-modify-request" == aTopic) {
var url = httpChannel.originalURI.spec;
for (var str_re in REGEX) {
var re = new RegExp(str_re, "g");
if (url.match(re)) {
console.log("Requested URL: " + url.match(re));
notif.notify({
title: "foo",
text: "foo"
});
aSubject.cancel(Cr.NS_BINDING_ABORTED); // Cancel request TODO: fix if uncommented notification won't pop up!
}
}
}
},
QueryInterface: function (aIID) {
if (aIID.equals(Ci.nsIObserver) || aIID.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
}
};
// Register service
observerService.addObserver(httpRequestObserver,
"http-on-modify-request", false);
exports.main = function () {
console.log("Addon is running...");
};
// Unload addon event
exports.onUnload = function (reason) {
// Unregister service
observerService.removeObserver(httpRequestObserver,
"http-on-modify-request");
};
Problem
The problem is that, no matter the order of the call to the cancel method and the notify method, the notification won't pop up.
Possible cause
I guess that it has something to do with the asynchronous nature of javascript and that the method cancel blocks somehow the notification call. However, I don't find any callbacks neither in the notification nor in the cancel method that I can use to chain the calls. Any idea?

Resources