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

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

Related

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

JFace TableViewer get multiple selected rows

I want to add a listener to the select button which gets the multiple rows selected in the checklist tableviewer. It then proccedes to check those boxes.
My question is how do I get the list of rows selected in the tableviewer?
Here is the code for the table:
private void createCheckViewer(Composite parent){
tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.MULTI| SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
if ( (GanttFrame.getListOfFunctionTasks()!= null)){
if (!(GanttFrame.getListOfFunctionTasks().isEmpty())){
// Data Rows
for (int i = 0; i < GanttFrame.getListOfFunctionTasks().size(); i++) {
tableViewer.add(GanttFrame.getListOfFunctionTasks().get(i));
GanttFrame.getListOfFunctionTasks().get(i).setCheckId(i);
}
}
}
// flow trace or function trace
String columnHeader;
if (TraceData.getFlowTraceFlag()){
columnHeader = "Flow Traces";
}else{
columnHeader = "Function Traces";
}
// define layout for the viewer
gridData = new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1);
gridData.heightHint = 400;
tableViewer.getControl().setLayoutData(gridData);
tableViewer.addCheckStateListener(this.getCheckListListener());
final Table table = tableViewer.getTable();
TableLayout layout = new TableLayout();
TableViewerColumn col = new TableViewerColumn(tableViewer, SWT.LEAD);
col.getColumn().setText(columnHeader);
layout.addColumnData(new ColumnWeightData(500));
table.setLayout(layout);
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
Use:
IStructuredSelection selection = (IStructuredSelection)tableViewer.getSelection();
You then have various choices for processing the selection:
Object [] selections = selection.toArray();
List<?> selections = selection.toList();
Iterator<?> iterator = selection.iterator();

AS2 inventory script

I'm trying to modify the below script so that it will automatically drop the first instance of "_item" and snap it to the nearest "slot"
The code works great except I cannot find a way to make it drop the item without the user clicking on it first. This is not my script. You can see it in action here- http://www.freeactionscript.com/2008/11/drag-drop-snap-inventory-system-v2/
Any help greatly appreciated, thanks!
/**
* Drag, Drop and Snap Inventory System
*
* Version: 2.0
* Author: Philip Radvan
* URL: http://www.freeactionscript.com
*/
var slots_array:Array = new Array(slot0, slot1, slot2, slot3, slot4, slot5, slot6, slot7, slot8, slot9, slot10, slot11, slot12, slot13, slot14, slot15);
var items_array:Array;
var uniqueItemId:Number = 0;
//
//start dragging
function dragItem(_item:Object):Void
{
//save position before dragging
_item.nowX = _item._x;
_item.nowY = _item._y;
//drag
_item.startDrag(true);
_item.onMouseMove = updateDrag;
}
//stop dragging
function dropItem(_item:Object):Void
{
//stop dragging
_item.stopDrag();
//delete mouse event
delete _item.onMouseMove;
//run loop on slots array
for (i=0; i<slots_array.length; i++)
{
//set temp slot var
currentSlot = eval(slots_array[i]);
//check slot hittest and slot itemID; if item is over slot and slot is empty, drop
if ((eval(_item._droptarget) == currentSlot) && (currentSlot.itemID == "empty"))
{
//place item in slot
_item._x = currentSlot._x;
_item._y = currentSlot._y;
//update current slot itemID
currentSlot.itemID = this;
//update previous slot itemID
temp = eval(_item.slotID);
temp.itemID = "empty";
//update current item slotID
_item.slotID = currentSlot.myName;
//item moved, end loop
return;
}
else
{
//return item to previous position if: item is NOT over slot or slot is NOT empty
_item._x = _item.nowX;
_item._y = _item.nowY;
}
}
}
/*
* updateAfterEven re-renders the screen
*/
function updateDrag():Void
{
updateAfterEvent();
}
/*
* Create Slots
*/
for (i=0; i<slots_array.length; i++)
{
var _currentSlot = slots_array[i];
_currentSlot.itemID = "empty";
_currentSlot.num = i;
_currentSlot.myName = "slot"+i;
}
/*
* Create Item
*/
function createInventoryItem()
{
//attach item to stage
var _item = attachMovie("item", "item"+uniqueItemId, _root.getNextHighestDepth());
//set item position
_item._x = 280;
_item._y = 320;
//set item settings
_item.myName = "item"+uniqueItemId;
_item.slotID = "empty";
//make item a button
_item.onPress = function()
{
dragItem(this)
}
_item.onRelease = _item.onReleaseOutside = function()
{
dropItem(this);
}
//add item to array
items_array.push(_item);
//update unique Item Id
uniqueItemId++;
}
//button to create a new inventory item
create_item_btn.onRelease = function()
{
createInventoryItem();
}
Fixed it. Rather than modifying this one I wrote my own. Thanks everyone : )
By placing the hit test code on the movie clip "_item" itself, a small array loop sorts it's position on clip event load, and snaps it to the slot. Super easy.

