How to close all branches in - qooxdoo

I try to close all branches in a qx.ui.treevirtual.TreeVirtual tree
this._tree.addListener( "dblclick", function( e )
{
for( var i = 0; i< this._tree.getDataModel().getRowCount(); i++ )
{
var child = this._tree.getDataModel().getNode( i );
if( child.level == 1 && child.bOpened == true )
{
this._tree.nodeSetOpened( i, false );
}
}
}, this );
however it says nodeSetOpened is not a function

nodeSetOpened is a method that is provided by the qx.ui.treevirtual.MNode mixin. Near the top of your application's main() method, add this code to include the mixin`:
// We want to use some of the high-level node operation convenience
// methods rather than manually digging into the TreeVirtual helper
// classes. Include the mixin that provides them.
qx.Class.include(qx.ui.treevirtual.TreeVirtual,
qx.ui.treevirtual.MNode);

Related

How to NOT delete existing translations with "react-intl-translations-manager"?

I use React-Intl in my app and it works great, but to be easier to manage new keys to translate I started using "react-intl-translations-manager".
My problem is that some of my translations are used through a notification system and the babel extractor don't recognize them because it's outside of his scan scope.
So when I run "react-intl-translations-manager" it deletes all the keys relatives to notifications and other non-scanned translations.
Here is my question: is there any method to "say" to "react-intl-translations-manager" that it's forbidden to delete those keys ?
I tried multiple solutions including whitelists and other but nothing is working.
Here is my translationRunner.js (the configuration file)
const manageTranslations = require('react-intl-translations-manager').default;
manageTranslations({
messagesDirectory: 'src/messages/',
translationsDirectory: 'src/locales/',
languages: ['en_GB', 'fr_FR']
});
There are two ways to do this. One is to use hooks and another way is to override the module where deletion of the actual code happens.
To do the same we can override the getLanguageReport module from react-intl-translations-manager/dist/getLanguageReport
getLanguageReport = require('react-intl-translations-manager/dist/getLanguageReport');
getLanguageReport.original = getLanguageReport.default
getLanguageReport.default = function(defaultMessages, languageMessages, languageWhitelist) {
data = getLanguageReport.original(defaultMessages, languageMessages, languageWhitelist)
// this whitelist ids can be read through a config file as well
whitelisted_id = ['helloworld2', 'helloworld']
deleted = data.deleted;
re_add = []
for (var i=0; i < deleted.length; ) {
if (whitelisted_id.indexOf(deleted[i].key)>=0) {
// we are removing a record so lets not increment i
removed_element = deleted.splice(i,1)[0];
data.fileOutput[removed_element.key] = removed_element.message;
} else {
i++;
}
}
return data;
}
const manageTranslations = require('react-intl-translations-manager').default;
manageTranslations({
messagesDirectory: 'build/messages/src/extracted/',
translationsDirectory: 'src/translations/locales/',
languages: ['de'] // Any translation --- don't include the default language
}
);
This method works fine and will keep the helloworld2 message even if it is not there in new code.
Hooks approach
In this we use the hook reportLanguage and override it to change the data
const manageTranslations = require('react-intl-translations-manager').default;
const writeFileSync = require('fs').writeFileSync
const stringify = require('react-intl-translations-manager/dist/stringify').default;
stringifyOpts = {
sortKeys: true,
space: 2,
trailingNewline: false,
};
manageTranslations({
messagesDirectory: 'build/messages/src/extracted/',
translationsDirectory: 'src/translations/locales/',
languages: ['de'], // Any translation --- don't include the default language
overrideCoreMethods: {
reportLanguage: function(langResults) {
data = langResults.report;
// this whitelist ids can be read through a config file as well
whitelisted_id = ['helloworld2', 'helloworld']
deleted = data.deleted;
re_add = []
for (var i=0; i < deleted.length; ) {
if (whitelisted_id.indexOf(deleted[i].key)>=0) {
// we are removing a record so lets not increment i
removed_element = deleted.splice(i,1)[0];
data.fileOutput[removed_element.key] = removed_element.message;
} else {
i++;
}
}
// original definition of reportLanguage from manageTranslations.js
// unfortunately the original core method is not exposed for us to re-use
// so we need to copy the code again
if (
!langResults.report.noTranslationFile &&
!langResults.report.noWhitelistFile
) {
// printers.printLanguageReport(langResults);
writeFileSync(
langResults.languageFilepath,
stringify(langResults.report.fileOutput, stringifyOpts)
);
writeFileSync(
langResults.whitelistFilepath,
stringify(langResults.report.whitelistOutput, stringifyOpts)
);
} else {
if (langResults.report.noTranslationFile) {
printers.printNoLanguageFile(langResults);
writeFileSync(
langResults,
stringify(langResults.report.fileOutput, stringifyOpts)
);
}
if (langResults.report.noWhitelistFile) {
printers.printNoLanguageWhitelistFile(langResults);
writeFileSync(
langResults.whitelistFilepath,
stringify([], stringifyOpts)
);
}
}
}
}
});

