2

I have a function called showBasket, which shows you a list of items added to a shoppingBasket. This happens everytime the user clicks a link; and everytime you click outside the menu, this hides itself again.

My problem is that in this menu, I have a list of links related to each item which allows you to delete the selected item. This link works fine sometime and also works diferently depending what web browser I use.

What I want is to delete the item without refreshing all the web page, so I think I have to do a preventDefault to the link, but also when I debug my code, I see that its repeated many times, so something is wrong, specially when I see that I don't get the result I want sometimes.

As you can see, I use two ajax functions, one to delete the item which I think it works fine, and the other function is used to refresh the datas.

If anybody could help me would be fantastic. I am stuck with this.

/*
SHOWS AND HIDE A BASKET MENU, EVERYTIME YOU CLICK IN THE SELECTED LINK
THIS MENU SHOWS A LIST OF ARTICLES ADDED TO A SHOPPING BASKET, AND EACH ITEM OF THE LIST
HAS A LINK THAT ALLOWS YOU TO DELETE THE SELECTED ITEM.

*/

function showBasket(){
    var $basket=$('#basket');
    var nstyle=$basket.css("display");
    $basket.on('click','a[title="delete article"]',function(e){
    e.preventDefault();
        del($(this));
        updateBasket($(this));

        function del(m){
            var n=m.attr("href");
            n=n.split("=");
            var l=n[1];
            $.ajax({
                type:"GET",
                data:{productoRemoveId:l},
            });
            return false;
        }

        function updateBasket(m){
            $.ajax({
                url:'updateBasket.php',
                success: function(response){
                    $cesta.html(response);
                }
            });
            return false;
        }
        return false;
    });
    if (nstyle=='none'){
        $basket.fadeIn(false,function(){//showing the basket
            $('html').bind("click",function(){
                $basket.fadeOut();//hidding the basket
                $("html").unbind("click");
            });
        });
    }
}

This is the HTML code, relative to the above script:

<div id="basket" class="box_menu" style="display: table;">  <div class="row header">
    <h1>Mi cesta</h1>
        <span>3 articulos añadidos)</span>  
</div>
    <div class="detalle">
        <div class="row">
            <div class="celda_detalle"><input type="text" name="tecantidad" maxlength="3" value="1"></div>
            <div class="celda_detalle"><span>lechuga</span></div>
            <div class="celda_detalle"><span>9.25</span></div>
            <div class="celda_detalle"><a title="delete article" href="./bienvenida.php?productoRemove=5">Eliminar Articulo</a></div>
        </div>
        <div class="row">
            <div class="celda_detalle"><input type="text" name="tecantidad" maxlength="3" value="1"></div>
            <div class="celda_detalle"><span>Lejia</span></div>
            <div class="celda_detalle"><span>8.23</span></div>
            <div class="celda_detalle"><a title="delete article" href="./bienvenida.php?productoRemove=2">Eliminar Articulo</a></div>
        </div>
        <div class="row">
            <div class="celda_detalle"><input type="text" name="tecantidad" maxlength="3" value="1"></div>
            <div class="celda_detalle"><span>limones</span></div>
            <div class="celda_detalle"><span>8.25</span></div>
            <div class="celda_detalle"><a title="delete article" href="./bienvenida.php?productoRemove=3">Eliminar Articulo</a></div>
        </div>
    </div>
        <div class="fila pie">
            <div class="celda_pie">
                <span>Subtotal: 25.73€</span>
            </div>
            <div class="celda_pie">
                <a title="Save Shopping" href="#">Save Shopping</a>
            </div>
            <div class="celda_pie">
                <a title="Pay Shopping" href="#">Pay Shopping</a>
            </div>
</div></div>

I have tried to translate main the code to english, so if you see any mistake just let me know.

The PHP code i wont post it all, but i will post the most relevant one:

class ShoppingCart implements Iterator, Countable {

// Array stores the list of items in the cart:
protected $items = array();

// For tracking iterations:
protected $position = 0;

// For storing the IDs, as a convenience:
protected $ids = array();

private $subtotal  = 0;
private $itemCount = 0;

//MORE CODE ....
// Removes an item from the cart:
public function deleteItem($id) {

    // Need the unique item id:
        //$id = $item->getId();

    // Remove it:
    if (isset($this->items[$id])) {
        unset($this->items[$id]);

        // Remove the stored id, too:
        $index = array_search($id, $this->ids);
        unset($this->ids[$index]);

        // Recreate that array to prevent holes:
        $this->ids = array_values($this->ids);

    }

    $this->itemCount=$this->count();

    $this->subtotal=$this->calcularTotal();
    return true;

} // End of deleteItem() method.

public function display_cart() {
    ////////////////////////////////////////////////////////////////////////
    // Output the cart

    // Return specified number of tabs to improve readability of HTML output
    function tab($n) {
        $tabs = null;
        while ($n > 0) {
            $tabs .= "\t";
            --$n;
        }
        return $tabs;
    }

    if (isset($_GET['productoRemove']))
        if($_GET['productoRemove'] && !$_POST) {
            $idp=$_GET['productoRemove'];
            $this->deleteItem($idp);
        }


    // Display the cart header
    echo tab(1) . "<div class='row header'>\n";
    echo tab(1) . "<h1>Mi cesta</h1>\n";
    echo tab(2) . "<span>". $this->count()." articles added)</span>";
    echo tab(1) . "</div>\n";
    echo tab(1) . "<div class='detalle'>";
    if ($this->count()==0){
        echo tab(2) . "<div class='row'>";
        echo tab(3) . "<span style='display:table-cell; width:450px; vertical-align:middle; text-align:center; color:#666; font-style:italic; font-size:12px;'>La cesta está vacía</span>";
        echo tab(2) . "</div>\n";
    } else {
        //$producto=$this->current();
        $lista=$this->getItems();
        foreach ($lista as $producto){
            echo tab(2) . "<div class='fila' class=".$producto['item']->getId().">\n";
            echo tab(3) . "<div class='celda_detalle'><input type='text' name='tecantidad' maxlength='3' value='".$producto['qty']."'></div>";
            echo tab(3) . "<div class='celda_detalle'><span>".$producto['item']->getNombre()."</span></div>";
            echo tab(3) . "<div class='celda_detalle'><span>".$producto['item']->getPrecio()."</span></div>";
            echo tab(3) . "<div class='celda_detalle'><a title='delete article' href='./bienvenida.php?productoRemove=".$producto['item']->getId()."'>Eliminar Articulo</a></div>";
            echo tab(2) . "</div>\n";
        }
    }
    echo tab(1) . "</div>\n";
    echo tab(2) . "<div class='fila pie'>";
    echo tab(3) . "<div class='celda_pie'>";
    echo tab(4) . "<span>Subtotal: ".$this->calcularTotal()."€</span>";
    echo tab(3) . "</div>\n";
    echo tab(3) . "<div class='celda_pie'>";
    echo tab(4) . "<a title='Save Shopping' href='#'>Save Shopping</a>";
    echo tab(3) . "</div>\n";
    echo tab(3) . "<div class='celda_pie'>";
    echo tab(4) . "<a title='Finish Shopping' href='#'>Finish Shopping</a>";
    echo tab(3) . "</div>\n";
}
}
// Start a new session in case it hasn't already been started on the including page
@session_start();

