How to make SAPUI5 TreeTable expanded by default? - expand

I use following code (in controller):
onAfterRendering: function () {
var t, i;
if (!this.initExpand) {
try {
t = this.getView().getContent()[1];
for (i=0; i<t.getRows().length; i++) {
t.expand(i);
}
this.initExpand = true;
} catch (e) {
console.log("expand failed: "+e.message);
}
}
},
for initial (after loading and rendering) expanding all nodes of following sap.ui.table.TreeTable (in view):
<mvc:View
displayBlock="true"
xmlns:l="sap.ui.layout"
xmlns:table="sap.ui.table"
xmlns:mvc="sap.ui.core.mvc"
controllerName="sap.app.controller.scr1"
>
<l:HorizontalLayout>
<SearchField liveChange="onSearch"/>
</l:HorizontalLayout>
<table:TreeTable rows="{/root}"
selectionMode="None"
visibleRowCount="11"
showColumnVisibilityMenu="true"
enableCellFilter="true"
enableColumnReordering="false"
class="sapUiSizeCompact"
expandFirstLevel="true"
>
<table:columns>
...
</table:columns>
</table:TreeTable>
</mvc:View>
But sometimes nodes still are not expanded (remains collapsed).
Is there some other (more stable) way for initial expanding all nodes of sap.ui.table.TreeTable?

The below code works:
onAfterRendering: function(){
var oTreeTable = this.getView().byId("myTreeTableId");
oTreeTable.expandToLevel(3); //number of the levels of the tree table.
}
Where '3' is the number of the levels for your tree table and,
myTreeTableId: is the Id of your control at XML view:
<table:TreeTable id="myTreeTableId" ...

Have a look at this demo.
/* code to expand */
for (i=0; i<oTable.getRows().length; i++) {
oTable.expand(i);
}

Related

Turning BSPMapGen demo into a flxTilemap object

I'm trying to use the BSPMapGen demo to generate maps for my game but I'm having issues. The resulting map contains too many rooms and the hallways are twice as thick as they need to be. My guess was that the code uses the game dimensions somewhere but I couldn't find it.
screenshot
Here is the code (only has several changes from GenerateState):
package mapgen;
import flixel.tile.FlxTilemap;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flixel.util.FlxStringUtil;
import flixel.FlxG;
import flixel.util.FlxColor;
class BSPMap extends FlxTilemap
{
var TILE_SIZE:Int = 16;
public static var mapData:BitmapData;
var rooms:Array<Rectangle>;
var hallways:Array<Rectangle>;
var leafs:Array<Leaf>;
var mapWidth:Int;
var mapHeight:Int;
public function new(w:Int, h:Int, tilesize:Int)
{
super();
TILE_SIZE = tilesize;
mapWidth = w;
mapHeight = h;
generateMap();
var csvData:String = FlxStringUtil.bitmapToCSV(mapData);
this.loadMapFromCSV(csvData, "assets/tiles.png", TILE_SIZE, TILE_SIZE, AUTO);
}
function generateMap():Void
{
// Reset mapData
mapData = new BitmapData(mapWidth, mapHeight, false, FlxColor.BLACK);
// Reset arrays
rooms = [];
hallways = [];
leafs = [];
// First, create leaf to be root of all leaves
var root = new Leaf(0, 0, mapWidth, mapHeight);
leafs.push(root);
var didSplit:Bool = true;
// Loop through every Leaf in array until no more can be split
while (didSplit)
{
didSplit = false;
for (leaf in leafs)
{
if (leaf.leftChild == null && leaf.rightChild == null) // If not split
{
// If this leaf is too big, or 75% chance
if (leaf.width > Leaf.MAX_SIZE || leaf.height > Leaf.MAX_SIZE || FlxG.random.float() > 0.25)
{
if (leaf.split()) // split the leaf!
{
// If split worked, push child leafs into vector
leafs.push(leaf.leftChild);
leafs.push(leaf.rightChild);
didSplit = true;
}
}
}
}
}
// Next, iterate through each leaf and create room in each one
root.createRooms();
for (leaf in leafs)
{
// Then draw room and hallway (if there is one)
if (leaf.room != null)
{
drawRoom(leaf.room);
}
if (leaf.hallways != null && leaf.hallways.length > 0)
{
drawHalls(leaf.hallways);
}
}
//updateSprite();
}
function drawHalls(hallRect:Array<Rectangle>):Void
{
for (rect in hallRect)
{
hallways.push(rect);
mapData.fillRect(rect, FlxColor.WHITE);
}
}
/**
* Add this room to room array, then draw onto mapData
*/
function drawRoom(roomRect:Rectangle):Void
{
rooms.push(roomRect);
mapData.fillRect(roomRect, FlxColor.WHITE);
}
}