Is there some how to detect changes on the window object?

I;'m working in a project that's uses a custom browser. This custom browser injects an object inside the window object. I need to track the changes...something like...
componentDidMount() {
window.customObject.addListener('onchange' , (changes) => console.log(changes))
}
The example above is just hypothetical to make this thing more easy to understand. Is there some how to archive it ?
Yes, you can observe dom changes with MutationObserver api.
var observeDOM = (function(){
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
return function( obj, callback ){
if( !obj || !obj.nodeType === 1 ) return; // validation
if( MutationObserver ){
// define a new observer
var obs = new MutationObserver(function(mutations, observer){
if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
callback( mutations[0] );
});
// have the observer observe foo for changes in children
obs.observe( obj, { childList:true, subtree:true });
}
else if( window.addEventListener ){
obj.addEventListener('DOMNodeInserted', callback, false);
obj.addEventListener('DOMNodeRemoved', callback, false);
}
}
})();
Usage example:
// Observe a specific DOM element:
observeDOM(document.querySelector('body'), function(m) {
console.log('Added:', m.addedNodes, 'Removed:', m.removedNodes);
});

Mistake with MongoDB Queries - Arrays - Loop For

I made this code today, and i don't nkow what's the problem? In theory, the findOne() function should work for() each loop of the for. And this is not that what happen. In the array there are several elements, and i want to save all of this. I'm newbie in NodeJS, but the loop for() always is the same, or not?
var sType = models.Type; // Model Mongoose
var word = ''; // Word
var i = 0;
for( i = 0; i < arrayData.length; i++ ){
word = arrayData[i]; // Save the element in word, I made this to try to pass the variable.
sType.findOne({ nameType: word }, { _id : 1 }, function( err, type ){
console.log( word ); // In the console, show me the last element of array x20.
if( err )
throw err;
if( !err && type == null ){
var types = new sType({
nameType: word
});
types.save( function( err ){
if( err )
throw err;
});
}
});
}
If I don't create the variable 'word', the program throw me a mistake 'Validation Error: Path 'nameTYpe' is required.'
If you use the method findOne inside a loop, you need to wait the callback, try to use the library async.js,
here is an example:
async.eachSeries(arrayData, function(data, dataCallback) {
sType.findOne({}, {}, function( err, type ) {
//your code after the findOne method
//return to the next element of array
dataCallback();
}
}, function done() {
console.log("loop end");
});

Listener afteritemexpand from ExtJS 4.2.1

I am working with a treepanel in ExtJS 4.2.1.
I used to set modifications on dom elements (precisely change the class name) with the listener afteritemexpand when I expand nodes of my tree. In fact it was to have leaves with even index with a different color than leaves with odd color.
It worked fine.
Getting the ids of the items which interest me, I can access them, and then modify the className.
I did the same way for another tree but the problem is that when I create this tree I expand it with an expandAll(), so the listener afteritemexpand is not called.
I need this expandAll(), but I need the afteritemexpand listener too. The reason I use this listener is because I have an easy access to item.id with the prototype afteritemexpand( node, index, item, eOpts ). With this id I can get the element I am looking for with the Ext.get(id) method.
I can do it with the afterlayout listener but I would rather not because the access to the id is not so easy.
I can't do it with the load listener because the dom elements are not present yet.
So I want to know, how could I totally expand my tree and use the code I made for my afteritemexpand?
Here is my listener so you can understand better want I want to do (in fact just add 'tree-even-node' to the className of even leaves of my tree).
listeners: {
afteritemexpand: function( node, index, item, eOpts ){
var domLeaf = Ext.get(item.id).next();
for ( var int = 0; int < node.childNodes.length; int++) {
if (node.childNodes[int].data.leaf && (int % 2) == 0) {
if (ids.indexOf(domLeaf.id) == -1) {
ids[indiceIds] = domLeaf.id;
indiceIds++;
}
}
domLeaf = domLeaf.next();
}
for ( var int = 0; int < ids.length; int++) {
domLeaf = Ext.get(ids[int]);
if (domLeaf != null) {
for ( var int2 = 0; int2 < domLeaf.dom.children.length; int2++) {
if (domLeaf.dom.children[int2].className.search('tree-even-node') == -1){
domLeaf.dom.children[int2].className += ' tree-even-node';
}
}
}
}
}
I finally used both load and afteritemexpand listeners. The loading enables me getting the right ids quite easily and I can set the classNames with afteritemexpand because I know the dom elements are loaded, so I don't get a null with my Ext.get(id).
It works great.
Here is the code:
listeners: {
load: function(node, records, successful, eOpts) {
var ownertree = records.store.ownerTree;
var boundView = ownertree.dockedItems.items[1].view.id;
var generalId = boundView+'-record-';
if (!node.tree.root.data.leaf) {
// Process each child node
node.tree.root.cascadeBy(function(currentChild) {
// Process only leaf
if (currentChild.data.leaf) {
var nodeId = ""+generalId+currentChild.internalId;
var index = currentChild.data.index;
if ( (index % 2) == 0 && ids.indexOf(nodeId) == -1 ) {
// even nodes
ids[indiceIds] = nodeId;
indiceIds++;
}
console.log(ids);
}
});
}
},
afteritemexpand: function( node, index, item, eOpts ){
for ( var int = 0; int < ids.length; int++) {
domLeaf = Ext.get(ids[int]);
if (domLeaf != null) {
for ( var int2 = 0; int2 < domLeaf.dom.children.length; int2++) {
if (domLeaf.dom.children[int2].className.search('tree-even-node') == -1){
domLeaf.dom.children[int2].className += ' tree-even-node';
}
}
}
}
},

Randomizing DOM elements with Angular

This doesn't seem to work. Is it ok to pass arguments to the random() callback?
function getAnswers($scope){
$scope.answers = conjugate("작다");
$scope.$on('$viewContentLoaded', random($(".answer")));
}
function random(r) {
r.children().sort(function() {
return (Math.round(Math.random()) - 0.5);
}).appendTo(r);
};
This isn't really the "Angular way" to do this.
You're not supposed to be doing any DOM manipulation or even referencing the DOM in your controller.
Instead, what you'd want to do is manipulate model data that affects your view. In your case, I'd randomize the array of data, rather than randomize the DOM elements themselves.:
function MyCtrl($scope) {
$scope.answers = [ /*... some data here ... */];
$scope.randomizeAnswers = function () {
fisherYates($scope.answers);
};
//a good randomization function
//(see: http://stackoverflow.com/questions/2450954/how-to-randomize-a-javascript-array)
function fisherYates ( myArray ) {
var i = myArray.length, j, tempi, tempj;
if ( i == 0 ) return false;
while ( --i ) {
j = Math.floor( Math.random() * ( i + 1 ) );
tempi = myArray[i];
tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
}
}
}
The use of $on is probably unnecessary here, it seems like you just want to randomize after the array is loaded? That's really going to depend on what in the world your conjugate() method is doing.
I have no idea what your conjugate() method does... but presuming it does some sort of Asynchronous work to return data, you might have to use $q and return a promise from that method. Then you can put your randomization call in a .then() callback that would fire when the data is loaded.

Resources