teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

追記

2021/04/15 03:20

投稿

Mario_11
Mario_11

スコア95

title CHANGED
@@ -1,1 +1,1 @@
1
- Django AjaxでIikeボタン作成
1
+ javascript preventDefault使い方
body CHANGED
@@ -1,133 +1,36 @@
1
1
  Django AjaxでIikeボタンの作成をしています。
2
- ー参考サイトー
3
- [https://github.com/hellopyplane/Social-Network](https://github.com/hellopyplane/Social-Network)
4
- 上記のコードを参考にしてLikeボタン作成できたのですが、Likeを押す際にページが読み込まれてしまいます。
2
+ Likeを押す際にページを読み込みたくないのです、が読み込まれてしまいます。
5
- バージョンなどは全て最新にしましたが、上手くいきませんでした。
6
3
 
4
+ `preventDefault`の指定箇所をいろいろ変更してみたのですが、読み込まれてしまいます。
5
+ そもそも書き方が違うのでしょうか?
7
- どうすればページが読み込れずにLikeを押せますか?
6
+ 他に必要なものがあれば追記いたしす。よろしくお願いいたします
8
7
 
9
-
10
-
11
- ```python
8
+ ```html
9
+ <form action="{% url 'app:like-post-view' %}" method="POST" class='like-form' id='{{item.id}}'>
10
+ {% csrf_token %}
11
+ <input type="hidden" name="post_id" value={{item.id}}>
12
+ <div class="LikesIcon">
13
+ {% if user not in item.liked.all %}
14
+ <i class="far fa-heart LikesIcon-fa-heart"></i><div class="like-count{{item.id}}"></div>
12
- models.py
15
+ {% else %}
13
-
14
- class Item(models.Model):
15
- post_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
16
- title = models.CharField(verbose_name='タイトル',max_length=200,)
17
- memo = models.TextField(verbose_name='備考',max_length=300,blank=True,null=True,)
18
- created_at = models.DateTimeField(verbose_name='登録日',auto_now_add=True)
19
- liked = models.ManyToManyField('User', blank=True, related_name='likes')
16
+ <i class="fas fa-heart LikesIcon-fa-heart" style="color:red;"></i><div class="like-count{{item.id}}"></div>
20
-
21
- # 管理サイト上の表示設定
17
+ {% endif %}
22
- def __str__(self):
18
+ </div>
23
- return self.title
19
+ </form>
24
-
25
- class Meta:
26
- verbose_name = 'アイテム'
27
- verbose_name_plural = 'アイテム'
28
-
29
- def num_likes(self):
30
- return self.liked.all().count()
31
20
  ```
32
-
33
- ```python
21
+ ```javascript
34
- #Likeボタン実装
35
- @login_required
36
- def like_unlike_post(request):
37
- user = request.user
38
- if request.method == 'POST':
39
- post_id = request.POST.get('post_id')
40
- post_obj = Item.objects.get(id=post_id)
41
- profile = User.objects.get(user_name=user)
42
-
43
- if profile in post_obj.liked.all():
44
- post_obj.liked.remove(profile)
45
- else:
46
- post_obj.liked.add(profile)
47
-
48
- like, created = Like.objects.get_or_create(user=profile, post_id=post_id)
49
-
50
- if not created:
51
- if like.value=='Like':
52
- like.value='Unlike'
53
- else:
54
- like.value='Like'
55
- else:
56
- like.value='Like'
57
-
58
- post_obj.save()
59
- like.save()
60
-
61
- #data = {'value': like.value,'likes': post_obj.liked.all().count()}
62
- #return JsonResponse(data, safe=False)
63
- return redirect('app:top')
64
- ```
65
-
66
- ```python
67
- urls.py
68
- path('', ItemFilterView.as_view(), name='top'),
69
- path('liked/', like_unlike_post, name='like-post-view'),
70
-
71
- ```
72
-
73
- ```html
74
- <div class="right floated">
75
- <form action="{% url 'app:like-post-view' %}" method="POST" class='like-form' id='{{item.id}}'>
76
- {% csrf_token %}
77
- <input type="hidden" name="post_id" value={{item.id}}>
78
-
79
- <button type="submit" class="ui button like-btn{{item.id}}">
80
- {% if profile not in item.liked.all %}
81
- Like<div class="like-count{{item.id}}">{{item.num_likes}}</div>
82
- {% else %}
83
- Unlike<div class="like-count{{item.id}}">{{item.num_likes}}</div>
84
- {% endif %}
85
- </button>
86
- </form>
87
- </div>
88
-
89
- {% block extrajs %}
90
22
  <script>
91
- function getCookie(name) {
92
- var cookieValue = null;
93
- if (document.cookie && document.cookie !== '') {
94
- var cookies = document.cookie.split(';');
95
- for (var i = 0; i < cookies.length; i++) {
23
+ $('.like-form').click(function() {
96
- var cookie = jQuery.trim(cookies[i]);
24
+ $('form').submit();
97
- // Does this cookie string begin with the name we want?
98
- if (cookie.substring(0, name.length + 1) === (name + '=')) {
99
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
100
- break;
101
- }
25
+ });
102
- }
103
- }
104
- return cookieValue;
105
- }
106
26
 
107
- var csrftoken = getCookie('csrftoken');
108
-
109
- function csrfSafeMethod(method) {
110
- // these HTTP methods do not require CSRF protection
111
- return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
112
- }
113
-
114
- $.ajaxSetup({
115
- beforeSend: function (xhr, settings) {
116
- if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
117
- xhr.setRequestHeader("X-CSRFToken", csrftoken);
118
- }
119
- }
120
- });
121
-
122
- $('#like-form').on('submit', e => {
27
+ $('.like-form').submit(function(e){
123
- // デフォルトのイベントをキャンセルし、ページ遷移しないように!
124
- e.preventDefault();
28
+ e.preventDefault()
125
29
 
126
30
  const post_id = $(this).attr('id')
127
31
 
128
- const likeText = $(`.like-btn${post_id}`).text()
32
+ const hasLike = $(`.LikesIcon${post_id}`).find('i').hasClass('like')
129
- const trim = $.trim(likeText)
33
+
130
-
131
34
  const url = $(this).attr('action')
132
35
 
133
36
  let res;
@@ -142,11 +45,11 @@
142
45
  'post_id':post_id,
143
46
  },
144
47
  success: function(response) {
145
- if(trim === 'Unlike') {
48
+ if(hasLike) {
146
- $(`.like-btn${post_id}`).text('Like')
49
+ $(`.like-btn${post_id}`).html('<i class="far fa-heart LikesIcon-fa-heart"></i>')
147
50
  res = trimCount - 1
148
51
  } else {
149
- $(`.like-btn${post_id}`).text('Unlike')
52
+ $(`.like-btn${post_id}`).html('<i class="fas fa-heart LikesIcon-fa-heart"></i>')
150
53
  res = trimCount + 1
151
54
  }
152
55
 
@@ -156,12 +59,24 @@
156
59
  console.log('error', response)
157
60
  }
158
61
  })
62
+ })
63
+ // Likeボタンクリック
64
+ $('.LikesIcon').on('click', function() {
65
+ let $btn = $(this);
66
+ // Likeボタンがonクラス持っていたら
67
+ if ($btn.hasClass('on')) {
159
68
 
69
+ $btn.removeClass('on');
70
+
71
+ // 白抜きアイコンに戻す
72
+ $btn.children("i").attr('class', 'far fa-heart LikesIcon-fa-heart');
73
+
74
+ } else {
75
+ $btn.addClass('on');
76
+ $btn.children("i").attr('class', 'fas fa-heart LikesIcon-fa-heart heart');
77
+
78
+ }
160
79
  })
80
+
161
81
  </script>
162
- {% endblock %}
163
-
164
- ```
82
+ ```
165
-
166
- Ajaxが間違っていると思い[このサイト](https://blog.narito.ninja/detail/88/)を見ながらやってもページがローディングされます。
167
- よろしくお願いします。