How to use sorting when using filterPlaceholder? - material-table

i'm using filterPlaceholder, what i'm doing is deleting the column title and using filterPlaceholder instead and here is my code
get columns() {
const { columns, enableColumnPlaceholder } = this.props;
// #In order to align lookups with other search Fields
const styledColumns = columns.map(column => {
const modifiedColumn = { ...column };
/**
* The Following To Align Lookup field with ordinary search fields
*/
if(modifiedColumn.lookup) {
modifiedColumn.filterCellStyle = { paddingTop: 0, paddingBottom: 24 };
}
/**
* The Following Code For Hiding Table Columns Titles
* And Put The Titles As A placeholder
*/
if(enableColumnPlaceholder) {
const columnTitle = column.title;
modifiedColumn.filterPlaceholder = columnTitle ? columnTitle : '';
delete modifiedColumn.title;
}
return modifiedColumn;
});
return styledColumns;
}
i did that because i don't want to use title and placeholder together, but by removing the title i lost the sorting functionality
Is there is a workarround to do that?
Thanks in advance.

Related

How to make SQL query when you have multiple if conditions

I am trying to build an API that supports, list, search, and filters. I am not sure where to put the where clause.
It works in some cases but doesn't in many. For example, when input body has search filed it will work but when you apply only the second filter which is pan in this case it didn't.
const query = {
text: `
select master.contact.id,
master.contact.name
from
master.contact
`
};
if (input.search) {
query.text += ` where
(master.contact.pan ILIKE '${input.search}%' or master.contact.ira ILIKE '${input.search}%')`;
}
if (input.filters) {
const {
isActive,
pan
} = input.filters;
if (isActive !== undefined) {
query.text += ` where master.contact.isActive = ${isActive}`;
}
if (pan) {
query.text += `and master.contact.pan = ${pan}`;
}
There are different ways to do this. One of them would be to have
Where 1=1
In you main query. So you can add And condition for every condition you have.
const query = {
text: `
select master.contact.id,
master.contact.name
from
master.contact
where 1=1
`
};
If (input.search) {
query.text += ` and (master.contact.pan ILIKE '${input.search}%' or master.contact.ira ILIKE '${input.search}%')`;
}
And so on...

How do you format a number to currency when using React native Expo?

How do I take a number like 10000 and have it output as $10,000.00?
I even had a problem with String.format(...) with a Not a function error.
I followed numerous articles, all incomplete and none working. I don't need full internationalization, just the ability to format a number
You can use toFixed method for showing 2 decimal point.
let num = 1000;
console.log(num.toFixed(2)); // 1000.00
And you can use Regex like this
function currencyFormat(num) {
return '$' + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
}
console.log(currencyFormat(2665)); // $2,665.00
You can use this library react-number-format. It has these features
Prefix, suffix and thousand separator.
Custom format pattern.
Masking.
Custom formatting handler.
Format number in an input or
format as a simple text
Sample usage
<NumberFormat value={2456981} displayType={'text'} thousandSeparator={true} prefix={'$'} />
Output : $2,456,981
Edit: Sorry -this is a React.js solution - not React Native.
None of the above worked for me ... but this chap had the right idea / solution https://medium.com/#nidhinkumar/react-js-number-format-and-styling-a1a6e211e629
const numberFormat = (value) =>
new Intl.NumberFormat('en-IN', {
style: 'currency',
currency: 'INR'
}).format(value);
numberFormat(50000); //output as ₹ 50,000.00
numberFormat(10000); //output as ₹ 10,000.00
To avoid using libraries, you can use the following code
const defaultOptions = {
significantDigits: 2,
thousandsSeparator: ',',
decimalSeparator: '.',
symbol: '$'
}
const currencyFormatter = (value, options) => {
if (typeof value !== 'number') value = 0.0
options = { ...defaultOptions, ...options }
value = value.toFixed(options.significantDigits)
const [currency, decimal] = value.split('.')
return `${options.symbol} ${currency.replace(
/\B(?=(\d{3})+(?!\d))/g,
options.thousandsSeparator
)}${options.decimalSeparator}${decimal}`
}
The fastest way is to use react-number-format, as stated above, but don't forget the renderText prop so that React Native don't throw rendering error.
Follow this step:
Install. Use this command:
npm i react-number-format
Use it in your React Native app like this:
import React from 'react';
import NumberFormat from 'react-number-format';
export function ReactNativeNumberFormat({ value }) {
return (
<NumberFormat
value={value}
displayType={'text'}
thousandSeparator={true}
prefix={'$'}
renderText={formattedValue => <Text>{formattedValue}</Text>} // <--- Don't forget this!
/>
);
}
It's working good. As you can see, I ended up creating my custom component that accept value as prop so I can use it everywhere I need it. Just like this:
<View>
<ReactNativeNumberFormat value={530000} />
</View>
Hope can be useful.
PS: This is my reference => https://github.com/s-yadav/react-number-format/issues/17#issuecomment-395187806.
Use toLocaleString native React function:
const formatNumber = (q) => {
return q.toLocaleString('en-US', {
style: 'currency',
currency: 'USD'
})
}
I wrote the following number format utility recently which can be used in OP's case as well as others. It should hopefully be fairly straightforward to amend it to cover other cases (I expect most would like to change my default values for example).
type NumberFormatProps = {
value: number;
thousandSeparator?: string;
decimalSeparator?: string;
significantDigits?: number;
showTrailingZeros?: boolean;
symbol?: '$' | 'kr.' | '%'; // Add other symbols as needed
showSymbol?: boolean;
symbolPosition?: 'before' | 'after';
showSymbolSpace?: boolean;
};
/**
* Formats a number. Supports changing symbol, thousand and decimal separators and more (see props).
* #param value The value to format
* #param thousandSeparator The separator to use between thousands
* #param decimalSeparator The separator to use before decimals
* #param significantDigits The number of significant digits to show
* #param showTrailingZeros Whether to show trailing zeros for significant digits (i.e. 1,00 if significant digits is 2)
* #param symbol The symbol to use
* #param showSymbol Whether to show the symbol
* #param symbolPosition Whether to show the symbol before or after the value
* #param showSymbolSpace Whether to show a space between the symbol and the value
* #returns
*/
export const getFormattedNumber = ({
value,
thousandSeparator = '.',
decimalSeparator = ',',
significantDigits = 0,
showTrailingZeros = false,
symbol = 'kr.',
showSymbol = true,
symbolPosition = 'after',
showSymbolSpace = true,
}: NumberFormatProps) => {
const significantDigitsExponent = 10 ** significantDigits;
const valueWithSignificantDigits = showTrailingZeros
? // If significant digits is 2 then this is e.g. 1.00, 1.10, 1.11
value.toFixed(significantDigits)
: // If significant digits is 2 then this is e.g. 1, 1.1, 1.11
`${Math.round((value + Number.EPSILON) * significantDigitsExponent) / significantDigitsExponent}`;
// Split the value into the parts before and after the decimal point
const [integerPart, fractionalPart] = valueWithSignificantDigits.toString().split('.');
// Replace thousand separator in integer part
const formattedIntegerPart = `${integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator)}`;
// Add decimal separator and fractional part if needed
const formattedValue = fractionalPart
? `${formattedIntegerPart}${decimalSeparator}${fractionalPart}`
: formattedIntegerPart;
// Add symbol
if (showSymbol && Boolean(symbol)) {
const formattedValueWithSymbol =
symbolPosition === 'after' ? `${formattedValue} ${symbol}` : `${symbol} ${formattedValue}`;
return showSymbolSpace ? formattedValueWithSymbol : formattedValueWithSymbol.replace(' ', '');
}
return formattedValue;
};
In OP's case this would be called like so:
getFormattedNumber({
value: 10000,
thousandSeparator: ',',
decimalSeparator: '.',
symbol: "$",
showSymbolSpace: false,
symbolPosition: 'before',
significantDigits: 2,
showTrailingZeros: true
})
export const CurrencyFormatter = (number, options) => {
const defaultOptions = {
significantDigits: 2,
thousandsSeparator: ",",
decimalSeparator: ".",
symbol: "$",
};
const currencyFormatter = (value, options) => {
if (typeof value !== "number") value = 0.0;
options = { ...defaultOptions, ...options };
value = value.toFixed(options.significantDigits);
let valueFormatted;
if (options.significantDigits == 0) {
const [currency] = value.split(".");
valueFormatted = `${options.symbol}${currency.replace(
/\B(?=(\d{3})+(?!\d))/g,
newOptions.thousandsSeparator
)}`;
} else {
const [currency, decimal] = value.split(".");
valueFormatted = `${options.symbol}${currency.replace(
/\B(?=(\d{3})+(?!\d))/g,
options.thousandsSeparator
)}${options.decimalSeparator}${decimal}`;
}
return valueFormatted;
};
return currencyFormatter(number, options);
};
could be achieved as shown below, and you could also remove trailing 00 at the end if there is no decimals
costing= () => {
const cost= 1478.90 + 940;
return parseFloat(cost).toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
}

React Native: how can I achieve the dynamic keys with multiple objects

Here is my code I tried,
var array=[];
var list = this.state.list;
var getList = function(i){
var add = +i + 1;
return {
["value"+add]:{
Description:list[i].Description,
Length:list[i].Length,
Height:list[i].Height,
Weight:list[i].Weight,
VolumeWeight:list[i].VolumeWeight,
ActualWeight:list[i].ActualWeight,
}
}
}.bind(this)
for(var i in list){
array.push(getList(i));
}
var dataArray = array.map(function(e){
return JSON.stringify(e);
});
dataString = dataArray.join(",");
data1 = {
ConsigneeBranchName:this.state.searchText,
ConsigneeBranchCode:this.state.code,
ConsigneeBranchFullAddress:this.state.DAddress,
SenderBranchCode:this.state.code1,
SenderBranchName:this.state.searchTexts,
SenderBranchFullAddress:this.state.Address,
CreatedByEmployeeCode:id,
CreatedByEmployeeFullName:userName,
jsonString:{
JsonValues:{
id:"MyID",
values:dataString
}
}
}
But I want the result is exactly this
var result = {
"ConsigneeBranchName":"",
"ConsigneeBranchCode":"",
"ConsigneeBranchFullAddress":"",
"SenderBranchCode":"",
"SenderBranchName":"",
"SenderBranchFullAddress":"",
"CreatedByEmployeeCode":"",
"CreatedByEmployeeFullName":"",
"jsonString":"{
"JsonValues": {
"id": "MyID",
"values": {
"value1":{
"Description”:"testSmarter1",
"Length”:"60",
"Height”:"50",
"Weight”:"70",
"VolumeWeight”:"75",
"ActualWeight”:”78"
},
"value2:{
"Description":"Documents",
"Length":"120",
"Height":"68",
"Weight":"75",
"VolumeWeight":"122.4",
"ActualWeight":"123"
},
}
}
}
};
Please any one help me
I want the object with dynamic keys within a single object {key1:{des:1,value:as},key2:{des:2,value:aw},key3:{des:3,value:au}}
can you please help me I have tried so many times
see this below image I want this part, inside the single object, I can join multiple objects with dynamic keys
lodash already has a function called keyBy, you can use it to get this functionality. If adding lodash doesn't make sense in your project.
I have implemented a vanilla JS version.
function keyBy(array, mapperFn) {
const resultObj = {};
array.map(item => resultObj[mapperFn(item)] = item);
return resultObj;
}
function arrayToObject (array, keyName = 'id') {
return keyBy(array, function(element) {return element[keyName]});
}
API:
arrayToObject(targetArray, stringNameOfThePorpertyYouWantToUseAsKey);
USAGE:
const listOfUsers = [{name: 'Jenitha', reputation: 6}, {name: 'Chandan', reputation: 3}];
const mapOfUsersByName = arrayToObject(listOfUsers, 'name');

