ShieldUI Grid Multiple CustomEditors - shieldui

i am wondering if anybody has used two or more shieldui grid custom editors on the same page. How would this work with the getCustomEditorValue function (updated with their stock example)? I am guessing that i need to do something inside of the getCustomEditorValue function to differentiate the 2 dropdowns?
$("#grid1").shieldGrid({
dataSource: {
data: products,
schema: {
fields: {
id: { path: "ProductID", type: Number},
name: { path: "ProductName", type: String, nullable: false },
quantity: { path: "SupplierID", type: Number },
price: { path: "UnitPrice", type: Number },
price2: { path: "UnitPrice2", type: Number },
units: { path: "UnitsInStock", type: Number },
discontinued: { path: "Discontinued", type: Boolean },
myDate: { path: "d", type: Date }}}
},
events: {
editorCreating: function(e) {
if (e.field == "price") {
e.options = { max: 50 };
}
}
},
rowHover: false,
columns: [
{ field: "id" },
{ field: "name", width: "200px" },
{ field: "quantity" },
{ field: "price", editor: myCustomEditor },
{ field: "price2", editor: myCustomEditor2 },
{ field: "units" },
{ field: "discontinued" },
{ field: "myDate", format: "{0:MM/dd/yyyy}" }
],
events: {
getCustomEditorValue: function (e) {
e.value = $("#test").swidget().value();
$("#test").swidget().destroy();
}
},
editing: {
enabled: true,
event: "doubleclick
type: "cell"
}
});
function myCustomEditor(cell, item) {
$('<div id="test"/>')
.appendTo(cell)
.shieldDropDown({
dataSource: {
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
},
value: !item["price"] ? null : item["price"].toString()
}).swidget().focus();
}
function myCustomEditor2(cell, item) {
$('<div id="test2"/>')
.appendTo(cell)
.shieldDropDown({
dataSource: {
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
},
value: !item["price2"] ? null : item["price2"].toString()
}).swidget().focus();
}

Thanks to support for the answer:
getCustomEditorValue: function (e) {
if ($("#dropdown1").length > 0) {
e.value = $("#dropdown1").swidget().value();
$("#dropdown1").swidget().destroy();
}
if ($("#dropdown2").length > 0) {
e.value = $("#dropdown2").swidget().value();
$("#dropdown2").swidget().destroy();
}
}

Related

Handling relational data in Zustand

I need some input from people more experienced with Zustand to share their way of managing relational state. Currently we have the following:
Let's assume we have the example entities Campaign, Elementss and their Settings. The REST API returning them is in the following format:
GET <API>/campaigns/1?incl=elements,elements.settings
{
"id":1,
"name":"Welcome Campaign",
"elements":[
{
"id":5,
"type":"heading",
"label":"Heading",
"content":"Welcome!",
"settings":[
{
"id":14,
"name":"backgroundColor",
"value":"#ffffff00"
},
{
"id":15,
"name":"color",
"value":"#ffffff00"
}
]
},
{
"id":6,
"type":"button",
"label":"Button",
"content":"Submit",
"settings":[
{
"id":16,
"name":"backgroundColor",
"value":"#ffffff00"
},
{
"id":17,
"name":"color",
"value":"#ffffff00"
},
{
"id":18,
"name":"borderRadius",
"value":"3px"
}
...
]
}
...
]
}
What we are currently doing in the Reactjs app is fetching this data, then transforming it to the following normalized format and set functions:
const useCurrentCampaignStore = create(
combine(
{
campaign: {
id: 1,
name: "Welcome Campaign"
},
elements: [
{
id: 5,
campaignId: 1,
type: "heading",
label: "Heading",
content: "Welcome!"
},
{
id: 6,
campaignId: 1,
type: "button",
label: "Button",
content: "Submit"
}
],
settings: [
{
id: 14,
elementId: 5,
name: "backgroundColor",
value: "#ffffff00"
},
{
id: 15,
elementId: 5,
name: "color",
value: "#ffffff00"
},
{
id: 16,
elementId: 6,
name: "backgroundColor",
value: "#ffffff00"
},
{
id: 17,
elementId: 6,
name: "disabled",
value: false
},
{
id: 18,
elementId: 6,
name: "borderRadius",
value: 3,
}
]
},
set => ({
updateSetting: (id: string | number, newValue: string | number | boolean) =>
set(state => {
const settings = [...state.settings];
return {
...state,
settings: settings.map(setting => {
if (setting.id == id) {
return { ...setting, value: newValue };
}
return setting;
})
};
}),
updateElementContent: (id: string | number, newValue: string) => {
set(state => {
const elements = [...state.elements];
return {
...state,
elements: elements.map(element => {
if (element.id == id) {
return { ...element, content: newValue };
}
return element;
})
};
});
}
})
)
);
I am, however, not sure this is the optimal solution, because It's rather tedious transforming all GET requests to a normalized format and then converting them back to nested objects when you want to construct either a POST, PUT or PATCH request.
So, to put it short, how do you guys design the state in your Zustand-based RESTful-API-backed React apps?

