0

I'm trying to generate a report of users creating blocks of components (div's) inside a div element. For that I need to show the appended components in the final report as image or as a html elements.

Work Demo

enter image description here

I need to show the copy of the grildline alone with the components (div's) created on top that.

ui.position gives the position of the element from the top of the page but I need the position inside the parent div tag.

$element.draggable({
  containment: '#convas',
  drag: function(event, ui) {
    var resposition = ui.position;
    console.log(resposition);
  }
}).resizable({
  containment: '#convas',
  resize: function(event, ui) {
    var resposition = ui.position;
    console.log(resposition);
  }
});

Please suggest me a better way to solve this situation.

James Z
  • 12,209
  • 10
  • 24
  • 44

1 Answers1

1

You can use .position() with relative pixel addressing with at.

Defines which position on the element being positioned to align with the target element: "horizontal vertical" alignment. A single value such as "right" will be normalized to "right center", "top" will be normalized to "center top" (following CSS convention). Acceptable horizontal values: "left", "center", "right". Acceptable vertical values: "top", "center", "bottom". Example: "left top" or "center center". Each dimension can also contain offsets, in pixels or percent, e.g., "right+10 top-25%". Percentage offsets are relative to the element being positioned.

Or, as seen below, you can use CSS positioning, where the parent is relative and the children are absolute.

Assuming your data is being retrieved someway, you can create a function to place an element at a specific position. Here is an example.

$(function() {
  var myItems = [{
      id: "el-1",
      label: "Administration",
      position: {
        top: 0,
        left: 0
      },
      props: {
        width: 90,
        height: 90
      }
    },
    {
      id: "el-2",
      label: "Canteen",
      position: {
        top: 0,
        left: 102
      },
      props: {
        width: 45,
        height: 90
      }
    }, {
      id: "el-3",
      label: "Storage (Cold)",
      position: {
        top: 103,
        left: 0
      },
      props: {
        width: 90,
        height: 25
      }
    }
  ];

  function placeElem(dObj, $p) {
    var item = $("<div>", {
      id: dObj.id,
      class: "placed draggable ui-widget-content",
      width: dObj.props.width + "px",
      height: dObj.props.height + "px"
    }).html(dObj.label).appendTo($p);
    item.css({
      left: dObj.position.left + "px",
      top: dObj.position.top + "px"
    });
  }

  function getElPosition($el) {
    var r = {
      top: Math.round(parseInt($el.css("top").slice(0, -2))),
      left: Math.round(parseInt($el.css("left").slice(0, -2)))
    };
    return r;
  }

  function log(h) {
    $("#log").prepend(h);
  }

  function getJSON() {
    // Get JSON data from Data Source and return it. Similar to 'myItems'
    // Use placeElem() to load the data as eleemnts to page
  }

  function saveJSON() {
    // Save JSON data, like myItems, to Data Source
    // Iterate each element and use getElPosition() to build data
    var items = $(".placed");
    var data = [];
    items.each(function(i, el) {
      data.push({
        id: $(el).attr("id"),
        label: $(el).text().trim(),
        position: getElPosition($(el)),
        props: {
          width: $(el).width(),
          height: $(el).height()
        }
      });
    });
    var json = JSON.stringify(data);
    console.log(data);
    console.log(json);
  }

  $.each(myItems, function(key, item) {
    log("<p>Adding " + item.id + ", left: " + item.position.left + ", top: " + item.position.top + "</p>");
    placeElem(item, $("#containment-wrapper"));
    var p = getElPosition($("#" + item.id));
    log("<p>" + item.id + " position left:  " + p.left + ", position top: " + p.top + "</p>");
  });

  $(".draggable").draggable({
    containment: "parent",
    start: function(e, ui) {
      var p = getElPosition($(this));
      log("<p>Drag Start " + $(this).attr("id") + " position left:  " + p.left + ", position top: " + p.top + "</p>");
    },
    stop: function(e, ui) {
      var p = getElPosition($(this));
      log("<p>Drag Stop " + $(this).attr("id") + " position left:  " + p.left + ", position top: " + p.top + "</p>");
    }
  });
});
.draggable {
  width: 90px;
  height: 90px;
  padding: 0.5em;
  float: left;
  margin: 0;
  font-size: 0.65em;
}

#containment-wrapper {
  width: 65%;
  height: 300px;
  border: 2px solid #ccc;
  padding: 0;
  position: relative;
}

#containment-wrapper .placed {
  position: absolute;
  background: #999;
}

h3 {
  clear: left;
}

#log {
  font-size: .5em
}

#log p {
  margin: 0;
  padding: 0;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<div id="containment-wrapper">
</div>

<div id="log"></div>

Once placed, you will want a function that can read the current position. Since it's inside a relative positioned div, the top and left positions should be all you need.

Your post does not talk about how you want to store this data. If it was me, I would use a SQL database yet other options like Cookies or LocalStorage are alternatives. You'd want a load and save style function to pull and push the data to its data source.

halfer
  • 19,824
  • 17
  • 99
  • 186
Twisty
  • 30,304
  • 2
  • 26
  • 45