dojo 1.8: populate select box with items from database including null values

Hi I just want to populate the select or comboBox.
I am able to populate both with the searchAttr to any string from JSON. But not so when there are null values.
JSON string :
[{"batch":"0000001000"},{"batch":"0000"},{"batch":""},{"batch":null}]
dojo code:
var selBatch = new ComboBox //located at the left side of the page and it is the second select box in a row
(
{ id:'ID_selBatch',
value:'',
searchAttr:'batch',
placeHolder:'Select...',
style:{width:'150px'},
}, 'node_selBatch'
);
on(selTest, 'change', function(valueCard)
{
var selectedTest = this.get('displayedValue');
var selBatch = registry.byId('ID_selBatch');
console.debug('Connecting to gatherbatches.php ...');
request.post('gatherbatches.php',
{ data:{nameDB:registry.byId('ID_selPCBA').value, nameCard : valueCard},
handleAs: "json"}).then
(
function(response)
{
var memoStore2 = new Memory({data:response});
selBatch.set('store', memoStore2);
selBatch.set('value','');
console.debug('List of batches per Test is completed! Good OK! ');
},
function(error)
{
alert("Batch's Error:"+error);
console.debug('Problem: Listing batches per Test in select Test is BAD!');
}
);
selBatch.startup();
});
Error :
TypeError: _32[this.searchAttr] is null
defer() -> _WidgetBase.js (line 331)
_3() -> dojo.js (line 15)
_f.hitch(this,fcn)(); -> _WidgetBase.js (line 331)
Please advise though it might strange to have null values populate in the select box but these null values are related to data in other columns in database, so the null values included so that I can apply mysql scripts later. Or do you have other better suggestion?
Clement
You can create a QueryFilter as in this jsfiddle to achieve what you want, but it might be simpler to have two data items. Your original model with possibly null batch properties, and the model you pass to the store which is used by the ComboBox.
But anyway, this can work:
function createQueryFilter(originalQuery, filter) {
return function () {
var originalResults = originalQuery.apply(this, arguments);
var results = originalResults.filter(filter);
return QueryResults(results);
};
}
and
var memoStore = new Memory({
data: data
});
memoStore.query = createQueryFilter(memoStore.query, function (item) {
console.log(item);
return !!item.batch;
});
and the dummy data:
function createData1() {
var data = [];
for (var i = 0; i < 10; i++) {
data.push({
name: "" + i,
batch: (0 === i % 2) ? "batch" + i : null
});
}
return data;
}
Screenshot. The odd numbered batch items are null in my example.

