Can you load the PopupAppender on demand? - log4javascript

I am trying to use log4javascript and was wondering if there is any way to load the PopupAppender on demand.
I am seeking functionality much like the in-browser tools, where there would be an icon in my application that indicates that something has been logged and when I click it, the PopupAppender opens and allows me to view the logs.
I'm thinking I could write my own very simple appender to show the icon if there are errors, but i'm not sure how I could load up the PopupAppender and show historic messages?

You'd have to have some kind of proxy appender, as you suggest, which stores logging messages and creates a PopUpAppender on demand. Something like this:
Demo: http://jsfiddle.net/hDRpT/
Code:
function OnDemandPopUpAppender() {
this.popUpAppender = new log4javascript.PopUpAppender();
this.poppedUp = false;
this.popperUpperDisplayed = false;
this.queuedLoggingEvents = [];
}
var proto = new log4javascript.Appender();
OnDemandPopUpAppender.prototype = proto;
proto.appendQueued = function() {
for (var i = 0, loggingEvent; loggingEvent = this.queuedLoggingEvents[i++]; ) {
this.popUpAppender.append(loggingEvent);
}
this.queuedLoggingEvents.length = 0;
};
proto.popUp = function() {
this.poppedUp = true;
this.appendQueued();
};
proto.append = function(loggingEvent) {
var appender = this;
this.queuedLoggingEvents.push(loggingEvent);
if (this.poppedUp) {
this.appendQueued();
} else if (!this.popperUpperDisplayed &&
loggingEvent.level.isGreaterOrEqual(log4javascript.Level.ERROR)) {
var popperUpper = document.createElement("div");
popperUpper.style.border = "solid red 2px";
popperUpper.innerHTML = "There are error messages in the log. Click to open.";
popperUpper.onclick = function() {
appender.popUp();
}
document.body.appendChild(popperUpper);
this.popperUpperDisplayed = true;
}
};
var log = log4javascript.getLogger("main");
log.addAppender(new OnDemandPopUpAppender());
log.debug("A debug message");
log.error("A horrible error!");

Related

How to add new fileds/values to line widgets in Barcode mobile view in Odoo14 EE?

