Skip to content

Instantly share code, notes, and snippets.

@webuilder240
Last active August 25, 2021 15:00
Show Gist options
  • Save webuilder240/19483f3732e7350ee2559b858a6d6f33 to your computer and use it in GitHub Desktop.
Save webuilder240/19483f3732e7350ee2559b858a6d6f33 to your computer and use it in GitHub Desktop.
MPAでページネーションをまたいでのチェックボックスの内容を保持するコードの比較(Vue, Stimulus)
<p id="notice"><%= notice %></p>
<h1>Users</h1>
<div data-controller="hello" data-hello-check-ids-value="[]">
<table>
<thead>
<tr>
<th>
<input type="checkbox" data-action="hello#toggleCheckAllDisplayUsers">
</th>
<th>Name</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td>
<input type="checkbox" data-hello-target="checkbox" data-id="<%= user.id %>" data-action="hello#checkUser">
</td>
<td><%= user.name %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<div data-hello-target="modal">
<p data-hello-target="modalText"></p>
</div>
</div>
<br>
<%= link_to 'New User', new_user_path %>
<%= paginate @users %>
import { Controller } from "stimulus"
export default class extends Controller {
static targets = ['checkbox', "modal", "modalText"]
static values = { checkIds: Array }
connect() {
const l = sessionStorage.getItem(this._sessionStorageKeyName())
if (l) {
const checkids = JSON.parse(l)
this.checkIdsValue = checkids
}
this.checkboxTargets.forEach(e => {
e.checked = this.checkIdsValue.includes(`${e.dataset.id}`)
})
}
toggleCheckAllDisplayUsers(e) {
const el = e.target
const lists = []
if (el.checked) {
this.checkboxTargets.forEach(e => {
e.checked = true
lists.push(e.dataset.id)
})
} else {
this.checkboxTargets.forEach(e => {
e.checked = false
})
}
this.checkIdsValue = lists
}
checkUser(e) {
const el = e.target
const checkUserId = el.dataset.id
const lists = this.checkIdsValue
if (el.checked) {
lists.push(checkUserId)
} else {
const index = this.checkIdsValue.indexOf(checkUserId)
if (index !== -1) {
lists.splice(index, 1)
}
}
this.checkIdsValue = lists
}
checkIdsValueChanged() {
if (this.checkIdsValue.length > 0) {
this.modalTarget.hidden = false
this.modalTextTarget.innerText = `${this.checkIdsValue.length}件を選択しています。`
} else {
this.modalTarget.hidden = true
this.modalTextTarget.innerText = ``
}
}
_sessionStorageKeyName() {
return `check_users`
}
}
<p id="notice"><%= notice %></p>
<h1>Users</h1>
<div id="vue-app">
<table>
<thead>
<tr>
<th>
<input type="checkbox" @click="allToggleCheckUsers($event)">
</th>
<th>Name</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<tr v-for="user in users">
<td>
<input type="checkbox" :value="user.id" v-model="checkedUserIds">
</td>
<td v-text="user.name"></td>
<td>
Show
</td>
<td>
Edit
</td>
<td>Destroy</td>
</tr>
</tbody>
</table>
<div v-if="showModal">
<p>{{ checkedUserIds.length }}件が選択されています</p>
</div>
</div>
<br>
<%= link_to 'New User', new_user_path %>
<%= paginate @users %>
<script>
window.users = <%= @users.to_json.html_safe %>
</script>
window.addEventListener('DOMContentLoaded', (event) => {
const vueEl = document.getElementById("vue-app")
if (vueEl) {
new Vue({
el: vueEl,
data() {
return {
users: window.users || [],
checkedUserIds: []
}
},
created() {
const l = sessionStorage.getItem(this.sessionStorageKeyName)
if (l) {
this.checkedUserIds = JSON.parse(l)
}
},
methods: {
allToggleCheckUsers(e) {
if (e.target.checked) {
this.checkedUserIds = this.users.map((user) => user.id )
} else {
this.checkedUserIds = []
}
}
},
computed: {
sessionStorageKeyName() {
return `check_users`
},
showModal() {
return this.checkedUserIds.length > 0
}
},
watch: {
checkedUserIds: function(value) {
sessionStorage.setItem(this.sessionStorageKeyName, JSON.stringify(value))
}
}
})
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment