I'm new to mxGraph, I want to get the vertex (cell) all related data when choosing it (clicking it), if you clicked the properties of a certain cell you will get its data, how can I get it with the code?
I tried this answer, but show this error
Update:
this code gives me an object of the clicked cell (mxGraph v3.9.8).
mxGraph.prototype.addListener(mxEvent.CLICK, function(sender, event){
var mouseEvent = event.getProperty("event");
var selectedCell = event.getProperty("cell");
console.log(selectedCell);
});
There is a function called 'showProperties' belonging to the mxEditor class. In there you can see how it works to show (and get) the properties of a cell.
Be sure the user object for these properties is a node, i.e.:
var doc = mxUtils.createXmlDocument();
var node = doc.createElement('MyNode');
node.setAttribute('label', 'My Name');
node.setAttribute('notes', 'My cell notes');
this helps me
mxGraph.prototype.addListener(mxEvent.CLICK, function(sender, event){
var mouseEvent = event.getProperty("event");
var selectedCell = event.getProperty("cell");
console.log(selectedCell);
});
Related
How to get current location after moving node to save to database new loc.
myDiagram.addDigramListener("SelectionMoved",
function(e) {
let part = e.subject.part;
console.log(part)
}
)
But the part always is null, why?
I was able to use the following code to get new location and key
myDiagram.addDiagramListener("SelectionMoved", function(event) {
// https://gojs.net/latest/api/symbols/Part.html#location
// * PART
var selectedNode = event.diagram.selection.first();
console.log("selectedNode",selectedNode);
console.log("selectedNodeKey",selectedNode.key);
console.log("selectedNode", selectedNode.location.toString());
console.log("selectedNode", selectedNode.location.x);
console.log("selectedNode", selectedNode.location.y);
console.log("locationObject", selectedNode.locationObject);
//Save new location
// key: selectedNode.key
// location-x: selectedNode.location.x
// location-y: selectedNode.location.y
});
e.subject is a collection, which is the selection of all moved Parts. There may be more than one part moved.
If you are reasonably sure that there is only one Part moved, you can write:
myDiagram.addDigramListener("SelectionMoved",
function(e) {
let part = e.subject.first();
console.log(part.toString())
}
)
But if you just want to save the location to the DB, why not make a two-way data binding on Location? The flowchart example demonstrates this:
// The Node.location comes from the "loc" property of the node data,
// converted by the Point.parse static method.
// If the Node.location is changed, it updates the "loc" property of the node data,
// converting back using the Point.stringify static method.
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
I am trying to see if a value in the "apply" sublist for customer payment data has changed and do some action based on it.
My SuiteScript is as follows:
define(['N/record', 'N/https'],
function(record,https)
{
function afterSubmit(context)
{
var oldRec = context.oldRecord;
log.debug({title: 'oldRec ', details: oldRec });
// This log shows that the JSON has an
// attribute called sublists which contains "apply" which has all the applied payments
// eg: {"id":"1234", "type":"customerpayment", "fields":{all the fields},
// "sublists": {"apply" : {"line 1"...}}}
var oldRecSublists = oldRec.sublists;
log.debug({title: 'oldRecApply ', details: oldRecSublists });
// This returns empty or null though there is data
What am I doing wrong here?
Basically what I am trying to achieve is compare the context.oldRecord.sublists.apply and context.newRecord.sublists.apply to find if the amt has changed or not.
Is there a better way to do this is SuiteScript 2.0?
Thanks in advance!
Part of what is going on there is that it looks like you are trying to spelunk the NS data structure by what you see in the print statement. You are not using the NS api at all.
When you send the NS object to the log function I believe it goes through a custom JSON.stringify process so if you want to just inspect values you can do:
var oldRecObj = JSON.parse(JSON.stringify(oldRec));
now oldRecObj can be inspected as though it were a simple object. But you won't be able to manipulate it at all.
You should be using the NS schema browser
and referring to the help docs for operations on N/record
A snippet I often use for dealing with sublists is:
function iter(rec, listName, cb){
var lim = rec.getLineCount({sublistId:listName});
var i = 0;
var getV = function (fld){
return rec.getSublistValue({sublistId:listName, fieldId:fld, line:i});
};
var setV = function(fld, val){
rec.setSublistValue({sublistId:listName, fieldId:fld, line:i, value:val});
};
for(; i< lim; i++){
cb(i, getV, setV);
}
}
and then
iter(oldRec, 'apply', function(idx, getV, setV){
var oldApplied = getV('applied');
});
I want to do a scroll list with bunch of surface images. Then when I click or touch on a surface, I want to get the surface object being affected and do something with it (like change content).
The way I setup below is to have scrollview -> container -> view -> modifier -> surface. I don't know if it is efficient or not (maybe redundant). But I cannot get the exact object triggering event in console.log(data) of each sync object.
define(function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var ContainerSurface = require("famous/surfaces/ContainerSurface");
var View = require('famous/core/View');
var Scrollview = require('famous/views/Scrollview');
var Transform = require('famous/core/Transform');
var Modifier = require("famous/core/Modifier");
var GenericSync = require("famous/inputs/GenericSync");
var MouseSync = require("famous/inputs/MouseSync");
var TouchSync = require("famous/inputs/TouchSync");
var mainContext = Engine.createContext();
GenericSync.register({
"mouse" : MouseSync,
"touch" : TouchSync
});
var scrollview = new Scrollview({});
var listContainer = [];
var questionContainer = [];
var imgSurface = [];
var sync = [];
var imgModifier = new Modifier({origin: [0.5, 0.5]});
for (var i=0; i<10; i++) {
questionContainer[i] = new ContainerSurface({
size: [undefined, 300],
properties:{
overflow: 'hidden'
}
});
imgSurface[i] = new Surface({
content: '<img width="100%" src="http://placehold.it/400x300">'
});
sync[i] = new GenericSync(
["mouse", "touch"],
{direction : GenericSync.DIRECTION_X}
);
questionContainer[i].add(imgModifier).add(imgSurface[i]);
questionContainer[i].pipe(sync[i]);
questionContainer[i].pipe(scrollview);
sync[i].on("end", function(data) {
console.log(data);
});
listContainer.push(questionContainer[i]);
}
scrollview.sequenceFrom(listContainer);
mainContext.add(scrollview);
});
So how do I access the triggering surface or view in this case? I was hoping to get something like data.triggerObject.setContent() that referenced back to that particular surface in the array. Well, such thing doesn't seem to exist...
UPDATE 1:
The answer doesn't need to follow my code above. My "high level" goals are:
Generate a list of surfaces with images. Data from some array.
Detect click AND touch event per surface and do something with that surface
Basically, I tried to do an "advance" version of this example https://github.com/Famous/examples/blob/master/src/examples/core/View/example.js
So GenericSync is working as an aggregator of the the Sync classes. The Sync classes give you useful information based on simpler events such as mousedown and mousemove. That means if you want more information, you are going to have to make MouseSync, for example, give it up.
If you do not wish to write your own MouseSync class, just take a look at where MouseSync emits its events. In the event handling function, you may access the original event. You can attach whatever you wish to the payload that is emitted.. Take for example _handleEnd in MouseSync.js
function _handleEnd(event) {
if (!this._prevCoord) return;
// I added this line..
this._payload.origin = event.origin;
this._eventOutput.emit('end', this._payload);
this._prevCoord = undefined;
this._prevTime = undefined;
}
If it feels too strange editing the source directly and tracking changes, you may just want to duplicate MouseSync to a different classname eg. MyMouseSync and make changes to only that file. The same logic applies to TouchSync.
Hope this helps!
EDIT TO YOUR UPDATED QUESTION:
You can use the default events available through famous surfaces. These include the origin property in the payload.
mousedown, mousemove mouseup, touchstart, touchmove, touchend
surface.on('touchstart',function(e){
touchedSurface = e.origin;
});
In most of these cases, I would detect touch with something like Modernizr, and only apply the necessary events. Good Luck!
I am working on an app to store data offline. My problem is when I try to retrieve the data from local storage for update/edit, it keeps calling only the id of the first item, and not calling the id of the data in view.
Please what am I doing wrong?
Here is my code for loading employees:
// load cases from localStorage
var employees;
if (localStorage.getItem('employees')) {
employees = JSON.parse(localStorage.getItem('employees'));
} else {
// If no cases, create and save them
employees = [];
// offling storing of our cases
localStorage.setItem('employees', JSON.stringify(employees));
}
// show case listing in list view page
var showEmployees = function () {
//erase existing content
$('#employee_list').html('');
//insert each employee
for (var i = 0; i<employees.length; i++) {
addEmployees(employees[i]);
}
};
Here is my code to add an employee to list view:
//add an eliment to list view
var addEmployees = function (empData) {
//HTML content of one list element
var listElementHTML = '<li><a class="employee_list" ui-btn ui-btn-e ui-btn-icon-right ui-icon-carat-r" data-transition="fade" data-split-icon="delete" href="#item'+empData.id+'">' + empData.employeename + '<br> ' + empData.dateofbirth + '</br></a></li>';
//appending the HTML code to list view
$('#employee_list').append(listElementHTML);
};
Here is my code for Edit function:
//User input to edit form
$('#edit_employee_page').on('click' , function () {
var editEmployee = JSON.stringify({
id: employees.length+1,
employeeno: $('#employeeno').val(),
employeename:$('#employeename').val(),
stateoforigine:$('#stateoforigine').val(),
employeephone: $('#employeephone').val(),
dateofbirth:$('#dateofbirth').val()
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
for (var i in employees) {
var id = JSON.parse(localStorage.getItem(employees[i]));
}
Here is my code for the Edit button:
//register Edit button
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
e.stopPropagation();
$.each(employees, function(a, b) {
//if(b.id == employees[i]){
$('#id').val(b.id);
$('#employeeno').val(b.employeeno);
$('#employeename').val(b.employeename);
$("#stateoforigine").val(i.stateoforigine);
$('#employeephone').val(b.employeephone);
$('#dateofbirth').val(b.dateofbirth);
$("#id").attr("readonly","readonly");
$('#employeeno').focus();
$.mobile.changePage('#edit_employee_page');
return false;
//}
});
});
Here is my local Storage:
[
{"id":1,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1965"},
{"id":2,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":3,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":4,
"employeeno":"DAST/003/2003",
"employeename":"Gold Base",
"stateoforigine":"",
"employeephone":"",
"dateofbirth":"12/03/1986"}
]
Thanks for helping me out
The way you are storing your employees into localStorage is correct, but the way you are getting them out is incorrect. You stored your employees by stating:
localStorage.setItem("employees", JSON.stringify(employees));
So, in order to retrieve them, you must use:
var employees = JSON.parse(localStorage.getItem("employees"));
You see, you stored the data as a string with a key of "employees"; therefore, you can only retrieve it by that key. Since all data stored in localStorage is saved as a string, you must use JSON.parse() to convert the data back into an object - an array in this case. Then you can iterate over your employees.
Update:
You should be running this code as soon as the page is rendered (see below). I'm not sure how you're doing that - if you're using an IIFE or jQuery's document.ready() function. I don't think it's necessary to store an empty array into localStorage if none were loaded initially, so, I took your else clause out.
var employees = [];
if (localStorage.getItem('employees') !== null) {
employees = JSON.parse(localStorage.getItem('employees'));
}
Debug this line-by-line when it runs and make positive your employees variable contains data. If it doesn't contain data, well then, there's nothing to edit.
If, however, there is data, then execute your showEmployees() function. Oddly, I'm not seeing in your code where you actually call this. Is it bound to a button or action in your UI? Also, what is that for loop doing after your $('#edit_employee_page') click event function? It's trying to read data from localStorage improperly and it does nothing.
I think if you simply stepped through your code one line at a time using breakpoints and desk-checking your inputs/outputs you'd find out where you're going wrong.
It also appears that there's a disconnect in your code. May be you left out some lines; you define a string editEmployee but out of the blues you store JSON.stringify(employees) whereas employees is not defined in your code:
$('#edit_employee_page').on('click' , function(){
var editEmployee = JSON.stringify({
id: employees.length+1,
//........
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
I had a similar task to do . I did it this way.
I passed the dynamic Id to be passed as an id attribute
id="'+empData.id+'"
and then inside the
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
var empId=$(this).attr('id');
rest of the code is same.
I am trying to implement the autocomplete with data from a database.
The data looks like
[
{"id":"1",name:"Jon"},
{"id":"2",name:"Carl"},
{"id":"3",name:"Jon"},
]
There is no example using such data even though this would be more common than selecting a string from a bunch of strings. Having the user select "Jon" doesn't mean anything unless you know the ID.
I was trying to add code to the following page and listen to an event when the user selects an item but first of all it's not documented in code and in the api what event that is and second none of the events seem to be triggered. Hopefully the event object would pass the object that was selected by the user (not the string) or the index of the selected item so I don't have to use access the private variable to get the object that was chosen.
ac1.dispose();
var DataItem = function(id,value){
this.id=id;
this.value=value;
};
DataItem.prototype.toString=function(){
return this.value;
};
DataItem.prototype.valueOf=function(){
return this.value;
};
var tcMovies = [
new DataItem(1,"one"),
new DataItem(2,"onetwo")
];
var ac1 = goog.ui.ac.createSimpleAutoComplete(
tcMovies, document.getElementById('txtInput1'), false);
goog.events.listen(ac1,goog.ui.ac.AutoComplete.EventType.SELECT,
function(e){
//never gets called
console.log(e);
//hoping to get an index so I can do something like
// ac1.getMatcher().rows_[selectedindex].id
// probably should not use rows_ but there is no get
// method for that either
}
);
Fiddling around a bit and looking through the source code I did find what hopefully is the way to implement it. The following comment in autocomplete.js would suggest it is the correct way:
/**
* Field value was updated. A row field is included and is non-null when a
* row has been selected. The value of the row typically includes fields:
* contactData and formattedValue as well as a toString function (though none
* of these fields are guaranteed to exist). The row field may be used to
* return custom-type row data.
*/
UPDATE: 'update',
Open the following page, press F12 and run the following code in the console.
//remove existing autocomplete
ac1.dispose();
//define data, need toString
// to display the values
var DataItem = function(id,value){
this.id=id;
this.value=value;
};
DataItem.prototype.toString=function(){
return this.value;
};
// create data
var tcMovies = [
new DataItem(1,"abbbbbbbb"),
new DataItem(2,"aabbbbbbb"),
new DataItem(3,"aaabbbbbb"),
new DataItem(4,"aaaabbbbb"),
new DataItem(5,"aaaaabbbb"),
new DataItem(6,"aaaaaabbb"),
];
// use easy method to create and attach the autocomplete
var ac1 = goog.ui.ac.createSimpleAutoComplete(
tcMovies, document.getElementById('txtInput1'), false);
//listen to UPDATE
goog.events.listen(ac1,goog.ui.ac.AutoComplete.EventType.UPDATE,
function(e){
//e.row should be the selected value
console.log("user selected",e.row);
}
);