Open a modal from a button in another component Vue JS - javascript

I have 2 components. One called TestSearchTool and another one called TestModal. I'd like to show my Modal when I click a button in the TestSearchTool component. These 2 components are siblings in the hierarchy so I didn't really find a way to pass the value between them ( there is vuex but I'd like to find a way without it )
I'm using Bootstrap 5 and Vue 3 to do this since Bootstrap Vue doesn't work on Vue 3.
Here is my TestModal component :
<template>
<div>
<div class="modal fade" ref="exampleModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" #click="modal.hide()" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" #click="modal.hide()">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { Modal } from 'bootstrap'
export default {
name: "App",
data: () => ({
modal: null
}),
mounted() {
this.modal = new Modal(this.$refs.exampleModal)
}
};
</script>
Here is my TestSearchTool component :
<template>
<div>
<div class="container ml-5 mt-3 border-1 rounded pl-5 pt-5 pr-5">
<div class="row mb-4">
<div class="col-md-6 mb-4" >
<label for="test" class="label-form">Titre</label>
<input autocomplete="off" placeholder="Rechercher par le titre du test" v-model="testName" type="text" id="test" class="form-control">
</div>
<div class="col-md-6 mb-4">
<label for="candidat" class="label-form">Candidat</label>
<select v-model="CandidateName" class="form-select" id="candidat">
<option value="" selected>Tous les candidats</option>
</select>
</div>
</div>
<div class="row">
<div class="col-12 mb-3">
<div class="col-12 mb-4">
<div class="col-sm-6 col-12 d-inline-block">
<!-- Modal is shown on this button's click !-->
<button type="button" #click="this.$emit('clickDone')" class=" btn btn-primary col-12 col-sm-11 mb-sm-0 mb-sm-0 mb-4 float-sm-left"><i class="fa-solid fa-file-circle-plus"></i> Ajouter Un Test</button>
</div>
<div class="col-sm-6 col-12 d-inline-block">
<button #click="deleteTests" type="button" class=" btn btn-primary col-sm-12 col-12" v-if="false"><i class="fa-solid fa-file-circle-minus"></i> Supprimer Le(s) Test(s)</button>
</div>
</div>
<button id="searchTest" #click="searchBy" class="col-12 btn btn-primary" ><i class="fas fa-search"></i> Rechercher</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
components:{
},
data(){
return {
testName:'',
CandidateName:'',
show:false,
}
},
methods:{
},
}
</script>
<style scoped>
</style>
And here is the parent component (called Tests) :
<template>
<div>
<test-search-tool></test-search-tool>
<test-modal></test-modal>
</div>
</template>
<script>
import TestSearchTool from "../components/TestSearchTool.vue"
import TestModal from "../components/TestModal.vue"
export default {
components : {
DashboardNavbar,
TestSearchTool,
TestModal,
},
mounted(){
document.body.style.backgroundImage='url("")';
document.body.style.background="white";
}
}
</script>
<style>
</style>

