Accessing child component data in view - php

Currently I'm using Laravel 5.2 with Elixir 5 and Vue 2.0.
I'm stuck on how to access and imported component's data from the element view using something like v-if.
Here's my setup:
resources\views\vuetest.blade.php
<div id="app">
<modal v-if="showModal"></modal>
<button>Show Modal</button>
</div>
resources\assets\vuejs\app.js
import Vue from 'vue';
import Modal from './components/modals/show-modal.vue';
Vue.component('modal', Modal);
if (document.getElementById("app")){
var app = new Vue({
el: '#app',
data: {
},
methods: {
},
computed: {
},
components: {
'modal': Modal
}
});
window.vue = app;
}
resources\assets\vuejs\components\modals\show-modal.vue
<template>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showModal: false
}
},
components: {
},
}
</script>
Now if I just use this without v-if then it works and pulls in the template correctly.
However if I use what I had in my example it gives me an error:
app.js:967 [Vue warn]: Property or method "showModal" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
(found in <Root>)
If I add data in main app.js it can access it but not in imported child components. I'd rather not make the main app.js messy and better to use imports and keep components in organized subfolders. How can I access these child component data properly?

If you want to change the state of the child component, you can set a ref on the component and access the properties directly.
In this example, a ref is set on each modal component.
<bootstrap-modal ref="modal1">
Then, to change a data value in the referenced component, simply set it like you would any other javascript value.
<button type="button" class="btn btn-primary" #click="$refs.modal1.visible = true">Show Modal One</button>
console.clear()
const BootstrapModal = {
template: "#modal-template",
data() {
return {
visible: false
}
},
watch: {
visible(show) {
if (show) $(this.$el).modal('show')
else $(this.$el).modal('hide')
}
},
mounted() {
// listen for the close event
$(this.$el).on("hidden.bs.modal", () => {
this.visible = false
})
}
}
new Vue({
el: "#app",
components: {
BootstrapModal
}
})
<script src="https://unpkg.com/vue#2.4.2"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<div id="app">
<button type="button" class="btn btn-primary" #click="$refs.modal1.visible = true">Show Modal One</button>
<bootstrap-modal ref="modal1">
<span slot="title">Modal One</span>
<p slot="body">Modal One Content</p>
</bootstrap-modal>
<button type="button" class="btn btn-success" #click="$refs.modal2.visible = true">Show Modal Two</button>
<bootstrap-modal ref="modal2">
<span slot="title">Modal Two</span>
<p slot="body">Modal Two Content</p>
</bootstrap-modal>
</div>
<template id="modal-template">
<div class="modal fade">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><slot name="title">Modal Title</slot></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<slot name="body"><p>Modal Body</p></slot>
</div>
<div class="modal-footer" v-if="$slots.footer">
<slot name="footer"></slot>
</div>
</div>
</div>
</div>
</template>

You need to declare the var showModal on your main app.
data: {
showModal: false
},
You also need to toggle that variable everytime they click the button, so add this to your button:
<button #click="showModal = !showModal">Show Modal</button>
Also i suggest to wrap your modal inside template with a div. Since vuejs required this.
<template>
<div>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</template>

Short answer: you are trying to access property of child component within the scope of parent component (or, the Root instance in your case). You should declare showModal property on the Parent component instead.
var app = new Vue({
el: '#app',
components: {Modal},
data: {
showModal: false
},
});
and then you would have the button changing the state of your property:
<button #click="showModal = true"></button>
The tricky part is close out the modal - because you can't reach your button anymore when the modal is active. You would have to change the state of your parent component from your child component. You can use custom events in this case, like so:
In the show-modal.vue
<div class="modal-footer">
<button type="button" class="btn btn-default" #click="close">
Close
</button>
</div>
...
<script>
export default {
methods: {
close() {
this.$emit('close');
}
}
}
And now, all we have to do is to listen on that custom event we just fired in the main template, like so;
<modal v-if="showModal" #close="showModal = false"></modal>

Not sure if best way but I figured it out with the help from this:
VueJS access child component's data from parent
What I did was in my child component I put the following:
<template>
<div>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
showModal: false
}
},
components: {
},
}
</script>
Then in my vuetest.blade.php I put this:
<div id="app">
<modal v-if="modalData.showModal"></modal>
<button>Show Modal</button>
</div>
Then lastly in my app.js I did this:
import Vue from 'vue';
import Modal from './components/modals/show-modal.vue';
if (document.getElementById("app")){
var app = new Vue({
el: '#app',
data: {
modalData: Modal.data()
},
methods: {
},
computed: {
},
components: {
'modal': Modal
}
});
window.vue = app;
}
I didn't complete the code for the show modal button obviously but at least using this way I can now access child data. I would just need to define this for every component which should account for as many vars it contains inside the data.
Also thanks Carlos for suggestion of wrapping it into a div.

Related

Bootstrap modal window in Laravel app not showing

