make input search box full screen overlay on click on mobile device - css

I am using buefy autocomplete input fields in my nuxtjs project, this is location search box, what i want is just for mobile device, when i click the input field, it should overlay on full screen with suggestion like i attached screenshot below and after select suggestion, it should close and return to normal.
here is my simple auto complete input field code.
<template>
<b-autocomplete
v-model="pickupairport"
:data="airports"
name="pickupairport"
class="ttc-search-input"
icon="map-marker-outline"
placeholder="Pickup Airport"
field="name"
:loading="isFetching"
#typing="getairports"
#select="(option) => (aptselected = option)"
>
<template slot-scope="props">
<div class="media">
<div class="media-content">
{{ props.option.name }}
<br />
<small> {{ props.option.cityName }}, {{ props.option.countryName }} </small>
</div>
</div>
</template>
</b-autocomplete>
</template>
<script>
import { debounce } from 'lodash'
export default {
data() {
return {
pickupairport: '',
airports: [],
aptselected: null,
isaptFetching: false,
}
},
methods: {
getairports: debounce(function (pickupairport) {
const aptsearchq = this.pickupairport
if (!pickupairport.length) {
this.airports = []
return
}
this.isaptFetching = true
fetch(`https://api.myurl.com/api/transfers/aplist?querystring=${aptsearchq}`)
.then((response) => {
return response.json()
})
.then((data) => {
this.airports = []
data.response.forEach((item) => this.airports.push(item))
})
.catch((error) => {
this.airports = []
throw error
})
.finally(() => {
this.isaptFetching = false
})
}, 500),
},
}
</script>
What I want to achieve is like this GIF - https://i.imgur.com/zOYPwBI.gif
What I have now is like this GIF - https://imgur.com/9ZBZzxa
i tried to find something related, but couldn't find, if any suggestion on how to achieve that, it would be helpful for me.

Related

If the value in one dropdown changed, how to reload the values for the second dropdown? How to do Partial Reload in InertiaJs

Q: If the value in one dropdown changed, how to reload the values for the second dropdown?
When user change the category dropdown, then I want to show the subcategory in the dropdown
Frontend: VueJs (v3)
Server Side Rendering: IneratiaJs
Backend: Laravel (v9)
VueComponent
const props = defineProps({
errors: Object,
categories: Object,
subcategories: Object,
})
const form = useForm({
category_id: '',
subcategory_id: '',
name: '',
price: '',
discount: '',
image: 'sample',
description: ''
});
let getSubcategory = (event) => {
if(event.target.value !== "") {
Inertia.reload({
'category_id': event.target.value
},
{ only: ['subcategories'],
onSuccess: page => {
alert();
console.log('onSuccess');
console.log(props.categories);
console.log(props.subcategories);
console.log(page);
}
}
);
}
}
const submit = () => {
form.post(route('store.subcategory'), {
onFinish: () => form.reset(),
});
};
Vue Template
<template>
<Head title="Add Product" />
<BreezeAuthenticatedLayout>
<template #header>
<form #submit.prevent="submit">
<div class="mt-4">
<BreezeLabel for="category_id" value="Category Name" />
<select #change="getSubcategory" v-model="form.category_id" id="category_id" class="block mt-1 w-full">
<option value="">Select Category</option>
<option v-for="category in categories" :value="category.id">{{ category.name }}</option>
</select>
<div v-if="errors.category_id" class="text-red-400">
{{ errors.category_id }}
</div>
</div>
<div class="mt-4">
<BreezeLabel for="subcategory_id" value="Subcategory Name" />
<select v-model="form.subcategory_id" id="subcategory_id" class="block mt-1 w-full">
<option value="">Select Sategory</option>
<option v-for="subcategory in subcategories" :value="subcategory.id">{{ subcategory.name }}</option>
</select>
<div v-if="errors.subcategory_id" class="text-red-400">
{{ errors.subcategory_id }}
</div>
</div>
</form>
</BreezeAuthenticatedLayout>
</template>
Laravel Route: routes/web.php
Route::get('/create/product/{category_id?}', [ProductController::class, 'create'])->name('create.product'); //Form: Create Product
Product Controller: ProductController.php
public function create($category_id = null)
{
return Inertia::render('Product/Create', [
//I want Evaluated immediately on Page Load.
'categories' => $categories = Category::all(),
//Want Lazy load here.
'subcategories' => function(){
if(!empty($category_id)){
$category = Category::find($category_id);
$subcategories = $category->subcategories()->get();
}
},
]);
}
After fixing Create method in Product Controller and script setup it's working
public function create($category_id = null)
{
return Inertia::render('Product/Create', [
// ALWAYS included on first visit - OPTIONALLY included on partial reloads - ALWAYS evaluated
'categories' => Category::has('subcategories')->get(),
// NEVER included on first visit - OPTIONALLY included on partial reloads - ONLY evaluated when needed
'subcategories' => Inertia::lazy(fn () =>
Subcategory::with('category')->where('category_id', '=', $category_id)->get()
),
]);
}
Vue SCRIPT: I was sending wrong parameters. Then I saw correct way of partial relaod on official site
let getSubcategory = (event) => {
if(event.target.value !== "") {
Inertia.visit(
route('create.product', {
category_id: event.target.value
}),{
only: ['subcategories'],
preserveState: true,
preserveScroll: true,
}
);
}
}