As I know the goal of writing codes in components in simple words is to have special duties specific to that component. So when we define a "modal" component, we expect that it shows modal content for us. So in my opinion it is not correct to say modal component (here called TestModal.vue) and TestSearchTool.vue are siblings. You could use TestModal.vue every where in your app structure that you need a modal content to be shown. In other words the TestModal.vue component does not have any special content or logic to be the direct child of Tests.vue (the parent component).
With the above description I used TestModal.vue as child of TestSearchTool.vue and by using props and watch and emit capabilities of Vue, here is the codes of all 3 components:
TestSearchTool.vue:
<template>
<div>
<div class="container ml-5 mt-3 border-1 rounded pl-5 pt-5 pr-5">
<div class="row mb-4">
<div class="col-md-6 mb-4" >
<label for="test" class="label-form">Titre</label>
<input autocomplete="off" placeholder="Rechercher par le titre du test" v-model="testName" type="text" id="test" class="form-control">
</div>
<div class="col-md-6 mb-4">
<label for="candidat" class="label-form">Candidat</label>
<select v-model="CandidateName" class="form-select" id="candidat">
<option value="" selected>Tous les candidats</option>
</select>
</div>
</div>
<div class="row">
<div class="col-12 mb-3">
<div class="col-12 mb-4">
<div class="col-sm-6 col-12 d-inline-block">
<!-- Modal is shown on this button's click !-->
<button type="button" #click="this.$emit('clickDone')" class=" btn btn-primary col-12 col-sm-11 mb-sm-0 mb-sm-0 mb-4 float-sm-left"><i class="fa-solid fa-file-circle-plus"></i> Ajouter Un Test</button>
</div>
<div class="col-sm-6 col-12 d-inline-block">
<button #click="deleteTests" type="button" class=" btn btn-primary col-sm-12 col-12" v-if="false"><i class="fa-solid fa-file-circle-minus"></i> Supprimer Le(s) Test(s)</button>
</div>
</div>
<!-- *********************** -->
<!-- this button is responsible for showing modal. you can use such a button in other parts of your app if you define "data" correctly -->
<button id="searchTest" #click="dataModal = true" class="col-12 btn btn-primary" ><i class="fas fa-search"></i> Rechercher</button>
</div>
<test-modal #closeModal="dataModal = false" :showModal="dataModal"></test-modal>
<!-- *********************** -->
</div>
</div>
</div>
</template>
<script>
import TestModal from "../components/TestModal.vue"
export default {
name: "TestSearchTool",
components:{
TestModal
},
data(){
return {
testName:'',
CandidateName:'',
show:false,
/* this data is used for showing modal */
dataModal: false
}
}
}
</script>
<style scoped>
</style>
TestModal.vue:
<template>
<div>
<div id="myModal" class="modal fade" ref="exampleModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" #click="hideModal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" #click="hideModal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { Modal } from 'bootstrap'
export default {
name: "TestModal",
data: () => ({
modalInstance: null
}),
props: {
showModal: {
type: Boolean,
default: false
}
},
watch: {
showModal(newValue, oldValue) {
console.log(newValue);
if (newValue === true) {
this.modalActive();
}
}
},
methods: {
modalActive: function () {
this.modalInstance = new Modal(document.getElementById('myModal'), {
target: "#my-modal",
backdrop: "static"
});
this.modalInstance.show()
},
hideModal: function () {
console.log("closed");
this.modalInstance.hide();
this.$emit('closeModal');
}
}
};
</script>
<style scoped>
</style>
Tests.vue:
<template>
<div>
<test-search-tool></test-search-tool>
</div>
</template>
<script>
import TestSearchTool from "../components/TestSearchTool.vue"
export default {
name: "Tests",
components : {
TestSearchTool
}
}
</script>
<style scoped>
</style>

Related

Show Data From Page-body to Modal-body

I want to show data from Body Their id(name + type) to Model Body. also i want data in page body as label but in model as input.
I want when edit click on Edit Button and open model have data in card to edit it.
https://codepen.io/fadynabilofficial/pen/PobJvER
<div class="container px-4 py-5 mx-auto">
<div class="row justify-content-center">
<div class="col-lg-12">
<div class="card">
<div class="row">
<div class="col-lg-6">
<div class="row px-1">
<div class="form-group col-md-8">
<label class="form-control-label" id="name">Cheesecake With Flavor</label>
<label class="form-control-label" id="type">Chocola</label>
</div>
</div>
</div>
<div class="col-lg-3 mt-2">
<div class="row d-flex justify-content-between px-4">
</div>
<button class="btn-block btn-edit" type="button" data-toggle="modal" data-target="#exampleModal" id="submit">
Edit
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<input id="name">
<br>
<button type="button" class="btn btn-success btn-sm" id="submit">
Submit
</button>
</div>
</div>
</div>
</div>

