Disable specific rows in datagrid/enhancedgrid - dojo

I want to disable one specific row in datagrid in following manner:
1) Highlight one row with a different color
2) Disable checkbox/radio button selection of that row
3) Disable inline editing of cells present in that row but allow inline editing for other rows.
Pls. help if you have any ideas.

You can use a combination of the following functions to extract stuff
// as example, one of youre items uses identifier:'id' and 'id:10'
var identifier = '10';
var item = store._arrayOfTopLevelItems[10]; // you probably have this allready
var index = grid.getItemIndex(item); // find which index it has in grid
var rowNode = grid.getRowNode(index); // find a DOM element at that index
You will have the <div> as rowNode, it contains a table with cells (as many as you got columns). Set its background-color
The checkbox thing, you will prly know which cell-index it has
var cellNode = dojo.query('td[idx='+cellIndex+']', rowNode)[0];
// with cellType Bool, td contains an input
var checkbox = cellNode.firstChild;
Editing is another store really.. works in focus handlers. To override it, you must keep like an array of rows which you dont want editable (allthough the cell.editable == true).
function inarray(arr, testVal) {
return dojo.some(arr, function(val) { return val == testVal }).length > 0
}
grid.setNonEditable = function (rowIndex) {
if(! inarray(this.nonEditable,rowIndex) )
this.nonEditable.push(rowIndex);
}
grid.setEditable = function (rowIndex) {
this.nonEditable = dojo.filter(this.nonEditable, function(val) { return val != rowIndex; });
}
var originalApply = grid.onApplyEdit
grid.onApplyEdit = function(inValue, inRowIndex) {
if(! inarray(this.nonEditable,inRowIndex) )
originalApply.apply(this, arguments);
}

If you are using dojox.grid.DataGrid you can use canEdit function to disable row editing or cell editing :
grid = new dojox.grid.DataGrid({
canEdit: function(inCell, inRowIndex) {
var item = this.getItem(inRowIndex);
var value = this.store.getValue(item, "name");
return value == null; // allow edit if value is null
}
}

Related

XMLPullParser returns only one element

I could not parse my XML file, it returns only one element instead of 4
Here's my XML file
<Quizzs>
<Quizz type="A">...</Quizz>
<Quizz type="B">...</Quizz>
<Quizz type="C">...</Quizz>
<Quizz type="D">...</Quizz>
</Quizzs>
It returns only the last one "D"
while (eventType != XmlPullParser.END_DOCUMENT) {
var eltName: String? = null
when (eventType) {
XmlPullParser.START_TAG -> {
eltName = parser.name
if ("Quizzs" == eltName) {
currentQuizz = Quizz()
quizz.add(currentQuizz)
} else if (currentQuizz != null) {
if ("Quizz" == eltName) {
currentQuizz.type = parser.getAttributeValue(null, "type")
}
}
}
}
eventType = parser.next()
}
printPlayers(quizz)
}
You need to .add() something to your currentQuizz for each "Quizz". With currentQuizz.type = ... you just overwrite each previous "Quizz" with the current one, so you end up with only the last one, which is D.
I think you are confused by your own code. For the "Quizzs" tag you create a Quizz() object instead of a QuizzList() object or something similar. It is for the "Quizz" tag you should create a new Quizz() object each time. And then you should add that object to your QuizzList.

use map function on condition in kotlin

I have a list of items and I want to edit its values before using it. I am using the map function to update each item in it. But the catch here is, I want to only update the items when the list size is 1. I want to return the list as it is if the size is larger than 1. How can I achieve this?
myList.map {
if(resources.getBoolean(R.bool.is_tablet) && it.itemList.size<6 && it.layerType == DOUBLE_LIST) {
it.layerType = SINGLE_LIST_AUTO
it.itemList.forEach {sectionItem->
sectionItem.layerType = SINGLE_LIST_AUTO
}
it
}else{
it
}
}
You can try using filter before map:
.filter { it.itemList.size == 1 }
I am assuming you want to modify the items in your list only if some conditions are met else return the same list unmodified.
You can consider using takeIf { } for this scenario if you desire to add some syntactic sugar
fun updateItemsInMyList(myList:List<SomeClass>): List<SomeClass> {
return myList
.takeIf {
// condition to modify items in your list
it.size > 1 && otherConditions
}
?.apply {
//update your items inside the list
}
?: myList // return the unmodified list if conditions are not met
}
If I understand your question correctly, you want to check if myList contains only one value else, you want update the values and return it. You could do something along the following lines,
myList.singleOrNull ?: myList.map {
if(resources.getBoolean(R.bool.is_tablet) && it.itemList.size<6 && it.layerType == DOUBLE_LIST) {
it.layerType = SINGLE_LIST_AUTO
it.itemList.forEach {sectionItem->
sectionItem.layerType = SINGLE_LIST_AUTO
}
it
}else{
it
}
}
return myList
Basically, check if there's only a single value in the list, if so, then return the value. In the case that there isn't (you get null), then you can map the value.

