My Blade View 'chat.blade.php'
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading"</div>
<div class="panel-body">Chats
<chat-messages :messages="messages"></chat-messages>
</div>
<div class="panel-footer">
<chat-form
v-on:messagesent="addMessage"
:user="{{ Auth::user() }}"
></chat-form>
</div>
</div>
</div>
</div>
</div>
#endsection
This code is extend from app.blade.php, which probably its not really the main focus of the problem
and here is My 2 Component From My Vue JS
'ChatMessages.vue'
<template>
<ul class="chat">
<li class="left clearfix" v-for="message in messages">
<div class="chat-body clearfix">
<div class="header">
<strong class="primary-font">
{{ message.user.name }}
</strong>
</div>
<p>
{{ message.message }}
</p>
</div>
</li>
</ul>
</template>
<script>
export default {
props: ['messages']
};
</script>
and here is the 'ChatForm.vue'
<template>
<div class="input-group">
<input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Type your message here..." v-model="newMessage" #keyup.enter="sendMessage">
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendMessage">
Send
</button>
</span>
</div>
</template>
<script>
export default {
props: ['user'],
data() {
return {
newMessage: ''
}
},
methods: {
sendMessage() {
this.$emit('messagesent', {
user: this.user,
message: this.newMessage
});
this.newMessage = ''
}
}
}
</script>
and here is the following screenshot of the problem
Click here for the Picture
as you can see in the screenshot, the chat component from vue.js listed below, wont show up, its just appear blank, only displaying scrollbar,navbar and 'Chats' text. which is came from app.blade.php]
Please help me :). Thanks
You do not commit any messages to your component. :messages="messages" is Vue syntax.
Assuming your controller assigns $messages to your view:
<chat-messages messages="{{ json_encode($messages) }}"></chat-messages>
should do it. You need to use blade variables to assign
Related
I have VUE Field and Form components which renders a form depending on dynamic data.
<template>
<form #submit="$emit('submit', $event)" >
<template v-for="(item, index) in form.elements">
<Field
v-model="value[index]"
:label="item.options.label"
:type="item.type"
/>
</template>
</form>
</template>
I can render a form by passing structure data
<Form :form="formStructure" v-model="state" #submit="save()" />
This renders the from elements with the order in the formStructure object
What I want to do is to add a decoration template to Form component and customize the view.
<Form :form="formStructure" v-model="state" #submit="save()" >
<template >
<div class="row">
<div class="col-4"><i class="icon-user"></i> <!-- Field component will be render here by Form componenet --> </div>
<div class="col-8"><i class="icon-mail"></i> <!-- Field component will be render here by Form componenet --> </div>
</div>
<h2>A Custom Header</h2>
<div class="row">
<!-- another row with other elements-->
</div>
</template>
</Form>
formStructure data is someting like
{
"form":{
"method":"post",
"id":"formF75a1543a"
},
"elements":{
"username":{
"type":"inputtext",
"options":{
"label":"Pick a username"
}
},
"email":{
"type":"inputtext",
"options":{
"label":"Your e-mail"
}
}
}
}
How can I achive this?
I found the answer after a long research. Slots are not enough to solve the problem. Teleport will do the trick.
<!-- The Form Component -->
<template>
<form #submit="$emit('submit', $event)" >
<slot name="default" ></slot>
<template v-for="(item, index) in form.elements">
<teleport :to="'#'+index" :disabled="!fieldTargetExists(index)">
<Field
v-model="value[index]"
:label="item.options.label"
:type="item.type"
/>
</teleport>
</template>
</form>
</template>
<!-- Using component with a template -->
<Form :form="formStructure" v-model="state" #submit="save()" >
<template >
<div class="row">
<div class="col-4"><i class="icon-user"></i> <span id="username"></span> </div>
<div class="col-8"><i class="icon-mail"></i> <span id="email"></span> </div>
</div>
<h2>A Custom Header</h2>
<div class="row">
<div id="submit"></div>
</div>
</template>
</Form>
I am using vue pretty checkbox to display a checkbox. However, based on if one of the checkboxes is checked or not my content has to change! So, I need something like a listener on those vue pretty checkbox components.
However, because vue pretty checkbox is a package I cannot modify the code. My question now is, how can I listen on those checkboxes if they have changed from another component.
Because the products-manager component gets the values. So, whenever the values of the checkboxes of the p-check inside the product-filter changes, I need to pass that to the products-manager component in order to reload the data!
Any ideas on how I can do this? I have already tried this and this but those aren't working for me...
Very important: The number of checkboxes is dynamically as you can see below. The first two checkboxes are always there but the checkbox below gets genereated by a v-for!
This is my sourcecode so far (home template):
<div id="home" class="row">
<div class="col-xl-12" id="product-sort-and-filter">
<products-filter ref="productsFilter" :product-types-prop="{{ json_encode($productTypes) }}"></products-filter>
</div>
<div class="col-xl-9">
<div class="products">
<products-manager ref="productsManager" :products-prop="{{ json_encode($products) }}" auth="{{ \Illuminate\Support\Facades\Auth::check() }}" :userprop="{{ json_encode(\Illuminate\Support\Facades\Auth::user()) }}" route="{{ route('product.index') }}"></products-manager>
</div>
</div>
<div class="col-xl-3">
<sidebar-manager ref="SidebarManager" :top-products-today-prop="{{ json_encode($products) }}" :top-products-week-prop="{{ json_encode($products) }}" :top-products-month-prop="{{ json_encode($products) }}"></sidebar-manager>
</div>
</div>
products filter component:
<template>
<div class="product-sort-and-filter-wrapper d-flex">
<div class="col-xl-9 product-sorting no-padding">
<ul class="list-inline">
<li class="list-inline-item">Highlights</li>
<li class="list-inline-item">Aktuell</li>
<li class="list-inline-item">Diskutiert</li>
</ul>
</div>
<div class="col-xl-3 product-filter no-padding text-right">
<div class="dropdown d-inline-flex">
<i class="fas fa-filter"></i>FILTERN
<div class="dropdown-menu" style="margin-top: 0px">
<div class="productTypesBoxes dropdown-item pretty-checkbox-wrapper">
<p-check name="productExpiredCheckbox" class="p-svg p-plain p-bigger p-smooth" ref="showExpired" toggle true-value false-value>
<span class="checkbox-label on rubik-medium">Abgelaufene anzeigen</span>
<label slot="off-label"><span class="checkbox-label off rubik-medium">Abgelaufene anzeigen</span></label>
<span slot="extra" class="svg"><i data-feather="check-square"></i></span>
<span slot="off-extra" class="svg"><i data-feather="square"></i></span>
</p-check>
</div>
<div class="dropdown-divider"></div>
<div class="productTypesBoxes dropdown-item pretty-checkbox-wrapper">
<p-check name="productTypeCheckbox" class="p-svg p-plain p-bigger p-smooth" ref="showAllProductTypes" toggle true-value false-value checked>
<span class="checkbox-label on rubik-medium">Alle anzeigen</span>
<label slot="off-label"><span class="checkbox-label off rubik-medium">Alle anzeigen</span></label>
<span slot="extra" class="svg"><i data-feather="check-square"></i></span>
<span slot="off-extra" class="svg"><i data-feather="square"></i></span>
</p-check>
</div>
<div class="productTypesBoxes sub dropdown-item pretty-checkbox-wrapper" v-for="productType in productTypes">
<p-check name="productTypeCheckbox" :value="productType.id" class="p-svg p-plain p-bigger p-smooth" :ref="'productType' + productType.id" toggle>
<span class="checkbox-label on ">{{ productType.label }}</span>
<label slot="off-label"><span class="checkbox-label off ">{{ productType.label }}</span></label>
<span slot="extra" class="svg"><i data-feather="check-square"></i></span>
<span slot="off-extra" class="svg"><i data-feather="square"></i></span>
</p-check>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ProductsFilter",
props: ['productTypesProp'],
data() {
return {
highlights: true,
aktuell: false,
diskutiert: false,
showExipredDeals: false,
productTypes: this.productTypesProp
}
}
}
</script>
<style scoped>
</style>
i have a problem when i click on insert text button on component B it will add text card which is component A.. when inserting card i need textarea, and save button to be show then after click on save textarea must be hidden that's done but the problem is when reload the page the text area and save button become shown again..
note A, B are siblings
//Component A
<template>
<div class="answer-text-container answer-inner-container">
<div class="content-inner">
<p class="answer-type">{{ text.type }}</p>
<p v-show="!this.show" class="answer-text">{{ text.body }}</p>
<textarea v-model="text.body" v-show="this.show" rows="3" class="edit-text-area border rounded" placeholder="Enter the text here"></textarea>
</div>
<div class="button-container" v-show="!this.show">
<button type="button" #click="editText" class="btn btn-primary edit-text-btn">
<i v-bind:class="[editTextString]"></i>
</button>
<button type="button" #click="$emit('delete')" class="btn btn-danger edit-text-btn">
<i class="fas fa-trash-alt"></i>
</button>
</div>
<button type="button" #click="editText" class="btn btn-success rounded" v-show="this.show">Save</button>
</div>
</template>
<script>
export default {
data: function() {
return {
show: 0,
editTextString: "far fa-edit"
};
},
props: ["text"],
methods: {
editText() {
this.show = !this.show;
console.log(this.text);
},
removeTextComp() {}
}
};
//component B
<template>
<div class="toolbar-container mb-4">
<div class="col-md-12 p-0 text-center">
<div class="row mx-0">
<div class="col-md-4 p-0 d-inline-block toolbar-sub-container">
<a #click="insertText" href="#">
<p>Insert Text</p>
</a>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data: function() {
return {};
},
mounted() {},
methods: {
insertText() {
this.$parent.insertTextComp();
}
}
};
</script>
show:0 is entry value. When you reload page, this value too reload. So if you wanna have an actual value of show after reloading use localStorage or vuex store. And one more, I mean be better if your show value will be boolean.
I want to add a product to my favorites, but I do not want to make a load for the entire page, so I use JavaScript as shown in the code where I made an ancor disruption and created a form and took an id from the form and implemented it by using the submit function, but the following error appears and does
Uncaught TypeError: Cannot read property 'submit' of null
Please advise the importance
Thank you
this view
<div class="product-info">
<div class="tab-content" id="myTabContent">
<!-- Start Single Tab -->
<div class="tab-pane fade show active" id="man" role="tabpanel">
<div class="tab-single">
<div class="row">
#foreach($products as $p)
<div class="col-xl-3 col-lg-4 col-md-4 col-12">
<form action="{{route('cart.store')}}" method="post" id="add-cart-{{$p->id}}">
{{ csrf_field() }}
<input type="hidden" name="id" value="{{$p->id}}">
<input type="hidden" name="Product_Name_ar" value="{{$p->Product_Name_ar}}">
<input type="hidden" name="Price" value="{{$p->Price}}">
<div class="single-product">
<div class="product-img">
<a href="{{route('product', ['product' => $p->id])}}">
<img class="default-img" src="{{ asset('images/products/'.$p->image) }}" alt="#">
<img class="hover-img" src="{{ asset('images/products/'.$p->image) }}" alt="#">
</a>
<div class="button-head">
<div class="product-action">
#if(Auth::guard('customer')->check())
<span class="favorite-count">{{ $p->favorite_to_customers->count() }}</span>
<a title="Wishlist" href="javascript:void (0);" onclick="document.getElementById('favorite-{{$p->id}}').submit()" class="{{ Auth::guard('customer')->user()->favorite_products()->where('product_id', $p->id)->count() != 0 ? 'favorite' : '' }}">
<i class="fa fa-heart "></i><span>Add to Favorite</span></a>
<form id="favorite-{{$p->id}}" action="{{route('product.favorite', $p->id)}}" method="post">
{{ csrf_field() }}
</form>
#else
<span class="favorite-count">{{ $p->favorite_to_customers->count() }}</span>
<a title="Wishlist" href="javascript:void (0);" onclick="toastr.info('To add favorite list you to need login first', 'info', {
closeButton: true,
progressBar: true
})">
<i class="fa fa-heart "></i>
<span>Add to Favorite</span></a>
#endif
</div>
<div class="product-action-2">
<button style="background: transparent; border: none; color: black" class="btn btn-warning">Add to chart</button>
</div>
</div>
</div>
<div class="product-content">
<h3>{{ $p->Product_Name_ar }}</h3>
<div class="product-price">
<span>{{ $p->Price }} K.D</span>
</div>
</div>
</div>
</form>
</div>
#endforeach
</div>
</div>
</div>
<!--/ End Single Tab -->
</div>
</div>
This Controller
class Favoritecontroller extends Controller
{
public function add($id) {
$customer = Auth::guard('customer')->user();
$isFavorite = $customer->favorite_products()->where('product_id', $id)->count();
if($isFavorite == 0) {
$customer->favorite_products()->attach($id);
}else {
$customer->favorite_products()->detach($id);
}
return redirect()->back();
}
}
This Route
Route::group(['middleware' => ['auth:customer']], function () {
Route::post('favorite/{id}/add', 'FavoriteController#add')->name('product.favorite');
});
I assume your JS fails here
... onclick="document.getElementById('favorite-{{$p->id}}').submit()"
The proper way to do it
... onclick="addToWhishList({{$p->id}})"
Then in your JS
<script>
function addToWhishList(formId) {
//console.log(formId);
document.getElementById('favorite-' + formId).submit();
}
</script>
Check working Demo
I have a chat with pusher, it's working well, but now I would like to change the color of your own username when you are talking. At the moment, my username et the username of another user is in black, but I would like to have the username of your own account in another color to know when you are talking. (My english is kinda medium sorry ask if you need more explanation)
Thanx for helping
This is in my app.blade
<div class="row">
<div class="col-md-12 col-md-offset-2">
<div class="col-md-12 col-md-offset-2">
<div class="panel-body panel-content" id="mess_cont">
<chat-messages id="mess" :messages="messages"></chat-messages>
</div>
<div class="panel-footer">
<chat-form
v-on:messagesent="addMessage"
:user="{{ Auth::user() }}"
></chat-form>
</div>
</div>
</div>
</div>
This is my ChatMessages.vue :
<template>
<ul class="chat messages" >
<li class="left clearfix list-group-item" v-for="message in messages" >
<div class="chat-body clearfix">
<div class="header">
<strong class="primary-font" >
{{ message.user.firstName }}
{{ message.user.lastName}}
</strong>
</div>
<p>
{{ message.message }}
</p>
</div>
</li>
</ul>
</template>
<script>
export default {
props: ['messages']
};
</script>
Assuming your User model has some sort of id, you could apply CSS classes or styles based on the id of the author of the message.
It could be something like this
<chat-messages id="mess" :messages="messages" :currentuserid="{{Auth::user()->id}}"></chat-messages>
<template>
<ul class="chat messages" >
<li class="left clearfix list-group-item" v-for="message in messages" >
<div class="chat-body clearfix">
<div class="header">
<strong class="primary-font "
v-bind:class="{
classForAuthorSameAsUser: (message.user.id === currentuserid),
classForAuthorDiffThanUser: (message.user.id !== currentuserid)
}">
{{ message.user.firstName }}
{{ message.user.lastName}}
</strong>
</div>
<p>
{{ message.message }}
</p>
</div>
</li>
</ul>
</template>
<script>
export default {
props: ['messages','currentuserid']
};
</script>
<style scoped>
.classForAuthorSameAsUser {
color: red;
}
.classForAuthorDiffThanUser {
color: blue;
}
</style>