Angular ngFor trackBy not working. Not Updating DOM

Hi y'all my dom is not being updated with trackBy for some reason. I have another component where trackBy is working great but for some reason I can't get it to work on my new component. I have to refresh the page everytime something is added to groceryList and I don't know why?
HTML:
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<div class="accordion" id="accordionExample">
<div class="card" *ngFor="let grocery of groceryList;trackBy:trackByIdGroceryCode;index as index;">
<div class="card-header" id="grocery1{{index}}">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" attr.data-target="#grocery2{{index}}" aria-expanded="false" aria-controls="grocery2{{index}}">
{{grocery.recipeName}}
</button>
</h5>
</div>
<div id="grocery2{{index}}" class="collapse" aria-labelledby="grocery1{{index}}" data-parent="#accordionExample">
<div class="card-body">
<ul class="list-group" id="filterList">
<li class="list-group-item">
<span class="glyphicon glyphicon-chevron-down"></span>
<ul id="subgroup" class="list-group">
<li class="list-group-item" *ngFor="let ingredient of grocery.ingredients">{{ingredient}}</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
<mat-icon svgIcon="shopping_cart"></mat-icon>
Component Code:
import { Component, OnInit, NgModule } from '#angular/core';
import {GetRecipesService} from '../getrecipes.service'
import { MatIconRegistry } from "#angular/material/icon";
import { DomSanitizer } from "#angular/platform-browser";
#Component({
selector: 'app-grocery-sidebar',
templateUrl: './grocery-sidebar.component.html',
styleUrls: ['./grocery-sidebar.component.css']
})
export class GrocerySidebarComponent implements OnInit {
constructor(getRecipesService: GetRecipesService,private matIconRegistry: MatIconRegistry,private domSanitizer: DomSanitizer) {
getRecipesService.getGroceryList().subscribe(promise=>{
this.groceryList = promise;
this.groceryList = this.groceryList.data;
});
this.recipeService=getRecipesService;
this.matIconRegistry.addSvgIcon("shopping_cart",this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/shopping-cart-solid.svg"));
}
addToGroceryList(recipeName,recipeIngredients){
this.recipeService.addToGroceryList(recipeName,recipeIngredients).subscribe(promise=>{
console.log("addToGroeryList Promise: "+promise);
this.refreshGroceryList();
});
}
refreshGroceryList(){
this.recipeService.getGroceryList().subscribe(promise=>{
console.log("refreshed groceryList: "+promise.data)
this.groceryList = promise.data;
console.log(this.groceryList);
})
}
deleteGroceryRecipeById(recipeId){
this.recipeService.deleteGroceryRecipeById(recipeId).subscribe(promise=>{
this.refreshGroceryList();
});
}
public trackByIdGroceryCode(index: number, grocery: any): string {
console.log("tracking");
return grocery._id;
}
ngOnInit(): void {
}
recipeService;
groceryList;
showFiller=false;
}
And if your wondering, the console.log("tracking") inside of trackByIdGroceryCode() is being called when adding to my groceryList array. So I'm not sure why my dom isnt being updated unless I refresh the page
Here's my console output if you're curious
tracking grocery-sidebar.component.ts:44:12
addToGroeryList Promise: [object Object] grocery-sidebar.component.ts:23:14
tracking grocery-sidebar.component.ts:44:12
refreshed groceryList: [object Object],...,[object Object] grocery-sidebar.component.ts:31:14
Array(23) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ] grocery-sidebar.component.ts:33:14
tracking
{{ groceryList | json }}
<div class="accordion" id="accordionExample">
<div class="card" *ngFor="let grocery of groceryList; index as index;">
<div class="card-header" [id]="'grocery1'+index">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" [attr.data-target]="'#grocery2'+index" aria-expanded="false" [aria-controls]="'grocery2'+index">
{{grocery.recipeName}}
</button>
</h5>
</div>
<div [id]="'grocery2' + index" class="collapse" [aria-labelledby]="'grocery1'+index" data-parent="#accordionExample">
<div class="card-body">
<ul class="list-group" id="filterList">
<li class="list-group-item">
<span class="glyphicon glyphicon-chevron-down"></span>
<ul id="subgroup" class="list-group">
<li class="list-group-item" *ngFor="let ingredient of grocery.ingredients">{{ingredient}}</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
<mat-icon svgIcon="shopping_cart"></mat-icon>
Recipe Component that invokes groceryComponent:
import {Component} from '#angular/core';
import {GetRecipesService} from './getrecipes.service'
import { TagInputModule } from 'ngx-chips';
import {GrocerySidebarComponent} from "./grocery-sidebar/grocery-sidebar.component";
TagInputModule.withDefaults({
tagInput: {
placeholder: 'Add a ag',
// add here other default values for tag-input
},
dropdown: {
displayBy: 'my-display-value',
// add here other default values for tag-input-dropdown
}
});
#Component({
selector: 'recipes', //<recipes>
styleUrls: ['./recipes.component.css'],
template: `
<script src="angular.min.js"></script>
<script src="ng-tags-input.min.js"></script>
<div class="recipeContainer container-fluid">
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="recipeNameInput1">Recipe Name</label>
<input [(ngModel)] ="formRecipeName" name="formRecipeName" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<tag-input [(ngModel)]="formIngredients" id="ingredientTags" [modelAsStrings]="true" name="formIngredients" [secondaryPlaceholder]="'Enter Ingredient'"> </tag-input>
</div>
<button type="submit" class="btn btn-primary" (click)="addRecipe()" data-dismiss="modal">Submit</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Are you Sure Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Are you sure?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<button type="submit" class="btn btn-primary" (click)="deleteRecipeInBuffer()" data-dismiss="modal">Delete</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="album py-5 bg-light">
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<a class="navbar-brand" href="#"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" data-toggle="modal" data-target="#exampleModal">Add Recipe</button>
</li>
<li class="nav-item">
</li>
</ul>
<form class="form-inline mt-2 mt-md-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<div class="row">
<div class="col-md-4" *ngFor = "let recipe of recipeList;trackBy:trackByIdCode">
<div class="card mb-4 box-shadow">
<sup>
<button type="button" data-toggle="modal" data-target="#deleteModal" class="close" aria-label="Close" (click)="prepareToDelete(recipe._id)">
<span aria-hidden="true">×</span>
</button>
</sup>
<h5 class="card-title">{{recipe.recipeName}} </h5>
<div class="card-body" >
<p class="card-text">{{recipe.recipeIngredients}}</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary" (click)="addToGroceryList(recipe.recipeName,recipe.recipeIngredients)">Add To Grocery List</button>
</div>
<small class="text-muted">9 mins</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
TODO: Edit Recipe. Ingreidents with quantity. Ingredients with style (Chopped. Diced. Sautee..etc). Search or Filter (by name or ingredient).
TODO: Add to grocery List. Undo Button
`,
})
export class RecipesComponent{
constructor(getRecipesService: GetRecipesService,groceryList:GrocerySidebarComponent){
getRecipesService.getRecipes().subscribe(promise=>{
this.recipeList = promise;
this.recipeList = this.recipeList.data;
console.log(this.recipeList);
});
this.recipeService=getRecipesService;
this.groceryList = groceryList;
}
addToGroceryList(recipe,ingredients){
this.groceryList.addToGroceryList(recipe,ingredients);
}
//when user presses x on card, the id is stored here. Then are you sure window appears
//if yes on are you sure then delete whats in buffer
//else clear what's in buffer
prepareToDelete(recipeId){
this.deleteBuffer = recipeId;
}
//if yes after are you sure, delete whats in buffer
deleteRecipeInBuffer(){
this.deleteRecipe(this.deleteBuffer);
}
addRecipe(){
this.recipeService.addRecipe(this.formRecipeName,this.formIngredients).subscribe(promise=>{
console.log("promise"+promise);
this.refreshRecipeList();
this.formIngredients = undefined;
this.formRecipeName = undefined;
});
}
deleteRecipe(recipeId){
this.recipeService.deleteRecipe(recipeId).subscribe(promise=>{
console.log(promise);
this.refreshRecipeList();
})
}
refreshRecipeList(){
this.recipeService.getRecipes().subscribe(promise=>{
console.log("refreshed");
this.recipeList = promise.data;
});
}
public trackByIdCode(index: number, recipe: any): string {
return recipe._id;
}
deleteBuffer;//buffer is used to store recipeId => are you sure window comes up. if yes then delete whats in deleteBuffer
formRecipeName;//form value in modal
formIngredients; //form value in modal
recipeService;//http access service
recipeList;//list of all recipes recieved from recipeService
groceryList;
}
UPADTE: I Learned that things update fine when deleting objects but when I call my function to add to my grocery component from my recipe component things don't update. I think my issue is that things arn't being called in the order that I think they are. I still don't know how to fix this but I really appreciate everyone that is trying to help
//
Looks like this could be an angular lifecycle issue; maybe the template is not getting updated after the subscriptions that are called when you run refreshGroceryList(). Try doing a manual change detection after you update the data, like so:
constructor(private cdr: ChangeDetectorRef, ...) {}
refreshGroceryList(){
this.recipeService.getGroceryList().subscribe(promise=>{
console.log("refreshed groceryList: "+promise.data)
this.groceryList = promise.data;
this.cdr.detectChanges();
console.log(this.groceryList);
})
}
The problem is you are trying to bind to aria and data attributes. If you change all the aria- attributes to attr.aria- and data- attributes to attr.data- it will work.
Here is a working StackBlitz https://stackblitz.com/edit/angular-ivy-kp6aev?file=src%2Fapp%2Fapp.component.html