EXTJS Grid row colour change dynamically with getting colour code from database

I am working on an EXTJS grid whose row-color will be set according to a field(status field) value from the table.
User can edit the fields of the row and after clicking update, the color of the row will change according to status field value set for that row.
I need the row background color should be set fetching from a table in db.
Currently I am setting different css class with checking the status field value using following code.
getRowClass: function(record, rowIndex, rp, ds)
{
if( record.get('status') == 'xxxxx' )
{
return 'status-xxxxx';
}
else if( record.get('status') == 'yyyyy' )
{
return 'status-yyyyy';
}
else
{
return 'status-zzzzzz';
}
}
I have the color in the store with the status value for each row.
But I need the color should be fetched from db and set as row background.
Can any one help me to achieve this.
Thanks
If you want to use as row background-color color from row record you will have to set background color of each row td elements after row is rendered.
You can do this in refresh event of gridView. So in grid config you should define something like this:
viewConfig: {
listeners: {
refresh: function(view) {
// get all grid view nodes
var nodes = view.getNodes();
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
// get node record
var record = view.getRecord(node);
// get color from record data
var color = record.get('color');
// get all td elements
var cells = Ext.get(node).query('td');
// set bacground color to all row td elements
for(var j = 0; j < cells.length; j++) {
console.log(cells[j]);
Ext.fly(cells[j]).setStyle('background-color', color);
}
}
}
}
}
Fiddle with live example: https://fiddle.sencha.com/#fiddle/2m8

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
}

Comparing DropDownLists

I'm having a page that contains several dropdownlists, all filled with the same values. I would like to compare them on the client as well as on the server side.
The problem is though, that the dropdownlists are generated dynamically because their quantity can vary.
Client side comparing:
<script type="text/javascript">
function CompareSelectedValues(dropDown1ID, dropDown2ID) {
var DropDownList1 = document.getElementById(dropDown1ID);
var DropDownList2 = document.getElementById(dropDown2ID);
if (DropDownList1.selectedIndex != -1 && DropDownList2.selectedIndex != -1) {
if (DropDownList1.options[DropDownList1.selectedIndex].value != DropDownList2.options[DropDownList2.selectedIndex].value)
alert('not same');
}
}
</script>
Classic server side comparing with C#:
private bool AreDropDownListValuesEqual(DropDownList ddlist1, DropDownList ddlist2)
{
// Check for invalid input or different number of items for early return
if (ddlist1 == null || ddlist2 == null || ddlist1.Items.Count != ddlist2.Items.Count)
{
return false;
}
// Check items one by one. We need a nested loop because the list could be sorted differently while having the same values!
foreach (ListItem outerItem in ddlist1.Items)
{
bool hasMatch = false;
foreach (ListItem innerItem in ddlist2.Items)
{
if (innerItem.Value == outerItem.Value && innerItem.Text == outerItem.Text)
{
hasMatch = true;
break;
}
}
if (!hasMatch)
{
return false;
}
}
// All items from ddlist1 had a match in ddlist2 and we know that the number of items is equal, so the 2 dropdownlist are matching!
return true;
}
What kind of comparison do you need? If you don't keep them in a List and that list in Session, you can never do anything with them since you add them dynamically. Add your dropdownlists where you create them (this should me when Page.IsPostBack == false) and keep that list in session. On postbacks, load your dropdowns from the list. You can compare them using the list you keep.