select2 doesn't show list in dialog modal - modal-dialog

select2 is not showing the attended results. Actually it doesn't show anything at all. already tried to fix it removing tabindex in dialog. thanks for your help.
this is the result
view page dialog :
<div id="edit-interv" class="modal" role="dialog" title="Intervento" aria-hidden="true" style="overflow-y: hidden;">
view page select:
<select id="pippo" class="select_family form-control"></select>
footer page:
$('#edit-interv').open(function() {
$("#pippo").select2({
dropdownParent: $("#edit-interv"),
ajax: {
url: "{{basepath}}/fetchfamily",
dataType: 'json',
delay: 250,
data: function (term, page) {
return {
q: term,
page: page
};
},
processResults: function(data, params) {
return {
results: $.map(data, function(item) {
return {
text: item.name,
id: item.id
}
})
};
},
cache: true
},
minimumInputLength: 0
})
});

Related

Preset input values of the form with Vuex

In my project (laravel/vue spa) I have a form opened in a modal window, the form shall display the initial values from the object kept in the vuex store. The problem is the input doesn't see objet property that I set through value, so with my code now when the modal is opened, no data is displayed inside the input, although if i output the section object in the markup it generally sees it.
How can I make the input work with the preset values?
Here's my code:
ModalForm.vue markup
<template>
<app-modal>
<Form #submit="submitSectionForm">
<div class="form-group">
<label for="title" class="control-label">Title</label>
//<p>{{ section }}</p>
<Field
:value="sectionTitle" #input="handleUpdateTitle"
:rules="isRequired"
type="text"
name="section_title"
class="form-control"
/>
<ErrorMessage
name="section_title"
class="pr-1 display-block color-red"
/>
</div>
<button class="btn btn-default" #click="closeModal">Cancel</button>
<button class="btn btn-primary ml-1">Ok</button>
</Form>
</app-modal>
</template>
ModalForm.vue functionality
<script>
import AppModal from "../../components/Modals/Modal.vue";
import { Field, ErrorMessage } from "vee-validate";
import { mapGetters, mapActions, mapState, mapMutations } from "vuex";
export default {
props: {
menu_type_id: Number,
menu_id: Number,
},
components: {
AppModal,
Field,
ErrorMessage,
},
methods: {
...mapActions("menu_sections", ["saveSection"]),
...mapMutations("menu_sections", ['updateTitle']),
isRequired(value) {
if (value && value.trim()) {
return true;
}
handleUpdateTitle(e) {
this.updateTitle(e.target.value);
}
submitSectionForm(value) {
console.log(value);
this.saveSection(value);
this.closeModal();
},
computed: {
...mapGetters("menu_sections", { section: "getSection" } ),
...mapGetters("menu_sections", { sectionTitle: "getSectionTitle" }),
},
};
</script>
section_store.js
import axios from "axios";
export default {
namespaced: true,
state: {
section: {},
message: "",
},
getters: {
indexById: (state) => (id) =>
state.sections.findIndex((item) => item.id == id),
sectionById: (state) => (id) =>
state.sections.filter((item) => item.id == id),
getSection: (state) => state.section,
getSectionTitle: (state )=>state.section.title
},
mutations: {
setSection(state, section) {
state.section = { ...section };
},
saveSection(state, data) {
state.message = data.message;
},
updateTitle(state, title) {
state.section.title = title;
console.log(state.section.title);
},
},
actions: {
saveSection({ commit }, section_object) {
axios
.post("/api/menu-sections/" + section_object)
.then((response) => {
commit("saveSection", response.data);
})
.catch((e) => {
console.log("Section save error");
});
}
},
};

Component $emit seems to stop event propagation in Bootstrap Vue table

I'm trying to do something like this in a BV table to send the result of a row click to a parent component using the row-clicked event:
<template>
<div>
<b-table :items='totals' selectable select-mode='single' hover #row-clicked='rowClicked'></b-table>
</div>
</template>
<script>
export default {
data: function() {
return { }
},
props: ['totals'],
methods: {
rowClicked(rowData) {
this.$emit("filter-total", rowData.total)
}
}
}
</script>
The $emit works fine, but seems to prevent the row-selected event, as the row never gets selected (which is confusing for the user). If I replace the $emit with something else, the row is selected correctly.
Why is this happening and how can I prevent it?
I implement your case in the code snippet, I think your problem is because of the bootstrap-vue version that you are using. Upgrade your bootstrap-vue package to the latest version and your problem should be solved.
Vue.component("customComponent", {
template:
"<b-table :items='items' selectable select-mode='single' hover #row-clicked='rowClicked' />",
data() {
return {
items: [
{
isActive: true,
age: 40,
first_name: "Dickerson",
last_name: "Macdonald"
},
{ isActive: false, age: 21, first_name: "Larsen", last_name: "Shaw" },
{ isActive: false, age: 89, first_name: "Geneva", last_name: "Wilson" },
{ isActive: true, age: 38, first_name: "Jami", last_name: "Carney" }
]
};
},
methods: {
rowClicked(items) {
this.$emit("filter-total", items.age);
}
}
});
new Vue({
el: "#app",
methods: {
do_sth(value) {
console.log(value);
}
}
});
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap#4.5.3/dist/css/bootstrap.min.css" />
<script src="https://unpkg.com/vue#2.6.12/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.js"></script>
<div id="app">
<custom-component #filter-total="do_sth" />
</div>

The API request from the Vuejs component is executed twice

I am creating To-do Application using Vuejs, Expressjs, and Mongodb.
I have already written through the New Component with a separate link. This is normal, but I am currently using the New Component by importing it into the Root Component without any additional links.
This works, but the API request is executed twice. (Two articles are written.)
I just imported the component, what's the problem?
I have only sent one request but strangely two responses are flying. (id is different, title and content are the same.)
frontend/components/TodoForm.vue
<template>
<form #submit.prevent="create">
title : <input v-model="todo.title">
content : <input v-model="todo.content">
<button v-on:click="create" >Create</button>
</form>
</template>
<script>
export default {
data: function () {
return {
todo: {}
}
},
methods: {
create: function() {
this.$http.post('/api/todos/create', this.todo)
.then(
(response) => {
console.log(response.data)
this.$router.push({name: 'Todo', params: { id: response.data._id }})
},
(err) => {
alert('Error')
}
)
.catch(function (error) {
alert('error')
})
}
}
}
</script>
fromtend/components/TodoList.vue
<template>
<todo-form/>
<div class="todos">
<h1>Todos</h1>
<div v-for="todo in todos" v-bind:key="todo" class="todo">
<div>
<strong>{{todo.title}}</strong>
<router-link :to="{ name: 'Todo', params: { id: todo._id }}">detail</router-link>
<router-link :to="{ name: 'Edit', params: { id: todo._id }}">edit</router-link>
<button type="submit" #click="deleteTodo(todo._id)">Delete</button>
</div>
</div>
</div>
</template>
<script>
import TodoForm from './TodoForm';
export default {
data () {
return {
todos: {}
}
},
created () {
this.$http.get('/api/todos')
.then((response) => {
this.todos= response.data
})
},
components: {
TodoForm
},
methods: {
deleteTodo (id) {
const targetIndex = this.todos.findIndex(v => v._id === id)
this.$http.delete(`/api/todos/${id}`)
.then((response) => {
this.todos.splice(targetIndex, 1)
})
}
}
}
</script>
backend/api
router.post ('/create', (req, res) => {
let todo = new Todo({
title: req.body.title || req.body.todo.title,
content: req.body.content || req.body.todo.content
});
todo.save((err) => {
if (err) {
res.status(500).send('Something broke!');
}
res.json(todo)
});
});
Try to change the following code :
<template>
<form>
title : <input v-model="todo.title">
content : <input v-model="todo.content">
<button v-on:click.once="create" >Create</button>
</form>
</template>

How to pass input value to form onSubmit without using state in component that renders multiple forms?

This is a bit of a longwinded problem and giving me a ton of headache to solve.
I'm making a voting app. On the page there will be a list of polls on which you can vote. Each poll is a form consisting of input radio buttons representing the different options available for that poll.
What I was doing previously was saving the option you choose to component state in this.state.value and then passing it as an argument to an action creator when the form is submitted.
Problem with this approach is that if I click an option of one poll, and then click submit on another poll, I've actually submitted the wrong option to the wrong poll.
Is there a way to pass input value to form onSubmit without storing it in component state?
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import Loading from '../Loading';
class MyPolls extends Component {
constructor(props) {
super(props);
this.state = {
skip: 0,
isLoading: true,
isLoadingMore: false,
value: ''
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.props.fetchMyPolls(this.state.skip)
.then(() => {
setTimeout(() => {
this.setState({
skip: this.state.skip + 4,
isLoading: false
});
}, 1000);
});
}
sumVotes(acc, cur) {
return acc.votes + cur.votes
}
loadMore(skip) {
this.setState({ isLoadingMore: true });
setTimeout(() => {
this.props.fetchMyPolls(skip)
.then(() => {
const nextSkip = this.state.skip + 4;
this.setState({
skip: nextSkip,
isLoadingMore: false
});
});
}, 1000);
}
handleSubmit(title, e) {
// console.log(e.target);
e.preventDefault();
const vote = {
title,
option: this.state.value
};
console.log(vote)
}
handleChange(event) {
this.setState({ value: event.target.value });
}
renderPolls() {
return this.props.polls.map(poll => {
return (
<div
className='card'
key={poll._id}
style={{ width: '350px', height: '400px' }}>
<div className='card-content'>
<span className='card-title'>{poll.title}</span>
<p>
Total votes: {poll.options.reduce((acc, cur) => { return acc + cur.votes }, 0)}
</p>
<form onSubmit={e => this.handleSubmit(poll.title, e)}>
{poll.options.map(option => {
return (
<p key={option._id}>
<input
name={poll.title}
className='with-gap'
type='radio'
id={option._id}
value={option.option}
onChange={this.handleChange}
/>
<label htmlFor={option._id}>
{option.option}
</label>
</p>
)
})}
<button
type='text'
className='activator teal btn waves-effect waves-light'
style={{
position: 'absolute',
bottom: '10%',
transform: 'translateX(-50%)'
}}
>
Submit
<i className='material-icons right'>
send
</i>
</button>
</form>
</div>
<div className='card-reveal'>
<span className='card-title'>{poll.title}
<i className='material-icons right'>close</i>
</span>
<p>
dsfasfasdf
</p>
</div>
</div>
)
})
}
render() {
return (
<div className='center-align container'>
<h2>My Polls</h2>
{this.state.isLoading ? <Loading size='big' /> :
<div
style={{
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-evenly',
alignItems: 'center',
alignContent: 'center'
}}>
{this.renderPolls()}
</div>}
<div className='row'>
{this.state.isLoadingMore ? <Loading size='small' /> :
<button
className='btn red lighten-2 wave-effect waves-light' onClick={() => this.loadMore(this.state.skip)}>
Load More
</button>}
</div>
</div>
);
}
}
function mapStateToProps({ polls }) {
return { polls }
}
export default connect(mapStateToProps, actions)(MyPolls);
App demo: https://voting-app-drhectapus.herokuapp.com/
(use riverfish#gmail.com and password 123 to login)
Github repo: https://github.com/drhectapus/voting-app
I'm open to any suggestions. Thanks!
The more "React'ish" pattern would be to break it down to more components.
a Poll is a component, a PollOption could be a component as well.
Where each can handle the state internally.
This will allow you to keep global state in your App or some other state manager like redux that will hold all of your polls and each can reference to the selected option (id).
Another thing worth pointing, is that you tend to pass a new function reference on each render call.
For example:
onSubmit={e => this.handleSubmit(poll.title, e)}
This is considered as bad practice because you can interfere with the Reconciliation and The Diffing Algorithm of react.
When you break it down to components that each can fire back a callback with its
props, then you don't need to pass the handler this way.
Here is a small example with your data:
const pollsFromServer = [
{
_id: "5a0d308a70f4b10014994490",
title: "Cat or Dog",
_user: "59f21388843e737de3738a3a",
__v: 0,
dateCreated: "2017-11-16T06:30:34.855Z",
options: [
{ option: "Cat", _id: "5a0d308a70f4b10014994492", votes: 0 },
{ option: "Dog", _id: "5a0d308a70f4b10014994491", votes: 0 }
]
},
{
_id: "5a0c7941e655c22b8cce43d7",
title: "Blonde or Brunette?",
_user: "59f21388843e737de3738a3a",
__v: 0,
dateCreated: "2017-11-15T17:28:33.909Z",
options: [
{ option: "Blonde", _id: "5a0c7941e655c22b8cce43d9", votes: 0 },
{ option: "Brunette", _id: "5a0c7941e655c22b8cce43d8", votes: 0 }
]
},
{
_id: "5a0c7924e655c22b8cce43d4",
title: "Coke or Pepsi",
_user: "59f21388843e737de3738a3a",
__v: 0,
dateCreated: "2017-11-15T17:28:04.119Z",
options: [
{ option: "Coke", _id: "5a0c7924e655c22b8cce43d6", votes: 0 },
{ option: "Pepsi", _id: "5a0c7924e655c22b8cce43d5", votes: 0 }
]
},
{
_id: "5a0c78c2e655c22b8cce43d0",
title: "Favourite german car?",
_user: "59f21388843e737de3738a3a",
__v: 0,
dateCreated: "2017-11-15T17:26:26.724Z",
options: [
{ option: "BMW", _id: "5a0c78c2e655c22b8cce43d3", votes: 0 },
{ option: "Mercedes", _id: "5a0c78c2e655c22b8cce43d2", votes: 0 },
{ option: "Audi", _id: "5a0c78c2e655c22b8cce43d1", votes: 0 }
]
}
];
class Poll extends React.Component {
onSubmit = optionId => {
const { pollId, onSubmit } = this.props;
onSubmit(pollId, optionId);
};
render() {
const { title, options, selectedOption } = this.props;
return (
<div>
<h3>{title}</h3>
<ul>
{options.map((o, i) => {
return (
<PollOption
isSelected={selectedOption === o._id}
onClick={this.onSubmit}
name={o.option}
optionId={o._id}
/>
);
})}
</ul>
</div>
);
}
}
class PollOption extends React.Component {
onClick = () => {
const { optionId, onClick } = this.props;
onClick(optionId);
};
render() {
const { name, isSelected } = this.props;
const selectedClass = isSelected ? "selected" : '';
return (
<li
className={`poll-option ${selectedClass}`}
onClick={this.onClick}
>
{name}
</li>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
polls: pollsFromServer,
submittedPolls: []
};
}
onPollSubmit = (pollId, optionId) => {
this.setState({
submittedPolls: {
...this.state.submittedPolls,
[pollId]: optionId
}
});
};
render() {
const { polls, submittedPolls } = this.state;
return (
<div>
{polls.map((p, i) => {
const selectedPoll = submittedPolls[p._id];
return (
<Poll
selectedOption={selectedPoll}
pollId={p._id}
onSubmit={this.onPollSubmit}
title={p.title}
options={p.options}
/>
);
})}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
.poll-option{
cursor: pointer;
display: inline-block;
box-shadow: 0 0 1px 1px #333;
padding: 15px;
}
.selected{
background-color: green;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

JQuery Autocomplete asp.net action not firing on select

Somehow action is not completed when I choose an item from the menu. Everything else works fine, except again - nothing happens when I select an item.
Here is the code:
<script type="text/javascript">
$(document).ready(function() {
$("#<%=txtSearchTerm.ClientID%>").autocomplete("Acc.ashx", {
formatItem: function(item) { return item.toString().split("#")[0]; },
formatResult: function(item) { return item.toString().split("#")[0]; },
select: function(event, ui) { alert('something'); }
});
});
</script>
I ended up with this working solution
<script type="text/javascript">
$(document).ready(function() {
$("#<%=txtSearchTerm.ClientID%>").autocomplete("Acc.ashx", {
formatItem: function(item) { return item.toString().split("#")[0]; },
formatResult: function(item) { return item.toString().split("#")[0]; }
});
$("#<%=txtSearchTerm.ClientID %>").result( function findValueCallback(event, data, formatted)
{
if(data)
{
$('#<%=hidOID.ClientID %>').val(data[0].toString().split('#')[1]);
}
});
});
</script>