How to Detect table start in itextSharp?

I am trying to convert pdf to csv file. pdf file has data in tabular format with first row as header. I have reached to the level where I can extract text from a cell, compare the baseline of text in table and detect newline but I need to compare table borders to detect start of table. I do not know how to detect and compare lines in PDF. Can anyone help me?
Thanks!!!
As you've seen (hopefully), PDFs have no concept of tables, just text placed at specific locations and lines drawn around them. There is no internal relationship between the text and the lines. This is very important to understand.
Knowing this, if all of the cells have enough padding you can look for gaps between characters that are large enough such as the width of 3 or more spaces. If the cells don't have enough spacing this will unfortunately probably break.
You could also look at every line in the PDF and try to figure out what represents your "table-like" lines. See this answer for how to walk every token on a page to see what's being drawn.
I was also searching the answer for the similar question, but unfortunately I didn't found one so I did it on my own.
A PDF page like this
Will give the output as
Here is the github link for the dotnet Console Application I made.
https://github.com/Justabhi96/Detect_And_Extract_Table_From_Pdf
This application detects the table in the specific page of the PDF and prints them in a table format on the console.
Here is the code that i used to make this application.
First of all I took the text out of PDF along with their coordinates using a class which extends iTextSharp.text.pdf.parser.LocationTextExtractionStrategy class of iTextSharp. The Code is as follows:
This is the Class that is going to store the chunks with there coordinates and text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace itextPdfTextCoordinates
{
public class RectAndText
{
public iTextSharp.text.Rectangle Rect;
public String Text;
public RectAndText(iTextSharp.text.Rectangle rect, String text)
{
this.Rect = rect;
this.Text = text;
}
}
}
And this is the class that extends the LocationTextExtractionStrategy class.
using iTextSharp.text.pdf.parser;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace itextPdfTextCoordinates
{
public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy
{
public List<RectAndText> myPoints = new List<RectAndText>();
//Automatically called for each chunk of text in the PDF
public override void RenderText(TextRenderInfo renderInfo)
{
base.RenderText(renderInfo);
//Get the bounding box for the chunk of text
var bottomLeft = renderInfo.GetDescentLine().GetStartPoint();
var topRight = renderInfo.GetAscentLine().GetEndPoint();
//Create a rectangle from it
var rect = new iTextSharp.text.Rectangle(
bottomLeft[Vector.I1],
bottomLeft[Vector.I2],
topRight[Vector.I1],
topRight[Vector.I2]
);
//Add this to our main collection
this.myPoints.Add(new RectAndText(rect, renderInfo.GetText()));
}
}
}
This class is overriding the RenderText method of the LocationTextExtractionStrategy class which will be called each time you extract the chunks from a PDF page using PdfTextExtractor.GetTextFromPage() method.
using itextPdfTextCoordinates;
using iTextSharp.text.pdf;
//Create an instance of our strategy
var t = new MyLocationTextExtractionStrategy();
var path = "F:\\sample-data.pdf";
//Parse page 1 of the document above
using (var r = new PdfReader(path))
{
for (var i = 1; i <= r.NumberOfPages; i++)
{
// Calling this function adds all the chunks with their coordinates to the
// 'myPoints' variable of 'MyLocationTextExtractionStrategy' Class
var ex = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(r, i, t);
}
}
//Here you can loop over the chunks of PDF
foreach(chunk in t.myPoints){
Console.WriteLine("character {0} is at {1}*{2}",i.Text,i.Rect.Left,i.Rect.Top);
}
Now for Detecting the start and end of the table you can use the coordinates of the chunks extracted from the PDF.
Like if the specific line is not having table then there will be no jumps in the right coordinate of the current chunk and and Left coordinate of next chunk. But the lines having table will be having those coordinate jumps of at least 3 points.
Like for Lines having table will have coordinates of chunks something like this:
right coord of current chunk -> 12.75pts
left coords of next chunk -> 20.30pts
so further you can use this logic to detect tables in the PDF.
The code is as follows:
using itextPdfTextCoordinates;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class LineUsingCoordinates
{
public static List<List<string>> getLineText(string path, int page, float[] coord)
{
//Create an instance of our strategy
var t = new MyLocationTextExtractionStrategy();
//Parse page 1 of the document above
using (var r = new PdfReader(path))
{
// Calling this function adds all the chunks with their coordinates to the
// 'myPoints' variable of 'MyLocationTextExtractionStrategy' Class
var ex = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(r, page, t);
}
// List of columns in one line
List<string> lineWord = new List<string>();
// temporary list for working around appending the <List<List<string>>
List<string> tempWord;
// List of rows. rows are list of string
List<List<string>> lineText = new List<List<string>>();
// List consisting list of chunks related to each line
List<List<RectAndText>> lineChunksList = new List<List<RectAndText>>();
//List consisting the chunks for whole page;
List<RectAndText> chunksList;
// List consisting the list of Bottom coord of the lines present in the page
List<float> bottomPointList = new List<float>();
//Getting List of Coordinates of Lines in the page no matter it's a table or not
foreach (var i in t.myPoints)
{
Console.WriteLine("character {0} is at {1}*{2}", i.Text, i.Rect.Left, i.Rect.Top);
// If the coords passed to the function is not null then process the part in the
// given coords of the page otherwise process the whole page
if (coord != null)
{
if (i.Rect.Left >= coord[0] &&
i.Rect.Bottom >= coord[1] &&
i.Rect.Right <= coord[2] &&
i.Rect.Top <= coord[3])
{
float bottom = i.Rect.Bottom;
if (bottomPointList.Count == 0)
{
bottomPointList.Add(bottom);
}
else if (Math.Abs(bottomPointList.Last() - bottom) > 3)
{
bottomPointList.Add(bottom);
}
}
}
// else process the whole page
else
{
float bottom = i.Rect.Bottom;
if (bottomPointList.Count == 0)
{
bottomPointList.Add(bottom);
}
else if (Math.Abs(bottomPointList.Last() - bottom) > 3)
{
bottomPointList.Add(bottom);
}
}
}
// Sometimes the above List will be having some elements which are from the same line but are
// having different coordinates due to some characters like " ",".",etc.
// And these coordinates will be having the difference of at most 4 points between
// their bottom coordinates.
//so to remove those elements we create two new lists which we need to remove from the original list
//This list will be having the elements which are having different but a little difference in coordinates
List<float> removeList = new List<float>();
// This list is having the elements which are having the same coordinates
List<float> sameList = new List<float>();
// Here we are adding the elements in those two lists to remove the elements
// from the original list later
for (var i = 0; i < bottomPointList.Count; i++)
{
var basePoint = bottomPointList[i];
for (var j = i+1; j < bottomPointList.Count; j++)
{
var comparePoint = bottomPointList[j];
//here we are getting the elements with same coordinates
if (Math.Abs(comparePoint - basePoint) == 0)
{
sameList.Add(comparePoint);
}
// here ae are getting the elements which are having different but the diference
// of less than 4 points
else if (Math.Abs(comparePoint - basePoint) < 4)
{
removeList.Add(comparePoint);
}
}
}
// Here we are removing the matching elements of remove list from the original list
bottomPointList = bottomPointList.Where(item => !removeList.Contains(item)).ToList();
//Here we are removing the first matching element of same list from the original list
foreach (var r in sameList)
{
bottomPointList.Remove(r);
}
// Here we are getting the characters of the same line in a List 'chunkList'.
foreach (var bottomPoint in bottomPointList)
{
chunksList = new List<RectAndText>();
for (int i = 0; i < t.myPoints.Count; i++)
{
// If the character is having same bottom coord then add it to chunkList
if (bottomPoint == t.myPoints[i].Rect.Bottom)
{
chunksList.Add(t.myPoints[i]);
}
// If character is having a difference of less than 3 in the bottom coord then also
// add it to chunkList because the coord of the next line will differ at least 10 points
// from the coord of current line
else if (Math.Abs(t.myPoints[i].Rect.Bottom - bottomPoint) < 3)
{
chunksList.Add(t.myPoints[i]);
}
}
// Here we are adding the chunkList related to each line
lineChunksList.Add(chunksList);
}
bool sameLine = false;
//Here we are looping through the lines consisting the chunks related to each line
foreach(var linechunk in lineChunksList)
{
var text = "";
// Here we are looping through the chunks of the specific line to put the texts
// that are having a cord jump in their left coordinates.
// because only the line having table will be having the coord jumps in their
// left coord not the line having texts
for (var i = 0; i< linechunk.Count-1; i++)
{
// If the coord is having a jump of less than 3 points then it will be in the same
// column otherwise the next chunk belongs to different column
if (Math.Abs(linechunk[i].Rect.Right - linechunk[i + 1].Rect.Left) < 3)
{
if (i == linechunk.Count - 2)
{
text += linechunk[i].Text + linechunk[i+1].Text ;
}
else
{
text += linechunk[i].Text;
}
}
else
{
if (i == linechunk.Count - 2)
{
// add the text to the column and set the value of next column to ""
text += linechunk[i].Text;
// this is the list of columns in other word its the row
lineWord.Add(text);
text = "";
text += linechunk[i + 1].Text;
lineWord.Add(text);
text = "";
}
else
{
text += linechunk[i].Text;
lineWord.Add(text);
text = "";
}
}
}
if(text.Trim() != "")
{
lineWord.Add(text);
}
// creating a temporary list of strings for the List<List<string>> manipulation
tempWord = new List<string>();
tempWord.AddRange(lineWord);
// "lineText" is the type of List<List<string>>
// this is our list of rows. and rows are List of strings
// here we are adding the row to the list of rows
lineText.Add(tempWord);
lineWord.Clear();
}
return lineText;
}
}
}
You can call getLineText() method of the above class and run the following loop to see the output in the table structure on the console.
var testFile = "F:\\sample-data.pdf";
float[] limitCoordinates = { 52, 671, 357, 728 };//{LowerLeftX,LowerLeftY,UpperRightX,UpperRightY}
// This line gives the lists of rows consisting of one or more columns
//if you pass the third parameter as null the it returns the content for whole page
// but if you pass the coordinates then it returns the content for that coords only
var lineText = LineUsingCoordinates.getLineText(testFile, 1, null);
//var lineText = LineUsingCoordinates.getLineText(testFile, 1, limitCoordinates);
// For detecting the table we are using the fact that the 'lineText' item which length is
// less than two is surely not the part of the table and the item which is having more than
// 2 elements is the part of table
foreach (var row in lineText)
{
if (row.Count > 1)
{
for (var col = 0; col < row.Count; col++)
{
string trimmedValue = row[col].Trim();
if (trimmedValue != "")
{
Console.Write("|" + trimmedValue + "|");
}
}
Console.WriteLine("");
}
}
Console.ReadLine();

Disable specific rows in datagrid/enhancedgrid

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
}
}