I want to take the image address and add it to data-original="image url"
Sample : <img src="Bengal-kedisi.jpg" data-original="Bengal-kedisi.jpg" class="lazy w-100 ortalaimg">
on: {
instanceReady: function() {
this.dataProcessor.htmlFilter.addRules( {
elements: {
img: function( el ) {
if ( !el.attributes["data-original"])
el.attributes["data-original"]= 'images URL';
el.addClass( 'lazy w-100 ortalaimg' );
}
}
} );
}
}
Related
I am doing the search engine section in VueJS and Laravel, but I have a problem that does not allow me to advance in the other sections. The search engine opens and everything but when I write it only sends the first letter or 2 but not all of them like this in this image:
image of the data you send
the data that I write
After that it shows me the following error in console:
Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/search?q=th"
Now showing my search engine code:
<template>
<div class="form_MCycW">
<form autocomplete="off" #sumbit.prevent>
<label class="visuallyhidden" for="search">Search</label>
<div class="field_2KO5E">
<input id="search" ref="input" v-model.trim="query" name="search" type="text" placeholder="Search for a movie, tv show or person..." #keyup="goToRoute" #blur="unFocus">
<button v-if="showButton" type="button" aria-label="Close" #click="goBack">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15"><g fill="none" stroke="#fff" stroke-linecap="round" stroke-miterlimit="10" stroke-width="1.5"><path d="M.75.75l13.5 13.5M14.25.75L.75 14.25"/></g></svg>
</button>
</div>
</form>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
data() {
return {
query: this.$route.query.q ? this.$route.query.q : ''
}
},
computed: {
showButton() {
return this.$route.name === 'search';
},
...mapState({
search: state => state.event.fromPage
})
},
mounted() {
this.$refs.input.focus();
},
methods: {
goToRoute() {
if (this.query) {
this.$router.push({
name: 'search',
query: { q: this.query },
});
} else {
this.$router.push({
path: this.fromPage,
});
}
},
goBack() {
this.query = '';
this.$router.push({
path: '/',
});
},
unFocus (e) {
if (this.$route.name !== 'search') {
const target = e.relatedTarget;
if (!target || !target.classList.contains('search-toggle')) {
this.query = '';
this.$store.commit('closeSearch');
}
}
}
}
}
</script>
This is the other section of the search engine:
<template>
<main class="main">
<div class="listing">
<div class="listing__head"><h2 class="listing__title">{{ title }}</h2></div>
<div class="listing__items">
<div class="card" v-for="(item, index) in data.data" :key="index">
<router-link :to="{ name: 'show-serie', params: { id: item.id }}" class="card__link">
<div class="card__img lazyloaded"><img class="lazyload image_183rJ" :src="'/_assets/img/covers/posters/' + item.poster" :alt="item.name"></div>
<h2 class="card__name">{{ item.name }}</h2>
<div class="card__rating">
<div class="card__stars"><div :style="{width: item.rate * 10 + '%'}"></div></div>
<div class="card__vote">{{ item.rate }}</div>
</div>
</router-link>
</div>
</div>
</div>
</main>
</template>
<script>
import { mapState } from 'vuex';
let fromPage = '/';
export default {
name: "search",
metaInfo: {
bodyAttrs: {
class: 'page page-search'
}
},
computed: {
...mapState({
data: state => state.search.data,
loading: state => state.search.loading
}),
query() {
return this.$route.query.q ? this.$route.query.q : '';
},
title() {
return this.query ? `Results For: ${this.query}` : '';
},
},
async asyncData ({ query, error, redirect }) {
try {
if (query.q) {
this.$store.dispatch("GET_SEARCH_LIST", query.q);
} else {
redirect('/');
}
} catch {
error({ message: 'Page not found' });
}
},
mounted () {
this.$store.commit('openSearch');
this.$store.commit('setFromPage', fromPage);
if (this.data.length == 0 || this.data === null) {
this.$store.dispatch("GET_SEARCH_LIST", this.query);
}
setTimeout(() => {
this.showSlideUpAnimation = true;
}, 100);
},
beforeRouteEnter (to, from, next) {
fromPage = from.path;
next();
},
beforeRouteUpdate (to, from, next) {
next();
},
beforeRouteLeave (to, from, next) {
const search = document.getElementById('search');
next();
if (search && search.value.length) {
this.$store.commit('closeSearch');
}
}
};
</script>
In my routes section it is defined as follows:
{
name: 'search',
path: '/search',
component: require('../views/' + themeName + '/control/search/index').default
}
It is supposed to be a real-time search engine. I would appreciate your help in solving this problem...
What you need is a debounce. What it does is that it wait or delay till the user had finished typing before the model get updated or before you send it to the server.
An example of how it works is here
Here is a package for it.
https://github.com/vuejs-tips/v-debounce
I have 2 of the same components in my laravel blade view, but they are conflicting.
What i'm trying to accomplish:
I've made a vue component that uploads a file to firebase and stores it in my database. In my blade view i have 2 places where i want to use this component. I configure the component with props so the component knows where to store the file.
What going wrong:
Every time i try to upload a file with the second component, i fire the function in the first component. How do i fix that the components can't conflict?
My laravel balde view:
component 1
<uploadfile
:key="comp100"
:user_data="{{ Auth::user()->toJson() }}"
store_path="/users/{{ Auth::user()->username }}/settings/email_backgrounds"
:store_route="'settings.project_email'"
:size="1000"
fillmode="cover"
></uploadfile>
component 2
<uploadfile
:key="comp200"
:user_data="{{ Auth::user()->toJson() }}"
store_path="/users/{{ Auth::user()->username }}/settings/email_backgrounds"
:store_route="'settings.project_email'"
:size="1000"
fillmode="cover"
></uploadfile>
The Vue component:
<template>
<div class="vue-wrapper">
<FlashMessage position="right top"></FlashMessage>
<div v-if="loading" class="lds-dual-ring"></div>
<div class="field">
<div class="control">
<label class="button main-button action-button m-t-20" for="uploadFiles"><span style="background-image: url('/images/icons/upload.svg')"></span>Kies bestand</label>
<input type="file" name="uploadFiles" id="uploadFiles" class="dropinput" #change="selectFile">
</div>
</div>
</div>
</template>
<script>
import { fb } from '../../firebase.js';
export default {
data() {
return {
fileObject: {
filePath: null,
url: null,
file: null,
resizedPath: null
},
loading: false
};
},
mounted() {
console.log(this.size)
console.log(this.fillmode)
},
props: [
'user_data',
'store_path',
'store_route',
'size',
'fillmode'
],
methods: {
selectFile(event)
{
var file = event.target.files[0];
this.fileObject.file = file
this.fileObject.filePath = this.store_path + '/' + file.name
this.fileObject.resizedPath = this.store_path + '/resized-' + file.name
if(file.type == 'image/png' || file.type == 'image/jpeg')
{
this.uploadFile(this.fileObject)
} else {
this.flashMessage.success({
title: 'Oeps!',
message: 'De afbeelding moet een png of een jpeg zijn!',
blockClass: 'success-message'
});
}
},
uploadFile(fileObject)
{
var vm = this
console.log(fileObject)
var storageRef = fb.storage().ref(fileObject.filePath)
var uploadTask = storageRef.put(fileObject.file)
this.loading = true
uploadTask.on('state_changed', function(snapshot){
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
},function(error) {
}, function() {
var resizeImage = fb.functions().httpsCallable('resizeImage')
resizeImage({filePath: fileObject.filePath, contentType: fileObject.file.type, watermark: false, size: vm.size, fit: vm.fillmode}).then(function(result){
var downloadRef = fb.storage().ref(fileObject.resizedPath);
downloadRef.getDownloadURL().then(function(url){
fileObject.url = url
vm.loading = false
vm.storeImage(fileObject)
}).catch(function(error){
console.log(error)
})
}).catch(function(error){
});
});
},
storeImage(file)
{
axios.post('/api/app/store_file', {
api_token: this.user_data.api_token,
user: this.user_data,
file: file,
storeRoute: this.store_route
}).then((res) => {
location.reload()
}).catch((e) => {
});
}
}
}
</script>
Does someone know how to fix this?
So I have this code:
<template>
<div id="search-wrapper">
<div>
<input
id="search_input"
ref="autocomplete"
placeholder="Search"
class="search-location"
onfocus="value = ''"
#keyup.enter.native="displayPic"
>
</div>
</div>
</template>
<script>
import VueGoogleAutocomplete from "vue-google-autocomplete";
export default {
data: function() {
return {
search_input: {},
pic: {}
};
},
mounted() {
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete
);
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
let pic=place.photos[0].getUrl()
console.log(pic);
});
}
});
},
methods: {
displayPic(ref){
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete);
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
let pic=place.photos[0].getUrl()
console.log(pic);
});
}
})
},
}
}
I want to pass the "pic" parameter, resulted in displayPic, which is a function, into my template, after one of the locations is being selected.
I've tried several approaches, but I'm very new to Vue so it's a little bit tricky, at least until I'll understand how the components go.
Right now, the event is on enter, but I would like it to be triggered when a place is selected.
Any ideas how can I do that?
Right now, the most important thing is getting the pic value into my template.
<template>
<div id="search-wrapper">
<div>
<input style="width:500px;"
id="search_input"
ref="autocomplete"
placeholder="Search"
class="search-location"
onfocus="value = ''"
v-on:keyup.enter="displayPic"
#onclick="displayPic"
>
<img style="width:500px;;margin:5%;" :src="pic" >
</div>
</div>
</template>
<script>
import VueGoogleAutocomplete from "vue-google-autocomplete";
export default {
data: function() {
return {
search_input: {},
pic:""
};
},
mounted() {
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete,
{componentRestrictions: {country: "us"}}
);
},
methods: {
displayPic: function(){
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
this.pic=place.photos[0].getUrl()
});
}
})
},
}
}
</script>
I'm working on a RestFulApi using Laravel and Vuejs, now want upload a photo using RestfulApi and vuejs. Here comes my sample code:
<div class="form-group form-group-default float-left required">
<label for="photo">Photo</label>
<input class="file-input" type="file" ref="photo" name="photo" v-
on:change="addFile($event)">
</div>
data(){
return{
films_info:
{
photo: null,
}
}
},
methods: {
addFile: function(e){
let that = this;
that.films_info.photo = this.$refs.photo.files[0];
},
saveFilms: function(){
let that = this;
axios.post('/api/films/save_films',that.films_info)
.then(function (response) {
location.reload(true);
})
.catch(function (error) {
that.errors = error.response.data.errors;
console.log("Error Here: "+error.response.data);
});
}
}
protected function saveFilms(Films $request)
{
if ( $request->photo ) {
$extension = $filmsObj->photo->getClientOriginalExtension();
$request->photo = 'films_'.\Carbon\Carbon::now().'.'.$extension; // renaming image
$request->photo->move($dir_path, $request->photo);
}
}
Here in this code I get error in getClientOriginalExtension() method call. It says:
getClientOriginalExtension() method called on string.
Finally I managed to solved the photo upload issue using VueJS and Laravel Api call.
<div class="form-group form-group-default float-left required">
<label for="file">File</label>
<input class="file-input" type="file" ref="file" name="file" v-
on:change="addFile($event)">
</div>
data(){
return{
films_info:
{
file: null,
}
}
},
methods: {
addFile(e){
this.films_info.file = this.$refs.file.files[0];
},
saveFilms(){
let formData = new FormData();
formData.append('file', this.films_info.file);
axios.post('/api/films/save_films',formData,{
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
location.reload(true);
})
.catch(error => {
that.errors = error.response.data.errors;
console.log("Error Here: "+error.response.data);
});
}
}
$dir_path = 'uploads/films/images';
$dir_path_resize = 'uploads/films/images/45x45';
if( $request ){
$filmsObj = new Film();
if (!File::exists($dir_path))
{
File::makeDirectory($dir_path, 0775, true);
}
if (!File::exists($dir_path_resize))
{
File::makeDirectory($dir_path_resize, 0775, true);
}
if ( $request->file ) {
$file = $request->file;
$extension = $file->getClientOriginalExtension(); // getting image extension
$file_name = 'films_'.\Carbon\Carbon::now().'.'.$extension; // renaming image
$file->move($dir_path, $file_name); // uploading file to given path
// Start : Image Resize
$image = Image::make(public_path($dir_path.'/'.$file_name));
// resize the image to a height of 45 and constrain aspect ratio (auto width)
$image->resize(null, 45, function ($constraint) {
$constraint->aspectRatio();
});
$image->save(public_path($dir_path_resize.'/'.$file_name));
// End : Image Resize
}
I'm new to Ionic/Angular 2..
Try to use custom validators to validate the username but at server but i´m stack into this problem...
Property 'getUserByLogin' does not exist on type 'typeof
UserValidator'.
I have an sigunp.html page ...
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>{{ "SIGNUP" | translate }}</ion-title>
</ion-navbar>
</ion-header>
<ion-content class="login-page">
<div class="logo">
<img src="assets/img/appicon.svg" alt="Ionic Logo">
</div>
<ion-card>
<p ion-text>Teste</p>
<ion-card-content *ngFor="let user of users">
<h1>{{user.nome}}</h1>
<p>{{user.password}}</p>
</ion-card-content>
</ion-card>
<form [formGroup]="signupForm" (ngSubmit)="postSignupForm()" >
<ion-list no-lines>
<ion-item>
<ion-label floating>{{ "USER_NAME" | translate }}</ion-label>
<ion-input type="text" formControlName="login" clearInput></ion-input>
</ion-item>
<ion-item text-wrap *ngIf="!signupForm.controls.login.valid && (signupForm.controls.login.dirty || submitAttempt)">
<p ion-text color="danger">{{ "INVALID_USER_NAME" | translate }}</p>
</ion-item>
<ion-item *ngIf="signupForm.controls.login.pending">
<p ion-text color="danger">{{ "VALIDATION_IN_PROGRESS" | translate }}</p>
</ion-item>
<ion-item *ngIf="!signupForm.controls.login.valid && !signupForm.controls.login.pending && (signupForm.controls.login.dirty || submitAttempt)">
<p ion-text color="danger">{{ "USER_NAME_IN_USE" | translate }}</p>
</ion-item>
<ion-item>
<ion-label floating>{{ "PASSWORD" | translate }}</ion-label>
<ion-input type="password" formControlName="password" clearInput></ion-input>
</ion-item>
<ion-item text-wrap *ngIf="!signupForm.controls.password.valid && (signupForm.controls.password.dirty || submitAttempt)">
<p ion-text color="danger">{{ "INVALID_PASSWORD" | translate }}</p>
</ion-item>
<ion-item>
<ion-buttons end>
<ion-row responsive-sm>
<ion-col>
<button [disabled]="signupForm.invalid" type="submit" ion-button icon-left block>
<ion-icon name="add"></ion-icon>
<label>{{ "CREATE" | translate }}</label>
</button>
</ion-col>
<ion-col>
<button (click)="onFacebook(signupForm)" ion-button icon-left block>
<ion-icon name="logo-facebook"></ion-icon>
<label>{{ "FACEBOOK" | translate }}</label>
</button>
</ion-col>
</ion-row>
</ion-buttons>
</ion-item>
</ion-list>
</form>
</ion-content>
And a signup.ts with
import { Component } from '#angular/core';
import {Validators, FormBuilder } from '#angular/forms';
import { NgForm } from '#angular/forms';
import { NavController } from 'ionic-angular';
import { TabsPage } from '../tabs/tabs';
import { UserData } from '../../providers/user-data';
import { UserProvider } from '../../providers/user-provider';
import { UserValidator } from '../../validators/user-validator';
#Component({
selector: 'page-user',
templateUrl: 'signup.html'
})
export class SignupPage {
signupForm : any = {};
users :any [];
id : number = 0;
signup: {username?: string, password?: string} = {};
submitted = false;
constructor(public navCtrl: NavController, public formBuilder : FormBuilder, public userData: UserData, public userService : UserProvider ) {
this.signupForm = this.formBuilder.group({
login : ['', Validators.compose( [ Validators.minLength(6)
, Validators.required
, Validators.pattern('[a-zA-Z]*') ] )
, UserValidator.checkUsername
],
password : ['', Validators.compose( [ Validators.minLength(6)
, Validators.required
] )
]
});
}
getAllUsers() {
return this.userService.getAllUsers().subscribe(
data=>this.users=data,
err=>console.log(err)
)
}
getUser( id : number ) {
return this.userService.getUser( id ).subscribe(
data=>this.users=data,
err=>console.log(err)
)
}
getUserByLogin( login : string ) {
return this.userService.getUserByLogin( login ).subscribe(
data=>this.users=data,
err=>console.log(err)
)
}
postSignupForm (){
console.log( this.signupForm.value );
}
onSignup(form: NgForm) {
this.submitted = true;
if (form.valid) {
this.userData.signup(this.signup.username);
this.navCtrl.push(TabsPage);
}
}
onFacebook(form: NgForm) {
this.getUser(2);
console.log( form.value );
}
}
Where i call an UserValidator.checkUsername that is created at...
import { FormControl } from '#angular/forms';
import { UserProvider } from '../providers/user-provider';
export class UserValidator {
wsreturn : any = [];
constructor( public userService : UserProvider ) {
}
getUserByLogin( login : string ) {
return this.userService.getUserByLogin( login ).subscribe(
data=>this.wsreturn=data,
err=>console.log(err)
)
};
static checkUsername(control: FormControl): any {
return new Promise(resolve => {
//console.log ( '------->' ); console.log ( control.value );
this.getUserByLogin( control.value ); /// I NEED HELP!
// Fake a slow response from server
setTimeout(() => {
if(control.value.toLowerCase() === "luciano"){
resolve({
"username taken": true
});
} else {
resolve(null);
}
}, 2000);
});
}
}
My user-privider is this one...
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
import { GlobalProvider } from '../providers/global-provider';
#Injectable()
export class UserProvider {
constructor(public http: Http, public global: GlobalProvider) {
}
getAllUsers() {
return this.http.get(this.global.serverAdress + '/usuario', { headers: this.global.headers } ).map(res=>res.json())
}
getUser( id : number ) {
return this.http.get(this.global.serverAdress + '/usuario/'+ id, { headers: this.global.headers } ).map(res=>res.json())
}
getUserByLogin( login : string ) {
return this.http.get(this.global.serverAdress + '/usuario/porlogin/'+ login, { headers: this.global.headers } ).map(res=>res.json())
}
postUser( id : number ) {
return this.http.get(this.global.serverAdress + '/usuario/'+ id, { headers: this.global.headers } ).map(res=>res.json())
}
}
you can not call instance method in static method with this keyword. create directive instead
import { Directive, forwardRef } from '#angular/core';
import { NG_VALIDATORS, FormControl, Validator } from '#angular/forms';
#Directive({
selector: '[checkUsername][ngModel],[checkUsername][formControl]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => CheckUsernameValidator), multi: true }
]
})
export class CheckUsernameValidator implements Validator {
constructor(public userService: UserProvider) {
}
getUserByLogin(login : string) {
return this.userService.getUserByLogin(login);
};
validate(c: FormControl) {
return new Promise(resolve => { //
this.getUserByLogin( control.value ).subscribe(
data => {
if(control.value.toLowerCase() === "luciano"){
resolve({
"username taken": true
});
} else {
resolve(null);
}
},
err => {
console.log(err);
resolve(null);
}
);
}
}
in your html:
<ion-input type="text" formControlName="login" checkUsername clearInput></ion-input>
I move checkUsername to signup.ts with and made some changes to "bind(this)"... its working as i want but i´m still reading more about "creating directives"...
thanks #tiep-phan and #suraj.
....
constructor(public navCtrl: NavController, public formBuilder : FormBuilder, public userData: UserData, public userService : UserProvider ) {
this.signupForm = this.formBuilder.group({
login : ['', Validators.compose( [ Validators.minLength(6)
, Validators.required
, Validators.pattern('[a-zA-Z]*') ] )
, this.checkUsername.bind(this)
],
password : ['', Validators.compose( [ Validators.minLength(6)
, Validators.required
] )
]
});
}
checkUsername(control: FormControl): any {
return new Promise( resolve => {
this.userService.getUserByLogin( control.value ).subscribe(
data=>{
// console.log('Sucesso:'); console.log(data[0]);
if ( typeof data[0] !== "undefined") {
if ( typeof data[0].login === "undefined") {
resolve(null);
} else {
// username encontrado no banco de dados
resolve( { "INVALID_USER_NAME": true } );
}
} else {
resolve(null);
}
},
err=>{ console.log('Erro:'); console.log(err); }
)
});
}
....