I'm writing a Laravel app and trying to implement a modal showing some details on an element. When I'm clicking on the link the backdrop is showing but not the modal window. In the network monitor of chrome it is showing the modal window in preview.
What's wrong?
Thank you in advance for your help!
Here is my code
index.blade.php
<td>
Details
</td>
modal.blade.php
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">#yield('title')</h5>
</div>
<div class="modal-body">
#yield('content')
</div>
<div class="modal-footer">
#yield('footer')
</div>
</div>
</div>
show.blade.php
#extends('layouts.modal')
#section('title')
Demo Modal
#endsection
#section('content')
<p>test</p>
#endsection
#section('footer')
<button type="button" data-dismiss="modal">Close</button>
#endsection
remote.js
$(document).on('ajax:success', function(e, xhr){
if(!$('#modal').length){
$('body').append($('<div class="modal" id="modal"></div>'))
}
$('#modal').html(xhr.responseText).modal('show');
});
ProjectController.php
public function show($id)
{
$project = Project::findOrFail($id);
return view('projects.show', compact('project'));
}
Hey never use HTML Element in making a clickable modals that has value on it.
I suggest you used add value on it , That can be "ID" then add modal attributes on it, Then boom everything is fine and working.
You need to specify the html id tag in your link.
I suggest you try this
<a data-toggle="modal" id="smallButton" data-target="#smallModal"
data-attr="{{ route('projects.show', $project->id) }}" title="show">
<i class="fas fa-eye text-success fa-lg"></i>
</a>
<!-- small modal -->
<div class="modal fade" id="smallModal" tabindex="-1" role="dialog" aria-labelledby="smallModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-sm" 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>
</div>
<div class="modal-body" id="smallBody">
<div>
<!-- the result to be displayed apply here -->
</div>
</div>
</div>
</div>
</div>
<script>
// display a modal (small modal)
$(document).on('click', '#smallButton', function(event) {
event.preventDefault();
let href = $(this).attr('data-attr');
$.ajax({
url: href,
beforeSend: function() {
$('#loader').show();
},
// return the result
success: function(result) {
$('#smallModal').modal("show");
$('#smallBody').html(result).show();
},
complete: function() {
$('#loader').hide();
},
error: function(jqXHR, testStatus, error) {
console.log(error);
alert("Page " + href + " cannot open. Error:" + error);
$('#loader').hide();
},
timeout: 8000
})
});
</script>
In your Remote.js file :
$(document).on('ajax:success', function(e, xhr){
if(!$('#modal').length){
$('body').append($('<div class="modal" id="modal"></div>'))
}
$('#modal').modal('show');
$('#modal').html(xhr.responseText);
});

Laravel: Is it possible to load blade view into a jquery modal?

Below is my main blade file that I want to load into modal.
#extends('layouts.app')
#section('title', trans('pages.jobs.show.header_title') ?: trans('pages.jobs.show.title'))
#section('navigation')
#endsection
#section('content')
<div class="container">
<div class="page-dashboard">
{{ all teh content loaded: such as SVG grapgh using JS }}
</div>
</div>
<nav class="container-fluid nav-bottom" data-js="nav-bottom">
<div class="nav-bottom__overlay"></div>
</nav>
#push('scripts')
<script src=""></script>
#endpush
#endsection
I have tried using bootstarp.js modal but the modal is not loading, it loads in the main page.
Is it possible to load an entire blade with its own CSS and js included?
Kindly provide me any example. Maybe, I have to use ajax:
$('#modellink').click(function(){
$.ajax({
type : 'GET',
url : $(this).data('path'),
success: function(result, url) {
$('.modal-body').html(result);
$('#myModal').modal('show');
$('.modal-container').load($(this).data('path'),function(result){
$('#myModal').modal({show:true});
});
}
});
});
If you have a file call modal.blade.php, which has all the HTML, CSS and JS for that modal, you can include it on any page with #include("modal"). For example:
modal.blade.php
<style>...</style>
<div class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" 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">Modal title</h4>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">...</script>
Then, in your main file:
main.blade.php
#extends("layout")
#section("content")
#include("modal")
<div>...</div>
Return the HTML string
// SomeController::getModal()
return view('layouts.someview', $data_array)->render();
Load it into the modal
$.ajax(
// blah,
// blah,
success: function(response) {
$('#modal').html(response)
}
)
In short - yes.
Im not sure how you're loading your modal - as you don't provide much information, but, if you can load an external page into your modal, then simply point to the laravel route that displays your blade view.
Alternatively, use an #include('modal.name.blade') and have that as part of the page which uses the modal with the correct html/css of course for your relevant modal script.

Should I (and how) run a php script with modal bootstrap?

I have created a phpscript - calculator it's here
How to optimize this short script in php - salary calc
and it is working.
Now I would like to do sth like this. A person on my web page clicks the button, the calculator opens in sth like little window, he uses calculator and when he finishes, closes the window with calculator and is on the webpage again. As I understand I should do it with bootstrap modal like this: http://www.w3schools.com/bootstrap/tryit.asp?filename=trybs_modal_sm&stacked=h
Do I understand it right?
How should I link my phpscript with this modal?
thank You for your hints?
what you need is an Ajax method with modal event listener,
Modal HTML
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Small Modal</button>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<div id="showcal"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
B.S Modal event listener with Ajax Method
$(document).ready(function(){
$('#myModal').on('shown.bs.modal', function () {
$.ajax({
type: 'GET',
url: "calculator.php", //this file has the calculator function code
success:function(data){
$('#showcal').html(data);
}
});
});
});
and in last calculator.php
<?php
//Here comes the calculator code
?>
Lemme know if it worked and if not will make it work.