covert list into another new list with new property name

I have one list look like allsettings. I want to convert that list to a new list. Since I am new to react I don't have much idea, I tried by doing the below way but 1st item in the new list is always empty.
const [mySetting, setMySet] = useState([]);
useEffect(() => {
const allSettings = [
{ name: "Setting1", value: true, label: 1 },
{ name: "Setting2", value: true, label: 2 },
{ name: "Setting3", value: true, label: 3 },
{ name: "Setting4", value: false, label: 4 },
{ name: "Setting5", value: true, label: 5 },
{ name: "Setting6", value: true, label: 6 },
{ name: "Setting7", value: true, label: 7 }
];
const settings = [];
const allSettingsMap = allSettings.reduce((resMap, current) => {
settings.push(resMap);
return {
...resMap,
SettingID: current.label,
Name: current.name,
value: current.value
};
}, {});
setMySet(settings);
}, []);
//I want new list like this:
const newSettings = [
{ name: "Setting1", value: true, SettingID: 1 },
{ name: "Setting2", value: true, SettingID: 2 },
{ name: "Setting3", value: true, SettingID: 3 },
{ name: "Setting4", value: false, SettingID: 4 },
{ name: "Setting5", value: true, SettingID: 5 },
{ name: "Setting6", value: true, SettingID: 6 },
{ name: "Setting7", value: true, SettingID: 7 }
];
You can use array#map to rename a key in your object and keeping other keys intact. For each object, you can pick label and rename it to SettingID and keep other key-values same.
const allSettings = [ { name: "Setting1", value: true, label: 1 }, { name: "Setting2", value: true, label: 2 }, { name: "Setting3", value: true, label: 3 }, { name: "Setting4", value: false, label: 4 }, { name: "Setting5", value: true, label: 5 }, { name: "Setting6", value: true, label: 6 }, { name: "Setting7", value: true, label: 7 } ],
result = allSettings.map(({label, ...other}) => ({...other, SettingID: label}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can easily do it by map on array
const allSettings = [
{ name: "Setting1", value: true, label: 1 },
{ name: "Setting2", value: true, label: 2 },
{ name: "Setting3", value: true, label: 3 },
{ name: "Setting4", value: false, label: 4 },
{ name: "Setting5", value: true, label: 5 },
{ name: "Setting6", value: true, label: 6 },
{ name: "Setting7", value: true, label: 7 }
];
const newAllSettings = allSettings.map(item => {
return {
name: item.name,
value: item.value,
SettingID:item.label
};
});
console.log(newAllSettings)
Replace your allSettings.reduce method with this map method
const settings = [];
allSettings.map((setting) => {
const item = { ...setting };
const tempValue = item?.label;
// delete item label
delete item["label"];
item["SettingID"] = tempValue;
settings.push(item);
});

react-graph-vis - Grapg is not re rendering even ofter state changes

When I try to update the state on the hover event, the actual state value is getting changed but the graph is not re-rendering.
in the console, I am able to see the node label is changed to sample. but the graph is not rerendering.
Here is my react function based component.
import React, { useEffect, useState } from 'react';
import Graph from 'react-graph-vis';
import './vis-network.css';
function RelationGraph1() {
const [graph, setGraph] = useState({
nodes: [
{
id: 1,
label: 'Node 1',
title: '',
},
{ id: 2, label: 'Node 2', title: '' },
{ id: 3, label: 'Node 3', title: '' },
{ id: 4, label: 'Node 4', title: '' },
{ id: 5, label: 'Node 5', title: '' },
],
edges: [
{ from: 1, to: 2 },
{ from: 1, to: 3 },
{ from: 2, to: 4 },
{ from: 2, to: 5 },
],
});
const options = {
layout: {
hierarchical: false,
},
edges: {
color: '#1D1D1D',
},
interaction: {
hover: true,
navigationButtons: true,
tooltipDelay: 0,
},
nodes: {
borderWidth: 0,
borderWidthSelected: 0,
color: '#0262C4',
shape: 'circle',
size: 1,
shadow: {
enabled: true,
color: 'rgba(0,0,0,0.5)',
size: 10,
x: 5,
y: 5,
},
font: {
color: '#fff',
size: 13,
bold: {
mod: 'bold',
},
},
},
};
const events = {
select: function (event) {
var { nodes, edges } = event;
console.log('Selected nodes:');
console.log(nodes);
console.log('Selected edges:');
console.log(edges);
},
showPopup: (id) => { // node id
const data = graph.nodes.map((el) => {
if (el.id === id) {
el.label = `sample node name`;
}
return el;
});
setGraph({ ...graph, nodes: data });
},
};
return (
<Graph
graph={graph}
options={options}
events={events}
style={{ height: '450px' }}
/>
);
}
export default RelationGraph1;
Really Appriciate for the help. Thanks !
I was able to update the label in hoverNode event like this:
hoverNode: (e) => {
const data = graph.nodes.map((el) => {
if (el.id === e.node) return { ...el, label: "sample node name" };
else return el;
});
const temp = { ...graph };
temp.nodes = data;
setGraph(temp);
},
Sample: https://codesandbox.io/s/long-bird-4h444?file=/src/App.js:1235-1501

How to customize each column in Highcharts stacked column

Hi I need to customize each column in highcharts stacked column
like this image
I this implementation i have given like this
{
categories:["6-7","7-8"]
series: [{
name: 'pass',
data: [5, 3, 4, 7, 2]
}, {
name: 'Fail',
data: [2, 2, 3, 2, 1]
}]
}
But now I need to change this implementation and i have to customize each column and add categories
how do i achieve this i'm having a array like this
[{"pass":2,"fail":3,"category":"6-7","percentage":"20%"}
{"pass":5,"fail":0,"category":"7-8","percentage":"10%"}]
i wanted like this
|percentage|
------------
| pass |
| fail |
-----------------
category
You need to preprocess your data to create series structure required by Highcharts. The 'category' label is achievable by using name property and 'percentage' by stack-labels formatter:
var data = [{
"pass": 2,
"fail": 3,
"category": "6-7",
"percentage": "20%"
}, {
"pass": 5,
"fail": 0,
"category": "7-8",
"percentage": "10%"
}];
var series = [{
name: 'Pass',
data: []
}, {
name: 'Fail',
data: []
}];
data.forEach(function(dataObj) {
series[0].data.push({
y: dataObj.pass,
name: dataObj.category,
percentage: dataObj.percentage
});
series[1].data.push({
y: dataObj.fail,
name: dataObj.category
});
});
Highcharts.chart('container', {
chart: {
type: 'column'
},
xAxis: {
type: 'category'
},
yAxis: {
stackLabels: {
enabled: true,
formatter: function() {
return this.axis.series[0].options.data[this.x].percentage;
}
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: series
});
Live demo: http://jsfiddle.net/BlackLabel/nfbq2soe/
API Reference: https://api.highcharts.com/highcharts/yAxis.stackLabels.formatter

Angular 2 pipe to filter grouped arrays

I have a group of arrays on my Angular2 app that I use to build a grouped list with *ngFor in my view:
[
{
category: 1,
items: [{ id: 1, name: "helloworld1" }, { id: 2, name: "helloworld2" }]
},
{
category: 2,
items: [{ id: 3, name: "helloworld3" }, { id: 4 }]
},
{
category: 3,
items:[{ id: 5 }, { id: 6 }]
}
]
I also have a boolean that when it's true should filter only the items that have the name property. If a group does not have any item that matches this condition it should not pass. So the result would be the following if the boolean is true:
[
{
category: 1,
items: [{ id: 1, name: "helloworld1" }, { id: 2, name: "helloworld2" }]
},
{
category: 2,
items: [{ id: 3, name: "helloworld3" }]
}
]
How can I implement a pipe to achieve this kind of result?
http://plnkr.co/edit/je2RioK9pfKxiZg7ljVg?p=preview
#Pipe({name: 'filterName'})
export class FilterNamePipe implements PipeTransform {
transform(items: any[], checkName: boolean): number {
if(items === null) return [];
let ret = [];
items.forEach(function (item) {
let ret1 = item.items.filter(function (e) {
return !checkName || (checkName && (e.name !== undefined));
});
if(ret1.length > 0) {
item.items = ret1;
ret.push(item);
}
});
return ret;
}
}

Resources