Remove detailPanel based in condition causes padding - html

Everyone, I'm trying to add detailPanel based in a condition, it leaves a space when I hide it like this
Link
And This Code works fine when I provide detail panel
get rowDetailsPanel() {
const { detailPanel, classes } = this.props;
// #Workarround To Hide Details Panel In Case There is No Details Panels Provided
return [
{
tooltip: 'Show Name',
disabled: !detailPanel,
icon: () => <ChevronRightIcon className={!detailPanel && classes.displayNone}/>,
render: rowData => detailPanel(rowData)
},
];
}
Link for working detailPanel,
So what I'm trying to do is when I hide the detailPanel, I want to delete the whole column
Any clue will be appreciated

This should work:
get rowDetailsPanel() {
const { detailPanel, classes } = this.props;
// #Workarround To Hide Details Panel In Case There is No Details Panels Provided
return detailPanel ? [
{
tooltip: 'Show Name',
disabled: !detailPanel,
icon: () => <ChevronRightIcon className={!detailPanel && classes.displayNone}/>,
render: rowData => detailPanel(rowData)
},
] : undefined;

Related

React Beautiful DnD, multiple columns inside single droppable

I am trying to have a grid column layout, (2 columns) inside a single droppable container. The project is for an online menu where you can create a menu item, which goes into a droppable container, then you can drag that onto the menu that will be displayed to the user. So there is currently two columns. However the style of the menu demands two columns. Currently I am assigning different classNames to the mapped columns so I can make one of them grid but its pretty messy. Maybe there is a way I can hardcode the droppable instead of map them and run the map on the lists themselves inside each of the hardcoded droppables? Sorry if this is confusing, it sure is for me.
'results' is API data that is initially mapped into savedItems array where newly created menu items will go. Later on menuItems array will pull from the database as well. Right now just trying to have better styling control over the different droppables.
you can see where im assigning different classNames to the droppable during the mapping and its really not a reliable option.
//drag and drop states
const [state, setState] = useState({
menuItems: {
title: "menuItems",
items: []
},
savedItems: {
title: "savedItems",
items: results
}
})
useEffect(() => {
setState({ ...state, savedItems: { ...state.savedItems, items: results } })
}, [results])
// console.log("state", state)
console.log("dummy data", dummyArry)
// updating title graphql mutation
const [elementId, setElementId] = useState(" ");
const updateTitle = async () => {
//api data
const data = await fetch(`http://localhost:8081/graphql`, {
method: 'POST',
body: JSON.stringify({
query: `
mutation {
updateMenu(menuInput: {_id: ${JSON.stringify(elementId)},title: ${JSON.stringify(inputValue)}}){
title
}
}
`
}),
headers: {
'Content-Type': 'application/json'
}
})
//convert api data to json
const json = await data.json();
}
//drag end function
const handleDragEnd = (data) => {
console.log("from", data.source)
console.log("to", data.destination)
if (!data.destination) {
// console.log("not dropped in droppable")
return
}
if (data.destination.index === data.source.index && data.destination.droppableId === data.source.droppableId) {
// console.log("dropped in same place")
return
}
//create copy of item before removing from state
const itemCopy = { ...state[data.source.droppableId].items[data.source.index] }
setState(prev => {
prev = { ...prev }
//remove from previous items array
prev[data.source.droppableId].items.splice(data.source.index, 1)
//adding new item to array
prev[data.destination.droppableId].items.splice(data.destination.index, 0, itemCopy)
return prev
})
}
const columnClass = [
"menuItems-column",
"savedItems-column"
]
let num = 0
return (
<>
<div className='app'>
{results && <DragDropContext onDragEnd={handleDragEnd}>
{_.map(state, (data, key) => {
return (
<div key={key} className='column'>
<h3>{data.title}</h3>
<Droppable droppableId={key}>
{(provided, snapshot) => {
return (
<div
ref={provided.innerRef}
{...provided.droppableProps}
className={columnClass[num]}
// className="droppable-col"
><span className='class-switch'>{num++}</span>
{data.items.map((el, index) => {
return (
<Draggable key={el._id} index={index} draggableId={el._id}>
{(provided) => {
return (
<div className='element-container'
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div contentEditable="true">
{el.title}
</div>
</div>
)
}}
</Draggable>
)
})}
{provided.placeholder}
</div>
)
}}
</Droppable>
</div>
)
})}
</DragDropContext>}
</div>
</>
)
}

how can I update the number of columns in angular-datatables with server-side rendering. version 6.0.0 or higher

