Custom Search in Filter tool panel of aggrid column which is rendered using a custom cell renderer - ag

As per our requirements , we had to render cell from a enum . So for that we used custom enum renderer to render value from a enum .
For eg :
enum Countries {
'Afghanistan' = 0,
'Algeria' =1 ,
'Argentina' = 2,
'Armenia' = 3,
'Australia' = 4,
'Azerbaijan' = 5
}
#Component({
template: `{{ mapEnumText() }}`,
})
export class CustomEnumRenderer implements AgRendererComponent {
public params: any;
refresh(): boolean {
return false;
}
agInit(params: ICellRendererParams): void {
this.params = params;
}
mapEnumText(){
return Countries[this.params.value];
}
}
We are able to render text using this custom renderer.
But when I am trying search from Filter tool panel , search works for enum value and not text .
If we try to type Aus , Australia should be filtered and shown in Filter Tool Panel
but it wont work as enum value is loaded to aggrid so we will have to type 4 for Australia to show up .
Is there anyway to customize the search so that we could implement a custom search for enum values ?

Related

Aspose: Image overflow the table when using with shape in imageFieldMerging

When I try to insert image directly to the ImageFieldMergingArgs it appears properly in the table cell using the following code...
override fun imageFieldMerging(imageFieldMergingArgs: ImageFieldMergingArgs) {
val fieldValue = imageFieldMergingArgs.fieldValue
if (fieldValue is DataString) {
val decodedImage = fieldValue.decode()
imageFieldMergingArgs.imageStream = ByteArrayInputStream(decodedImage)
}
}
But when I'm trying to insert an image using Shape in MailMerge. then it is appearing outside the table. I'm using the following code
override fun imageFieldMerging(imageFieldMergingArgs: ImageFieldMergingArgs) {
val fieldValue = imageFieldMergingArgs.fieldValue
if (fieldValue is DataString) {
val shape = Shape(imageFieldMergingArgs.document, ShapeType.IMAGE)
shape.wrapType = WrapType.SQUARE
shape.aspectRatioLocked = false
shape.anchorLocked = true
shape.allowOverlap = false
shape.width = imageFieldMergingArgs.imageWidth.value
shape.height = imageFieldMergingArgs.imageHeight.value
imageFieldMergingArgs.shape = shape
}
}
is there any way I can add an image into the table cell using shape to imageFieldMergingArgs.
Thanks
When you specify imageFieldMergingArgs.imageStream the shape is inserted with WrapType.INLINE. In you second snippet you specify WrapType.SQUARE. This might be the difference. It is difficult to say exactly what is wrong without your template. But I would try specifying WrapType.INLINE. I tested both your code snippets on my side with a simple template an in both cases the image is inside table cell.

Acumatica GI - Inventory Transaction History Screen

I want to create a GI for Inventory Transaction History Screen (IN405000).
Since the table InventoryTranHistEnqResult isn't present in the database...few of the columns of this screen are taken from INTran Table.
I am not able to find following columns: BegQty, QtyIn, QtyOut, EndQty...
I also tried the following query on database to find these columns
SELECT c.name AS ColName, t.name AS TableName
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE '%EndQty%'
The DAC for these fields is:
enter image description here
Looking at the information behind the page in the page Graph will give you the answers to your question. Inventory Transaction History Screen (IN405000) uses graph InventoryTranHistEnq. The grid in this page uses DAC InventoryTranHistEnqResult in the following view:
PXSelectJoin<InventoryTranHistEnqResult,
CrossJoin<INTran>,
Where<True, Equal<True>>,
OrderBy<Asc<InventoryTranHistEnqResult.gridLineNbr>>> ResultRecords
The ResultsRecords are built dynamically in the inquiry using the following:
protected virtual IEnumerable resultRecords()
{
int startRow = PXView.StartRow;
int totalRows = 0;
decimal? beginQty = null;
List<object> list = InternalResultRecords.View.Select(PXView.Currents, PXView.Parameters, new object[PXView.SortColumns.Length], PXView.SortColumns, PXView.Descendings, PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);
PXView.StartRow = 0;
foreach (PXResult<InventoryTranHistEnqResult> item in list)
{
InventoryTranHistEnqResult it = (InventoryTranHistEnqResult)item;
it.BegQty = beginQty = (beginQty ?? it.BegQty);
decimal? QtyIn = it.QtyIn;
decimal? QtyOut = it.QtyOut;
beginQty += (QtyIn ?? 0m) - (QtyOut ?? 0m);
it.EndQty = beginQty;
}
return list;
}
So i guess the short answer is you cannot use the results of this page for a GI as it is built in the page only. You might want to look into adding what you need to this history page via a customization or make your own version of this page/graph/dac if the information you need is that important.

