Iam learning symfony and I want to build a shop system for my school project. I want to send the list of items that the user select to another controller i don't know how.
here is my ShowItemAction
public function ShowItemAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createFormBuilder()
->add('search', 'textbox', array(
'attr' => array(
'label' => false
)))->getForm();
$form->handleRequest($request);
if (($form->isSubmitted()) && ($form->isValid())) {
$formdata = $request->request->get('form');
$search = $formdata['search'];
$products_Repo = $em->getRepository('MyShopBundle:Products')->GetProducts($search);
return $this->render('MyShopBundle:Products:show.html.twig',array(
'form' => $form->createView(),
'products'=> $products_Repo
));
}
return $this->render('MyShopBundle:Products:show.html.twig',array(
'form' => $form->createView()
));
}
and my show.html.Twig
{% block body%}
<div id="cart-content">
</div>
<div class="cart-buttons">
<button id="cart">View Shopping Cart</button>
<button id="clear-cart">Clear Cart</button>
</div>
{{ form(form) }}
{% if products is defined %}
<table>
<thead>
<tr>
<th>Partner-Name</th>
<th>ProductNr</th>
<th>Description</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr>
<td><div class="partner">{{product.partner}}</div></td>
<td><div class="partnerdata" data-value="{{ product.id }}">{{ product.productnr }}</div></td>
<td><div class="description"> {{ product.description }}</div></td>
<td><div class="price">{{ product.price }}</div></td>
<td class="counter"><input type="number" name="count" min="1" step="1"></td>
<td class="cart">
<button type='submit'>in den Warenkorb</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %}
my javascript:
$('.cart').click(function (event) {
event.preventDefault();
var closestTr = $(this).closest('tr');
var ref = closestTr.find('.partner').text();
var data_value = closestTr.find('.partnerdata').data('value');
var productNr= closestTr.find('.partnerdata').html();
var price= closestTr.find('.price').html();
var count = closestTr.find('input').val();
if (count < 1) {
}
else {
$(".cart-content").prepend(HS_ref + "|" + data_value + "|" + herstellerNr + "|" + count + "|" + vk);
}
});
I can see the data which the user has selected(inside <div id="cart-content"></div>) but I don't know how to send those contents perhaps as a POST to the controller.
Something like this: https://www.codeofaninja.com/2013/04/shopping-cart-in-php.html
I am working on Symfony 2.7
You can do this with AJAX
First, you need to get the html data
Second, you have to send this data to the controller
Third, you have to get the data in the controller
Here is an example :
First "you need to get the html data"
HTML :
<div id="cart-content" data-route="{{ path('get_user_card_items') }}">
<span data-item-id="item1" data-quantity="2"></span>
<span data-item-id="item2" data-quantity="1"></span>
<span data-item-id="item3" data-quantity="5"></span>
</div>
JS
/**
* Get the content of #cart-content
*/
function getCartItems() {
var items = [];
$('#cart-content span').each(function(){ // loop into all span
var item = { // create an item object who get all the data
'id' : $(this).attr('data-item-id'),
'quantity' : $(this).attr('data-quantity'),
}
items.push(item); // push into an array
});
return items;
}
Second "you have to send this data to the controller"
JS
function sendCartItems() {
$.ajax({
url: $('#cart-content').attr('data-route'), // here is a route variable
method: 'POST',
data: {items: getCartItems()},
success: function (data) {
// do some stuff when it's send
}
});
}
Third "you have to get the data in the controller"
CustomController.php
class CustomController extends Controller
{
/**
* #Route("/getUserCardItems", name="get_user_card_items")
*/
public function getUserCardItemsAction(Request $request)
{
$items = $request->get('items');
var_dump($items);die; // display for you the items to see if it's works (look into the networks console tab on google chrome)
// some stuff like sending items to database...
}
}
Access network tab google chrome
And you done ;)
Related
I am working on a Symfony project where I have a product entity and I need an Ajax search bar to search for through my products and select some of them. The problem is I have a search bar which gives me live results from the database but if I select the product it should show the data in my table. For some reason I am not able to show the selected results in my table.
js
$('.js-data-example-ajax').select2({
ajax: {
url: '/product/api/search',
dataType: 'json',
}
});
Controller
public function viewActionSearch(Request $request)
{
$query = $request->get('term');
$result = [
'results' => [],
];
if ($query !== null){
$products = $this->productRepository->getSearchList($query);
$result['results'];
foreach ($products as $product) {
$result['results'][] = [
'id' => $product['id'],
'text' => $product['name'],
];
}
} else {
$products = $this->productRepository->getResultList(1);
foreach ($products as $entity) {
$result['results'][] = [
'id' => $entity['id'],
'text' => $entity['name'],
];
}
}
return new JsonResponse($result);
}
ProductList
public function getPage(Request $request)
{
$products = $this->productRepository->getAllProducts($currentPage);
return $this->render(
'#app_bar/Product/productList.twig',
[
'products' => $products,
]
);
}
Twig
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<!-- select2 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/gh/ttskch/select2-bootstrap4-theme#master/dist/select2-bootstrap4.min.css" rel="stylesheet">
<div class="container mt-5">
<form>
<div class="form-group">
<select class="js-data-example-ajax form-control"></select>
</select>
</div>
</form>
</div>
<table class="table table-hover table-responsive">
<thead>
<tr>
<th>id</th>
<th>Title</th>
<th>SKU</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr>
<td>
{{ product.id }}
</td>
<td>
{{ product.name }}
</td>
<td>
{{ product.sku }}
</td>
<td>
<a href="{{ path('app_product_getproduct', {'id': product.id}) }}" class="btn btn-success btn-sm" >
<span class="glyphicon glyphicon-pencil"></span>
</a>
<a href="{{ path('app_product_delete', {'id': product.id}) }}" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
If I visit the route /product/api/search/ it's giving my a result back but i am not able to show these selected products in my table.
You missing something here. Symfony does not work like frontend frameworks like vue.js or similar. What you are doing you are rendering serverside request and after that, you just fetch data via AJAX and you do nothing with that data. jQuery needs instructions on what to do with data you get from the server. You can always use Symfony alongside some frontend framework, but you need to understand the difference when serverside renders your twig template and when frontend framework renders it.
http://api.jquery.com/jquery.ajax/
Hint:
$('.js-data-example-ajax').select2({
ajax: {
url: '/product/api/search',
dataType: 'json',
success: function (data) {
$.each(response, function () {
$('#mytable').append('<tr><td>' + this.product_name + '</td><td>' + this.product_price + '</td></tr>');
});
}
}
});
There are different methods of what you can render, you can reload whole table or just rows that you need.
I have an huge issue with my shopping cart system. The problem is when I select products and try to send through ajax to server side, products not always counted. I have to use ajax to collect all data because I'm using JQuery datatables plugin.
List of products should looks like this:
Incorrect view is a screen from my windows firefox, correct view is from my chromium broswer on linux. It looks like there is some dependency on which browser running my webservice. I'm testing my webservice on server production and it works properly only on my chromium browser.
My buddy said there is in inappropriate data sent in Ajax code.
Here's my HTML template:
{% block content %}
<div class="panel-body">
<form method="post" action="{{ path('order') }}" id="orderList">
<table class="table table-bordered table-striped mb-none" id="datatable-default">
<thead>
<tr>
<th>Nazwa</th>
<th>Kod</th>
<th>Cena netto(zł)</th>
<th class="hidden-xs">Cena brutto(zł)</th>
<th class="hidden-xs">Ilość</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr>
<td>{{ product.productName }}</td>
<td>{{ product.code }}
</td>
<td>{{ product.priceNetto }}</td>
<td class="center hidden-xs">{{ product.priceBrutto }}</td>
<td>
<input type="number" class="spinner-input form-control" min="0" value="0" name="cart[{{ product.code }}]" />
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if app.user != null %}
<button id="getData" type="submit" class="btn btn-primary hidden-xs">Zamów</button>
{% else %}
<p>Zaloguj się aby dokonać zamówienia</p>
{% endif %}
</form>
</div>
{% endblock %}
AJAX code:
$(document).ready(function () {
$('#getData').click( function (event) {
//event.preventDefault();
var paginator = $('#datatable-default').DataTable();
var dat = paginator.$('input').serialize();
console.log(dat);
console.log(decodeURIComponent(dat));
$.ajax({
type: "POST",
url: $('#orderList').attr('action'),
data: {'orders': decodeURIComponent(dat)},
success: function (response) {
console.log(response)
}
});
});
});
And my server side code:
public function orderAction(Request $request)
{
$session = $request->getSession();
$totalPriceNetto = 0;
$totalPriceBrutto = 0;
$user = $this->getUser();
$address = $user->getStreet();
if($request->isXmlHttpRequest())
{
$repository = $this->getDoctrine()->getRepository('AppBundle:Products');
$jsitems = $request->get('orders');
$items = [];
parse_str($jsitems, $items);
$orderItems = [];
foreach ($items['cart'] as $index=>$item)
{
if( $item != 0)
{
$orderItems[$index] = $item;
$orders[$index] = $repository->findBy(['code' => $index]);
//$orders[$index][0]->setPriceBrutto(str_replace(',', '.', str_replace('.', '', $orders[$index][0]->getPriceBrutto())));
//$orders[$index][0]->setPriceNetto(str_replace(',', '.', str_replace('.', '', $orders[$index][0]->getPriceNetto())));
$orders[$index]['value'] = $item;
}
}
$session->set('orders', $orders);
$session->set('orderItems', $orderItems);
foreach ($orders as $index=>$item)
{
$productObject = $item[0];
$totalPriceNetto += floatval(str_replace(',', '.', str_replace('.', '', $productObject->getPriceNetto()))) * (float)$item['value'];
$totalPriceBrutto += floatval(str_replace(',', '.', str_replace('.', '', $productObject->getPriceBrutto()))) * (float)$item['value'];
}
$totalPriceBrutto = round($totalPriceBrutto - ($totalPriceBrutto * $user->getPromo()/100), 2);
$session->set('dd', $totalPriceNetto);
$session->set('de', $totalPriceBrutto);
return $this->render("/default/shop/makeOrder.html.twig", ['totalPriceNetto' => $totalPriceNetto, 'totalPriceBrutto' => $totalPriceBrutto, 'address' => $address]);
}
if($session->has('dd') && $session->has('de'))
{
$totalPriceBrutto = $session->get('de');
$totalPriceNetto = $session->get('dd');
$session->remove('dd');
$session->remove('de');
}
return $this->render("/default/shop/makeOrder.html.twig", ['totalPriceNetto' => $totalPriceNetto, 'totalPriceBrutto' => $totalPriceBrutto, 'address' => $address]);
}
I have a Symfony app which allows CRUD operations on some events and also searching for them. The problem I get is when trying to get the results I'm searching for displayed without refreshing the page. It's the first time I'm using ajax and I think it's something wrong with the function. When I search for a word in any event name, the page is not refreshing and it shows undefined instead of showing the entries.
I appreciate any help!
Here's the method from the Controller:
public function ajaxListAction(Request $request){
//fetch the data from the database and pass it to the view
$em = $this->getDoctrine()->getManager();
$searchTerm = $request->get('search');
$form = $this->createFormBuilder()
->add('search', SubmitType::class, array('label' => 'Search', 'attr' => array('class' => 'btn btn-primary', 'style' => 'margin-bottom:15px')))->getForm();
$organizer = array();
if($searchTerm == ''){
$organizer = $this->getDoctrine()->getRepository('AppBundle:Organizer')->findAll();
}
elseif ($request->getMethod() == 'GET') {
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
$organizer = $em->getRepository('AppBundle:Organizer')->findAllOrderedByName($searchTerm);
}
$response = new JsonResponse();
$results = array();
foreach ($organizer as $value) {
$results[] = json_encode($value);
}
return $response->setData(array(
'results' => $results
));
}
and here's the script for the search:
$(document).ready( function(event) {
$("#search").submit(function(event) {
event.preventDefault(); //prvent default submission event
$form = $(this);
var data = $('#search_term').val();
$.ajax({
url: '/ajax',
type: "GET",
data: {'search' : data },
success: function(response){
var output = '';
for (var i = 0; i < response.length; i++) {
output[i] = output + response;
}
$('#ajax_results').html('<tr><td>' + response.id + '</td></tr>' + '<tr><td>' + response.name + '</td></tr>' + '<tr><td>' + response.dueDate + '</td></tr>');
}
})
});
});
and the index.html.twig file for displaying the data:
{% extends 'base.html.twig' %}
{% block body %}
<h2 class="page-header"> Latest events </h2>
<form id="search" method="GET" action="">
<input type="text" name="search" id="search_term" />
<input type="submit" name="submit" value="Search" />
</form>
<hr />
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Event</th>
<th>Due Date</th>
<th></th>
</tr>
</thead>
<tbody id="ajax_results">
{% for Events in organizer %}
<tr>
<th scope="row">{{Events.id}}</th>
<td>{{Events.name}}</td>
<td>{{Events.dueDate|date('j F, Y, g:i a')}}</td>
<td>
View
Edit
Delete
</td>
</tr>
{% endfor %}
<table class="table table-striped">
{% if organizer|length > 0 %}
{% for items in organizer %}
{% endfor %}
{% else %}
<tr>
<td colspan="2">No matching results found!</td>
</tr>
{% endif %}
</table>
</tbody>
</table>
{% endblock %}
Lets try to refactor your code first. Perhaps it will bring you near the solution.
public function ajaxListAction(Request $request){
$searchTerm = $request->get('search');
//don't need form here
if($searchTerm == ''){
$organizer = $this->getDoctrine()->getRepository('AppBundle:Organizer')->findAll();
}else{
//repository should search by searchterm in next step
$organizer = $this->getDoctrine()->getRepository('AppBundle:Organizer')->findAllOrderedByName($searchTerm);
}
return new JsonResponse($organizer);
}
and javascript:
$(document).ready( function(event) {
$("#search").submit(function(event) {
event.preventDefault(); //prvent default submission event
$form = $(this);
var data = $('#search_term').val();
$.ajax({
url: '/ajax',
type: "GET",
data: {'search' : data },
success: function(response){
$('#ajax_results').html('');
$.each(response, function(key, value) {
console.log(key, value);
$('#ajax_results').append('<tr><td>' + response[key].id + '</td></tr>' + '<tr><td>' + response[key].name + '</td></tr>' + '<tr><td>' + response[key].dueDate + '</td></tr>');
});
}
})
});
});
Please tell what do you see in js console after submit the search?
I managed to make it work. The problem was that I didn't have all the fields sent into the array in the jsonSerialize() method in the Entity file and thus the fields were showing undefined.
I also completed the append method in the .js file in order to have the whole markup replicated upon the ajax call.
Thanks to Rawburner for the suggestions!
I’m new to jQuery/ajax and even PHP/Symfony2 but I’m learning.
I simply am trying to update my quantity field in my Quantity table in my database using this jQuery number spinner.
The script does work (I get success in console) but if I refresh the page, the quantity changes back to the default/original of ‘1’. How can I make it so if the user changes the quantity it gets updated through to the database. I’m lost on how to do this correctly. Do I need additional code in my controller?
twig:
{% extends '::base.html.twig' %}
{% block body %}
<h1 class="text-center"><u><i>Your Cart</i></u></h1>
<div class="container">
<div class="who_is_logged_in">
{% if user is null %}
Login
{% else %}
<u>Hello<strong> {{ user }}</strong></u>
{% endif %}
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price Per Unit</th>
<th>Remove Product</th>
</tr>
</thead>
<tbody>
{% for key, product in quantity %}
<tr>
<td>{{ product.product }}</td> <!--Product-->
<td>
<input class="spinner" value="{{ product.quantity }}" style="width:30px">
</td> <!--Quantity-->
<td>${{ product.product.price|default('') }}</td> <!--Price-->
<td>
<a href="{{ path('product_remove', {'id': product.product.id }) }}">
<button name="REMOVE" type="button" class="btn btn-danger" id="removeButton">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</a>
</td><!--Remove-->
</tr>
{% endfor %}
</tbody>
</table> <!--top table-->
<div class="money-container">
<p class="text-right">Total Cost: ${{ totalCostOfAllProducts }}</p>
</div> <!--moneyContainer-->
{% for flash_message in app.session.flashbag.get('notice') %}
<div class="flash-notice">
<strong>{{ flash_message }}</strong>
</div> <!--flashNotice-->
{% endfor %}
</div> <!--container-->
<ul>
<li>
<a href="{{ path('product') }}">
Add More Products
</a>
</li>
<li>
<a href="{{ path('product_bought') }}">
Buy These Products
</a>
</li>
</ul>
<script type="text/javascript">
$(".spinner").spinner();
$('input.spinner').on('spinstop', function(){
min: 0
console.log('spinner changed');
var $this = $(this);
var $value = $('spinner').val();
$.ajax({
url: "{{ path('product_showCart') }}",
method: 'POST',
data : {
quantity: $this.val()
}
}).done(function(resp){
console.log('success', resp);
}).error(function(err){
console.log('error', resp);
});
});
</script>
{% endblock %}
ProductController Relevant Functions:
/**
* Creates the option to 'add product to cart'.
*
* #Route("/{id}/addToCart", name="product_addToCart")
* #Method("GET")
* #Template()
*/
public function addToCartAction(Request $request, $id) {
$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('ShopBundle:Product')->find($id);
$product->getId();
$product->getName();
$product->getPrice();
$cart = $em->getRepository('ShopBundle:UserCart')->findOneBy(['user' => $this->getUser(), 'submitted' => false]);
// $quantity = $em->getRepository('ShopBundle:Quantity')->findOneBy(['id' => $this->getUser()]);
if ($this->checkUserLogin()) {
$this->addFlash('notice', 'Login to Create a Cart');
return $this->redirectToRoute('product');
}
// --------------------- assign added products to userCart id ------------------------ //
$quantity = new Quantity();
if (is_null($cart) || $cart->getSubmitted(true)) {
$cart = new UserCart();
}
$cart->setTimestamp(new \DateTime()); // Set Time Product was Added
$quantity->setQuantity(1); // Set Quantity Purchased.......Make jQuery # Spinner the input of setQuantity()
$cart->setSubmitted(false); // Set Submitted
$cart->setUser($this->getUser()); // Sets the User ONCE
$cart->addQuantity($quantity); // Add Quantity ONCE
$quantity->setUserCart($cart); // Create a UserCart ONCE
$quantity->setProduct($product); // Sets the Product to Quantity Association ONCE
$em->persist($product);
$em->persist($cart);
$em->persist($quantity);
$em->flush();
$this->addFlash('notice', 'The product: '.$product->getName().' has been added to the cart!');
return $this->redirectToRoute('product');
}
/**
* Shows Empty Cart
*
* #Route("/showCart", name="product_showCart")
* #METHOD("GET")
* #Template()
*/
public function showCartAction(Request $request) {
// --------------------------- show only what the user added to their cart --------------------------- //
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
if ($this->checkUserLogin()) {
$this->addFlash('notice', 'Login to Create a Cart');
return $this->redirectToRoute('product');
}
$cart = $em->getRepository('ShopBundle:UserCart')->findOneBy(['user' => $this->getUser(), 'submitted' => false]);
$prodsInCartCost = $cart->getQuantities();
//BELOW just to show what I think I should do...doesn't work though
foreach ($prodsInCartCost as $key => $value) {
$prodsInCartCost = $value->getQuantity();
//Is the below condition on the right track??
if ($request->getMethod() == 'POST') {
$value->setQuantity([/*WHAT GOES HERE?*/]);
$em->persist($value);
$em->flush();
}
}
//end showing what I think I should do example
if (!$cart) {
$this->addFlash('notice', 'There is NO CART');
return $this->redirectToRoute('product');
}
$sub = $cart->getSubmitted();
/**
* Function in UserCart that Maps to Quantity where product values lives.
* $quantity is an object (ArrayCollection / PersistentCollection)
*/
if ($sub == false) {
$quantity = $cart->getQuantities();
} else {
$this->addFlash('notice', 'Cart should be EMPTY');
}
if (!$cart) {
throw $this->createNotFoundException(
'ERROR: You got past Gondor with an EMPTY CART'
);
}
$totalCostOfAllProducts = 0;
$totalCostOfAllProducts = $this->getTotalCost($cart, $totalCostOfAllProducts);
if (empty($price) && empty($quantity) && empty($totalCostOfAllProducts)) {
$price = 0; $quantity = 0; $totalCostOfAllProducts = 0;
}
return array(
'user' => $cart->getUser(), // for :UserCart
'cart' => $cart,
'quantity' => $cart->getQuantities(), // for :UserCart
// 'quantity' => $quantity, // for :UserCart
'totalCostOfAllProducts' => $totalCostOfAllProducts,
);
}
As far as I know you can't mix flash messages with ajax request. You must change your controller action for return a json message that would be processed in javascript, and them maybe change the html value of some element. In that way you can inform the user about the action be successful. After refresh the page the quantity values should be loaded from database in the same way that it was the first time.
//controller action
public function ajaxAction($id)
{
...
$result = array("responseCode" => 200, "data" => $data);
return new Response(json_encode($result ), 200, array('Content-Type' => 'application/json'));
}
//js code
$.ajax({
url: "{{ path('product_showCart') }}",
method: 'POST',
data : {
quantity: $this.val()
}
}).done(function(resp){
if (resp.responseCode == 200) {
$('#div_quantity').html(resp.data)
}
}).error(function(err){
console.log('error', resp);
});
This code is not tested but you can get the idea.
I’m not sure if I’m asking my question in the best way possible or being totally clear but I’ll do my best.
I have the field $quantity in my Quantity entity. Then in one of my controllers I create an instance of my class entity Quantity like this: $quantity = new Quantity();. Finally I set the quantity like this: $quantity->setQuantity(1); just so things make sense and my app can run.
Then in my twig file I implement the jQuery number spinner (https://jqueryui.com/spinner/). I place the quantity field (1) in as the value.
Then in my script for the spinner I try to make it so when I click up or down the quantity is consequently updated in the database. I FAIL. This is what I need help with.
Ultimately I want to update the total cost of the users cart depending on the quantity of the products in the cart.
ProductController relevant functions:
/**
* Creates the option to 'add product to cart'.
*
* #Route("/{id}/addToCart", name="product_addToCart")
* #Method("GET")
* #Template()
*/
public function addToCartAction(Request $request, $id) {
$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('ShopBundle:Product')->find($id);
$product->getId();
$product->getName();
$product->getPrice();
$cart = $em->getRepository('ShopBundle:UserCart')->findOneBy(['user' => $this->getUser(), 'submitted' => false]);
// $quantity = $em->getRepository('ShopBundle:Quantity')->findOneBy(['id' => $this->getUser()]);
if ($this->checkUserLogin()) {
$this->addFlash('notice', 'Login to Create a Cart');
return $this->redirectToRoute('product');
}
// --------------------- assign added products to userCart id ------------------------ //
$quantity = new Quantity();
if (is_null($cart) || $cart->getSubmitted(true)) {
$cart = new UserCart();
}
$cart->setTimestamp(new \DateTime()); // Set Time Product was Added
$quantity->setQuantity(1); // Set Quantity Purchased.......Make jQuery # Spinner the input of setQuantity()
$cart->setSubmitted(false); // Set Submitted
$cart->setUser($this->getUser()); // Sets the User ONCE
$cart->addQuantity($quantity); // Add Quantity ONCE
$quantity->setUserCart($cart); // Create a UserCart ONCE
$quantity->setProduct($product); // Sets the Product to Quantity Association ONCE
$em->persist($product);
$em->persist($cart);
$em->persist($quantity);
$em->flush();
$this->addFlash('notice', 'The product: '.$product->getName().' has been added to the cart!');
return $this->redirectToRoute('product');
}
/**
* Shows Empty Cart
*
* #Route("/showCart", name="product_showCart")
* #METHOD("GET")
* #Template()
*/
public function showCartAction(Request $request) {
// --------------------------- show only what the user added to their cart --------------------------- //
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
if ($this->checkUserLogin()) {
$this->addFlash('notice', 'Login to Create a Cart');
return $this->redirectToRoute('product');
}
// $product = $em->getRepository('ShopBundle:Product')->f
$cart = $em->getRepository('ShopBundle:UserCart')->findOneBy(['user' => $this->getUser(), 'submitted' => false]);
// $productsInUsersCart = $em->getRepository('ShopBundle:Quantity')->findOneBy(['product' => $cart->getId()]);
// dump($productsInUsersCart); die;
// dump($cart); die;
if (!$cart) {
$this->addFlash('notice', 'There is NO CART');
return $this->redirectToRoute('product');
}
$sub = $cart->getSubmitted();
/**
* Function in UserCart that Maps to Quantity where product values lives.
* $quantity is an object (ArrayCollection / PersistentCollection)
*/
if ($sub == false) {
$quantity = $cart->getQuantities();
} else {
$this->addFlash('notice', 'Cart should be EMPTY');
}
if (!$cart) {
throw $this->createNotFoundException(
'ERROR: You got past Gondor with an EMPTY CART'
);
}
$totalCostOfAllProducts = 0;
$totalCostOfAllProducts = $this->getTotalCost($cart, $totalCostOfAllProducts);
if (empty($price) && empty($quantity) && empty($totalCostOfAllProducts)) {
$price = 0; $quantity = 0; $totalCostOfAllProducts = 0;
}
return array(
'user' => $cart->getUser(), // for :UserCart
'cart' => $cart,
'quantity' => $cart->getQuantities(), // for :UserCart
// 'quantity' => $quantity, // for :UserCart
'totalCostOfAllProducts' => $totalCostOfAllProducts,
);
}
twig file where jQuery spinner script is (and the only thing that works is the jQuery spinner increasing or decreasing numbers...nothing else):
{% extends '::base.html.twig' %}
{% block body %}
<h1 class="text-center"><u><i>Your Cart</i></u></h1>
<div class="container">
<div class="who_is_logged_in">
{% if user is null %}
Login
{% else %}
<u>Hello<strong> {{ user }}</strong></u>
{% endif %}
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price Per Unit</th>
<th>Remove Product</th>
</tr>
</thead>
<tbody>
{% for key, product in quantity %}
<tr>
<td>{{ product.product }}</td> <!--Product-->
<td>
<input class="spinner" value="{{ product.quantity }}" style="width:30px">
</td> <!--Quantity-->
<td>${{ product.product.price|default('') }}</td> <!--Price-->
<td>
<a href="{{ path('product_remove', {'id': product.product.id }) }}">
<button name="REMOVE" type="button" class="btn btn-danger" id="removeButton">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</a>
</td><!--Remove-->
</tr>
{% endfor %}
</tbody>
</table> <!--top table-->
<div class="money-container">
<p class="text-right">Total Cost: ${{ totalCostOfAllProducts }}</p>
</div> <!--moneyContainer-->
{% for flash_message in app.session.flashbag.get('notice') %}
<div class="flash-notice">
<strong>{{ flash_message }}</strong>
</div> <!--flashNotice-->
{% endfor %}
</div> <!--container-->
<ul>
<li>
<a href="{{ path('product') }}">
Add More Products
</a>
</li>
{# {% if cartArray is empty %} #}
{# {% else %} #}
<li>
<a href="{{ path('product_bought') }}">
Buy These Products
</a>
</li>
{# {% endif %} #}
</ul>
<script type="text/javascript">
$(".spinner").spinner();
$('input.spinner').on('change', function(){
var $this = $(this);
$.ajax({
url: '{{ path('product_showCart') }}',
method: 'POST',
data : {
quantity: $this.val()
}
}).done(function(resp){
console.log('success', resp);
}).error(function(err){
console.log('error', resp);
});
});
</script>
{% endblock %}
If you can't already tell I'm new to jQuery/web development but I'm learning day by day. I could really use some help/guidance!
EDIT:
I changed my script to this and now I see my messages in my console but still nothing gets updated/changed in the database and when I refresh my page, the quantity goes back to display '1'.
<script type="text/javascript">
$(".spinner").spinner();
$('input.spinner').on('spinstop', function(){
console.log('spinner changed');
var $this = $(this);
$.ajax({
url: "{{ path('product_showCart') }}",
method: 'GET',
data : {
quantity: $this.val()
}
}).done(function(resp){
console.log('success', resp);
}).error(function(err){
console.log('error', resp);
});
});
</script>