Vue.js add class on specific element - laravel

So im creating a basic tasklist where i want to set them done, when the <li>is clicked. When it's clicked i want that a class is added to the <li> thats clicked. i could not figure this out with the docs so i hope someone could help me out :D
The code i already have:
<transition-group name="list">
<li class="list-item list-group-item" v-for="(task, index) in list" :key="task.id" v-on:click="finishTask(task.id)" >
#{{ task.text }}
<button #click="removeTask(task.id)" class="btn btn-danger btn-xs pull-right">Delete</button>
</li>
</transition-group>
</ul>
</div>
// get the csrf token from the meta
var csrf_token = $('meta[name="csrf-token"]').attr('content');
export default {
data() {
return {
list: [],
taskInput: {
id: '',
text: ''
}
};
},
// So the tasks will show when the page is loaded
created() {
this.allTasks();
},
methods: {
// get all the existing tasks
allTasks() {
axios.get('tasks').then((response) => {
this.list = response.data;
});
},
// create a new task
createTask() {
axios({
method: 'post',
url: '/tasks',
data: {
_token: csrf_token,
text: this.taskInput.text,
},
}).then(response => {
this.taskInput.text = '';
this.allTasks();
});
},
// remove the tasks
removeTask(id) {
axios.get('tasks/' + id).then((response) => {
this.allTasks();
});
},
finishTask(id) {
axios({
method: 'post',
url: 'tasks/done/' + id,
data: {
_token: csrf_token,
data: this.taskInput,
},
}).then(response => {
this.allTasks();
});
}
}
}
I know how i should do this with jquery but not with vue js, i hope this aint a to stupid question :D