Fetch and display lists of an user

I have a profile page that displays the user info. The page shows the user name / email and a button to create a list.
I can also edit the name and email correctly, and it reflects in the firebase instantaneously. Ok. I get the user data and I can edit it.
What I'm trying to do now is to show the lists that the user has created.
Look, this user has created one list, and what is returned to me is that he doesn't have lists.
I'll try to shorten the code as much as possible:
<script>
imports.....
import { db } from '../../firebase.config.js'
let listings = []
let auth = getAuth()
// fetch the user's listings
const fetchUserListings = async () => {
const listingsRef = collection(db, 'listings')
const q = query(
listingsRef,
where('userRef', '==', auth.currentUser.uid),
orderBy('timestamp', 'desc')
)
const querySnap = await getDocs(q)
querySnap.forEach((doc) => {
return listings.push({
id: doc.id,
data: doc.data()
})
})
}
fetchUserListings()
</script>
<!-- display the user's listings -->
<div>
{#if listings.length > 0}
<p class="listingText">My lists</p>
{#each listings as listing}
<ListingItem listing={listing.data} id={listing.id} />
{/each}
{:else}
<p class="noListings">You have no lists</p>
{/if}
</div>
My ListItem component:
<script>
export let listing
export let id
export let handleDelete
import DeleteIcon from '../../static/assets/svg/deleteIcon.svg'
</script>
<li class="categoryListing">
<a href={`/category/${listing.type}/${id}`} class="categoryListingLink">
<img src={listing.imgUrls[0]} alt={listing.name} class="categoryListingImg" />
<div class="categoryListingDetails">
<p class="categoryListingLocation">
{listing.location}
</p>
<p class="CategoryListingName">
{listing.name}
</p>
<p class="categoryListingPrice">
${listing.offer ? listing.discountedPrice : listing.regularPrice}
{listing.type === 'rent' ? '/ por mês' : ''}
</p>
<div class="categoryListingInfoDiv">
<img src="/assets/svg/bedIcon.svg" alt="cama" />
<p class="categoryListingInfoText">
{listing.bedrooms > 1 ? `${listing.bedrooms} camas` : `${listing.bedrooms} cama`}
</p>
<img src="/assets/svg/bathtubIcon.svg" alt="banheiro" />
<p class="categoryListingInfoText">
{listing.bathrooms > 1
? `${listing.bathrooms} banheiros`
: `${listing.bathrooms} banheiro`}
</p>
</div>
</div>
</a>
{#if handleDelete}
<DeleteIcon
class="removeIcon"
fill="rgb(231, 76, 60)"
onClick={() => {
handleDelete(listing.id, listing.name)
}}
/>
{/if}
</li>
Just when you think you've reached the simplest part, it's still tough.
Update:
I think that the problem is in firebase. The "docs" are empty:
Now I am in serious trouble!
querySnap.forEach((doc) => {
return listings.push({
id: doc.id,
data: doc.data()
})
})
I see two things here. The less important: The .forEach() method returns undefined, so the return is redundant. The more important: the .push() alone won't automatically trigger updates. Have a look at this section in the Docs
Did you try logging listings? I assume the data is there, it's just not displayed, so I propose to change this part to
querySnap.forEach((doc) => {
listings = [...listings, {
id: doc.id,
data: doc.data()
}]
})
or
querySnap.forEach((doc) => {
listings.push({
id: doc.id,
data: doc.data()
})
listings = listings
})

How to use Vue.Draggble and sort Firebase Realtime Storage?

I have a Vue.js project and I have Customers List with First Name- Last Name- Address-City-State/Province-Email like this >>>
See project image here...
With Blue Button --Kayit Ol-- I fill the form and make a registiration. See picture>> Register Form
When I click the Yellow Button --Ayarlar-- I need to see the all cities in the Draggble List and when I sort in the Draggble and click the Green Button --Şehre Göre Sırala-- , the Customer List below should be sorted same as Draggble List. I used Vue.Draggble package (https://github.com/SortableJS/Vue.Draggable) but I cannot take firebase data properly and sort them.
SignUp.vue
// Musteriler
var clientRef = db.ref('musteriler/');
var newClient = clientRef.push();
//Cities
var citiesRef=db.ref('cities/');
var newCity = citiesRef.push();
export default {
data() {
return {
form: {
firstName: '',
lastName: '',
address: '',
city:'',
province:'',
email: '',
},
selectedCities:['Ankara', 'Adana',],
cities : ['','Adana', 'Adıyaman', 'Afyon', 'Ağrı', 'Amasya', 'Ankara', 'Antalya', 'Artvin',
'Aydın', 'Balıkesir', 'Bilecik', 'Bingöl', 'Bitlis', 'Bolu', 'Burdur', 'Bursa', 'Çanakkale',
'Çankırı', 'Çorum', 'Denizli', 'Diyarbakır', 'Edirne', 'Elazığ', 'Erzincan', 'Erzurum', 'Eskişehir',
'Gaziantep', 'Giresun', 'Gümüşhane', 'Hakkari', 'Hatay', 'Isparta', 'Mersin', 'İstanbul', 'İzmir',
'Kars', 'Kastamonu', 'Kayseri', 'Kırklareli', 'Kırşehir', 'Kocaeli', 'Konya', 'Kütahya', 'Malatya',
'Manisa', 'Kahramanmaraş', 'Mardin', 'Muğla', 'Muş', 'Nevşehir', 'Niğde', 'Ordu', 'Rize', 'Sakarya',
'Samsun', 'Siirt', 'Sinop', 'Sivas', 'Tekirdağ', 'Tokat', 'Trabzon', 'Tunceli', 'Şanlıurfa', 'Uşak',
'Van', 'Yozgat', 'Zonguldak', 'Aksaray', 'Bayburt', 'Karaman', 'Kırıkkale', 'Batman', 'Şırnak',
'Bartın', 'Ardahan', 'Iğdır', 'Yalova', 'Karabük', 'Kilis', 'Osmaniye', 'Düzce'],
show: true
}
},
methods: {
onSubmit(evt) {
evt.preventDefault();
newClient.set(this.form);
this.selectedCities.push(...this.selectedCities, this.form.city);
console.log(this.selectedCities);
newCity.set(this.selectedCities);
alert(JSON.stringify(this.form))
},
onReset(evt) {
evt.preventDefault()
// Reset our form values
this.form.firstName = ''
this.form.lastName = ''
this.form.address = ''
this.form.city = ''
this.form.province = ''
this.form.email = ''
// Trick to reset/clear native browser form validation state
this.show = false
this.$nextTick(() => {
this.show = true
})
}
}
}
</script>
Settings.Vue
<template>
<div class="col s12 drag">
<div class="col s12">
<p>Şehirleri sürükleyerek listeyi istediğiniz şekilde sıralandırabilirsiniz.</p>
</div>
<div class="col s12 mx-auto">
<draggable v-model="cities" class="draggable-container" #ended="onEnd" ghost-class='ghost'>
<transition-group type="transition" name="flip-list">
<div class="sortable mx-auto" v-for="item in cities" :key="item">
<strong>{{item}}</strong>
</div>
</transition-group>
</draggable>
<button class="btn btn-success mb-3" #click="onSort">Şehre Göre Sırala</button>
</div>
</div>
</template>
<script>
import {db} from '../firebase/db';
import draggable from 'vuedraggable'
var cityRef=db.ref('cities')
console.log(cityRef);
export default {
components: {
draggable,
},
firebase:{
cities: cityRef,
},
data() {
return {
}
},
methods: {
onEnd(evt) {
evt.preventDefault();
console.log(evt);
},
onSort() {
this.cities = this.cities.sort((a, b) => a.order - b.order);
}
}
}
</script>
Firebase Data
See Firebase RealTime Database musteriler Picture >>> musteriler.json
See Firebase RealTime Database cities Picture >>> cities.json
So how should I arrange the Database and how can I sort Customer List by Vue.Draggble properly ?
Thanks.

Pushing data to object in different component using POST

TL;DR I want to show submitted posts instantly instead of having to refresh my page
Using the Wordpress REST API I am able to create a new post without any issue. The post is being displayed as soon as the page refreshes, so what I want to do is update the posts object in my Hello.vue file as soon as I create that post so I don't need to refresh to show my newest posts.
I'm not really sure where to start - I've removed all of the experiments I've done so far (importing Post in Create, defining props, pushing to an array, reading about object reactivity on the official Vue documentation, nothing helped).
My App.js consists of the <router> object which shows Hello.vue and a component called Create which displays the Create.vue component. This is how my app currently looks like:
My App.vue file:
<template>
<div id="app">
<section class="posts">
<router-view></router-view>
<create></create>
</section>
</div>
</template>
<script>
import Create from '#/components/Create.vue'
export default {
name: 'app',
components: {
Create
}
}
</script>
<style lang="scss">
#import '../src/assets/styles/style.scss'
</style>
My Hello.vue which displays all the posts:
<template>
<div>
<section class="posts__Feed">
<ul class="posts__List">
<post v-for="item in posts" :item="item" :key="item.id"></post>
</ul>
</section>
</div>
</template>
<script>
var postsUrl = '/wp-json/wp/v2/posts/'
import Post from '#/components/Post.vue'
export default {
name: 'hello',
props: ['responseData'],
components: {
Post
},
data () {
return {
posts: []
}
},
beforeCreate () {
this.$http.get(postsUrl).then((response) => {
this.posts = response.data
})
}
}
</script>
And finally, the Create.vue file which creates the post:
<template>
<div>
<section class="posts__Create">
<form class="posts__CreateForm" v-on:submit="createPosts">
<div class="posts__CreateFormWrapper" v-bind:class="{ 'is-Loading': loading }">
<p>
<input v-model="formInfo.title" type="text" name="title" id="title" placeholder="Name" :disabled="formSent">
</p>
<p>
<textarea v-model="formInfo.content" name="content" id="content" cols="20" rows="10" maxlength="140" placeholder="Message" :disabled="formSent"></textarea>
</p>
<p>
<button :disabled="formSent">Send</button>
</p>
</div>
</form>
</section>
</div>
</template>
<script>
var postsUrl = '/wp-json/wp/v2/posts/'
export default {
name: 'create',
data () {
return {
formInfo: [],
responseData: [],
loading: false,
formSent: false
}
},
methods: {
createPosts (e) {
e.preventDefault()
var info = this.formInfo
// Check if fields are empty
if (this.formInfo.title && this.formInfo.content) {
this.loading = true
// POST
this.$http.post(postsUrl, info).then((response) => {
this.formSent = true
this.loading = false
// get body data
this.responseData = response.data
})
}
} // EOF createPosts
}
}
</script>
Any help would be much appreciated!
I ended up using an event bus as suggested by wotex. First, I've createad a file called bus.js with the below code:
import Vue from 'vue'
export const EventBus = new Vue()
Next, import bus.js to both .vue layouts using:
import { EventBus } from '#/bus.js'
Now emit the event as soon as a new post is created (this is sitting in my axios POST request inside the Create.vue file):
EventBus.$emit('newPost', this.responseData)
And finally, check if the event has happened on the other end (my Hello.vue file):
EventBus.$on('newPost', function (postData) {
Thanks for pointing me in the right direction!

Ionic - set style to Checkbox-Text when checked

I am trying to create a first ToDo-App for my own.
I want to use ionic, because we will need it later at work (so I can make some experiences).
Now - I have my app with simple to-do tasks, which is a list of checkboxes, implemented as
<ion-checkbox ng-repeat="task in activeProject.tasks"
ng-model="task.checked"
ng-change="toggleItemDisplay(task)">
{{ task.title }}
</ion-checkbox>
I can write something into the console with this "toggleItemDisplay"-Function, which is implemented in the controller
//Toggle the text-display on checkbox
$scope.toggleItemDisplay = function(task) {
if(task.checked == true) {
console.log(task.title);
} else {
console.log('not checked!');
}
}
I would like the text which is displayed next to the checkbox (-> it's the task.title) to get the style "text-decoration: line-through" when the checkbox is checked.
How can I add the style-Attribut? It must be so simple but I just can't find the right solution..
Thanks in advance.
Just add ng-class for a conditional CSS class
angular.module('example', ['ionic'])
.controller('c', ['$scope', function($scope) {
// Mock of your tasks
$scope.tasks = [
{ title : "test 1", checked : false },
{ title : "test 2", checked : true },
];
$scope.toggleItemDisplay = function(task) {
if(task.checked == true) {
console.log(task.title);
} else {
console.log('not checked!');
}
}
}]);
.task-done {
text-decoration: line-through;
}
<script src="http://code.ionicframework.com/1.0.0-beta.13/js/angular/angular.min.js "></script>
<script src="http://code.ionicframework.com/1.0.0-beta.13/js/ionic.js"></script>
<script src="http://code.ionicframework.com/1.0.0-beta.13/js/ionic.bundle.js"></script>
<div ng-app="example">
<div ng-controller="c">
<ion-checkbox ng-repeat="task in tasks"
ng-model="task.checked"
ng-change="toggleItemDisplay(task)"
ng-class="{'task-done': task.checked}">
{{ task.title }}
</ion-checkbox>
</div>
</div>

Resources