I want to show Modal popup and pass data to modal according to user-id in Laravel Blade

I want to show a popup modal with information for an individual user when someone clicks on view Details Button.
I want to pass the user data according to the user-id and show this in the modal popup. My data are in $user.
I want to do exactly done in the link below website http://ssipgujarat.in/sgh201920/problem_statement.php as you click on view details, it shows the modal for that particular problem statement. I hope that it make sense to you.
#extends('layouts.app')
#section('content')
<div class="container" id="blur-wrapper">
<div class="row">
#foreach($data as $user)
#if($user->user_type == 'user')
<div class="col-md-6 col-sm-12">
<div class="card-wrapper">
<div class="info-wrapper">
<h2>{{ $user->first_name }} {{ $user->last_name }}</h2>
<h6>{{ $user->email }}</h6>
<hr/>
<h6>Department: {{$user->StudentProfile->department}}</h6>
<h6>Sem: {{ $user->StudentProfile->sem }}</h6>
</div>
<div class="button-wrapper">
<form action="{{ $user->id }}">
{{-- <button class="btn btn-primary" id="view-detail">View Details</button>--}}
<a class="btn btn-info" id="view-detail" href="{{ $user->id }}">View Details</a>
</form>
<form method="POST" action="/admin/reject/{{ $user->id }}">
#csrf
<button class="btn btn-danger" type="submit">Delete Account</button>
</form>
</div>
</div>
<div class="popup">
<h2>{{ }}</h2>
</div>
</div>
#endif
#endforeach
</div>
</div>
#endsection
On your view details button assuming you are using bootstrap,your code should
<input type="button" class="button_edit" data-toggle="modal" data-target="#exampleModal{{$user->id}}" value="Edit"/>
on your routes
on your modal's code
#foreach($users as $user)
<div class="modal fade" id="exampleModal{{$user->id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">
Edit Brand
</h5>`enter code here`
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="col-md-offset-2">
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" class="form-control" value="{{$user->first_name}}">
</div>
<input type="submit" value="Edit" class="btn btn-success">
</div>
</div>
</div>
</div>
</div>
#endforeach
Did this with jQuery and Ajax and a data-entry attribute:
blade (CSS: bulma)
<!-- list of elements -->
<li class="dashboard">
<p class="img-hover-dashboard-info showQuickInfo" data-entry="{{ $highlight->id }}"></p>
</li>
<!-- MODAL -->
<div class="modal" id="QuickInfo">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Quick-Info</p>
<button class="delete closeQuickInfo" aria-label="close"></button>
</header>
<section class="modal-card-body">
<!-- PUT INFORMATION HERE, for example: -->
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Rubrik</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" id="category" type="text" value="" readonly>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Kunde</label>
</div>
<div class="field-body">
<div class="field">
<input class="input" id="customer" type="text" value="" readonly>
</div>
</div>
</div>
<!-- END PUT INFORMATION HERE -->
</section>
<footer class="modal-card-foot">
<button class="button is-link closeQuickInfo">Schließen</button>
</footer>
</div>
</div>
jQuery
$(document).ready(function () {
$('.showQuickInfo').click(function () {
$('#QuickInfo').toggleClass('is-active'); // MODAL
var $entry = this.getAttribute('data-entry');
getEntryData($entry);
});
}
function getEntryData(entryId) {
$.ajax({
url: '/entries/getEntryDataForAjax/' + entryId,
type: 'get',
dataType: 'json',
success: function (response) {
if (response.length == 0) {
console.log( "Datensatz-ID nicht gefunden.");
} else {
// set values
$('#category').val( response[0].category );
$('#customer').val( response[0].customer );
// and so on
}
}
});
}
Controller
public function getEntryDataForAjax(int $id)
{
$entries = new Entry();
$entry = $entries->where('id', $id)->get();
echo json_encode($entry);
}

How to access map data in modal button in react

upgrademodalPlan(el){
let data = {
subscription_plan_id: el.subscription_plan_id,
recurrence_time: el.payment_frequency,
}
}
Here I can able to access the el but in model button how to access this el
{ el.is_subscribed ? <button element={el} className="btn btn-success waves-effect waves-light m-t-20" data-toggle="modal" data-target="#upgradePlan" onClick=
{this.upgrademodalPlan.bind(this, el)}>Upgrade Plan</button> : null }
makePayment(el){
the same data what i was accessing in upgrademodalPlan should be accessed here, but i cannot able to access
}
<div id="upgradePlan" className="modal fade emp-add-list" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style={{display: "none"}}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h6 className="modal-title">Upgrade Plan</h6>
<button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div className="modal-body">
<div className="form-group row m-b-0">
<div className="col-md-12 col-sm-6 col-xs-6">
<div className="">
<div className="row">
<div className="col-md-12">
<form>
<div className="form-group">
</div>
<div className="form-group">
<div className="checkbox">
<button type="button" className="btn btn-danger" onClick={this.makePayment.bind(this, this.props)}>Make Payment</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I am not sure to understand your question, but if you want pass el in model button you can use props maybe
{ el.is_subscribed ? <button element={el} className="btn btn-success waves-effect waves-light m-t-20" data-toggle="modal" data-target="#upgradePlan" onClick=
{this.upgrademodalPlan.bind(this, el)}>Upgrade Plan</button> : null }

jQuery plugin not working inside a .vue component

I'm working in a vue component for my application in Laravel 5.3, I try to integrate the Laravel File Manager in a standalone button, but this not working, nothing happend when I clic on the button for choose an image, this component required a jQuery init setup, like the following line:
$('.lfm-img').filemanager('image');
I checked the component outside the .vue file and its working fine, only inside the .vue file is not working.
This is the vue component
<template>
<div class="modal fade"
id="section-{{ section.id }}"
tabindex="-1"
role="dialog"
aria-labelledby="sectionLabel-{{ section.id }}">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="sectionLabel-{{ section.id }}">
{{ section.name }}
</h4>
</div>
<div class="modal-body">
<!-- Field List -->
<div v-if="editing != true">
<ul class="list-group">
<li class="list-group-item" v-for="field in fields">
<div class="clearfix">
<div class="pull-left">
<span>
{{ field.name }}
</span>
</div>
<div class="pull-right">
<button type="button"
class="btn btn-default"
data-toggle="tooltip"
title="Editar valor"
#click="setField(field)">
<i class="fa fa-pencil-square fa-lg"
aria-hidden="true"></i>
</button>
</div>
</div>
</li>
</ul>
</div>
<!-- / Field List -->
<!-- Save value form -->
<div v-else>
<form #submit.prevent="updateFieldValue()">
<!-- Fields types -->
<div v-if="field.fieldtype_id === 1">
<div class="form-group vertical-align">
<label class="col-md-2 text-right">
Texto
</label>
<div class="col-md-10">
<input type="text"
v-model="value"
placeholder="Ingrese el valor"
class="form-control"
required="required">
</div>
</div>
<p><br></p>
</div>
<div v-if="field.fieldtype_id === 2">
<div class="form-group">
<textarea v-model="value"
placeholder="Ingrese texto"
class="form-control"
rows="5"
required="required">
</textarea>
</div>
<p><br></p>
</div>
<div v-if="field.fieldtype_id === 3">
<div class="form-group vertical-align">
<label class="col-md-3 text-right">
Seleccione una imagen
</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-btn">
<a data-input="value"
data-preview="holder"
class="btn btn-primary lfm-img">
<i class="fa fa-picture-o"
aria-hidden="true"></i> Seleccionar
</a>
</span>
<input id="value"
v-model="value"
class="form-control"
type="text"
name="value"
required="required">
</div>
</div>
</div>
<img id="holder" style="margin-top:15px;max-height:100px;">
<p><br></p>
</div>
<!-- Actions -->
<div class="clearfix">
<div class="pull-right">
<button type="button"
class="btn btn-default"
data-dismiss="modal"
#click="finishEdit()">
Cancelar
</button>
<button type="submit"
class="btn btn-primary">
Guardar
</button>
</div>
</div>
</form>
</div>
<!-- / Save value form -->
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-default"
#click="finishEdit()"
data-dismiss="modal">
Cerrar
</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['section'],
data()
{
return {
fields: [],
field: [],
value: '',
loading: true, // start the spin loader
editing: false // show field list
}
},
ready()
{
this.loading = false; // stop the spin loader
this.getSectionFields();
},
methods:
{
startEdit()
{
this.editing = true;
},
finishEdit()
{
this.field = [];
this.value = '';
this.editing = false;
},
setField(field) {
this.field = field;
if (this.field.pivot.value !== null) {
this.value = this.field.pivot.value;
}
this.startEdit();
},
getSectionFields()
{
var self = this; // store "this." scope
// GET request
this.$http.get('/api/getSectionFields/' + this.section.id )
.then((response) => {
// sucess callback
var json = JSON.parse(response.body); // json parse
self.fields = json.fields;
this.loading = false; // stop the spin loader
}, function(response) {
// error callback
console.log(response);
});
},
updateFieldValue()
{
this.loading = true // start the spin loader
var params = { section : this.section.id,
field : this.field.id,
value : this.value
};
// POST request
this.$http.post('/api/update-value', params)
.then((response) => {
// sucess callback
this.getSectionFields();
this.finishEdit();
}, function(response) {
// error callback
console.log(response);
this.getSectionFields();
});
}
}
}
</script>
I solved the problem using Vue.nextTick, running the following code before the file manager be shown to ensure the initialization of the plugins in the latest DOOM update.
initFilemanager()
{
this.$nextTick(function() {
$('.lfm-img').filemanager('image');
});
},

Categories