2012-05-25 19 views
23

संक्षेप में, मैं jquery-ui के शॉपिंग कार्ट डेमो के मूल संस्करण को पुन: पेश करने की कोशिश कर रहा हूं: http://jqueryui.com/demos/droppable/shopping-cart.html ember.js और HTML5 देशी ड्रैग एन ड्रॉप के साथ।एम्बर.जेएस + एचटीएमएल 5 ड्रैग और ड्रॉप शॉपिंग कार्ट डेमो

पहले से खींचें को लागू करने और एंबर + jQuery ui को साथ ड्रॉप करने की कोशिश करते हैं और इस समाधान का उपयोग कठिनाई हो रही करने के बाद: http://jsfiddle.net/Wu2cu/2/, मैं pangratz का HTML5 समाधान देखा: http://jsfiddle.net/pangratz666/DYnNH/ और यह एक शॉट देने का फैसला किया।

मैं pangratz के jsfiddle अलग किया गया है, एक productsController और एक addedToCartController कि एक isAdded संपत्ति के आधार पर productsController फिल्टर बनाया: http://jsfiddle.net/GU8N7/3/

कि ठीक काम करता है, लेकिन फिर मैं अटक जाते हैं जब मैं एक #each iterator उपयोग करने के लिए कोशिश करते हैं और इटरेटर में प्रत्येक ऑब्जेक्ट में अद्वितीय ड्रैगगेबल दृश्य संलग्न करें। मैं प्रत्येक "उत्पाद" ऑब्जेक्ट को खींचने में सक्षम होना चाहता हूं, और जब इसे "शॉपिंग कार्ट" क्षेत्र में गिरा दिया जाता है, तो उस वस्तु को सेट किया गया है, जो कि संपत्ति को सही है, इस प्रकार यह "शॉपिंग कार्ट" में दिखाई देता है।

किसी भी मदद की सराहना की जाएगी !!

(यह भी एक बोनस के रूप में, मैं शॉपिंग कार्ट में आइटम sortable करना चाहते हैं, लेकिन वह शायद के लिए जब तक पहले पुल को पार कर जाता है पूछने के लिए बहुत ज्यादा है।)

उत्तर

47

कोड पर एक नज़र डालें एक समाधान के लिए नीचे (कुछ अतिरिक्त के साथ)। कार्ट आइटमों को सॉर्ट करना शामिल है (जेएस के अंत में cartController देखें)।

और यहां एक कामकाजी पहेली: http://jsfiddle.net/ud3323/5uX9H/

अद्यतन: एक ड्रैग छवि उदाहरण जोड़ा गया।

Handlebars

