Add port to a custom elements in jointJS

1,203 views
Skip to first unread message

Zahra Maslavi

unread,
Oct 6, 2014, 10:02:21 AM10/6/14
to joi...@googlegroups.com

Hi,

I am new to jointJs library and I am trying to add ports to my custom element that contains html code in it. I followed this tutorial (http://www.jointjs.com/tutorial/html-elements) and created my element. But when I try to add ports to it (based on this tutorial: http://www.jointjs.com/tutorial/ports) it does not work. Another problem I have is that I want the textbox(textarea on my custom shape) to disappear when I click on the blank paper, and just the label with its content stays visible on the element. For that I used the following piece of code (but it does not give me the above-mentioned functionality):

paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });

        this.model.on('cell:pointerclick', function(evt, x, y) {this.$box.find('textarea').toFront();});

My whole code is as below:

<!DOCTYPE html>
<html>
<head>


<link rel="stylesheet" href="graph.css">

<script type="text/javascript" src="http://www.jointjs.com/downloads/joint.js" ></script>
<script src="http://www.jointjs.com/downloads/joint.shapes.devs.js" ></script>
<script src="http://www.jointjs.com/downloads/joint.shapes.devs.min.js" ></script>

</head>
<title>Test</title>

<body>
    <div id="myholder"></div>
</body>
<script>

    var graph = new joint.dia.Graph;

    var paper = new joint.dia.Paper({
        el: $('#myholder'),
        width: 1500,
        height: 700,
        model: graph
    });

    // Create a custom element.
    // ------------------------
    joint.shapes.html = {};
    joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
        defaults: joint.util.deepSupplement({
            type: 'html.Element',
            attrs: {
                rect: { stroke: 'none', 'fill-opacity': 0 }
            }
        }, joint.shapes.basic.Rect.prototype.defaults)
   });

   // Create a custom view for that element that displays an HTML div above it.
   // -------------------------------------------------------------------------

    joint.shapes.html.ElementView = joint.dia.ElementView.extend({

        template: [
            '<div class="html-element">',
            '<button class="delete">x</button>',
            '<span id="lbl" value="Please write here"></span>', 
            '<textarea id="txt" type="text" value="Please write here"></textarea>',
            '</div>'
        ].join(''),

    initialize: function() {
        _.bindAll(this, 'updateBox');
        joint.dia.ElementView.prototype.initialize.apply(this, arguments);

        this.$box = $(_.template(this.template)());
        // Prevent paper from handling pointerdown.
        this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });


        // This is an example of reacting on the input change and storing the input data in the cell model.
        this.$box.find('textarea').on('change', _.bind(function(evt) {
            this.model.set('textarea', $(evt.target).val());
        }, this));
        this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
        // Update the box position whenever the underlying model changes.
        this.model.on('change', this.updateBox, this);
        // Remove the box when the model gets removed from the graph.
        this.model.on('remove', this.removeBox, this);

        this.updateBox();
    },


     render: function() {
        joint.dia.ElementView.prototype.render.apply(this, arguments);
        this.paper.$el.prepend(this.$box);
        this.updateBox();
        return this;
    },

    updateBox: function() {
        // Set the position and dimension of the box so that it covers the JointJS element.
        var bbox = this.model.getBBox();
        // Example of updating the HTML with a data stored in the cell model.
        paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
        this.$box.find('span').text(this.model.get('textarea'));
        this.model.on('cell:pointerclick', function(evt, x, y) { this.$box.find('textarea').toFront(); });
        this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
    },
    removeBox: function(evt) {
        this.$box.remove();
    }
}); 


// Create JointJS elements and add them to the graph as usual.
// -----------------------------------------------------------

var el1 = new joint.shapes.html.Element({ 
    position: { x: 600, y: 250 }, 
    size: { width: 200, height: 100 }, 
    inPorts: ['in'],
    outPorts: ['out'],
    attrs: {
        '.inPorts circle': { fill: 'gray'},
        '.outPorts circle': { fill: 'gray'}
    },
 textarea: 'Start writing'});

graph.addCells([el1]);

paper.on('cell:pointerdblclick', function(cellView, evt, x, y) {
   var el2 = new joint.shapes.html.Element({ position: { x: 600, y: 400 }, size: { width: 200, height: 100 }, textarea: 'Start writing'});

   var l = new joint.dia.Link({
        source: { id: el1.id },
        target: { id: el2.id },
        attrs: { '.connection': { 'stroke-width': 1, stroke: 'gray' } }
    });

    graph.addCells([el2, l]);
});


</script>
</html>

I have searched a lot for answers to these problems but I was not successful finding simple and comprehensive ones. Any help will be appreciated. Thanks.

Reply all
Reply to author
Forward
0 new messages