Surtep's avatar

Vue.js - Preventdefault ?

Hello, I follow the video Easy FIltering and Ordering (https://laracasts.com/series/learning-vuejs/episodes/6) and it's working great. But when I click on 'name' or 'age', the page is reloaded. How can I prevent that? In jQuery you can prevent that with e.preventDefault()... How to do that in vue.js?

0 likes
17 replies
mstnorris's avatar

@Surtep It is the same. You include it within a method that you can call from your v-on="click: someMethod"

This screenshot is from the third lesson :)

1 like
Surtep's avatar

Thank you for you fast answer. This is my code ''' methods:{ sortBy: function(e){ e.preventDefault(); } ''' and in the inspector of Chrome, I get 'Uncaught TypeError: e.preventDefault is not a function'... Don't understand...

mstnorris's avatar

@Surtep please post your full code, not just a small snippet. Also, you can format it correctly by using

```
your code in here

```

Surtep's avatar

Ok, sorry for bad formating my code.

demo2 = new Vue({
    el: "#demo2",
    data: {
        sortKey: '',
        search: '',
        reverse : false,
        columns: ['name', 'age'],
        people: [
        {name: 'Pierre', age:53},
        {name: 'Marie', age:25},
        {name: 'Sophie', age:35},
        {name: 'Gijs', age:85},
        {name: 'Bart', age:105},
        {name: 'Christina', age:26},
        {name: 'Lucia', age:3}
        ]
    },
    methods:{
    sortBy: function(e){
        e.preventDefault();
        // Do sort ...
    }
}

In fact I try to make again the exercice of this video https://laracasts.com/series/learning-vuejs/episodes/6 But clicking on age or name the page reloads.

Thank you for your help.

Updated: this is the HTML in a blade file

<div class="container" id="demo2">

<input class="form-control" v-model="search">
<br>
<table class="table table-striped">
    <thead>
        <tr>
        <th v-repeat="column : columns">
        <a href="#"
        v-class="active: sortKey == column"
        v-on="click: sortBy(column)"
        >@{{ column | capitalize }}</a></th>
        </tr>
    </thead>
    <tbody>
        <tr v-repeat="people | filterBy search | orderBy sortKey reverse ">
            <td>@{{ name }}</td>
            <td>@{{ age }}</td>
        </tr>
    </tbody>
</table>
<br> <br> <br> 
<!-- <pre>
    @{{ $data | json }}
</pre> -->
</div>
Surtep's avatar

I just updated my post with the HTML code in a blade template.

Yes I use "a href".

mstnorris's avatar

@Surtep below is my code, it is a slightly modified example but it works. Hope it helps. As you can see, you don't need preventDefault.

index.html

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Filtering</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
        <link rel="stylesheet" type="text/css" href="./style.css">
        <link rel="author" href="humans.txt">
    </head>
    <body>
        <div id="demo" class="container">
        <div class="row">
            <input type="text" placeholder="Search" v-model="search" class="form-control">
        </div>
            <div class="row">
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th v-repeat="column: columns">
                            <a  href="#"
                                v-on="click: sortBy(column)"
                                v-class="active: sortKey == column">
                                {{ column | capitalize }}
                                  {{ <i class="fa fa-sort"></i> }}
                            </a>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-repeat="
                    people
                    | filterBy search
                    | orderBy sortKey reverse">
                        <td>{{ name }}</td>
                        <td>{{ email }}</td>
                        <td>{{ age }}</td>


                </tr></tbody>
            </table>

                <pre>{{ $data | json }}</pre>
            </div>
        </div>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.11.10/vue.min.js"></script>
    <script src="app.js"></script>
</body>
</html>

app.js

new Vue({
    el: '#demo',

    data: {
        sortKey: '',
        search: '',
        reverse: false,
        columns: [
            'name',
            'email',
            'age'
        ],
        people: [
            { name: 'Abigail', email: 'abi@gmail.com', age: 17 },
            { name: 'Freddie', email: 'fred2001@gmail.com', age: 48 },
            { name: 'Hannah', email: 'hanman20@hotmail.com', age: 42 },
            { name: 'Susan', email: 'test@gmail.com', age: 40 },
            { name: 'Charlie', email: 'test@gmail.com', age: 31 },
            { name: 'Carol', email: 'test@gmail.com', age: 30 },
            { name: 'Harry', email: 'test@gmail.com', age: 29 },
            { name: 'John', email: 'test@gmail.com', age: 18 },
            { name: 'Amanda', email: 'test@gmail.com', age: 17 },
            { name: 'Freddie', email: 'test@gmail.com', age: 28 },
            { name: 'Jane', email: 'test@gmail.com', age: 27 },
            { name: 'Aaron', email: 'test@gmail.com', age: 24 },
            { name: 'Neil', email: 'test@gmail.com', age: 22 },
            { name: 'David', email: 'test@gmail.com', age: 25 },
            { name: 'Nick', email: 'test@gmail.com', age: 37 },
            { name: 'Holly', email: 'test@gmail.com', age: 39 },
            { name: 'Michael', email: 'test@gmail.com', age: 19 },
            { name: 'James', email: 'test@gmail.com', age: 18 },
            { name: 'Stephen', email: 'test@gmail.com', age: 26 },
            { name: 'Teresa', email: 'test@gmail.com', age: 28 },
            { name: 'Steve', email: 'test@gmail.com', age: 54 },
            { name: 'Tony', email: 'test@gmail.com', age: 36 },
            { name: 'Peter', email: 'test@gmail.com', age: 24 },
            { name: 'Patrick', email: 'test@gmail.com', age: 34 }
        ]
    },

    methods: {
        sortBy: function(sortKey) {
            this.reverse = (this.sortKey == sortKey) ? ! this.reverse : false;
            this.sortKey = sortKey;
        }
    }
});

style.css

body {
    margin: 2em 0;
    color: #34495e;
}

a {
    color: #34495e;
    text-decoration: none;
    font-weight: normal;
}

a.active {
    color: #d35400;
    text-decoration: underline;
}
Surtep's avatar

This is the full HTMl code. In fact I try to use Vue.js inside a blade template in Laravel.

It works fine escept the proble with e.preventdefault.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel</title>

    <link href="http://laralab.dev/css/app.css" rel="stylesheet">

    <!-- Fonts -->
    <link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'>

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    <span class="sr-only">Toggle Navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#">Laravel</a>
            </div>

            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li><a href="http://laralab.dev">Home</a></li>
                </ul>

                <ul class="nav navbar-nav navbar-right">
                                            <li><a href="http://laralab.dev/auth/login">Login</a></li>
                        <li><a href="http://laralab.dev/auth/register">Register</a></li>
                                    </ul>
            </div>
        </div>
    </nav>

<div class="container">
<style>
    .active{
        background:lightgreen;
    }
</style>
<h1>Vue.js</h1>
<p>Essais de <a href="http://vuejs.org/guide/installation.html">Vue.js</a></p>

<h2>v-on, v-show, v-class (méthodes)</h2>

<article id="demo1" class="jumbotron" v-show=isVisible>
    <button class="glyphicon glyphicon-remove-sign pull-right"
    v-on="click: cacheDemo1"
    ></button>
    <h2>Un article de blog</h2>
    <div v-text=message></div>
    <button class="btn btn-standard btn-lg" 
    v-on="click: jaime"
    v-class="active: liked"
    >
        
        <span class="glyphicon glyphicon-thumbs-up"></span>
        {{ likesCount }}
    </button>


<br> <br> <br>
 <!-- <pre>{{ $data | json }}</pre> -->
</article>

<h2>Filtering</h2>
<div class="container" id="demo2">

<input class="form-control" v-model="search">
<br>
<table class="table table-striped">
    <thead>
        <tr>
        <th v-repeat="column : columns">
        <a href="#"
        v-class="active: sortKey == column"
        v-on="click: sortBy(column)"
        >{{ column | capitalize }}</a></th>
        </tr>
    </thead>
    <tbody>
        <tr v-repeat="people | filterBy search | orderBy sortKey reverse ">
            <td>{{ name }}</td>
            <td>{{ age }}</td>
        </tr>
    </tbody>
</table>
<br> <br> <br> 
<!-- <pre>
    {{ $data | json }}
</pre> -->
</div>

<h2>Liste (ajouter élément)</h2>

<div id="demo3">
    
    <ul v-repeat="name: names">
        <li>{{ name }}</li>
    </ul>
    <input type="text" placeholder="Ajoutez un nom" v-model="newName" v-on="blur : addName">
    <br> <br> <br> 
    <pre>{{ $data | json }}</pre>
</div>

</div>
    <!-- Scripts -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="/js/vuejs/vue.min.js"></script>
<script src="/js/vuejs/app.js"></script>
</body>
</html>
Surtep's avatar

Ok, I will try you code and come back. Thank you very much for your time.

Surtep's avatar

Thank you, I will study the code of Jeffrey. I test you code and it does the same as mine. If you place a few div with 'lorem' before the table, so you need to scroll to see the table header. And then you click a column, you'll see that the page is reloaded. It's annoying.

But thank you very much for your time. Maybe the solution comes in the next lessons. Cheers!

mstnorris's avatar

@Surtep you must be doing something else wrong as the code I gave you behaves exactly as expected.

Did you add anything to it?

Surtep's avatar

No, I just added some div with lorem before the table. Please see your code here http://laralab.dragaly.com/mstnorris.html Just to test purposes. If you scroll with th mouse you'll see the table. Then click a column to sort and you'll see that the page reload. Strange....

Surtep's avatar

Thanks to the thread in stackoverflow you give me: I add this : onclick="return false" to the anchor tag and it works.

Now my code is

<tr>
    <th v-repeat="column : columns">
        <a href="#"
        onclick="return false" 
        v-class="active: sortKey == column"
        v-on="click: sortBy(column)"
        >@{{ column | capitalize }}</a>
    </th>
</tr>

and it works... Thank you very much for your help and the time you dedicated. Have a good day

1 like

Please or to participate in this conversation.