<script type="text/x-handlebars" > 
    <b>Available Products</b> 
    <br /><br /> 
    {{#each App.productsController}} 
     {{#view App.ProductView contentBinding="this"}} 
     {{content.name}} 
     {{/view}}<br /> 
    {{/each}} 
    <hr /> 

    {{#view App.ProductDropTarget 
      dragContextBinding="App.productsController.currentDragItem"}} 
    Shopping Cart 
    <div style="height: 20px">{{helpText}}</div> 
    {{/view}} 
    <br /> 
    {{#each App.cartController}} 
     {{#view App.ProductView contentBinding="this"}} 
     {{content.name}} 
     {{/view}}<br /> 
    {{/each}}  
</script>​ 

जावास्क्रिप्ट:

App = Ember.Application.create({}); 

DragNDrop = Ember.Namespace.create(); 

DragNDrop.cancel = function(event) { 
    event.preventDefault(); 
    return false; 
}; 

DragNDrop.Draggable = Ember.Mixin.create({ 
    attributeBindings: 'draggable', 
    draggable: 'true', 
    dragStart: function(event) { 
     var dataTransfer = event.originalEvent.dataTransfer; 
     dataTransfer.setData('Text', this.get('elementId')); 
    } 
}); 

DragNDrop.Droppable = Ember.Mixin.create({ 
    dragEnter: DragNDrop.cancel, 
    dragOver: DragNDrop.cancel, 
    drop: function(event) { 
     event.preventDefault(); 
     return false; 
    } 
}); 

App.Product = Ember.Object.extend({ 
    name: null, 
    isAdded: null 
}); 

App.ProductView = Ember.View.extend(DragNDrop.Draggable, { 
    tagName: 'span', 

    // .setDragImage (in #dragStart) requires an HTML element as the first argument 
    // so you must tell Ember to create the view and it's element and then get the 
    // HTML representation of that element. 
    dragIconElement: Ember.View.create({ 
     attributeBindings: ['src'], 
     tagName: 'img', 
     src: 'http://twitter.com/api/users/profile_image/twitter' 
    }).createElement().get('element'), 

    dragStart: function(event) { 
     this._super(event); 
     // Let the controller know this view is dragging 
     this.setPath('content.isDragging', true); 

     // Set the drag image and location relative to the mouse/touch event 
     var dataTransfer = event.originalEvent.dataTransfer; 
     dataTransfer.setDragImage(this.get('dragIconElement'), 24, 24); 
    }, 

    dragEnd: function(event) { 
     // Let the controller know this view is done dragging 
     this.setPath('content.isDragging', false); 
    } 
}); 

App.ProductDropTarget = Ember.View.extend(DragNDrop.Droppable, { 
    tagName: 'div', 
    classNames: ['dropTarget'], 
    classNameBindings: ['cartAction'], 
    helpText: null, 

    // This will determine which class (if any) you should add to 
    // the view when you are in the process of dragging an item. 
    cartAction: Ember.computed(function(key, value) { 
     if(Ember.empty(this.get('dragContext'))) { 
      this.set('helpText','(Drop Zone)'); 
      return null; 
     } 

     if(!this.getPath('dragContext.isAdded')) { 
      this.set('helpText', '(Drop to Add)'); 
      return 'cart-add'; 
     } else if(this.getPath('dragContext.isAdded')) { 
      this.set('helpText', '(Drop to Remove)'); 
      return 'cart-remove'; 
     } else { 
      this.set('helpText', '(Drop Zone)'); 
      return null; 
     } 

    }).property('dragContext').cacheable(), 

    drop: function(event) { 
     var viewId = event.originalEvent.dataTransfer.getData('Text'), 
      view = Ember.View.views[viewId]; 

     // Set view properties 
     // Must be within `Ember.run.next` to always work 
     Ember.run.next(this, function() { 
      view.setPath('content.isAdded', !view.getPath('content.isAdded')); 
     }); 

     return this._super(event); 
    } 
}); 

App.productsController = Ember.ArrayController.create({ 
    content: [ 
     App.Product.create({ name: "MacBook Pro", isAdded: false }), 
     App.Product.create({ name: "iPhone", isAdded: false }), 
     App.Product.create({ name: "iPad", isAdded: true }), 
     App.Product.create({ name: "iTV", isAdded: false }) 
    ], 

    currentDragItem: Ember.computed(function(key, value) { 
     return this.findProperty('isDragging', true); 
    }).property('@each.isDragging').cacheable(), 

    productsInCart: Ember.computed(function(key, value) { 
     return this.filterProperty('isAdded', true); 
    }).property('@each.isAdded').cacheable() 

}); 

App.cartController = Ember.ArrayController.create({  
    content: Ember.computed(function(key, value) { 
     var cartItems = this.get('cartItems'); 

     if(!Ember.empty(cartItems)) { 
      // Sort desc by name 
      return cartItems.sort(function(a,b){ 
       if((a.get('name').toLowerCase()) < (b.get('name').toLowerCase())) 
        return -1; 
       else return 1; 
      }); 
     } 
    }).property('cartItems').cacheable(), 

    cartItemsBinding: 'App.productsController.productsInCart' 
}); 

+3

धन्यवाद इतना आदमी, यह कमाल है! आप सवाल का जवाब देने के ऊपर और परे गए थे। आपकी मदद के लिए बहुत बहुत धन्यवाद! मैं इसे उत्पाद फ़ोटो के क्लोन खींचने के साथ कार्यान्वित करने जा रहा हूं - क्या इस डेमो में क्लोन ड्रैगिंग को लागू करने का कोई आसान तरीका है? एक बार फिर, बहुत बहुत धन्यवाद आदमी, आप बहुत गधे लात मारो। –

+1

मैंने दिखाया है कि ड्रैग आइकन का उपयोग कैसे करें। –

+1

आप महोदय, एक सज्जन और विद्वान हैं –

2

पने ड्रॉप पूर्व एक खींचें लिए देख रहा था emple और तुम्हारा मिल जाए, मैं 1.0.0-RC5 के लिए थोड़ा कोड अद्यतन और मनोरंजन के लिए आइटम क्षमता पर डबल क्लिक करें जोड़ें ...

http://jsfiddle.net/kadactivity/hhBrM/1/

Handlebars

<script type="text/x-handlebars" > 
    <b>Available Products</b> 
    <br /><br /> 
    {{#each product in model}} 
     {{#view App.ProductView contentBinding="product"}} 
      {{view.content.name}} 
     {{/view}}<br /> 
    {{/each}} 
    <hr /> 

    {{#view App.ProductDropTarget 
     dragContextBinding="currentDragItem"}} 
    Shopping Cart 
    <div style="height: 20px">{{helpText}}</div> 
    {{/view}} 
    <br /> 
    {{#each cart in productsInCart}} 
     {{#view App.ProductView contentBinding="cart"}} 
      {{view.content.name}} 
     {{/view}}<br /> 
    {{/each}}  
</script> 

जावास्क्रिप्ट

App = Ember.Application.create(); 

App.Router.map(function() { 
    // put your routes here 
}); 

App.ApplicationRoute = Ember.Route.extend({ 
    model: function() { 
    return [ 
     App.Product.create({ name: "MacBook Pro", isAdded: false }), 
     App.Product.create({ name: "iPhone", isAdded: false }), 
     App.Product.create({ name: "iPad", isAdded: true }), 
     App.Product.create({ name: "iTV", isAdded: false }) 
    ]; 
    } 
}); 

DragNDrop = Ember.Namespace.create(); 

DragNDrop.cancel = function(event) { 
    event.preventDefault(); 
    return false; 
}; 

DragNDrop.Draggable = Ember.Mixin.create({ 
    attributeBindings: "draggable", 
    draggable: "true", 
    dragStart: function(event) { 
    var dataTransfer = event.originalEvent.dataTransfer; 
    dataTransfer.setData("Text", this.get("elementId")); 
    } 
}); 

DragNDrop.Droppable = Ember.Mixin.create({ 
    dragEnter: DragNDrop.cancel, 
    dragOver: DragNDrop.cancel, 
    drop: function(event) { 
    event.preventDefault(); 
    return false; 
    } 
}); 

App.Product = Ember.Object.extend({ 
    name: null, 
    isAdded: null 
}); 

App.ProductView = Ember.View.extend(DragNDrop.Draggable, { 
    tagName: "span", 

    // .setDragImage (in #dragStart) requires an HTML element as the first argument 
    // so you must tell Ember to create the view and it"s element and then get the 
    // HTML representation of that element. 
    dragIconElement: Ember.View.create({ 
    attributeBindings: ["src"], 
    tagName: "img", 
    src: "http://twitter.com/api/users/profile_image/twitter" 
    }).createElement().get("element"), 

    dragStart: function(event) { 
    this._super(event); 
    // Let the controller know this view is dragging 
    this.set("content.isDragging", true); 

    // Set the drag image and location relative to the mouse/touch event 
    var dataTransfer = event.originalEvent.dataTransfer; 
    dataTransfer.setDragImage(this.get("dragIconElement"), 24, 24); 
    }, 

    dragEnd: function(event) { 
    // Let the controller know this view is done dragging 
    this.set("content.isDragging", false); 
    }, 

    doubleClick: function(event) { 
    this.set("content.isAdded", !this.get("content.isAdded")); 
    } 
}); 

App.ProductDropTarget = Ember.View.extend(DragNDrop.Droppable, { 
    tagName: "div", 
    classNames: ["dropTarget"], 
    classNameBindings: ["cartAction"], 
    helpText: null, 

    // This will determine which class (if any) you should add to 
    // the view when you are in the process of dragging an item. 
    cartAction: function() { 
    if(Ember.isEmpty(this.get("dragContext"))) { 
     this.set("helpText","(Drop Zone)"); 
     return null; 
    } 

    if(!this.get("dragContext.isAdded")) { 
     this.set("helpText", "(Drop to Add)"); 
     return "cart-add"; 
    } else if(this.get("dragContext.isAdded")) { 
     this.set("helpText", "(Drop to Remove)"); 
     return "cart-remove"; 
    } else { 
     this.set("helpText", "(Drop Zone)"); 
     return null; 
    } 

    }.property("dragContext"), 

    drop: function(event) { 
    var viewId = event.originalEvent.dataTransfer.getData("Text"), 
     view = Ember.View.views[viewId]; 

    // Set view properties 
    // Must be within `Ember.run.next` to always work 
    Ember.run.next(this, function() { 
     view.set("content.isAdded", !view.get("content.isAdded")); 
    }); 

    return this._super(event); 
    } 
}); 

App.ApplicationController = Ember.ArrayController.extend({ 
    currentDragItem: function() { 
     return this.findProperty("isDragging", true); 
    }.property("@each.isDragging"), 

    productsInCart: function() { 
    var cartItems = this.filterProperty("isAdded", true); 
    console.log(cartItems); 
    if(!Ember.isEmpty(cartItems)) { 
     // Sort desc by name 
     return cartItems.sort(function(a,b){ 
      if((a.get("name").toLowerCase()) < (b.get("name").toLowerCase())) 
       return -1; 
      else return 1; 
     }); 
    } 
    }.property("@each.isAdded") 
}); 
+0

अपडेट करने के लिए बहुत बहुत धन्यवाद! हालांकि, jsfiddle वास्तव में काम नहीं करता है :( –

+1

जेएसफ़िल्ड काम नहीं करता था क्योंकि हैंडलबार्स को निर्भरता के रूप में नहीं जोड़ा गया था। मैंने एम्बर संस्करण को अपूर्ण संस्करण में बदल दिया और हैंडलबार जोड़े और यह काम करता है! धन्यवाद। Http: // jsfiddle.net/jlsuttles/bc5sn/ –

संबंधित मुद्दे