Visual Programming

by mmarcon

HTML

<div id="inputs">
    <div id="i0" class="input">
        <p>10</p>
        <p>20</p>
    </div>
</div>
<div id="blocks">
    <div id="add" class="block">
        <p>Add</p>
        <p class="function">a:b#return a + b</p>
    </div>
    <div id="sub" class="block">
        <p>Subtract</p>
        <p class="function">a:b#return a - b</p>
    </div>
</div>
<div id="program"></div>
<button id="run">Run!</button>
<button id="clear">Clear!</button>
<div id="result"></div>

CSS

#blocks, #inputs {
    overflow: hidden;
}

#program {
    width: 200px;
    height: 200px;
    border: 1px solid #999;
    border-radius: 5px;
    margin: 10px auto;
    padding: 5px;
}

.block, .input {
    width: 80px;
    height: 40px;
    float: left;
    border-radius: 3px;
    cursor: move;
    text-align: center;
    margin: 5px;
}

.block {
    border: 1px solid #AA0000;
}

.input {
    border: 1px solid #00AA00;
}

.block p, .input p {
    font-family: sans-serif;
    text-transform: uppercase;
    font-weight: bold;
}

.input p {
    float: left;
    margin: 0 5px;
}

.block.dropped, .input.dropped {
    width: 198px;
    margin: auto;
    float: none;
    cursor: default;
    margin-bottom: 5px;
}

.function {
    display: none;
}

JavaScript

$(function() {
    $('.block,.input').draggable({
        helper: 'clone'
    });
    $('#program').droppable({
        accept: '.block,.input',
        drop: function (event, ui) {
            if (ui.draggable.hasClass('block')) {
                $(this).children('.block').remove();
            }
            var $clone = ui.draggable.clone (true);
            $clone.addClass ('dropped').appendTo($(this));
        }
    });
    
    $('.block').each (function() {
        var fn = undefined;
        var frags = $(this).find('.function').text().split('#');
        var params = frags[0].split(':');
        var pString = '';
        for (var i in params) {
            pString += ',"' + params [i] + '"';
        }
        pString = pString.substring (1);
        var body = frags [1];
        eval ('fn = new Function (' + pString + ', "' + body + '")');
        
        $(this).data ('data', {func: fn});
    });
    
    $('#run').click(function() {
        var res = undefined;
        var input0 = parseFloat($('#program .input').children('p').eq(0).text());
        var input1 = parseFloat($('#program .input').children('p').eq(1).text());
        var fn = $('#program').children ('.block').eq(0).data('data').func;
        var res = fn (input0, input1);
        $('#result').text (res);
    });
    
    $('#clear').click(function(){$('#program').empty(); $('#result').text('');});
});