Hi i am trying to add two new fields to the Barcode mobile view. I went through the default js code of odoo, but didn't find a way to add my custome fields to it.
Here is the default code
stock_barcode/static/src/js/client_action/lines_widget.js
init: function (parent, page, pageIndex, nbPages) {
this._super.apply(this, arguments);
this.page = page; #don't know where this argument page coming from in argument list.
this.pageIndex = pageIndex;
this.nbPages = nbPages;
this.mode = parent.mode;
this.groups = parent.groups;
this.model = parent.actionParams.model;
this.show_entire_packs = parent.show_entire_packs;
this.displayControlButtons = this.nbPages > 0 && parent._isControlButtonsEnabled();
this.displayOptionalButtons = parent._isOptionalButtonsEnabled();
this.isPickingRelated = parent._isPickingRelated();
this.isImmediatePicking = parent.isImmediatePicking ? true : false;
this.sourceLocations = parent.sourceLocations;
this.destinationLocations = parent.destinationLocations;
// detect if touchscreen (more complicated than one would expect due to browser differences...)
this.istouchSupported = 'ontouchend' in document ||
'ontouchstart' in document ||
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
},
In _renderLines function,
_renderLines: function () {
//Skipped some codes here
// Render and append the lines, if any.
var $body = this.$el.filter('.o_barcode_lines');
console.log('this model',this.model);
if (this.page.lines.length) {
var $lines = $(QWeb.render('stock_barcode_lines_template', {
lines: this.getProductLines(this.page.lines),
packageLines: this.getPackageLines(this.page.lines),
model: this.model,
groups: this.groups,
isPickingRelated: this.isPickingRelated,
istouchSupported: this.istouchSupported,
}));
$body.prepend($lines);
for (const line of $lines) {
if (line.dataset) {
this._updateIncrementButtons($(line));
}
}
$lines.on('click', '.o_edit', this._onClickEditLine.bind(this));
$lines.on('click', '.o_package_content', this._onClickTruckLine.bind(this));
}
In the above code, you can see this.page.lines field, i need to add my custom two more fields.
Actually it's dead-end for me.
Any solution?

Logs for Protractor

I am new to protractor and want to create logs for my test cases. I used if and else to write logs. I wanted to know if there is any better way of writing logs for protractor test cases?
My Code:
var colors = require('colors/safe');
var mapFeedBackpage=require('./mapFeedBack-page.js')
describe("Map feedback Automation",function()
{
var mapFeedBack= new mapFeedBackpage();
it("Check if the Url works ",function() //spec1
{
console.log("Checking the url :"+browser.params.url+'\n')
browser.get(browser.params.url);
browser.getCurrentUrl().then(function(value){
if(/report/.test(value) === false) {
fail("Result: URL doesnt works-FAIL \n");
}
else
{
console.log(colors.green("PASS :")+browser.params.url+ "is reachable \n");
}
});
});
it("test browser should reach report road option",function() //spec2s
{
console.log("Checking if road report option is available \n");
mapFeedBack.REPORT_ROAD.click();
expect(browser.getCurrentUrl()).toContain("report_road");
browser.getCurrentUrl().then(function(value){
if(/report_road/.test(value) === false) {
fail("Result: URL doesnt works-FAIL");
}
else
{
console.log(colors.green("PASS")+" Road report option is available");
}
});
});
Yes, you can use https://www.npmjs.com/package/log4js which is basically log4j module for nodejs apps. Since protractor is nodejs program it would certainly support this. It's very easy to implement this-
var log4js = require('log4js');
var logger = log4js.getLogger();
logger.debug("Some debug messages");
or you could write a custom logger:
var logger = exports;
logger.debugLevel = 'warn';
logger.log = function(level, message) {
var levels = ['error', 'warn', 'info'];
if (levels.indexOf(level) >= levels.indexOf(logger.debugLevel) ) {
if (typeof message !== 'string') {
message = JSON.stringify(message);
};
console.log(level+': '+message);
}
}
and then use this in your scripts as :
var logger = require('./logger');
logger.debugLevel = 'warn';
logger.log('info', 'Everything started properly.');
logger.log('warn', 'Running out of memory...');
logger.log('error', { error: 'flagrant'});

XPages:Saving special character to dojo grid

When ever i try to save special character like ä,ö to my DojoGrid which loads and saves data via xe:restService the character get messedup,
When ever i end the grid directly it save ok, but when ever i work on it in the background and save it, it get messedup.below is the script on my button
var args = {
onComplete: function() {},
onError: function() { alert('Update error'); }
}
var grid = dijit.byId('#{id:grid}');
var selectedIDs =grid.selection.getSelected();
var store = dataGrid.store;
var Index = grid.selection.selectedIndex;
if(Index != null){
var curEntry = dataGrid.getItem(Index);
var nextEntry = dataGrid.getItem(Index-1);
currentViewIndex = store.getValue(curEntry,"ViewIndex");
nextViewIndex = store.getValue(nextEntry,"ViewIndex");
store.setValue(curEntry, 'ViewIndex',nextViewIndex);
store.setValue(nextEntry, 'ViewIndex',currentViewIndex);
grid.update();
restService1.save(args)
XSP.partialRefreshPost("#{id:gridDiv}",{});
}

Alternative to Application.DoEvents in console application to make Forms.WebBrowser load javascripts

I'm using System.Windows.Forms.WebBrowser in console application to render a web page then invoke scripts on it. To render the web page, I use Application.DoEvents to load and execute scripts.
However sometime the app hangs on calling Application.DoEvents. I found no reason. I don't think I'm creating deadlock on the event loop.
Many people on the web says that one should not use Application.DoEvents at all because it creates more problems than it solves. So I'm thinking there must be an alternative to it. But I've searched a lot and find no alternative to Application.DoEvents.
Does anyone know one?
Any information is appreciated. Thank you in advance!
Thanks to Noseratio's help, I finished drafting my code but still there's freezing issue.
Take following code as example(code is too long so I pasted it on pastebin): http://pastebin.com/DkDcrirU
When you run this code, occasionally there will be at least one window fail to close. And if you attach to the frozen process, you will find the code stuck at following line(indicated by ">>>"):
public static bool NavigateLoadAndRender(WebBrowserContext browserContext, string url, TimeSpan loadTimeout, TimeSpan renderTime, out string errMsg)
{
ForceInitActiveXInstance(browserContext);
object axi = null;
Func<Uri> getBrowserUri = null;
Action<Uri> navigateBrowser = null;
Func<IHTMLDocument2> getBrowserDoc = null;
switch (browserContext.WebBrowserType)
{
case WebBrowserTypeEnum.Forms:
{
var browser = browserContext.GetWebBrowserAsFormsType();
getBrowserUri = () => browser.Url;
navigateBrowser = u =>
{
var finished = false;
browserContext.SyncContext.Post(state =>
{
browser.Navigate(u);
finished = true;
}, null);
while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
};
getBrowserDoc = () =>
{
IHTMLDocument2 doc = null;
bool finished = false;
browserContext.SyncContext.Post(state =>
{
doc = (IHTMLDocument2)browser.Document.DomDocument;
finished = true;
}, null);
>>> while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
return doc;
};
axi = GetActiveXInstance(browserContext);
}
break;
case WebBrowserTypeEnum.Wpf:
{
var browser = browserContext.GetWebBrowserAsWpfType();
axi = GetActiveXInstance(browser);
getBrowserUri = () => browser.Source;
navigateBrowser = u =>
{
var finished = false;
browserContext.SyncContext.Post(state =>
{
browser.Navigate(u);
finished = true;
}, null);
while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
};
getBrowserDoc = () =>
{
IHTMLDocument2 doc = null;
bool finished = false;
browserContext.SyncContext.Post(state =>
{
doc = (IHTMLDocument2)browser.Document;
finished = true;
}, null);
while (!finished) Thread.Sleep(DefaultConfig_SyncContextPostCheckInterval);
return doc;
};
axi = GetActiveXInstance(browserContext);
}
break;
default: throw new ArgumentException("unknown browser type", browserContext.WebBrowserType.ToString());
}
var success = NavigateLoadAndRender(
axi, url,
getBrowserUri,
navigateBrowser,
//() => DoEvents(browser),
getBrowserDoc,
loadTimeout, renderTime, out errMsg);
return success;
}
Anyone knows what's happening?

Titanium not running function upon click

I am reading through titanium best practises and i was wondering why this doesnt appear to work can some one tell me whats changed with the api?
https://wiki.appcelerator.org/display/guides/Mobile+Best+Practices
ui/ToggleBox.js - A custom check box
function ToggleBox(onChange) {
this.view = Ti.UI.createView({backgroundColor:'red',height:50,width:50});
//private instance variable
var active = false;
//public instance functions to update internal state, execute events
this.setActive = function(_active) {
active = _active;
this.view.backgroundColor = (active) ? 'green' : 'red';
onChange.call(instance);
};
this.isActive = function() {
return active;
};
//set up behavior for component
this.view.addEventListener('click', function() {
this.setActive(!active);
});
}
exports.ToggleBox = ToggleBox;
Sample usage in app.js
var win = Ti.UI.createWindow({backgroundColor:'white'});
var ToggleBox = require('ui/ToggleBox').ToggleBox;
var tb = new ToggleBox(function() {
alert('The check box is currently: '+this.isActive());
});
tb.view.top = 50;
tb.view.left = 100;
win.add(tb.view);
it doesn't seem to want to return the setActive method when called from the add event listener?
The "this" in your click listener isn't what you're expecting it to be. (It's probably the view.) Because your function is already the ToggleBox context, the easiest solution is to just use a direct reference to setActive. "this." is only necessary for the API you're exposing for other code.
function ToggleBox(onChange) {
var view = this.view = Ti.UI.createView({backgroundColor:'red',height:50,width:50});
//private instance variable
var active = false;
//public instance functions to update internal state, execute events
var setActive = this.setActive = function(_active) {
active = _active;
view.backgroundColor = (active) ? 'green' : 'red';
onChange.call(instance);
};
var isActive = this.isActive = function() {
return active;
};
//set up behavior for component
view.addEventListener('click', function() {
setActive(!active);
});
}
exports.ToggleBox = ToggleBox;