You can bind css classes and styles, add a Boolean done property to your note object with default value of false, when you click the note change its done property to true. here is an example
new Vue({
el:"#app",
data:{
notes: [
{ text: "First note", done:false },
{ text: "Second note", done:false },
{ text: "Third note", done:false },
{ text: "Fourth note", done:false },
{ text: "Fifth note", done:false }
]
},
methods:{
finishNote(note){
// send your api request
// then update your note
note.done = true
}
}
})
.done{
background-color:green;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.min.js"></script>
<div id="app">
<ul>
<li v-for="note in notes" :class="{done:note.done}" #click="finishNote(note)">{{note.text}}</li>
</ul>
</div>

You can use the event argument. Which is automatically provided on your on click method.
onListClicked(event) {
event.target.className += " myClass";
}
Here I did a demo for you: https://jsfiddle.net/6wpbp70g/

Related

Shopify Ajax API, Alpine JS, add user selected options to cart using Ajax

I am building this Build A Box section where a user can select various items that make up 1 product. I'm having trouble getting items into the cart.
UPDATE:
Current state is can add the hard coded main product in formData I did this first to get addToCart started. It’s adds the main product but does not redirect to cart page. If you change url in browser to /cart its in there.
I need to figure out 2 things.
1 how to redirect to cart page after firing addToCart()
2 How to add user selected items as 1 product to cart not variants.
See Logs
I can select elements and push into an array in my x-data component. The data looks like this:
[
{img_string: 'https://cdn.shopify.com/s/files/1/0695/7495/1222/files/Barky.webp?
v=1672528086&width=150', title: 'Barky', id: 'selected_item-1'},
{img_string: 'https://cdn.shopify.com/s/files/1/0695/7495/1222/files/Barky.webp?
v=1672528086&width=150', title: 'Barky', id: 'selected_item-1'}
]
For my latest iteration, I just hard coded the variant id & a quantity. Still have to figure out how to get all the selected items into the cart.
UPDATE: I added preventDefault filter to Alpine addToCart() call now it does not redirect but if you change url in browser to /cart the hard coded main product is in there.
<div x-data="items: []">
<div
x-data="
{
qty: 1,
addToCart(){
let formData = {
'items': [{
'id': 44202123100470,
'quantity': 1
}]
};
fetch(window.Shopify.routes.root + 'cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => {
console.log(response)
return response.json();
})
.catch((error) => {
console.error('Error:', error);
});
}
}
"
class="tw-mt-12 tw-flex tw-flex-col tw-p-auto tw-bg-brandText tw-opacity-80"
>
<div class="tw-p-8">
<h2 class="tw-mb-4 tw-text-white">Your Selections</h2>
{% assign product_form_id = 'product-form-' | append: section.id %}
{%- form 'product',
product,
id: product_form_id,
class: 'form',
novalidate: 'novalidate',
data-type: 'add-to-cart-form'
-%}
<input
type="hidden"
name="id"
value="{{ product.selected_or_first_available_variant.id }}"
disabled
>
<input type="hidden" name="quantity" x-model="qty" value="1">
<div class="product-form__buttons">
<button
type="add"
#click="addToCart()"
:class="full_box ? 'tw-bg-ctaColor' : ''"
class="tw-bg-white tw-text-brandText tw-flex tw-justify-center tw-py-4 tw-px-6 tw-rounded-full tw-font-bold"
>
<p class="" x-show="!full_box">
<span x-text="items_selected" class="tw-mr-2"></span><span class="tw-mr-2">of</span
><span class="tw-font-bold" x-text="box_size"></span><span class="tw-ml-2">Selected</span>
</p>
<p x-show="full_box" class="">Add to cart</p>
</button>
</div>
{%- endform -%}
</div>
</div>
The way I solved the redirect issue was to use the Location API add location.href="/cart" in the success promise of the Ajax call.
fetch(window.Shopify.routes.root + 'cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => {
console.log(response)
return response.json();
})
.then((data) => {
location.href = '/cart';
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
To solve the issue of how to get all selected items into the cart. I mapped over the items array of objects and returned an array of strings. Then I assigned to a variable selectedItems and called toString()
In the properties key of formData I added a value of selectItems to Box Items key. Kinda ugly at the moment no spaces in string. Definitely need to refactor this. Any feedback would be Super Cool πŸ„β€β™‚οΈ
<div
x-data="
{
addToCart(items, id){
let itemsToAdd = items.map((item) => {
return item['title'];
})
let selectedItems = itemsToAdd.toString()
let formData = {
'items': [{
'id': id,
'quantity': 1,
'properties': {
'Box Items': selectedItems,
}
}]
};
fetch(window.Shopify.routes.root + 'cart/add.js', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => {
console.log(response)
return response.json();
})
.then((data) => {
location.href = '/cart';
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
reset()
}
}
"
class="tw-mt-12 tw-flex tw-flex-col tw-p-auto tw-bg-brandText tw-opacity-80"
>...</div>

Managing alpine component outside x-data

So I am trying to manage the data of an alpine component outside the x-data... for example:
<div x-data="toastr()" x-show="isOpen">
<span x-text="title"></span>
<span x-text="body"></span>
</div>
<script>
function toastr() {
isOpen: false,
title: '',
body: '',
open() {
this.isOpen = true
},
set(data) {
this.title = data.title
this.body = data.body
}
}
</script>
.... other html
<script>
toastr().open();
toastr().set({
'title': "Hello",
'body': "Some body",
});
</script>
When I call toastr() for open and set, it doesn't show the toaster and I am assuming it doesn't update the title and body too... How can I achieve this?

Vue Object is Empty

I'm using Vuejs to display data from an API to a template. I'm trying to figure out why I am not returning data for the team so I can display in for the template. Right now when I use the VueJS Chrome Extention it shows that the team is an empty object.
<div v-if="team">
<div class="row">
<div class="col-12 col-sm-12">
<div class="fw-700 pb3 mb5" style="border-bottom: 1px solid #333;">Name:</div>
<div class="mb10" style="font-size: 20px;">{{ team.name }}</div>
</div>
</div>
<script>
module.exports = {
http: {
headers: {
'X-CSRF-TOKEN': window.Laravel.csrfToken
}
},
props: [ 'id', 'editable' ],
data: function(){
return {
modalName: 'additionalInfo',
team:{
}
}
};
},
methods: {
fetchInfo: function(){
this.$http.get('/api/teams/info', { params: { id: this.id } }).then((response) => {
this.team = response.data;
});
},
},
}
}
</script>
It is empty because your method fetchInfo isn't being called, so you need to do something like this:
created () {
this.fetchInfo()
}
This will call the function fetchInfo which in turn will fetch and fill this.team

SmartAdmin DataTable Button Column

Regards, I have a problem I am using the SmartAdmin DataTable and I need to put three buttons in a column to edit, view and delete an element I have already put the buttons in a Column, but until now I have not been able to make them respond to the even to click.
Thank you.
enter image description here
This is the code I have in my ngOnInit
this.options = {
dom: "Bfrtip",
ajax: (data, callback, settings) => {
this._usuarioService.readUsuarios()
.subscribe((data) => {
callback({
aaData: data
})
})
},
columns: [
{ data: 'id' },
{ data: 'persona.nombre' },
{ data: 'persona.apellido' },
{ data: 'persona.correo' },
{ data: 'rol.nombre' },
{ data: 'persona.sede.nombre' },
{defaultContent: '<center><button class=\'btn btn-success btn-xs\'(click)=\'leerUnUsuario(id)\'> Ver </button> ' +
'<button class=\'btn btn-info btn-xs\' (click)=\'actualizarUsuario(id)\'> Editar </button> ' +
'<button class=\'btn btn-danger btn-xs\' (click)=\'eliminarUsuario(id)\'> Borrar </button></center>' },
]
};
Already solved, I received help from Alain D'EURVEILHER and everything is already very well.
ngOnInit() {
this.options = {
dom: "Bfrtip",
ajax: (data, callback, settings) => {
this._usuarioService.readUsuarios()
.subscribe((data) => {
callback({
aaData: data
})
})
},
columns: [
{ data: 'id' },
{ data: 'persona.nombre' },
{ data: 'persona.apellido' },
{ data: 'persona.correo' },
{ data: 'rol.nombre' },
{ data: 'persona.sede.nombre' },
{
render: (data, type, fullRow, meta) => {
return `
<button class="btn btn-xs btn-success accion-ver-usuario" data-usuario-id="${fullRow.id}">ver</button>
<button class="btn btn-xs btn-info accion-editar-usuario" data-usuario-id="${fullRow.id}">editar</button>
<button class="btn btn-xs btn-danger accion-borrar-usuario" data-usuario-id="${fullRow.id}">borrar</button>
`;
}
}
]
};
ngAfterViewInit(){
document.querySelector('body').addEventListener('click', (event)=> {
let target = <Element>event.target;// Cast EventTarget into an Element
if (target.tagName.toLowerCase() === 'button' && $(target).hasClass('accion-ver-usuario')) {
this.verUsuario(target.getAttribute('data-usuario-id'));
}
if (target.tagName.toLowerCase() === 'button' && $(target).hasClass('accion-editar-usuario')) {
this.editarUsuario(target.getAttribute('data-usuario-id'));
}
if (target.tagName.toLowerCase() === 'button' && $(target).hasClass('accion-borrar-usuario')) {
this.borrarUsuario(target.getAttribute('data-usuario-id'));
}
});
}
verUsuario(userId){
console.log("user displayed:", userId);
}
editarUsuario(userId){
console.log("user edited:", userId);
}
borrarUsuario(userId){
console.log("Delete user", userId, "?");
}

checkbox in vuejs and laravel

I want to generate checkbox using v-for and use v-model. But i am having difficult time trying the get the value of checkbox. Here is what i am doing. My view looks like this:
<div class="checkbox" v-for="role in userRole">
<label>
<input v-model="newUser.urole" type="checkbox"
value="#{{role.roName}}">#{{role.roName}}</label>
</div>
Here is my Vue Js:
var emailRe = /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*#([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i
var vm = new Vue({
el: '#userMgt',
data: {
newUser:{
fname: '',
mname: '',
lname: '',
email: '',
username: '',
password: '',
conpassword: '',
utype: '',
urole:''
},
},
methods: {
fetchUser: function () {
this.$http.get('../api/users', function (data) {
this.$set('users', data)
});
},
fetchUserType: function () {
this.$http.get('../api/usertype', function (data) {
this.$set('userType', data);
});
},
fetchUserRole: function () {
this.$http.get('../api/role', function (data) {
this.$set('userRole', data);
});
},
AddNewUser: function(){
//user input
var user = this.newUser;
alert(user.urole) ///not alerting right info
//clear form input
this.newUser = {fname:'',mname:'',lname:'',email:'',username:'',password:'',conpassword:'',utype:'',urole:''};
this.$http.post('../api/users', user);
;
},
selectAll: function(){
}
},
computed: {
},
ready: function () {
this.fetchUser();
this.fetchUserType();
this.fetchUserRole();
}
});
I am not able to get the selected value in newUser.urole and more over all my checkbox gets selected when i click one. How can i do this?. Thanks

Resources