Using Bootstrap Modal for ZfcUser in ZF2?

as i am a complete newbie to Zend Framework this might be a total beginner question:
I did some tutorials and now i have a Zend-Framework skeleton-application with ZfcUser (and ZfcBase) up and running.
Everything works fine so far, but what i want to accomplish is that the Login and Registration opens up in a Bootstrap-Modal-Dialog.
So now i see that in ./vendor/ZfcUser/config/module.config.php you can define the routes, but i have no idea what to do, when i want the whole dialogs being "served" with the index of my main-application (i guess i will need this to let the login dialog open up from the main menu from anywhere in the application).
So can someone help me with getting this to work? I really have no idea how to start at all and any help is highly appreciated :)
best regards
If you want to use Bootstrap Model for ZfcUser login, You need to change approach of login a bit.
You should use ZfcUser API Calls to validate login instead of post data on /user/login page.
You need to override the ZfcUser login.html to change form action button from submit to simple button/link binded with ajax request.
Call ZfcUserLoginWidget into Bootstrap Model's body
Form/ajax action set to your custom auth page
Where ZfcUser API Calls validate & return json response with success/failure.
ZfcUser validation no more work automatically, You need to apply through jQuery, Javascript from Json Response.
So First copy vendor/ZfcUser/view/user/login.html to module/[YourModule]/view/zfc-user/user/login.phtml
Now replace submit button with normal button like that :
<input type="button" value="Sign in" onClick="javascript:verifyLogin(this.form);" />
--
--
<script type="text/javascript">
function verifyLogin(frm)
{
var data = $(frm).serialize();
$.ajax({
type: "POST",
url: "<?php echo $this->url('authurl') ?>",
data: data,
success: function(resp){
alert(resp.status);
},
error: function(resp){
},
dataType: 'json'
});
}
</script>
You should add a route for authurl for YourController/authAction
Add your html for Bootstrap model on parent template view :
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Login Box
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<?php echo $this->zfcUserLoginWidget(); ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Now YourController/authAction code should work like that :
$request = $this->getRequest();
$data = $request->getPost();
$this->getRequest()->getPost()->set('identity', $data['identity']);
$this->getRequest()->getPost()->set('credential', $data['credential']);
$this->zfcUserAuthentication()->getAuthAdapter()->resetAdapters();
$this->zfcUserAuthentication()->getAuthService()->clearIdentity();
$adapter = $this->zfcUserAuthentication()->getAuthAdapter();
$adapter->prepareForAuthentication($this->getRequest());
$auth = $this->zfcUserAuthentication()->getAuthService()->authenticate($adapter);
if (!$auth->isValid()) {
//$this->flashMessenger()->setNamespace('zfcuser-login-form')->addMessage($this->failedLoginMessage);
$adapter->resetAdapters();
$response_data = array(
'status' => 'Failure'
) ;
}
else
{
$response_data = array(
'status' => 'OK'
) ;
}
$response = $this->getResponse();
$response->setStatusCode(200);
$response->setContent(json_encode($response_data));
return $response;
The Login Widget viewhelper is probably what you are looking for. Within your desired .phtml template just add the viewhelper to render the login form.
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">× </button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<?php //Add the Widget to the Modal Body here!?>
<?php echo $this->zfcUserLoginWidget(); ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
If you want to alter the template of the widget you'll need to edit/add the zfcuser.global.php in your ../config/autoload/ folder and change/uncomment this the following to your desired login-widget template.
'user_login_widget_view_template' => 'your_module/whatever/login.phtml',

Unable to load Bootstrap Modal via Ajax

I have my html code as:
<button class="btn btn-default" id="openForm">
New
</button>
<!-- Modal -->
<div class="modal fade hide" id="formModal">
<div class="modal-header">
<h4>
Form
</h4>
</div>
<div class="modal-body" id="formModalBody">
</div>
<div class="modal-footer">
Close
</div>
</div>
My Java script reads as:
$(document).on('click', '#openForm', function(e) {
e.preventDefault();
$("#formModalBody").html("");
$("#formModal").modal('show');
$.post('index.php/customers/view/-1/',
{id: -1},
function (html) {
$("#formModalBody").html(html);
}
);
});
I am using Twitter Bootstrap & Codeignitor. The post url above is index.php/Controller/function
When I am clicking on the button; I am not able to see the Bootstrap Modal. The page fades in, but there is no modal visible.
this is for bootstrap 3 and can be triggered by html alone without javascript it will run
Launch demo modal
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body" id="formModalBody">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<!-- For javascript -->
$.post('index.php/customers/view/-1/',
{id: -1},
function (html) {
$("#formModalBody").html(html);
}
);
You should use anchor link instead of button, it will work default settings
<a href="/model_link" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</a>
The href link response code will append in
<div class="modal-body" id="formModalBody">
<!-- modal body -->
</div>

Categories