When I wrap a form with jquery geocomplete in a Vue modal, the geocomplete stops working. I'm not sure how to fix it so that geocomplete works when the modal is active.
Here is a working example without Vue or a modal:
https://jsfiddle.net/3gzovugy/68/
Here is the same example, wrapped in the vue site's example modal, that won't geocode. Any suggestions?
https://jsfiddle.net/3gzovugy/96/
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<modal v-if="showModal" #close="showModal = false">
<div slot="body">
<form>
<div class="item">
<input id="autocomplete" placeholder="Look up your address" type="text">
</div>
<div class="item">
<input class="cat_textbox" id="houseNo" data-geo="street_number" type="text" placeholder="House Number" maxlength="50" />
</div>
<div class="item">
<input class="cat_textbox" id="street" data-geo="route" type="text" placeholder="street" maxlength="50" />
</div>
<div class="item">
<input class="cat_textbox red" id="BillingAddress" data-geo="street_address" type="text" placeholder="Billing Address" maxlength="50" name="BillingAddress" />
</div>
</form>
</div>
</modal>
</div>
<template id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
default header
</slot>
</div>
<div class="modal-body">
<slot name="body">
default body
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</template>
I see your geocomplete related code is in $(document).ready(function(). Taking inspiration from this answer, you can move code inside document.ready to one of the lifecycle hooks for this purpose. You can try using mounted as it comes pretty close to $(document).ready():
Vue.component('modal', {
template: '#modal-template',
mounted () {
$("#autocomplete").geocomplete({
details: "form div",
detailsAttribute: "data-geo",
types: ["(cities)"],
componentRestrictions: {
country: "in"
}
});
}
})
With these changes, you code starts to show suggestion: check here. You may need some other UI changes to see the geocomplete dropdown on top.
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>
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
I have a slider which consists of products.
Right now I'm getting a list of products from the server and populating that slider with the result returned from the server. For this I have the following
<div class="most_buy_slider container special_proposal">
<div v-for="product in mostBoughtProducts">
<div>
<div class="goods_item">
<img :src="product.ProductPreviewImages[0]">
<div class="name">
{{product.Name}}
<span>{{product.Manufacturer}}</span>
</div>
<div class="price">{{product.Price}} грн</div>
<div class="economy">економія складає 57% від роздрібної вартості</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
</div>
</div>
But this result in the following:
however, when I render simple html without v-for it loads correctly.
<div class="most_buy_slider container bigger_width special_proposal">
<div>
<div v-for="index in 10" class="goods_item">
<img src="images/samples/whiskyjackdan.png">
<div class="name">
Вологі серветки Вологі серветки Вологі серветки Вологі серветки
<span>Ruta Selecta Ruta SelectaRuta SelectaRuta Selecta</span>
</div>
<div class="price">
45,55 грн
</div>
<div class="economy">
економія складає 57% від роздрібної вартості
</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
<div>
<div class="goods_item">
<img src="images/samples/ruta1.png">
<div class="name">
Вологі серветки
<span>Ruta Selecta</span>
</div>
<div class="price">
45,55 грн
</div>
<div class="economy">
економія складає 57% від роздрібної вартості
</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
I don't know your CSS, but in first code snippet you included you use additional div for v-for directive, that can break your styles.
Try this code instead:
<div class="most_buy_slider container special_proposal">
<div v-for="product in mostBoughtProducts">
<div class="goods_item">
<img :src="product.ProductPreviewImages[0]" />
<div class="name">
{{ product.Name }}
<span>{{ product.Manufacturer }}</span>
</div>
<div class="price">{{ product.Price }} грн</div>
<div class="economy">економія складає 57% від роздрібної вартості</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
</div>
I finally solved the problem
I was using Slick slider to display items. While data is being loaded from the server, the slick slider already gets initialized with 0 item in it. And when items has been loaded from the server, vue.js inserts data into the slider, but the slider still assumes that it has 0 item.
So the solution is to reinitialize the slick slider when data loaded from the server.
I called the following after the data load:
reInit() {
$('.most_buy_slider').slick('unslick');
$(".most_buy_slider").slick(this.sliderSettings())
}
sliderSettings() {
return {
infinite: true,
slidesToShow: 4,
slidesToScroll: 1
}
}
I am creating a sample app using reactjs. I am very new in reactjs. I set up all the things for reactjs like
1) Babel
2)Webpack
Using webpack I am genrating a file code.js which is included in the index file where all the code runs.
I am creating my first page but i got error like:
ERROR in ./components/Login/Login.js
Module build failed: SyntaxError: C:/xampp/htdocs/reactApp/components/Login/Logi
n.js: Expected corresponding JSX closing tag for <img> (18:33)
I dont know why the html rendering gives me error.
My code is like:
import React, {Component} from 'react';
import {Link} from 'react-router'
export default class Home extends Component {
render () {
return (
<div class="page-content container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-wrapper">
<div class="box">
<div class="content-wrap">
<h6>Sign In</h6>
<div class="social">
<a class="face_login" href="#">
<span class="face_icon">
<img src="images/facebook.png" alt="fb">
</span>
<span class="text">Sign in with Facebook</span>
</a>
<div class="division">
<hr class="left">
<span>or</span>
<hr class="right">
</div>
</div>
<input class="form-control" type="text" placeholder="E-mail address">
<input class="form-control" type="password" placeholder="Password">
<div class="action">
<a class="btn btn-primary signup" href="index.html">Login</a>
</div>
</div>
</div>
<div class="already">
<p>Dont have an account yet?</p>
Sign Up
</div>
</div>
</div>
</div>
</div>
)
}
}
Please help me to solve this problem
There is at least one more problem: You used class= instead of className= everywhere. Obviously you did try to copy & paste html code. There is a great online converter which i use. It allows you to do that without errors: http://magic.reactjs.net/htmltojsx.htm
import React, {Component} from 'react';
import {Link} from 'react-router'
export default class Home extends Component {
render () {
return (
<div className="page-content container">
<div className="row">
<div className="col-md-4 col-md-offset-4">
<div className="login-wrapper">
<div className="box">
<div className="content-wrap">
<h6>Sign In</h6>
<div className="social">
<a className="face_login" href="#">
<span className="face_icon">
<img src="images/facebook.png" alt="fb" />
</span>
<span className="text">Sign in with Facebook</span>
</a>
<div className="division">
<hr className="left" />
<span>or</span>
<hr className="right" />
</div>
</div>
<input className="form-control" type="text" placeholder="E-mail address" />
<input className="form-control" type="password" placeholder="Password" />
<div className="action">
<a className="btn btn-primary signup" href="index.html">Login</a>
</div>
</div>
</div>
<div className="already">
<p>Dont have an account yet?</p>
Sign Up
</div>
</div>
</div>
</div>
</div>
)
}
}
Hope you found this useful.
The error clearly mentions what needs to be done. In JSX you need to close the singleton tags like <br> , <img> and <input>
import React, {Component} from 'react';
import {Link} from 'react-router'
export default class Home extends Component {
render () {
return (
<div class="page-content container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-wrapper">
<div class="box">
<div class="content-wrap">
<h6>Sign In</h6>
<div class="social">
<a class="face_login" href="#">
<span class="face_icon">
<img src="images/facebook.png" alt="fb" />
</span>
<span class="text">Sign in with Facebook</span>
</a>
<div class="division">
<hr class="left">
<span>or</span>
<hr class="right">
</div>
</div>
<input class="form-control" type="text" placeholder="E-mail address" />
<input class="form-control" type="password" placeholder="Password" />
<div class="action">
<a class="btn btn-primary signup" href="index.html">Login</a>
</div>
</div>
</div>
<div class="already">
<p>Dont have an account yet?</p>
Sign Up
</div>
</div>
</div>
</div>
</div>
)
}
}
I have got a meteor app which uses the Semantic UI. I am using the semantic:ui-css package for this.
I have got a template called project where I want to show a modal.
There for I created a second template which is the modal like this:
<template name="xform">
<div id="modal" class="ui modal">
<i class="close icon"></i>
<div class="header">New Project</div>
<div class="content">
<div class="ui form" id="newProject">
<div class="one fields">
<div class="field">
<legend>Project Details</legend>
<label>Name</label>
<input id="name" name="name" type="text" placeholder="Project name">
</div>
<input type="submit" class="button small createProject" style="color:white;position:relative;float:right;padding: 0.875rem 1.75rem 0.9375rem 1.75rem;font-size: 0.8125rem;" value="Create">
</div>
</div>
</div>
<div class="actions">
<div class="ui button">
Cancel
</div>
<div class="ui button">
Okay
</div>
</div>
</div>
</template>
Then I haved added a event to a button like this to show the modal:
Template.projects.events({
'click .newProject': function(event, template){
template.$('.ui.modal').modal({
onDeny : function(){
return false;
}}).modal('show');
}
});
If I click the button for the first time the modal opens like wanted.
I can see that the modal is now not anymore inside the html of my template but at the end of my body.
I can close the modal using the close button but when I now try to open it again it does not open any more.
The modal div is still on the bottom of my body.
I have tried several ways to workaround this problem but none have worked.
Here my complete code: http://i.imgur.com/r9JNrlr
To follow up from my comment, this is the code that is working for me. It definitely seems like you have an issue with jQuery finding multiple elements. I created a new meteor project:
$ meteor create semantic
$ cd semantic
$ meteor add semantic:ui-css
$ meteor add iron:router
semantic.html
<template name="MainLayout">
<h1>Title</h1>
{{> yield}}
</template>
<template name="projects">
{{> xform}}
<button class="newProject">New Project</button>
</template>
<template name="xform">
<div id="modal" class="ui modal">
<i class="close icon"></i>
<div class="header">New Project</div>
<div class="content">
<div class="ui form" id="newProject">
<div class="one fields">
<div class="field">
<legend>Project Details</legend>
<label>Name</label>
<input id="name" name="name" type="text" placeholder="Project name">
</div>
<input type="submit" class="button small createProject" style="color:white;position:relative;float:right;padding: 0.875rem 1.75rem 0.9375rem 1.75rem;font-size: 0.8125rem;" value="Create">
</div>
</div>
</div>
<div class="actions">
<div class="ui button">
Cancel
</div>
<div class="ui button">
Okay
</div>
</div>
</div>
</template>
semantic.js
if (Meteor.isClient) {
Template.projects.events({
'click .newProject': function(event, template){
$('.ui.modal').modal({
onDeny : function(){
return false;
}}).modal('show');
}
});
Meteor.startup(function() {
Router.configure({
layoutTemplate: 'MainLayout'
})
Router.route('/',{
name: 'projects'
})
});
}
After running meteor and loading http://localhost:3000 I can open and close the modal multiple times.
Try to set the modal non-detachable in onRendered callback function of template.
Template.projects.onRendered(() => {
$('.ui.modal').modal({ detachable: false });
});
Hope it helps.