Sortable draggable with jQuery problem


#1

Hello, I’m a new in ember and have problem.

sortabledraggable

After sorting i’ll try to add new item between item 1 and item 2, but they rendered in not expected place.

What i’m doing wrong?

ember version is 2.16

Thank you!

Component
export default Component.extend( {
items: [],
sortedData: Ember.computed.sort( 'items', 'sortDefinition' ),
sortDefinition: ['index'],
init: function () {
this._super( ...arguments );

let array = [];
let object1 = {id: 1, index: 1, title: "item 1"};
let object2 = {id: 2, index: 2, title: "item 2"};
let object3 = {id: 3, index: 3, title: "item 3"};

array.pushObject( Ember.Object.create( object1 ) );
array.pushObject( Ember.Object.create( object2 ) );
array.pushObject( Ember.Object.create( object3 ) );

this.get( 'items' ).setObjects( array );
},
didInsertElement() {
let component = this;
let invalid = false;
Ember.$( '.sortable-view' ).sortable( {
  update: function ( e, ui ) {
    let indices = {};
    $( this ).children().each( ( index, item ) => {
      indices[$( item ).attr( 'item-id' )] = index + 1;
    } );
    component.updateSortedOrder( indices );
  }
 } );

  Ember.$( '.draggable-area' ).draggable( {
  connectToSortable: ".sortable-view",
  helper: function () {
    var object = jQuery( this ).clone();
    object.width( jQuery( this ).width() );
    object.height( jQuery( this ).height() );
    return object;
  },
  revert: function ( socketObj ) {
    if ( socketObj ) {
      invalid = false;
      return false;
    }
    else {
      invalid = true;
      return true;
    }
  },
  stop: function ( event, ui ) {
    if ( !invalid ) {
      var currentPosition = 0;
      $( Ember.$( '.sortable-view' ) ).children().each( ( index, item ) => {
        if ( $( item ).hasClass( 'draggable-area' ) ) {
          currentPosition = index;
        }
      } );
      Ember.$( ui.helper ).remove();

      component.createNew( currentPosition );
    }
  }
} );
Ember.$( '.sortable-view' ).disableSelection();
},
updateSortedOrder( indices ) {
this.beginPropertyChanges();
let tracks = this.get( 'items' ).forEach( ( item ) => {
  var index = indices[item.get( 'id' )];
  if ( item.get( 'index' ) !== index ) {
    item.set( 'index', index );
  }
 } );
 this.endPropertyChanges();
 },
actions: {
add: function () {
  this.createNew( this.get( 'items' ).length );
},
test() {
  console.log( 'items:' );
  this.get( 'items' ).forEach( ( item ) => {
    console.log( item.get( 'id' ) + " - " + item.get( 'index' ) + " - " + item.get( 'title' ) );
  } );
  console.log( 'sortedData:' );
  this.get( 'sortedData' ).forEach( ( item ) => {
    console.log( item.get( 'id' ) + " - " + item.get( 'index' ) + " - " + item.get( 'title' ) );
  } );
}
},
createNew( position ) {
let id = this.get( 'items' ).length + 1;
if ( this.get( 'items' ).length === position ) {
  this.get( 'items' ).pushObject( Ember.Object.create( {id: id, index: position, title: 'created item ' + id} ) );
} else {
  this.get( 'items' ).insertAt( position, Ember.Object.create( {
    id: id,
    index: position + 1,
    title: 'created item ' + id
  } ) );
}

},
} );
template
  <div>
  Draggable:
 <div style="margin: 10px" class="draggable-area">
 <div>Item</div>
 </div>
 Sortable view:
 <div style="margin: 10px" class="sortable-view">
  {{#each sortedData as |item|}}
    <div item-id="{{item.id}}">{{item.title}}</div>
  {{/each}}
</div>
<button type="button" {{action 'add'}}>Add</button>
<button type="button" {{action 'test'}}>Test</button>
</div>

#2

Hmm, have you considered using an Ember add-on to help with drag and drop? It’s possible to use jQuery add ons to do things if you’re careful and have a good understanding of what is going on your templates, but often it’s easier to use a community-supported add-on that handles the hard aspects of integrating with jQuery for you …

https://emberobserver.com/categories/drag-and-drop