Changes reflecting in payload but is not getting applied on target widget in workdetails page in casemanager 5.2.1

In Workdetails page, under ‘Documents’ tab, when I set the alignment to ‘center’ from ‘right’ for the column value, its getting updated in payload but is not actually getting applied on target widget.
I have tried thru controller/Grid as well but its not getting set. Attached snap of same. A pointer in this regard would be of immense help.
Here is the snip:
var callbackFolderContent = function (resultset)
{
var classText = 'Abc';
var found = 0;
for (var i=0; i < resultset.length; i++)
{
var items = resultset[i].resultSet.items;
for (var j=0; j < items.length; j++)
{
var pos = id.indexOf(classText);
if(pos !== -1)
{
var PC= items[j].resultSet.structure.cells[0][3];
if(PC.styles=="text-align:right;")
{
PC.styles="text-align:center;";
var NEWpc=PC.styles; //Its reflecting in payload.
alert("Changed aligning to: "+NEWpc);
}
found ++;
} //end f if loop
} //end of inner for loop
} //end of for loop
if (found < 1)
{
payload.stateCode = 4;
payload.hideMessage=true;
abort({silent:true});
}
else
{
complete();
}
}; //end of callback function

Vue2 using $set does not fix change detection caveat when using push() on object

Following on from this issue: Strange issue with Vue2 child component object v-for list render
I have a function which loops through an array products, which takes certain values and adds them to an object called attributes. I need to use this.$set to update my attributes object to make sure that Vue can detect the update.
My functions look like this:
//// checks if the value exists in the object to avoid adding duplicates
doesItExist: function(key, value) {
for (let i = 0; i < this.attributes[key].length; i++) {
if (this.attributes[key][i] == value) return true;
}
return false;
},
//// if the value does not exist, then add it to the object
pushIfNotExists: function(key, value) {
if (!this.doesItExist(key, value)) { // returns true/false
this.$set(this.attributes[key], key, this.attributes[key].push(value));
}
},
//// main function looping through the original products array to extract attributes
createAttributes: function() {
for (let i = 0; i < this.products.length; i++) {
for (let j = 0; j < this.products[i]['attributes_list'].length; j++) {
let attributeName = this.products[i]['attributes_list'][j]['attribute_name'];
if (!this.attributes[attributeName]) {
this.attributes[attributeName] = new Array();
};
this.pushIfNotExists(attributeName, this.products[i]['attributes_list'][j]['value']);
}
}
console.log(this.attributes); // outputs expected object
},
The problem I have is that in my child component, the attribute data is still not being rendered, which means this must not be working correctly (even though my console log shows the data is there).
Any ideas?
Thanks

Pure javascript pixel manipulation with processing.js

I would like to manipulate pixels with processing.js. I would like to do this in pure javascript but am having difficulties. The following simple case fails
<canvas id="canvas1"></canvas>
<script type="text/javascript">
function sketchProc(p){
// Configure page and init variables
function setup() {
p.size(300, 300);
console.log(p.pixels)
p.background(100,200,100)
}
function draw() {
p.loadPixels();
for (var i = 0; i < 3000 ; i++) {
p.pixels[i] = p.color(0,0,0)
}
p.updatePixels();
}
// Attach functions to processing object
p.setup = setup;
p.draw = draw;
}
var canvas = document.getElementById("canvas1")
var processingInstance = new Processing(canvas, sketchProc)
</script>
which (I believe) should convert the first 3000 pixels to black. Looking at the console.log for p.pixels I am wondering if this type of array access fails in pure javascript? Any suggestions welcome and thanks in advance.
That is because you must Attach the functions directly to p:
function sketchProc(p){
// Attach functions to processing object
p.setup = function setup() {
p.size(300, 300);
console.log(p.pixels);
p.background(100,200,100);
};
p.draw = function draw() {
p.loadPixels();
for (var i = 0; i < 3000 ; i++) {
p.pixels[i] = p.color(0,0,0);
}
p.updatePixels();
};
}
var canvas = document.getElementById("canvas1");
var processingInstance = new Processing(canvas, sketchProc);

ExtJS TreeStore update event fire instead of create

