Can u help me customizing node and relative css of AllouUI DiagramBuilder ?
After a few attempts and thanks above all to the help of the previous posts on the same tool
AlloyUI (diagram-builder) extends
Add custom node to Alloyui DiagramBuilder in JAVA
How to add custom nodes and properties to AlloyUI diagram builder
I managed to create new custom nodes but CSS doesn't work as I expect:
If I modify the NAME attribute of the node, obtaining the application of the style defined by the CSS sheet (only the color at the moment) but I lose
enabling the Settings tab.
If I extend the css class diagram-node (.diagramnode;) with the desired background, the change is ignored.
JS:
<script type="text/javascript">
YUI().use('aui-diagram-builder',
function(Y) {
//definizione del nuovo DropDown
Y.CustomDropDownCellEditor = Y.Component
.create({
NAME : 'CustomDropDownCellEditor',
EXTENDS : Y.DropDownCellEditor
});
//definizione del nuovo nodo
Y.DiagramNodeCustomWithDropDown = Y.Component
.create({
NAME : 'diagram-node',
ATTRS : {
type : {
value : 'customTaskWithDropDown'
},
currency : {
validator : Y.Lang.isValue
}
},
EXTENDS : Y.DiagramNodeTask,
prototype : {
initializer : function() {
this.SERIALIZABLE_ATTRS
.push('choseOne');
},
//configura ed inserisce la dropDown
getPropertyModel : function() {
var model = Y.DiagramNodeTask.superclass.getPropertyModel
.apply(this, arguments);
var values = new Y.CustomDropDownCellEditor(
{
options : {
dollar : 'Dollar',
euro : 'Euro',
yen : 'Yen',
gold : 'Gold'
}
});
model
.push({
name : 'Currency',
attributeName : 'currency',
editor : values
});
return model;
}
}
});
//definiziane del secondo nodo custom
Y.DiagramNodeCustomWithTwoMoreField = Y.Component
.create({
NAME : 'diagram-node',
ATTRS : {
type : {
value : 'customWithTwoMoreField'
},
price : {
validator : Y.Lang.isString,
value : 'A Custom default'
},
cost : {
validator : Y.Lang.isString,
value : 'A Custom default'
}
},
EXTENDS : Y.DiagramNodeTask,
prototype : {
getPropertyModel : function() {
var model = Y.DiagramNodeTask.superclass.getPropertyModel
.apply(this,
arguments);
model
.push({
attributeName : 'price',
name : 'Price'
});
model.push({
attributeName : 'cost',
name : 'Cost'
});
return model;
}
}
});
Y.DiagramBuilder.types['customTaskWithDropDown'] = Y.DiagramNodeCustomWithDropDown;
Y.DiagramBuilder.types['customWithTwoMoreField'] = Y.DiagramNodeCustomWithTwoMoreField;
//ORIGINALE
var availableFields = [
....., {
iconClass : 'diagram-node-task-icon',
label : 'Limited Chose',
type : 'customTaskWithDropDown'
}, {
iconClass : 'diagram-node-state-icon',
label : 'Description State',
type : 'customWithTwoMoreField'
} .....
];
new Y.DiagramBuilder({
availableFields : availableFields,
boundingBox : '#DiagramBuilderContainer',
fields : [ {
name : 'HellGate',
type : 'start',
xy : [ 10, 10 ]
} ],
srcNode : '#DiagramBuilderBuilder'
}).render();
});
CSS:
.customdropdowncelleditor-hidden {
display: none;
}
.diagramnodecustomwithdropdown {
background-color: #00FFFF ;
}
.diagramnodecustomwithtwomorefield {
background-color: #FF0090 ;
}
How can I define two different styles for the DiagramNodeCustomWithDropDown and DiagramNodeCustomWithTwoMoreField nodes? I need to define background and border, nothing more for now.
To proceed further I am now trying to save the diagram on my database in json format (logically passing through a form and a servlet)
the obstacle in front of me is:
how do I save the result of the JS function on an hidden input:
Y.DiagramBuilder().toJSON() ??
perhaps it is useful to know that I am working in Liferay 7.1 ...
Here is my JSP page:
<div id="DiagramBuilderContainer">
<div id="DiagramBuilderBuilder"></div>
<div>
<portlet:actionURL var="editDiagramCampaign" name="editDiagramCampaign" >
<portlet:param name="mvcPath" value="/campaign-aui-diagramBuilder.jsp" />
<portlet:param name="redirect" value="<%=currentURL%>" />
<portlet:param name="campaignId" value="<%=String.valueOf(campaignId)%>" />
</portlet:actionURL>
<aui:form action="<%=editDiagramCampaign%>" method="post" name="saveDiagramForm">
<aui:model-context bean="<%=campaign%>" model="<%= Campaign.class %>" />
<aui:button-row>
<aui:input type="hidden" id="diagramBuilderHiddenJSON" name="diagramBuilderHiddenJSON" value="" />
<aui:button type="submit" id="saveDiagram" name="saveDiagram" value="Salva Diagramma"
onClick="updateDiagramBuilderHiddenJSON();" primary="true" />
</aui:button-row>
</aui:form>
</div>
</div>
<script type="text/javascript">
YUI().use('aui-diagram-builder',
function(Y) { ( *read above if u need it*) });
</script>
UPDATE:
Here the solution:
var availableFields = [ {...}, {...}, {...}, {...}, {...} ];
/** RETRIVE SAVED JSON DIAGRAM OR CREATE NEW ONE **/
var diagramBuilderObj = null;
var _campaignDiagramJSON = JSON.parse( '<%=campaignDiagramJSON%>' ) ;
if ( _campaignDiagramJSON && _campaignDiagramJSON != "" ) {
diagramBuilderObj = new Y.DiagramBuilder({
availableFields : availableFields,
boundingBox : '#DiagramBuilderContainer',
fields : _campaignDiagramJSON.nodes,
srcNode : '#DiagramBuilderBuilder'
}) ;
diagramBuilderObj.render();
} else {
diagramBuilderObj = new Y.DiagramBuilder({
availableFields : availableFields,
boundingBox : '#DiagramBuilderContainer',
fields : [ {
name : 'Start Here',
type : 'start',
xy : [ 10, 10 ]
} ],
srcNode : '#DiagramBuilderBuilder'
});
diagramBuilderObj.render();
}
/** SAVE MODIFIED JSON DIAGRAM TROUGH FORM **/
Y.one('#<portlet:namespace/>'+'saveDiagramButton').on('click', function() {
Y.one('#<portlet:namespace/>'+'diagramBuilderHiddenJSON').set('value', JSON.stringify( diagramBuilderObj.toJSON() ) );
});
NEW UPDATE:
Damn, it's not over yet...
and here I really ran out of ideas and can't find support elsewhere:
the conversion to json and the saving on db works but the recovery from json fails with the following error
TypeError: n.get(...) is undefined[Ulteriori informazioni] combo:15:2351
prepareTransition http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-property-builder/aui-property-builder-min.js&/o/frontend-js-web/aui/matrix/matrix-min.js&/o/frontend-js-web/aui/graphics/graphics-min.js&/o/frontend-js-web/aui/graphics-svg-default/graphics-svg-default-min.js&/o/frontend-js-web/aui/graphics-svg/graphics-svg-min.js&/o/frontend-js-web/aui/aui-diagram-builder-connector/aui-diagram-builder-connector-min.js&/o/frontend-js-web/aui/aui-diagram-node-manager-base/aui-diagram-node-manager-base-min.js&/o/frontend-js-web/aui/aui-diagram-node/aui-diagram-node-min.js&/o/frontend-js-web/aui/aui-diagram-node-state/aui-diagram-node-state-min.js&/o/frontend-js-web/aui/aui-diagram-node-condition/aui-diagram-node-condition-min.js&/o/frontend-js-web/aui/aui-diagram-node-end/aui-diagram-node-end-min.js&/o/frontend-js-web/aui/aui-diagram-node-fork/aui-diagram-node-fork-min.js&/o/frontend-js-web/aui/aui-diagram-node-join/aui-diagram-node-join-min.js:15
_setTransitions http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-property-builder/aui-property-builder-min.js&/o/frontend-js-web/aui/matrix/matrix-min.js&/o/frontend-js-web/aui/graphics/graphics-min.js&/o/frontend-js-web/aui/graphics-svg-default/graphics-svg-default-min.js&/o/frontend-js-web/aui/graphics-svg/graphics-svg-min.js&/o/frontend-js-web/aui/aui-diagram-builder-connector/aui-diagram-builder-connector-min.js&/o/frontend-js-web/aui/aui-diagram-node-manager-base/aui-diagram-node-manager-base-min.js&/o/frontend-js-web/aui/aui-diagram-node/aui-diagram-node-min.js&/o/frontend-js-web/aui/aui-diagram-node-state/aui-diagram-node-state-min.js&/o/frontend-js-web/aui/aui-diagram-node-condition/aui-diagram-node-condition-min.js&/o/frontend-js-web/aui/aui-diagram-node-end/aui-diagram-node-end-min.js&/o/frontend-js-web/aui/aui-diagram-node-fork/aui-diagram-node-fork-min.js&/o/frontend-js-web/aui/aui-diagram-node-join/aui-diagram-node-join-min.js:16
forEach self-hosted:262
forEach jQuery
_setTransitions http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-property-builder/aui-property-builder-min.js&/o/frontend-js-web/aui/matrix/matrix-min.js&/o/frontend-js-web/aui/graphics/graphics-min.js&/o/frontend-js-web/aui/graphics-svg-default/graphics-svg-default-min.js&/o/frontend-js-web/aui/graphics-svg/graphics-svg-min.js&/o/frontend-js-web/aui/aui-diagram-builder-connector/aui-diagram-builder-connector-min.js&/o/frontend-js-web/aui/aui-diagram-node-manager-base/aui-diagram-node-manager-base-min.js&/o/frontend-js-web/aui/aui-diagram-node/aui-diagram-node-min.js&/o/frontend-js-web/aui/aui-diagram-node-state/aui-diagram-node-state-min.js&/o/frontend-js-web/aui/aui-diagram-node-condition/aui-diagram-node-condition-min.js&/o/frontend-js-web/aui/aui-diagram-node-end/aui-diagram-node-end-min.js&/o/frontend-js-web/aui/aui-diagram-node-fork/aui-diagram-node-fork-min.js&/o/frontend-js-web/aui/aui-diagram-node-join/aui-diagram-node-join-min.js:16
jQuery 7
syncConnectionsUI http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-property-builder/aui-property-builder-min.js&/o/frontend-js-web/aui/matrix/matrix-min.js&/o/frontend-js-web/aui/graphics/graphics-min.js&/o/frontend-js-web/aui/graphics-svg-default/graphics-svg-default-min.js&/o/frontend-js-web/aui/graphics-svg/graphics-svg-min.js&/o/frontend-js-web/aui/aui-diagram-builder-connector/aui-diagram-builder-connector-min.js&/o/frontend-js-web/aui/aui-diagram-node-manager-base/aui-diagram-node-manager-base-min.js&/o/frontend-js-web/aui/aui-diagram-node/aui-diagram-node-min.js&/o/frontend-js-web/aui/aui-diagram-node-state/aui-diagram-node-state-min.js&/o/frontend-js-web/aui/aui-diagram-node-condition/aui-diagram-node-condition-min.js&/o/frontend-js-web/aui/aui-diagram-node-end/aui-diagram-node-end-min.js&/o/frontend-js-web/aui/aui-diagram-node-fork/aui-diagram-node-fork-min.js&/o/frontend-js-web/aui/aui-diagram-node-join/aui-diagram-node-join-min.js:15
syncConnectionsUI http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-diagram-node-start/aui-diagram-node-start-min.js&/o/frontend-js-web/aui/aui-diagram-node-task/aui-diagram-node-task-min.js&/o/frontend-js-web/aui/aui-diagram-builder/aui-diagram-builder-min.js:3
each jQuery
forEach self-hosted:262
jQuery 2
syncConnectionsUI http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-diagram-node-start/aui-diagram-node-start-min.js&/o/frontend-js-web/aui/aui-diagram-node-task/aui-diagram-node-task-min.js&/o/frontend-js-web/aui/aui-diagram-builder/aui-diagram-builder-min.js:3
syncUI http://localhost:8080/combo/?browserId=firefox&minifierType=&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/aui-diagram-node-start/aui-diagram-node-start-min.js&/o/frontend-js-web/aui/aui-diagram-node-task/aui-diagram-node-task-min.js&/o/frontend-js-web/aui/aui-diagram-builder/aui-diagram-builder-min.js:3
renderer http://localhost:8080/combo?browserId=firefox&minifierType=js&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/event-hover/event-hover.js&/o/frontend-js-web/aui/event-key/event-key.js&/o/frontend-js-web/aui/event-mouseenter/event-mouseenter.js&/o/frontend-js-web/aui/event-mousewheel/event-mousewheel.js&/o/frontend-js-web/aui/event-outside/event-outside.js&/o/frontend-js-web/aui/event-resize/event-resize.js&/o/frontend-js-web/aui/event-simulate/event-simulate.js&/o/frontend-js-web/aui/event-synthetic/event-synthetic.js&/o/frontend-js-web/aui/intl/intl.js&/o/frontend-js-web/aui/io-base/io-base.js&/o/frontend-js-web/aui/io-form/io-form.js&/o/frontend-js-web/aui/io-queue/io-queue.js&/o/frontend-js-web/aui/io-upload-iframe/io-upload-iframe.js&/o/frontend-js-web/aui/io-xdr/io-xdr.js&/o/frontend-js-web/aui/json-parse/json-parse.js&/o/frontend-js-web/aui/json-stringify/json-stringify.js&/o/frontend-js-web/aui/node-base/node-base.js&/o/frontend-js-web/aui/node-core/node-core.js&/o/frontend-js-web/aui/node-event-delegate/node-event-delegate.js&/o/frontend-js-web/aui/node-event-simulate/node-event-simulate.js&/o/frontend-js-web/aui/node-focusmanager/node-focusmanager.js&/o/frontend-js-web/aui/node-pluginhost/node-pluginhost.js&/o/frontend-js-web/aui/node-screen/node-screen.js&/o/frontend-js-web/aui/node-style/node-style.js&/o/frontend-js-web/aui/oop/oop.js&/o/frontend-js-web/aui/plugin/plugin.js&/o/frontend-js-web/aui/pluginhost-base/pluginhost-base.js&/o/frontend-js-web/aui/pluginhost-config/pluginhost-config.js&/o/frontend-js-web/aui/querystring-stringify-simple/querystring-stringify-simple.js&/o/frontend-js-web/aui/queue-promote/queue-promote.js&/o/frontend-js-web/aui/selector-css2/selector-css2.js&/o/frontend-js-web/aui/selector-css3/selector-css3.js&/o/frontend-js-web/aui/selector-native/selector-native.js&/o/frontend-js-web/aui/selector/selector.js&/o/frontend-js-web/aui/widget-base/widget-base.js&/o/frontend-js-web/aui/widget-htmlparser/widget-htmlparser.js&/o/frontend-js-web/aui/widget-skin/widget-skin.js:11923
_defRenderFn http://localhost:8080/combo?browserId=firefox&minifierType=js&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/event-hover/event-hover.js&/o/frontend-js-web/aui/event-key/event-key.js&/o/frontend-js-web/aui/event-mouseenter/event-mouseenter.js&/o/frontend-js-web/aui/event-mousewheel/event-mousewheel.js&/o/frontend-js-web/aui/event-outside/event-outside.js&/o/frontend-js-web/aui/event-resize/event-resize.js&/o/frontend-js-web/aui/event-simulate/event-simulate.js&/o/frontend-js-web/aui/event-synthetic/event-synthetic.js&/o/frontend-js-web/aui/intl/intl.js&/o/frontend-js-web/aui/io-base/io-base.js&/o/frontend-js-web/aui/io-form/io-form.js&/o/frontend-js-web/aui/io-queue/io-queue.js&/o/frontend-js-web/aui/io-upload-iframe/io-upload-iframe.js&/o/frontend-js-web/aui/io-xdr/io-xdr.js&/o/frontend-js-web/aui/json-parse/json-parse.js&/o/frontend-js-web/aui/json-stringify/json-stringify.js&/o/frontend-js-web/aui/node-base/node-base.js&/o/frontend-js-web/aui/node-core/node-core.js&/o/frontend-js-web/aui/node-event-delegate/node-event-delegate.js&/o/frontend-js-web/aui/node-event-simulate/node-event-simulate.js&/o/frontend-js-web/aui/node-focusmanager/node-focusmanager.js&/o/frontend-js-web/aui/node-pluginhost/node-pluginhost.js&/o/frontend-js-web/aui/node-screen/node-screen.js&/o/frontend-js-web/aui/node-style/node-style.js&/o/frontend-js-web/aui/oop/oop.js&/o/frontend-js-web/aui/plugin/plugin.js&/o/frontend-js-web/aui/pluginhost-base/pluginhost-base.js&/o/frontend-js-web/aui/pluginhost-config/pluginhost-config.js&/o/frontend-js-web/aui/querystring-stringify-simple/querystring-stringify-simple.js&/o/frontend-js-web/aui/queue-promote/queue-promote.js&/o/frontend-js-web/aui/selector-css2/selector-css2.js&/o/frontend-js-web/aui/selector-css3/selector-css3.js&/o/frontend-js-web/aui/selector-native/selector-native.js&/o/frontend-js-web/aui/selector/selector.js&/o/frontend-js-web/aui/widget-base/widget-base.js&/o/frontend-js-web/aui/widget-htmlparser/widget-htmlparser.js&/o/frontend-js-web/aui/widget-skin/widget-skin.js:11897
jQuery 3
render http://localhost:8080/combo?browserId=firefox&minifierType=js&languageId=en_US&b=7102&t=1552559958516&/o/frontend-js-web/aui/event-hover/event-hover.js&/o/frontend-js-web/aui/event-key/event-key.js&/o/frontend-js-web/aui/event-mouseenter/event-mouseenter.js&/o/frontend-js-web/aui/event-mousewheel/event-mousewheel.js&/o/frontend-js-web/aui/event-outside/event-outside.js&/o/frontend-js-web/aui/event-resize/event-resize.js&/o/frontend-js-web/aui/event-simulate/event-simulate.js&/o/frontend-js-web/aui/event-synthetic/event-synthetic.js&/o/frontend-js-web/aui/intl/intl.js&/o/frontend-js-web/aui/io-base/io-base.js&/o/frontend-js-web/aui/io-form/io-form.js&/o/frontend-js-web/aui/io-queue/io-queue.js&/o/frontend-js-web/aui/io-upload-iframe/io-upload-iframe.js&/o/frontend-js-web/aui/io-xdr/io-xdr.js&/o/frontend-js-web/aui/json-parse/json-parse.js&/o/frontend-js-web/aui/json-stringify/json-stringify.js&/o/frontend-js-web/aui/node-base/node-base.js&/o/frontend-js-web/aui/node-core/node-core.js&/o/frontend-js-web/aui/node-event-delegate/node-event-delegate.js&/o/frontend-js-web/aui/node-event-simulate/node-event-simulate.js&/o/frontend-js-web/aui/node-focusmanager/node-focusmanager.js&/o/frontend-js-web/aui/node-pluginhost/node-pluginhost.js&/o/frontend-js-web/aui/node-screen/node-screen.js&/o/frontend-js-web/aui/node-style/node-style.js&/o/frontend-js-web/aui/oop/oop.js&/o/frontend-js-web/aui/plugin/plugin.js&/o/frontend-js-web/aui/pluginhost-base/pluginhost-base.js&/o/frontend-js-web/aui/pluginhost-config/pluginhost-config.js&/o/frontend-js-web/aui/querystring-stringify-simple/querystring-stringify-simple.js&/o/frontend-js-web/aui/queue-promote/queue-promote.js&/o/frontend-js-web/aui/selector-css2/selector-css2.js&/o/frontend-js-web/aui/selector-css3/selector-css3.js&/o/frontend-js-web/aui/selector-native/selector-native.js&/o/frontend-js-web/aui/selector/selector.js&/o/frontend-js-web/aui/widget-base/widget-base.js&/o/frontend-js-web/aui/widget-htmlparser/widget-htmlparser.js&/o/frontend-js-web/aui/widget-skin/widget-skin.js:11881
<anonima> http://localhost:8080/group/guest/~/control_panel/manage?p_p_id=it_treeffe_feedback_web_portlet_CampaignManagementPortlet&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_redirect=http://localhost:8080/group/guest/~/control_panel/manage?p_p_id=it_treeffe_feedback_web_portlet_CampaignManagementPortlet&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_mvcPath=%2Fview_campaign_crud_mngToolbar.jsp&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_cur=1&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_delta=10&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_orderByCol=modifiedDate&p_p_auth=O2ifcGJf&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_mvcPath=/campaign-aui-diagramBuilder.jsp&_it_treeffe_feedback_web_portlet_CampaignManagementPortlet_campaignId=109&p_p_auth=O2ifcGJf line 355 > scriptElement:143
jQuery 34
The script of the diagram Builder is above, and then i leave a json for a nonsense diagram used for the test.
JSON:
{"nodes":[{"transitions":[{"source":"Tutto Comincia Qui","target":"fork1259","uid":"yui_patched_v3_18_1_2_1554213706673_1417","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector1433","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[657.7999877929688,255.10000610351562],"p2":[988,344]}}],"description":"","name":"Tutto Comincia Qui","required":false,"type":"start","width":40,"height":40,"zIndex":100,"xy":[10,10]},{"transitions":[{"source":"fork1259","target":"condition1779","uid":"yui_patched_v3_18_1_2_1554213706673_1937","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector1953","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1013,369],"p2":[898,482]}},{"source":"fork1259","target":"condition2254","uid":"yui_patched_v3_18_1_2_1554213706673_2412","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector2428","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1038,344],"p2":[1220,377]}}],"description":"","name":"fork1259","required":false,"type":"fork","width":60,"height":60,"zIndex":100,"xy":[370.20001220703125,91.89999389648438]},{"transitions":[{"source":"condition1779","target":"customTaskWithDropDown2790","uid":"yui_patched_v3_18_1_2_1554213706673_3313","sourceXY":[60,30],"targetXY":[27.199951171875,4.9000091552734375],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector3329","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[908,492],"p2":[1069.800048828125,621.0999755859375]}},{"source":"condition1779","target":"state3603","uid":"yui_patched_v3_18_1_2_1554213706673_3761","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector3777","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[883,517],"p2":[874.7999877929688,679.0999755859375]}}],"description":"","name":"condition1779","required":false,"type":"condition","width":60,"height":60,"zIndex":100,"xy":[240.20001220703125,239.89999389648438]},{"transitions":[{"source":"condition2254","target":"customTaskWithDropDown2790","uid":"yui_patched_v3_18_1_2_1554213706673_2948","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector2964","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1245,402],"p2":[1129.800048828125,621.0999755859375]}},{"source":"condition2254","target":"state4334","uid":"yui_patched_v3_18_1_2_1554213706673_4492","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector4508","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1245,402],"p2":[1302.800048828125,667.0999755859375]}}],"description":"","name":"condition2254","required":false,"type":"condition","width":60,"height":60,"zIndex":100,"xy":[602.2000122070312,124.90000915527344]},{"transitions":[{"source":"customTaskWithDropDown2790","target":"customStateWithTwoMoreField7588","uid":"yui_patched_v3_18_1_2_1554213706673_7746","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector7762","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1129.800048828125,681.0999755859375],"p2":[1130,788]}}],"description":"","name":"customTaskWithDropDown2790","required":false,"type":"customTaskWithDropDown","width":70,"height":70,"zIndex":100,"xy":[452.20001220703125,394.90000915527344]},{"transitions":[{"source":"state3603","target":"customTaskWithDropDown2790","uid":"yui_patched_v3_18_1_2_1554213706673_7246","sourceXY":[37.20001220703125,20.899993896484375],"targetXY":[7.199951171875,45.899993896484375],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector7262","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[887.7999877929688,692.0999755859375],"p2":[1069.800048828125,681.0999755859375]}}],"description":"","name":"state3603","required":false,"type":"state","width":40,"height":40,"zIndex":100,"xy":[240,452]},{"transitions":[{"source":"state4334","target":"customTaskWithDropDown2790","uid":"yui_patched_v3_18_1_2_1554213706673_6965","sourceXY":[1.199951171875,18.899993896484375],"targetXY":[65.199951171875,34.899993896484375],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector6981","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1289.800048828125,682.0999755859375],"p2":[1129.800048828125,681.0999755859375]}}],"description":"","name":"state4334","required":false,"type":"state","width":40,"height":40,"zIndex":100,"xy":[672.2000122070312,440.90000915527344]},{"transitions":[{"source":"customStateWithTwoMoreField7588","target":"end8225","uid":"yui_patched_v3_18_1_2_1554213706673_8383","sourceXY":[],"targetXY":[],"connector":{"color":"#27aae1","lazyDraw":false,"name":"connector8399","shapeSelected":{"stroke":{"color":"#ff6600","weight":5,"opacity":0.8}},"shapeHover":{"stroke":{"color":"#ffd700","weight":5,"opacity":0.8}},"p1":[1113,801],"p2":[942,789]}}],"description":"","name":"customStateWithTwoMoreField7588","required":false,"type":"customStateWithTwoMoreField","width":40,"height":40,"zIndex":100,"xy":[495.20001220703125,560.8999938964844]},{"transitions":[],"description":"","name":"end8225","required":false,"type":"end","width":40,"height":40,"zIndex":100,"xy":[294.20001220703125,543.9000091552734]}]}
Is there anyone who can help me?
LAST UPDATE (SOLUTION):
I have published the solution in my comment HERE
Have a nice day!
I want to implement JSON to CSV on my server but I am facing an issue with entries that contain commas, as comma is my separator.
This result in some content not being in the corresponding columns.
How can I skip commas when they are in an entry thus in a string.
Thanks
function convertArrayOfObjectsToCSV(args) {
var result, ctr, keys, columnDelimiter, lineDelimiter, data;
data = args.data || null;
if (data == null || !data.length) {
return null;
}
columnDelimiter = args.columnDelimiter || ',';
lineDelimiter = args.lineDelimiter || '\n';
keys = Object.keys(data[0]);
result = '';
result += keys.join(columnDelimiter);
result += lineDelimiter;
data.forEach(function (item) {
ctr = 0;
keys.forEach(function (key) {
if (ctr > 0) result += columnDelimiter;
result += item[key];
ctr++;
});
result += lineDelimiter;
});
return result;
}
function downloadCSV(args) {
var data, filename, link;
var csv = convertArrayOfObjectsToCSV({
data: activitesExport
});
if (csv == null) {
console.log("CSV null");
return;
}
filename = args.filename || 'export.csv';
if (!csv.match(/^data:text\/csv/i)) {
csv = 'data:text/csv;charset=utf-8,' + csv;
}
data = encodeURI(csv);
link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', filename);
link.click();
}
A sample of how my data looks like :
{
"-LSKp07UQ7TAEXYxK6Li" : {
"activiteId" : "-LSKp07UQ7TAEXYxK6Li",
"adresseCodePostal" : "38340",
"adresseVille" : "VOREPPE",
"adresseVoie" : " 517 rue de Nardan",
"ageMaximum" : "",
"ageMinimum" : "",
"categorie" : "CULTURE",
"description" : "l’Arrosoir est un équipement destiné à accueillir de nombreux événements festifs et culturels tout au long de l’année.",
"divers" : "",
"horaires" : "Horaires divers en fonction des événements",
"illustration" : "https://firebasestorage.googleapis.com/",
"indoor" : true,
"latitude" : 45.2916646,
"longitude" : 5.6349276,
"nom" : "L’arrosoir",
"outdoor" : false,
"siteWeb" : "",
"tarifs" : "En fonction de la manifestation",
"telephone" : "0476504747"
},
"-LSKpWYf9fPaBjtU578e" : {
"activiteId" : "-LSKpWYf9fPaBjtU578e",
"adresseCodePostal" : "38340",
"adresseVille" : "VOREPPE",
"adresseVoie" : "Rue Jean Achard,",
"ageMaximum" : "",
"ageMinimum" : "",
"categorie" : "LOISIRS",
"description" : "Deux terrains de 4 jeux pour la boule lyonnaise ou la pétanque.",
"divers" : "",
"horaires" : "Accès libre ",
"illustration" : "https://firebasestorage.googleapis.com/",
"indoor" : false,
"latitude" : 45.296335,
"longitude" : 5.6363899,
"nom" : "Gradins de la verronière",
"outdoor" : true,
"siteWeb" : "https://www.voreppe.fr/article/terrains-de-boule",
"tarifs" : "gratuit",
"telephone" : "0476504747"
}
}
I've had to do something very similar with big data text rows
I'd suggest using this library
https://www.npmjs.com/package/csv-stringify
Here's a function i wrote to create a CSV from 'dirty' arrays using csv-stringify
export const convertToCSV = (output: string[][]) => {
return new Promise ((resolve,fail) => {
stringify(output, (err, outputData) => {
if (!err) {
resolve(outputData as string[][]);
} else {
fail(err);
}
});
})
}
I have 2 collection tables that only share emails as the unique ids of these 2 tables. The first one is Meteor.users() and SchoolStudents. I want to update the SchoolStudents collection based on the user's email. Though I have successfully updated using _id but the update isn't working using email as the Id. What's the better approach?
In this, it returned a success feedback but no update is made to the record. Bert.alert('Record updated successfully', 'success', 'growl-top-right');
Client code:
let user = Meteor.user();
let studentemail = user && user.emails && user.emails[0].address;
if (studentemail) {
console.log(studentemail);
Meteor.call('UpdateUser', studentemail, function (error, response) {
if (error) {
Bert.alert(error.reason, 'danger', 'growl-top-right');
return false;
} else {
Bert.alert('Record updated successfully', 'success', 'growl-top-right');
}
})
}
Server method
SchoolStudents.update({useremail: studentemail}, {$set: {'status.active': true, 'status.activedate': new Date()}});
This is a sample document from the SchoolStudents collection:
{
"_id" : "xgxZJFRkXGhHmHupY",
"firstname" : "Kehinde",
"lastname" : "Adeoya",
"middlename" : "Adekusibe",
"username" : "ken10ward",
"password" : "PvyLwY9d",
"useremail" : "kadeoya#appzonegroup.com",
"studentclass" : "ss8",
"dateofbirth" : "9-Mar-00",
"gender" : "f",
"ethinicity" : "black",
"mobile" : "8023472442",
"address" : "7 Abrahamoivc",
"city" : "bolson",
"lg" : "loveland",
"state" : "ekiti",
"country" : "Ukraine",
"registra" : "kadeoya",
"status" : {
"active" : false,
"activedate" : null
},
"userId" : "n5rqFSHbhm7zqADyB",
"createdAt" : ISODate("2017-09-05T18:45:14.877Z"),
"friendlySlugs" : {
"slug" : {
"base" : "kehinde-adeoya",
"index" : 5
}
},
"slug" : "kehinde-adeoya-5"
}
This is the server update code:
UpdateUser: function (studentemail) {
check(studentemail, String);
if (!Meteor.userId()) {
Meteor.Error('Not authorized');
return false;
} else {
SchoolStudents.update({useremail: studentemail}, {status: {active: true, activedate: new Date()}}, { upsert: true });
}
}
As it has been pointed to you, you're using user && user.emails && user.emails[0].address construct wrong way.
I suggest you to use this template to do things like that:
let studentemail;
try {
studentemail = user.emails[0].address.valueOf();
} catch (e) {
studentemail = null;
}
if (studentemail != null) {
...
}
This way you can omit numerous checks, like user != null and user.emails != null and user.emails.length > 0 etc and it will be guaranteed that in your studentemail variable you will get either null or user email address.
Added: User email address could be undefined, that's why you need != null check (non-strict). It will be false if variable is undefined or null.
I'm building a forum, and I'm in the step of views. I have this (simplified) code:
//Setting Views
//Adding Them..
$scope.views = $firebaseObject(refService.ref().child("Topics"))
refService.ref().child("Topics").once("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
var childData = childSnapshot.val();
if(childData.DateCreated == $stateParams.DATE && childData.Email == $stateParams.EMAIL){
refService.ref().child("Topics").child(childData.pushKey).child("Views").child(currentAuth.uid).set({
Views : true
})
}
})
})
//Viewing them
$scope.viewableView = $firebaseObject(refService.ref().child("Topics"))
As you can see adding the views was pretty easy job. And I did it correctly. The problem is with displaying the number of views, and I have to do it using AngularFire's $firebaseObject, or $firebaseArray... Here is the structure in database:
{
"Topics" : {
"-KG9rDNLZksJDiLfAXwH" : {
"Avatar" : "http://cs624223.vk.me/v624223037/2b1bb/GRTKddkmXiw.jpg",
"DateCreated" : 1461544873669,
"Email" : "abogale2#gmail.com",
"Title" : "Check",
"UID" : "3caf2136-7a2d-4ae4-a4a9-119f2b08133c",
"Username" : "BruhBrhu",
"Value" : "Check",
"Views" : {
"3caf2136-7a2d-4ae4-a4a9-119f2b08133c" : {
"Views" : true
}
},
"pushKey" : "-KG9rDNLZksJDiLfAXwH"
}
},
"UserAuthInfo" : {
"3caf2136-7a2d-4ae4-a4a9-119f2b08133c" : {
"BronzeBadge" : 0,
"Description" : "Just a wierd 15 year old coder...",
"Email" : "abogale2#gmail.com",
"GoldBadge" : 0,
"Image" : "http://cs624223.vk.me/v624223037/2b1bb/GRTKddkmXiw.jpg",
"Moderator" : false,
"Password" : "KfUcQ1yedOi1gEnGP6i1KQ==",
"PlatinumBadge" : 0,
"SilverBadge" : 0,
"UID" : "3caf2136-7a2d-4ae4-a4a9-119f2b08133c",
"Username" : "BruhBrhu"
}
}
}
As you can see I used push(), to get the topic.. My Concern now is how to view the topics! Please Help! I can't think of a "algorithm" to do it!
Mind you, all of the topics have unique ID's. I have to get the specific ID The user is in.
This worked for me:
refService.ref().child("Topics").once("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key();
var childData = childSnapshot.val();
if(childData.DateCreated == $stateParams.DATE && childData.Email == $stateParams.EMAIL){
refService.ref().child("Topics").child(childData.pushKey).child("Views").on("value", function(snapshot){
console.log(snapshot.numChildren())
$scope.countViews = snapshot.numChildren();
})
}
})
})
I dont know how but somehow $scope.countViews, became three way binded to my HTML, so it actually shows!
You're nesting keys inside an object, which the Firebase documentation explicitly recommends against.
But it can work once you realize that you can also add methods to the scope:
var app = angular.module('app', ['firebase']);
app.constant('FB_URL', 'https://yours.firebaseio.com/');
app.controller('MainCtrl', function(FB_URL, $scope, $firebaseArray, $firebaseObject) {
var ref = new Firebase(FB_URL);
$scope.topics = $firebaseArray(ref.child('Topics'));
$scope.getCount = function(obj) {
return Object.keys(obj).length;
};
});
And the view:
<body ng-controller='MainCtrl'>
<ol><li ng-repeat='topic in topics'>{{topic.Title}} - {{topic.Username}} - {{getCount(topic.Views)}}</li></ol>
</body>
Working jsbin: http://jsbin.com/dapoga/edit?html,js,output