3

I ran into a problem which I am not sure how to fix. When I drag the knob into the picture a clone is created. Below the image, a form is then shown with the position of the button. The problem is that sometimes this value is not updated in this input field.

In line 85 I set that value. Then on lines 89 and 90 I check if this value is there in the first place. By means of: console.log(ui.position.left); console.log($("#dragItemPositionX[data-id=" + UUID + "]").val());

A value always appears here but when I look at the form I sometimes see no value in the input field. ( As a test case for this, drag a button to the picture a few times. Sometimes you will see no value in the input field.

How is this possible and how can I fix this?

function uuid() {
  var dt = new Date().getTime();
  var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = (dt + Math.random() * 16) % 16 | 0;
    dt = Math.floor(dt / 16);
    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  });
  return uuid;
}

$(document).ready(function() {
  // Create default knob
  $('#knob').jqxKnob({
    width: 34,
    height: 34,
    disabled: true,
    value: 0,
    min: 0,
    max: 100,
    startAngle: 120,
    endAngle: 420,
    snapToStep: true,
    rotation: 'clockwise',
    style: {
      stroke: '#000',
      strokeWidth: 1,
      fill: {
        color: '#fff'
      }
    },
    pointer: {
      type: 'line',
      thickness: 4,
      style: {
        fill: "#00a4e1",
        stroke: "#00a4e1"
      },
      size: '70%',
      offset: '0%'
    }
  });

  //Drag default knob in #droppable div

  $(".draggable").draggable({
    containment: "#droppable",
    appendTo: "#droppable",
    helper: "clone"
  });
});

  // Drag&Drop default knob

  $("#droppable").droppable({
    drop: function(event, ui) {

      //Generate UUID
      var UUID = uuid();

      // Change class in order to stop the cloning in droppable div.

      if (ui.draggable.hasClass("draggable")) {
        var $item = $(ui.helper).clone();
        $item.removeClass("draggable");
        $item.addClass("editable");
        $item.attr('data-id', UUID);
        $(this).append($item);
  $(".editable").draggable({
    containment: "#droppable",
    appendTo: "#droppable",
    drag: function(event, ui) {
     $("#dragItemPositionX[data-id=" + UUID + "]").val(ui.position.left);
        $("#dragItemPositionY[data-id=" + UUID + "]").val(ui.position.top);
    }
  });
        //Add a form  & fill some values

        $("#info").append("<form class='pure-form knob' name=" + UUID + " data-id=" + UUID + ">");
        $("form[data-id=" + UUID + "]").append($("#template").html());
        $("form[data-id=" + UUID + "]").find('input').each(function() {
          $('input').attr('data-id', UUID);
          $(this).attr('name', $(this).attr('name') + "[]");
        });

        $("#dragItemPositionX[data-id=" + UUID + "]").val(ui.position.left);
        $("#dragItemPositionY[data-id=" + UUID + "]").val(ui.position.top);


        console.log(ui.position.left);
        console.log($("#dragItemPositionX[data-id=" + UUID + "]").val());

        // Show form and active knob

        $("form.knob").hide();
        $("form[data-id=" + UUID + "]").show();
        $("body").find(".active_knob").removeClass("active_knob");
        $(".jqx-knob[data-id=" + UUID + "]").find("line").eq(-1).addClass("active_knob");
      }
    }
  })

JSfiddle

Bits
  • 59
  • 6

1 Answers1

1

Made some minor updates. You had a few items outside of your jQuery block. I suspect that you had some syntax issues.

Test: https://jsfiddle.net/Twisty/acr1dvbf/5/

JavaScript

$(function() {
  function uuid() {
    var dt = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = (dt + Math.random() * 16) % 16 | 0;
      dt = Math.floor(dt / 16);
      return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
  }

  // Create default knob
  $('#knob').jqxKnob({
    width: 34,
    height: 34,
    disabled: true,
    value: 0,
    min: 0,
    max: 100,
    startAngle: 120,
    endAngle: 420,
    snapToStep: true,
    rotation: 'clockwise',
    style: {
      stroke: '#000',
      strokeWidth: 1,
      fill: {
        color: '#fff'
      }
    },
    pointer: {
      type: 'line',
      thickness: 4,
      style: {
        fill: "#00a4e1",
        stroke: "#00a4e1"
      },
      size: '70%',
      offset: '0%'
    }
  });

  //Drag default knob in #droppable div

  $(".draggable").draggable({
    containment: "#droppable",
    appendTo: "#droppable",
    helper: "clone"
  });

  // Drag&Drop default knob

  $("#droppable").droppable({
    drop: function(event, ui) {

      //Generate UUID
      var UUID = uuid();

      // Change class in order to stop the cloning in droppable div.

      if (ui.draggable.hasClass("draggable")) {
        var $item = $(ui.helper).clone();
        $item.toggleClass("draggable editable");
        $item.attr('data-id', UUID);
        $(this).append($item);
        $(".editable").draggable({
          containment: "#droppable",
          appendTo: "#droppable",
          drag: function(event, ui) {
            $("#dragItemPositionX[data-id=" + UUID + "]").val(ui.position.left);
            $("#dragItemPositionY[data-id=" + UUID + "]").val(ui.position.top);
          }
        });
        //Add a form  & fill some values

        $("#info").append("<form class='pure-form knob' name=" + UUID + " data-id=" + UUID + ">");
        $("form[data-id=" + UUID + "]").append($("#template").html());
        $("form[data-id=" + UUID + "]").find('input').each(function(i, el) {
          $('input').attr('data-id', UUID);
          $(el).attr('name', $(this).attr('name') + "[]");
        });

        $("#dragItemPositionX[data-id=" + UUID + "]").val(ui.position.left);
        $("#dragItemPositionY[data-id=" + UUID + "]").val(ui.position.top);


        console.log(ui.position.left);
        console.log($("#dragItemPositionX[data-id=" + UUID + "]").val());

        // Show form and active knob

        $("form.knob").hide();
        $("form[data-id=" + UUID + "]").show();
        $(".active_knob").removeClass("active_knob");
        $(".jqx-knob[data-id=" + UUID + "]").find("line").eq(-1).addClass("active_knob");
      }
    }
  });
});