I am using tree.Panel with TreeStore when I call
sel_node.parentNode.appendChild(node);
tree.getSampleStore().sync();
ExtJS fire event called sample store proxy: update url instead of create url what could I have done wrong?
What exact version of ExtJS4 do you use?
In my situation, with ext-4.0.7-gpl, I debugged a bit a found out that appendChild method creates a node from and object and then performs some update operations concerning the node's position in the tree, like setting next sibling, parent etc., see [1].
When syncing, the store uses getUpdatedRecords and getNewRecords [2] methods to determine which operation to run. update or create. Somehow, our appended children turn out to be updated, not created.
Note that the method doesn't check whether the children of a parent node was loaded, just pushes the new node into an empty childNodes array; after all these operations end, other children of a parent node are never shown in the tree; and if the update operation caused the serverside generation of new id, the code breaks on the line original = me.tree.getNodeById(record.getId()); - there is no such node with the old id generated on client side..
Simply put, I think it's a bug.
[1] http://docs.sencha.com/ext-js/4-0/source/NodeInterface.html#Ext-data-NodeInterface-method-appendChild
[2] http://docs.sencha.com/ext-js/4-0/source/AbstractStore.html#Ext-data-AbstractStore-method-getUpdatedRecords
Add: ExtJS 4.1 beta 2 doesn't work better for me
Update with temp solution: I hacked a bit and think I solved the issue by overriding the appendChild method of NodeInterface like below (just to set phantom property so that the record becomes created, not updated).
Please note:
1) You should include your appendChild call in the NodeInterface expand method callback, or the bug with pushing to the empty childNodes will remain: the new node will appear somewhere in the wrong place;
2) I had to override updateIndexes of the AbstractView as well, try not to do this and maybe you'll find out why;
3) there are some issues when the store tries to delete our newly created node the next time it syncs - couldn't trace it yet;
0) I am no way ExtJS or even JS guru, so feel free to correct this hack)
Ext.data.NodeInterface.oldGpv = Ext.data.NodeInterface.getPrototypeBody;
Ext.data.NodeInterface.getPrototypeBody = function(){
var ret = Ext.data.NodeInterface.oldGpv.apply(this, arguments);
ret.appendChild = function(node, suppressEvents, suppressNodeUpdate) {
var me = this,
i, ln,
index,
oldParent,
ps;
if (Ext.isArray(node)) {
for (i = 0, ln = node.length; i < ln; i++) {
me.appendChild(node[i]);
}
} else {
node = me.createNode(node);
if (suppressEvents !== true && me.fireEvent("beforeappend", me, node) === false) {
return false;
}
index = me.childNodes.length;
oldParent = node.parentNode;
if (oldParent) {
if (suppressEvents !== true && node.fireEvent("beforemove", node, oldParent, me, index) === false) {
return false;
}
oldParent.removeChild(node, null, false, true);
}else{
node.phantom = true;
}
if(me.isLoaded()){
index = me.childNodes.length;
if (index === 0) {
me.setFirstChild(node);
}
me.childNodes.push(node);
node.parentNode = me;
node.nextSibling = null;
me.setLastChild(node);
ps = me.childNodes[index - 1];
if (ps) {
node.previousSibling = ps;
ps.nextSibling = node;
ps.updateInfo(suppressNodeUpdate);
} else {
node.previousSibling = null;
}
node.updateInfo(suppressNodeUpdate);
}
//console.log('appendChild was called');
// I don't know what this code mean even given the comment
// in ExtJS native source, commented out
// As soon as we append a child to this node, we are loaded
//if (!me.isLoaded()) {
// me.set('loaded', true);
//}
// If this node didnt have any childnodes before, update myself
//else
//if (me.childNodes.length === 1) {
// me.set('loaded', me.isLoaded());
//}
if (suppressEvents !== true) {
me.fireEvent("append", me, node, index);
if (oldParent) {
node.fireEvent("move", node, oldParent, me, index);
}
}
return node;
}
};
return ret;
};
this is my code to add a node by values taken from a form domainForm. The form opens by clicking an icon in an actioncolumn of our tree grid:
var node = grid.store.getAt(rowIndex);
node.expand(false, function(){
var newDomain = domainForm.getValues();
newDomain.parent = {id: node.raw.id}; // i don't know whether you'll need this
var newNode = node.appendChild(newDomain);
me.store.sync();
});
and updateIndexes overrider:
Ext.override(Ext.view.AbstractView, {
updateIndexes : function(startIndex, endIndex) {
var ns = this.all.elements,
records = this.store.getRange(),
i;
startIndex = startIndex || 0;
endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length < records.length?(ns.length - 1):records.length-1) );
for(i = startIndex; i <= endIndex; i++){
ns[i].viewIndex = i;
ns[i].viewRecordId = records[i].internalId;
if (!ns[i].boundView) {
ns[i].boundView = this.id;
}
}
}
});
Had the same issue, an update to ext-4.1.0-beta-2 fixed it.
The reason might be wrong format of data that comes from the server in response to your request.
Syncronization doesn't happen. Pass 'success' key with the value of TRUE in the server response.
Hmm ... try this ...
beforeitemexpand(node, eOpts){
if (node.data.expanded) return false
}