The question has a javascript
and coffescript
jsfiddle at the bottom of the question.
Both fiddle include explanatory comments that needs to be read in a specific order, it print out values to the console
when you click on product
or submit div
, in addition I give you this basic explanation of my issue.
- I have 3 Javascript classes
Purchase
,Product
andItem
- One
Purchase
has manyProducts
, OneProduct
has manyItems
- The
Purchase
object sets aclick event handler
on the$('submit')
andonClick()
will post theitems
data to my backend api This is the
data
format accepted from my backend api{ 'purchase' => { 'items_attributes' => { '0' => { 'purchase_id' => '1' }, '1' => { 'purchase_id' => '2' } } } }
My coffeescript jsfiddle is at the following link
Click below to open the javascript fiddle
.
(function() {
var Item, Product, Purchase,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Purchase = (function() {
function Purchase() {
/* on $(document).ready a new Purchase is created */
this.submit = $('#submit');
/* for each div.product a new Product instance is created */
this.products = $.map($('.product'), function(product, i) {
return new Product(product);
});
/ @onSubmit() */
/* Comment 3)
My issue here is how to I access the this.items from the Purchase class and call serialize()?
onSubmit: function () {
@submit.click(function(){console.log(Product.serialize())};
} */
}
return Purchase;
})();
Product = (function() {
Product.items = [];
function Product(product) {
this.product = $(product);
this.id = this.product.data("id");
this.submit = $('#submit');
this.setEvent();
this.onSubmit();
}
Product.prototype.setEvent = function() {
return this.product.click((function(_this) {
return function() {
/* Comment 1)
Product.items is a class variable of Product, because I need to access it from the Purchase class and send post request. When the user clicks on the $('submit') button*/
Product.items.push(new Item(_this.id));
return console.log(Product.items);
};
})(this));
};
Product.prototype.onSubmit = function() {
return this.submit.click(function() {
/* Comment 2)
This works as you can see, but we have 4 products and this operation will
be performed 4 times. I want to achieve this in the Purchase object so it is perfomed only once, by creating a sumit event handler in Purchase */
return console.log(Product.serialize());
});
};
Product.serialize = function() {
var item;
return {
items_attributes: (function() {
var j, len, ref, results;
ref = Product.items;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
item = ref[j];
results.push(item.serialize());
}
return results;
})()
};
};
return Product;
})();
Item = (function() {
function Item(product_id) {
this.product_id = product_id;
this.serialize = bind(this.serialize, this);
}
Item.prototype.serialize = function() {
return {
product_id: this.product_id.toString()
};
};
return Item;
})();
$(document).ready(function() {
return new Purchase();
});
}).call(this);
.console {
background-color: grey;
color: white;
height: 500px;
} # I print to the console Product.items
h4 {
color: red;
width: 100%;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
<li class="product" data-id="1">Product 1</li>
<li class="product" data-id="2">Product 2</li>
<li class="product" data-id="3">Product 2</li>
<li class="product" data-id="4">Product 3</li>
<li class="product" data-id="5">Product 4</li>
<div id="submit">Create Purchase</div>
</ul>
<h4>check logs by opening the console</h4>
as I write opensource, you can review my commit history, the specific commit and fork the project