IcCube - Treemap Chart with duplicate names

In the Google Treemap Chart every node has to have a unique id, but two nodes can have the same name (https://groups.google.com/d/msg/google-visualization-api/UDLD-a-0PCM/IwVCGzsWOg8J).
I used the schema from the parent/child demo (http://www.iccube.com/support/documentation/user_guide/schemas_cubes/dim_parentchild.php)
Using the following MDX statement in the treemap works, as long as the names of the nodes are unique:
WITH
MEMBER [parent_name] as IIF( [dim (ALL)].[Hierarchy].currentmember
is [dim (ALL)].[Hierarchy].[ALL],'',
[dim (ALL)]. [Hierarchy].currentmember.parent.name )
SELECT
{[parent_name],[Measures].[value]} on 0,
non empty [dim (ALL)].[Hierarchy].members on 1
FROM
[Cube]
If I added the line to the In-memory table in icCube's schema :
7,4,Spain, 2, 32
but the name Spain is double when rendering the Treemap. To support names a child definition in the GVI table should be something like this:
{v:'uniqueID-Spain', f:'Spain'}
As a workaround you can use the following code that modifies GviTable processing for the google tree widget. Check the example here:
https://drive.google.com/file/d/0B3kSph_LgXizSVhvSm15Q1hIdW8/view?usp=sharing
Report JavaScript:
function consumeEvent( context, event ) {
if (event.name == 'ic3-report-init') {
if(!_.isFunction(ic3.originalProcessGviTable)) {
ic3.originalProcessGviTable = viz.charts.GenericGoogleWidget.prototype.processGviTable
}
viz.charts.GenericGoogleWidget.prototype.processGviTable = function(gviTable){
if(this.props.ic3chartType === "TreeMap") {
gviTable = gviTable || this.gviTable();
var underlying = _.cloneDeep(gviTable.getUnderlyingGviTable());
_.each(underlying.rows, function(row){
// Replace id with parent prefixed
if(_.isObject(row.c[0]) && !_.isString(row.c[0].f)) {
row.c[0].f = row.c[0].v;
if(_.isObject(row.c[0].p) && _.isString(row.c[0].p.mun)) {
row.c[0].v = row.c[0].p.mun;
}
}
});
gviTable = viz.GviTable.fromSnapshot(underlying);
this.startColumnSelection = gviTable.getNumberOfHeaderColumns() - 1;
return viz.charts.toGoogleDataTableOneRowHeader(gviTable);
} else {
return ic3.originalProcessGviTable.apply(this, gviTable);
}
}
}
}
For the query like:
WITH
MEMBER [parent_name] as
IIF( [dim (ALL)].[Hierarchy].currentmember.isAll(),
'',
([dim (ALL)].[Hierarchy].currentmember.parent.uniqueName)
)
SELECT
{[parent_name],[Measures].[value]} on 0,
non empty [dim (ALL)].[Hierarchy].members on 1
FROM
[Cube]
This is a limitation of Google Treemap chart that is using the same column for the id and the label. Besides changing the names to ensure they are unique (e.g. adding the parent) I don't see a workaround to this.
An option would be using another Treemap chart (e.g. one from D3) that has not this limitation.
--- icCube Schema ---
The schema is working (just use , instead of ; as separator )
--- icCube Reporting ---
The issue using Treemap is that you've two rows with the same id (Germany), fiddle
This fiddle is a running example of treemap

What is the best way to set/read UI values in Qt Quick

I am writing a new C++ application and I decided to use Qt Quick instead of traditional Qt widgets, I know QML well but I am facing some trouble regarding the best way to read and set UI controls' values
in my application, it's called DOO, I have two QML files for each display, the first defines the UI elements and the second is a helper class to read/set UI values and it has a save() function to save to a database
for example lets take an object that is called Son and see how it is defined
in SonDisplay.qml
import QtQuick 2.0
import QtQuick.Layouts 1.1
import DOO.Entities.Son 1.0
import DOOTypes 1.0
import "../UIElements"
import "../UIElements/DOOTheme.js" as DOOTheme
import "../DOO"
Display {
id:sonDisplay
contentHeight: 350
contentWidth: 800
// this is a QObject derived class, that I use as an entity to a table in a MySQL database
// I use it here to set/read UI from/to it
property Son son : Son{}
property int disMode : DOO.Show
property bool inEditMode : false
....
in the helper file SonHelper.qml
import QtQuick 2.0
import DOO.Commands.Son 1.0
import DOOTypes 1.0
QtObject {
// read a Son object values into local son
function readValues(pSon)
{
son.sonID = pSon.sonID
son.name = pSon.name
son.image = pSon.image
son.age = pSon.age
son.entryDate = pSon.entryDate
son.commingFrom = pSon.commingFrom
son.disabilityKind.kind = pSon.disabilityKind.kind
son.caseDescription = pSon.caseDescription
son.more = pSon.more
}
// copy local son values into a Son object
function copyValues(pSon)
{
pSon.sonID = son.sonID
pSon.name = son.name
pSon.image = son.image
pSon.age = son.age
pSon.entryDate = son.entryDate
pSon.commingFrom = son.commingFrom
pSon.disabilityKind.kind = son.disabilityKind.kind
pSon.caseDescription = son.caseDescription
pSon.more = son.more
}
// read ui values into local son
function readUIValues()
{
son.name = sonName.text
son.image = sonImage.picture
son.age = sonAge.text
son.entryDate = Date.fromLocaleDateString(Qt.locale(), sonEntryDate.text, "dd-MM-yyyy")
son.commingFrom = sonCommingFrom.text
son.disabilityKind.kind = sonDisabilityKind.currentIndex
son.caseDescription = sonCaseDescription.text
son.more = sonMore.text
}
function validateUIValues()
{
if (Date.fromLocaleDateString(Qt.locale(), sonEntryDate.text, "dd-MM-yyyy") == "Invalid Date") return false
//if(!sonSonID.acceptableInput) return false
//if(!sonAge.acceptableInput) return false
//if(!sonDisabilityKind.acceptableInput) return false
return true
}
// save or update a son into database
function save()
{
var v_son = SonFactory.createObject()
if (!validateUIValues())
{
dooNotifier.showMessage("Error","You Have some invalid input")
return
}
readUIValues()
copyValues(v_son) // copy local son values into v_son
if(disMode === DOO.CreateNew)
{
if(SonCommands.insert(v_son))
{
dooNotifier.showMessage("Success","Son added successfully ")
SonResultsModel.update()
sonDisplay.hide()
}
else
{
dooNotifier.showMessage("Failed","Error adding son")
DOOLogger.log(SonCommands.lasrErrorText())
}
}
else
{
if(SonCommands.update(v_son))
{
dooNotifier.showMessage("Success","Son updated successfully ")
SonResultsModel.update()
sonDisplay.hide()
}
else
{
dooNotifier.showMessage("Failed","Error updating son")
DOOLogger.log(SonCommands.lasrErrorText())
}
}
v_son.destroy()
}
}
As you can see, I use a function to read a Son object values into local son object, a second one to copy local son object's values into a Son object, and a third function to read UI values into local son object
Now I am wondering if is there any better way to handle this scenario instead of readValues(pSon), copyValues(pSon), and readUIValues() functions
or this is a good pattern to do that
Edit
I think I could use a QAbstractItemModel derived class to read/ save to databaase and pass UI values to it as a JavaScript object or read UI values into local son object and pass it to a C++ save() function that will validate and save data like this:
var uivalues = {
name : sonName.text ,
image : sonImage.picture ,
age : sonAge.text ,
entryDate : Date.fromLocaleDateString(Qt.locale(), sonEntryDate.text, "dd-MM-yyyy") ,
commingFrom : sonCommingFrom.text ,
disabilityKind : sonDisabilityKind.currentIndex ,
caseDescription : sonCaseDescription.text ,
more : sonMore.text ,
}
SonResultsModel.save(uivalues)
First:
I think you should move more logic to the C++ code. For the best performance it's better to use minimum js code as possible.
Create your son as C++ class with properties then bind this properties to UI if it's possible.
Second:
Last method in helper class save() could be in the special class. That can be usefull when you use more classes like son because the work with that classes will be simillar.
EDIT:
I think it's better now. See comments below.

Faceted search on multilist in sitecore 7

I'm able to generate the facet and bind the result in Linkbutton within repeater control. Now I'm facing problem in generating the facet query with OR operator when the user selects more than 1 value of same facet type in Sitecore 7.
What can be done to solve it?
Thanks
Here's a blog post about solving this using PredicateBuilder with a specific code example:
http://www.nttdatasitecore.com/en/Blog/2013/November/Building-Facet-Queries-with-PredicateBuilder.aspx
To implement the Facet search in Sitecore use PredicateBuilder class to build the filter query and then add the filter query to the base query. Code is mentioned below:
List<PeopleFields> objPeoplefields = new List<PeopleFields>();
IQueryable<PeopleFields> Query = null;
var predicatePractice = Sitecore.ContentSearch.Utilities.PredicateBuilder.False<PeopleFields>();
var predicateOffice = Sitecore.ContentSearch.Utilities.PredicateBuilder.False<PeopleFields>();
using (var context = ContentSearchManager.GetIndex(SITECORE_WEB_INDEX).CreateSearchContext())
{
//Base query
Query = context.GetQueryable<PeopleFields>().Where(i => i.FirstName.StartsWith(txtFirstName.Text)).Where(i => i.LastName.StartsWith(txtLastName.Text));
foreach (string strselecteFacet in lstPracticefacetSelected)
{
//filter query
predicatePractice = predicatePractice.Or(x => x.Practice.Like(strselecteFacet));
}
foreach (string strselecteFacet in lstOfficefacetSelected)
{
//Filter query
predicateOffice = predicateOffice.Or(x => x.Office.Like(strselecteFacet));
}
//Joining the filter query alongwith base query
if (lstPracticefacetSelected.Count > 0 && lstOfficefacetSelected.Count > 0)
Query = Query.Filter(predicatePractice).Filter(predicateOffice);
else if (lstPracticefacetSelected.Count > 0 && lstOfficefacetSelected.Count == 0)
Query = Query.Filter(predicatePractice);
else if (lstPracticefacetSelected.Count == 0 && lstOfficefacetSelected.Count > 0)
Query = Query.Filter(predicateOffice);
objPeoplefields = Query.ToList();
}
As a quick way, if you're ok with having SitecoreUISearchResultItem as the query result type, you may be able to utilize the same method Sitecore 7 uses to parse queries entered in the content editor search:
Sitecore.Buckets.Util.UIFilterHelpers.ParseDatasourceString(string query)
If that's not up to what you're after, reading how it's implemented with a decompiler (ILSpy, DotPeek, Reflector, Resharper, etc) may help you in composing an expression manually based on dynamic criteria.