Custom data source with WinJS?

I am currently implementing a custom data source in a Windows8 application. However, I got some trouble with it: no data is displayed.
First, here is the code:
var dataArray = [
{ title: "Basic banana", text: "Low-fat frozen yogurt", picture: "images/60banana.png" },
// Other data taken from Windows8 ListView quick start
{ title: "Succulent strawberry", text: "Sorbet", picture: "images/60strawberry.png" }
];
var searchAdDataAdapter = WinJS.Class.define(
function () {}, // Constructor
{
itemsFromIndex: function (requestIndex, countBefore, countAfter) {
var that = this;
if (requestIndex >= that._maxCount) {
return WinJS.Promise.wrapError(new WinJS.ErrorFromName(UI.FetchError.doesNotExist));
}
var fetchSize, fetchIndex;
// See which side of the requestIndex is the overlap.
if (countBefore > countAfter) {
// Limit the overlap
countAfter = Math.min(countAfter, 10);
// Bound the request size based on the minimum and maximum sizes.
var fetchBefore = Math.max(
Math.min(countBefore, that._maxPageSize - (countAfter + 1)),
that._minPageSize - (countAfter + 1)
);
fetchSize = fetchBefore + countAfter + 1;
fetchIndex = requestIndex - fetchBefore;
} else {
countBefore = Math.min(countBefore, 10);
var fetchAfter = Math.max(Math.min(countAfter, that._maxPageSize - (countBefore + 1)), that._minPageSize - (countBefore + 1));
fetchSize = countBefore + fetchAfter + 1;
fetchIndex = requestIndex - countBefore;
}
// Create an array of IItem objects:
// results =[{ key: key1, data : { field1: value, field2: value, ... }}, { key: key2, data : {...}}, ...];
for (var i = 0, itemsLength = dataArray.length ; i < itemsLength ; i++) {
var dataItem = dataArray[i];
results.push({
key: (fetchIndex + i).toString(),
data: dataArray[i]
});
}
// Get the count.
count = dataArray.length;
return {
items: results, // The array of items.
offset: requestIndex - fetchIndex, // The index of the requested item in the items array.
totalCount: count
};
},
getCount: function () {
return dataArray.length;
}
}
);
var searchAdDataSource = WinJS.Class.derive(WinJS.UI.VirtualizedDataSource, function () {
this._baseDataSourceConstructor(new searchAdDataAdapter());
});
// Create a namespace to make the data publicly
// accessible.
var publicMembers = {
itemList: new searchAdDataSource()
};
WinJS.Namespace.define("DataExample", publicMembers);
I know the code is a little bit long, but the major part of it is taken from official Microsoft custom data source quick start.
I tried to debug it, but it seems the code contained in itemFromIndex is never used (my breakpoint is never reached).
The HTML code is:
<div id="basicListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : DataExample.itemList.dataSource}">
</div>
I do not use any template for the moment, to simplify the code as more as I can. Data are normally displayed in text this way (but nothing appears).
Have one of this great community any idea?
Furthermore, I do not understand the countBefore and countAfter parameters, even with the documentation. Can somebody explain it to me with other words?
Thanks a lot! :)
Try modifying your HTML code to the following:
<div id="basicListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : DataExample.itemList}">
</div>
No need to call the .datasource member, as you are talking to the datasource directly.