// Initialize jcart after session start
if (empty($_SESSION['carrito']))
    $carrito="";
else
    $carrito = $_SESSION['carrito'];
if(!is_object($carrito)) {
    $carrito = $_SESSION['carrito'] = new ShoppingCart();
}

To have a better idea of what i get, i also show a picture:

enter image description here

My inspiration for the code is taken from the following code:

http://conceptlogic.com/jcart/

myhappycoding
  • 648
  • 7
  • 20
  • move the `l.preventDefault();` befor this line `del($(this));`. Maybe `actualizarCesta($(this));` cause the problem? What is in that function? – vaso123 Nov 13 '14 at 10:07
  • Sorry, i have changed the name of the function actualizarCesta() to updateBasket(). I translated the names of my function to make it easier to understand, and i forgot to translate that name. – myhappycoding Nov 13 '14 at 10:18
  • I have moved l.preventDefault(), but still with the same problem, it almost works, but sometimes it fails. – myhappycoding Nov 13 '14 at 10:20
  • You're expecting it to represent a boolean value and only call it when it's `true`... seems like a very strange implementation. Can you point to a working example of this technique in action? – Sparky Nov 13 '14 at 16:39
  • Does it work properly when you replace `l.preventDefault() ? l.preventDefault() : l.returnValue = false;` with simply this `l.preventDefault();`? – Sparky Nov 13 '14 at 16:41
  • well, that is the thing, it works fine, but not allways, the only difference is that l.preventDefault(); doesnt work properly in IE. On the other hand i still dont know, why the jquery code is executed many times every time. – myhappycoding Nov 13 '14 at 16:53
  • So you removed that whole line and replaced it with `l.preventDefault()` and that's not working reliably? [jQuery has normalized `preventDefault()`](http://api.jquery.com/event.preventdefault/) so that it works the same cross-browser. Also, why not change the `l` into an `e` to remove any chance of spelling mistakes? – Sparky Nov 13 '14 at 17:00
  • you are right Sparky, i have just removed that line and i have updated the change now. But it still doesnt work, it works when it wants, because the code is executed many times, and i cant find out the way to fix it – myhappycoding Nov 13 '14 at 17:09
  • Sorry about your troubles. At least now we're looking at a more standard implementation and can focus on your root problem. Also show the relevant HTML for this jQuery so we can setup working demos and such. – Sparky Nov 13 '14 at 17:13
  • ahh, no, no, dont worry, if i am honest i am used to use the standard implementation and i am using this one, because the code i am looking is not clear to me enought, and i copied. But I agree, i think it is a good idea to post the HTML code, to give you more details. – myhappycoding Nov 13 '14 at 17:20

1 Answers1

0

1- e.preventDefault() should be first function to call.

2- IE has different syntax for this:

 event.returnValue = false;

check it here.

Community
  • 1
  • 1
mohsen dorparasti
  • 8,107
  • 7
  • 41
  • 61
  • Thank you mohsen. d, but now it is wierd because it almost works fine in IE and Chrome, but it still doesnt work in Firefox. The problem in firefox is that it follows the link. Have to say, that sometimes it doesnt work, is it that possible? – myhappycoding Nov 13 '14 at 11:37
  • sorry for not posted before. I have edited the code and it works in all browsers now, although sometimes i have two click twice in the link to delete the element from the shopping basket. My code in php is based in a jcart code where it creates an object shopping cart with its methods. The object works fine and its methods too, but in jcart implementation doesnt need to use a jquery 'updateBasket()' function, in fact the update is automatic, but i dont really understand the way its done, so that i did it my self doing it in my own way. – myhappycoding Nov 13 '14 at 16:30
  • 1
    [`.preventDefault()` has been normalized by jQuery](http://api.jquery.com/event.preventdefault/) so you do not need additional code or special syntax for IE. – Sparky Nov 13 '14 at 16:35
  • and if I use stopPropagation()?? or stopImmediatePropagation()? – myhappycoding Nov 13 '14 at 16:57