When I move the clone around, I always get value updates.

Update

If you add more knobs, you will then need to conditionally Add the knob or if it's an existing knob, show the correct form and show the proper position.

Example: https://jsfiddle.net/Twisty/acr1dvbf/95/

JavaScript

$(function() {
  function getId() {
    var dt = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = (dt + Math.random() * 16) % 16 | 0;
      dt = Math.floor(dt / 16);
      return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
  }

  function makeKnobDrag(item) {
    return $(item).draggable({
      containment: "#droppable",
      drag: function(event, ui) {
        $("#knob-form-" + $(item).data("form") + " .drag-x").val(ui.position.left);
        $("#knob-form-" + $(item).data("form") + " .drag-y").val(ui.position.top);
      }
    });
  }

  function getActiveKnobPosition() {
    return $(".active_knob").closest(".jqx-knob").position();
  }

  function makeForm(target, uuid) {
    var c = $(".active_knob").closest(".jqx-knob").data("form");
    var form = $("<form>", {
      class: "pure-form knob",
      name: uuid,
      "data-id": uuid,
      id: "knob-form-" + c
    }).appendTo(target);
    form.append($("#template form").children().clone());
    form.find('input').each(function(i, el) {
      $(el).attr({
        name: $(el).attr("name") + "[]",
        "data-id": uuid,
        id: $(el).attr("id").substring(0, $(el).attr("id").indexOf("-")) + c
      });
    });
    $("form.knob").hide();
    var kPos = getActiveKnobPosition();
    $(".drag-x", form).val(kPos.left);
    $(".drag-y", form).val(kPos.top);
    form.show();
  }


  // Create default knob
  $('#knob').jqxKnob({
    width: 34,
    height: 34,
    disabled: true,
    value: 0,
    min: 0,
    max: 100,
    startAngle: 120,
    endAngle: 420,
    snapToStep: true,
    rotation: 'clockwise',
    style: {
      stroke: '#000',
      strokeWidth: 1,
      fill: {
        color: '#fff'
      }
    },
    pointer: {
      type: 'line',
      thickness: 4,
      style: {
        fill: "#00a4e1",
        stroke: "#00a4e1"
      },
      size: '70%',
      offset: '0%'
    }
  });

  //Drag default knob in #droppable div

  $(".draggable").draggable({
    containment: "#droppable",
    helper: "clone",
    start: function(e, ui) {
      ui.helper.addClass("new-item");
    }
  });

  // Drag&Drop default knob

  $("#droppable").droppable({
    drop: function(event, ui) {
      var $self = $(this);
      var UUID;
      var $item = $(ui.helper).clone();
      $(".active_knob").removeClass("active_knob");
      if ($item.hasClass("new-item")) {
        UUID = getId();
        $item.removeClass("new-item").toggleClass("draggable editable ui-draggable ui-draggable-dragging");
        $item.attr({
          "data-id": UUID,
          "data-form": "knob-form-" + ($("form.knob").length + 1)
        });
        $self.append($item);
        $item.find("line").eq(-1).addClass("active_knob");
        makeKnobDrag($item, UUID);
        makeForm("#info", UUID);
      } else {
        UUID = $item.data("id");
        c = $item.data("form");
        $("form.knob").hide();
        $item.find("line").eq(-1).addClass("active_knob");
        $("#knob-form-" + c).show();
      }
    }
  });
});

As you can see, if it's a new item, it will be added to the droppable. If it's not a new item, it will show the proper form and update the position.

Twisty
  • 30,304
  • 2
  • 26
  • 45
  • Thanks for your answer. But the issue is still there. If you drag another knob in the image the values arent updated sometimes. – Bits Aug 22 '21 at 19:53
  • @Bits you stated, '*When I drag the knob into the picture a clone is created.*' You did not indicate a second knob needed to be created. – Twisty Aug 22 '21 at 20:14
  • Ok sorry, English is not my native language. I also mentioned a testcase however in the openingspost. ( As a test case for this, drag a button to the picture a few times. Sometimes you will see no value in the input field. – Bits Aug 22 '21 at 20:19
  • I would like to have multiple knobs with different UUID's, which I can move freely in the droppable div. ( with correct positioning in the input fields for every knob) – Bits Aug 22 '21 at 20:22
  • Wow, thank you very much for the update version. I see you changed quite a bit of code. I have to look into it more to see how you made this work. Thanks again. – Bits Aug 23 '21 at 08:22