I am having trouble getting my angular-datatable to show a new column list after a rerender. I have followed the example shown in the docs for rerendering and I can get the table to rerender. I am able to manipulate certain features like searching and pageLength, but for some reason I cannot get my columns to change.
I have a very deep data set that would make my table look awful if I rendered all the columns at once, so I would like to give users the ability to select which columns they see.
I would even be open to loading in all the columns at once and just switching visibility off and on, but I cannot effect visibility either.
Has anyone had this issue before?
Rerender function:
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
// these work
this.dtOptions.searching = true;
this.dtOptions.pageLength = 2;
// these do not
this.dtOptions.columns = newColumnList;
this.dtOptions.columns[some-index].visible = false;
this.dtTrigger.next();
});}
Initial dtOptions:
this.dtOptions = {
searching: false,
pagingType: 'full_numbers',
pageLength: 10,
retrieve: true,
serverSide: true,
processing: true,
language: {
zeroRecords: 'Nothing Found'
},
ajax: (dataTablesParameters: any, callback) => {
const payload = this.passFilterService.processPagination(this.filter, dataTablesParameters);
this.http
.post<any>(
environment.api + '/things/list',
{payload: payload}, {}
).subscribe(resp => {
if (resp.data.data === null) {
resp.data.data = 0;
}
callback({
recordsFiltered: resp.data.totalCount,
data: resp.data.data,
recordsTotal: resp.data.totalCount
});
});
},
columns: this.tableColumns
};
Initial Columns (limited fields):
tableColumns = [
{
title: 'Customer',
data: 'Id',
render: function(data) {
return `Action`;
}
}, {
title: 'Created',
data: 'createdAt',
orderable: true,
visible: true,
}, {
title: 'Updated',
data: 'updatedAt',
orderable: true,
visible: true,
}, {
title: 'Disabled',
data: 'isVoided',
orderable: true,
visible: true,
}
];
Table implementation:
<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
</table>
I faced the same issue, spent hours debugging it until I found something that worked for me. I will advice separating the DT config into an independent object that can be loaded separately. Once you update your DT options and any other config, you can use the functions below to reload the entire DT, destroying and reloading it accordingly;
async rerender(newSettings?: DataTables.Settings) {
try {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
if (newSettings) {
// FIX To ensure that the DT doesn't break when we don't get columns
if (newSettings.columns && newSettings.columns.length > 1) {
dtInstance.destroy();
this.dtOptions = Promise.resolve(newSettings);
this.displayTable(this.dtTableElement);
}
}
});
} catch (error) {
console.log(`DT Rerender Exception: ${error}`);
}
return Promise.resolve(null);
}
This function calls the below one to actually destroy the DT and rerender it.
private displayTable(renderIn: ElementRef): void {
this.dtElement.dtInstance = new Promise((resolve, reject) => {
Promise.resolve(this.dtOptions).then(dtOptions => {
// Using setTimeout as a "hack" to be "part" of NgZone
setTimeout(() => {
$(renderIn.nativeElement).empty();
var dt = $(renderIn.nativeElement).DataTable(dtOptions);
// this.dtTrigger.next();
resolve(dt);
});
}).catch(error => reject(error));
});
}
I removed the dtTrigger execution from the reconstruction function as this was executing twice.
The dtTableElement is defined as #ViewChild('dtTableElement') dtTableElement: ElementRef; where the HTML contains the respective reference on the datatable as:
<table #dtTableElement datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="table table-striped row-border hover" width="100%"></table>

How to use treeview with angular ui grid

Ho guys, i'm using angular ui grid in my project..heres my code :
$scope.gridOptions = {
enableSorting: false,
enableRowSelection: true,
multiSelect: false,
exporterMenuCsv: false,
// enableGridMenu: true,
enableSelectAll: true,
enableColumnResizing: true,
enableSorting: true,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi; //set gridApi on scope
gridApi.core.on.renderingComplete($scope, function () {
$timeout(function () {
var gridBodyElem = document.getElementById(gridApi.grid.id + '-grid-container');
gridBodyElem.addEventListener('mouseup', handleGridClick);
});
});
},
columnDefs: [
{ field: 'name',displayName:'Name',cellClass: 'gridField'},
{ field: 'uniqueid',displayName:'ID',cellClass: 'gridField'},
{ field: 'devicetime',displayName:'GPS DATE',cellClass: 'gridField'},
{ field: 'adress',displayName:'Adresse',cellClass: 'gridField'},
{ field: 'company',displayName:'Company',cellClass: 'gridField'}
]
};
it works good but i want to use a treeview in this grid to obtain like this table grid below..
what i want exacly is, when i click on item, i want to show a html code below like the image above...is there anyone has any idea how to do this..??
Example controller :
var SomeController = function () {
this.customHtml = '<ul><li>render me please</li></ul>';
}
Example view :
<div ng:bind="customHtml"></div>
Gives :
<div>
"<ul><li>render me please</li></ul>"
</div>

Sencha Touch searchable list -- new view with data proxy

Two quick questions here... How can I use this example
http://try.sencha.com/touch/2.0.0/examples/list-search/
of a searchable list, but opened in a NEW view? The example has it defined as the main application in app.js, but I would like to use it in "FirstApp.view.searchlist"
I know the answer is pretty easy but I am still a young grasshoppa and need a push in the right direction.
Also, rather than pulling the data from the embedded store like the example, I would like to modify it to pull my data from my external/proxy JSON store, which is defined as follows:
Store:
Ext.define('FirstApp.store.StudentStore',{
extend:'Ext.data.Store',
config:{
autoLoad:true,
model:'FirstApp.model.people',
sorters: 'lastName',
proxy:{
type:'ajax',
url:'http://xxxyyyzzz.com/data/dummy_data.json',
reader:{
type:'json',
rootProperty:'results'
}
}
}
});
Model:
Ext.define('FirstApp.model.people', {
extend: 'Ext.data.Model',
config: {
fields: ['firstName', 'lastName' , 'image','status', 'phone','rank','attendance', 'discipline','recent']
}
});
So, how can I turn that example into a "view" inside my application, with my data store and model?
Any help is greatly appreciated! Thank you!
Jake
-----------UPDATE-------------
Ok fantastic. I was able to implement the search feature (stoked) by combining your methods with another tutorial I found. Now one more question...Seems so easy but it is tough! How can I open my new 'Details' view once an item is selected/clicked ??
Search list:
Ext.define('FirstApp.view.MainPanel', {
extend: 'Ext.dataview.List',
alias : 'widget.mainPanel',
config: {
store : 'Students',
itemTpl:
'<h1>{firstName:ellipsis(45} {lastName:ellipsis(45)}</h1>' ,
itemCls:'place-entry',
items: [
{
xtype: 'toolbar',
docked: 'top',
items: [
{
xtype: 'searchfield',
placeHolder: 'Search People...',
itemId: 'searchBox'
}
]
}
]
}
});
Details view (that I want to open when name is clicked from Search list/Mainpanel view):
Ext.define('FirstApp.view.Details',{
extend:'Ext.Panel',
xtype:'details',
config:{
layout:'fit',
tpl:'<div class="image_container"><img src="{image}"></div>' +
'<h1>{firstName:ellipsis(25)} {lastName:ellipsis(25)}</h1>'+
'<div class="status_container">{status:ellipsis(25)}</div> '+
'<div class="glance_container"> <div class="value_box"><div class="value_number"> {rank:ellipsis(25)}</div> <p class="box_name">Rank</p> </div> <div class="value_box"><div class="value_number"> {attendance:ellipsis(25)}</div> <p class="box_name" style="margin-left: -10px;">Attendance</p> </div> <div class="value_box"><div class="value_number">{discipline:ellipsis(25)}</div> <p class="box_name" style="margin-left: -4px;">Discipline</p> </div> <div class="value_box"><div class="value_number"> {recent:ellipsis(25)}</div> <p class="box_name">Recent</p> </div> </div> '+
'<h2>Phone:</h2> <div class="phone_num"><p>{phone:ellipsis(25)}</p></div>'+
'<h3>Some info:</h3><p>Round all corners by a specific amount, defaults to value of $default-border-radius. When two values are passed, the first is the horizontal radius and the second is the vertical radius.</p>',
scrollable:true,
styleHtmlContent:true,
styleHtmlCls:'details'
}
})
Search Controller:
Ext.define('FirstApp.controller.SearchController', {
extend : 'Ext.app.Controller',
config: {
profile: Ext.os.deviceType.toLowerCase(),
stores : ['StudentStore'],
models : ['people'],
refs: {
myContainer: 'MainPanel',
placesContainer:'placesContainer'
},
control: {
'mainPanel': {
activate: 'onActivate'
},
'mainPanel searchfield[itemId=searchBox]' : {
clearicontap : 'onClearSearch',
keyup: 'onSearchKeyUp'
},
'placesContainer places list':{
itemtap:'onItemTap'
}
}
},
onActivate: function() {
console.log('Main container is active');
},
onSearchKeyUp: function(searchField) {
queryString = searchField.getValue();
console.log(this,'Please search by: ' + queryString);
var store = Ext.getStore('Students');
store.clearFilter();
if(queryString){
var thisRegEx = new RegExp(queryString, "i");
store.filterBy(function(record) {
if (thisRegEx.test(record.get('firstName')) ||
thisRegEx.test(record.get('lastName'))) {
return true;
};
return false;
});
}
},
onClearSearch: function() {
console.log('Clear icon is tapped');
var store = Ext.getStore('Students');
store.clearFilter();
},
init: function() {
console.log('Controller initialized');
},
onItemTap:function(list,index,target,record){ // <-----NOT WORKING
this.getPlacesContainer().push({
xtype:'details',
store:'Students',
title:record.data.name,
data:record.data
})
}
});
Good question. I assume you are trying to build a List or dataview. The key here is to give your store a 'storeId'. I have modified your store below:
Ext.define('FirstApp.store.StudentStore',{
extend:'Ext.data.Store',
config:{
storeId: 'Students', // Important for view binding and global ref
autoLoad:true,
model:'FirstApp.model.people',
sorters: 'lastName',
proxy:{
type:'ajax',
url:'http://xxxyyyzzz.com/data/dummy_data.json',
reader:{
type:'json',
rootProperty:'results'
}
}
}
});
Then inside your view, you reference the store to bind to. Here is an example List view from one of my applications. Notice the config object has 'store' which references our above store:
Ext.define('app.view.careplan.CarePlanTasks', {
extend: 'Ext.dataview.List',
xtype: 'careplanTasks',
requires: [
'app.view.template.CarePlan'
],
config: {
store: 'Students', // Important! Binds this view to your store
emptyText: 'No tasks to display',
itemTpl: Ext.create('app.view.template.CarePlan'),
},
constructor : function(config) {
console.log('CarePlan List');
this.callParent([config]);
}
});
Now that you have a storeId, you can access this store anywhere in your application by doing the following:
Ext.getStore('Students')
You can load records from your server by calling the load method as well:
Ext.getStore('Students').load();
You can do this anywhere in your application, but typically it's best to do in your controllers.
Hope this helps.
======= Updates to your updates ======
So looking at your code I think you need to modify your List view and the controller. Give 'FirstApp.view.MainPanel' an xtype: 'MainPanel'. Next modify your controller config as follows:
config: {
profile: Ext.os.deviceType.toLowerCase(),
stores : ['StudentStore'],
models : ['people'],
refs: {
mainPanel: 'MainPanel', // set the object KEY to the name you want to use in the control object and set the VALUE to the xtype of the view
placesContainer:'placesContainer'
},
control: {
'mainPanel': { // this matches the key above, which points to your view's xtype
activate: 'onActivate',
itemtap: 'onItemTap' // listen for the item tap event on this List
},
'mainPanel searchfield[itemId=searchBox]' : {
clearicontap : 'onClearSearch',
keyup: 'onSearchKeyUp'
},
'placesContainer places list':{
itemtap:'onItemTap'
}
}
},

How to insert a radio group inside data-grid?

I have a rough model of my application which looks some like as shown in picture below:
I am using jquery easyui data-grid framework to get this but i am not able to insert radio group type as one of my column as shown in Status column of my picture. Can anyone please help me how to insert radio button inside data-grid table? And other thing is, is the datagrid is only way to get these type of functions or any other way through which we can get same thing? If anyone know any other way please help me.
Thank you.
I am using easyui grid and other components too. You can use easyui datagrid's formatter property look here
On formatter property you can add any innerHTML like radiobuttons,buttons,labels etc to datagridcolumns.Look my example below, I am using this sample on my project;
var btnid="";
FILL_TESTGRID: function (_data) {
try {
$('#TestGrid').datagrid({
singleSelect: true,
remoteSort: false,
fitcolumns: true,
nowrap: false,
columns: [[
{ field: 'ID', title: 'ID', sortable: true },
{ field: 'NAME', title: 'NAME', sortable: true },
{ field: 'action', title: 'ColumntTitle3', formatter: function (value, row, index) {
var col;
if (row.ID!= null) {
col = '<input type="button" id="Btn'+row.ID+'" onclick="TestFunc(' + row.ID + ')" value="Add" class="GridButton"/>';
btnid = "Btn"+row.ID; //set to a global for getting out grid
}
return col;
}
}
]]
}
catch (err) {
alert(err)
}
}
}
document.getElemntById(btnid); //getting button, radio or text (value,checked etc)