I need some help in debugging a problem that is driving me nuts.
I have a laravel project with Vue3 as the frontend, using InertiaJS for connecting to the backend.
The folder structure is as follows
|_resources
|__js
|___Pages
|____AddContent
|_____Index.vue
|____Home
|_____Index.vue
|___Shared
|____Footer.vue
My Footer.vue (below) is working fine when called at Home/Index.vue
<div class="m-6 text-ternary-dark dark:text-ternary-light text-lg">
<div class="flex justify-between">
<Link href="/">
<i data-feather="home" class="ml-0 sm:ml-1 mr-2 sm:mr-3 w-5 sm:w-6"></i>
</Link>
<Link href="/market"><i data-feather="package" class="ml-0 sm:ml-1 mr-2 sm:mr-3 w-5 sm:w-6"></i></Link>
<Link href="/add"><i data-feather="plus-square" class="ml-0 sm:ml-1 mr-2 sm:mr-3 w-5 sm:w-6"></i></Link>
<Link href="/message"><i data-feather="send" class="ml-0 sm:ml-1 mr-2 sm:mr-3 w-5 sm:w-6"></i></Link>
<Link href="/profile"><i data-feather="user" class="ml-0 sm:ml-1 mr-2 sm:mr-3 w-5 sm:w-6"></i></Link>
</div>
</div>
</template>
<script>
import { Link } from "#inertiajs/inertia-vue3";
import feather from 'feather-icons';
export default {
components: {
Link,
},
};
</script>
Home.vue
<template>
<Header />
<div class="mb-4 text-ternary-dark dark:text-ternary-light text-lg">
<!-- The top section of homepage, reserved for hastags, news, and other features -->
<div>
<p>Top Component</p>
</div>
<!-- The rest of the homepage contents -->
<div>
<p>The Rest</p>
<div class="wrapper" v-if="blogs.length">
<div class="blog" v-for="blog in blogs" :key="blog">
<Link href="blogs/{id}/show" method="get" :data="{id: blog.id}">
<!-- <img v-bind:src="blog.image"/> -->
<small>posted by: {{ blog.id }}</small>
{{ blog.title }}
</Link>
</div>
</div>
</div>
</div>
<Footer />
</template>
<script>
import { Link } from '#inertiajs/inertia-vue3'
import Header from "../../Shared/Header.vue";
import Footer from "../../Shared/Footer.vue";
export default {
components: {
Header,
Footer,
Link
},
props: {
blogs: Object,
},
};
</script>
Here's the look of Home/Index.vue:
Then, the problem is, at the AddContent/Index.vue (below), I have the same code as the Home/Index.vue to import the footer.
<template>
<div class="mb-4 text-ternary-dark dark:text-ternary-light text-lg">
<form #submit.prevent="submit">
<label for="title">Title: </label>
<input type="text" id="title" v-model="form.title" placeholder="type something" class="rounded-full py-1 px-4"/>
<label for="body">Body: </label>
<input type="text" id="body" v-model="form.body" placeholder="type something" class="rounded-full py-1 px-4"/>
<button type="submit">Submit</button>
</form>
</div>
<Footer />
</template>
<script>
import { reactive } from "vue";
import { Inertia } from "#inertiajs/inertia";
import Footer from "../../Shared/Footer.vue";
export default {
components: {
Footer,
},
setup() {
const form = reactive({
title: null,
body: null,
});
function submit() {
Inertia.post("/", form);
}
return { form, submit };
},
};
</script>
<style scoped>
* {
outline: 1px solid red;
}
</style>
However, in my AddContent/index.vue, the footer bar just does not show up.
I have no idea what the heck is going on... as the red outline was wrapping the footer just fine but nothing from the footer passed to the AddContent page. Any hints on this would be greatly appreciated!
#ShayaUlman suggestion resolved the issue by changing the component into a layout https://inertiajs.com/pages.
For future reference, if your layout does not appear, try to remove or comment out the contents, re-start npm and re-add the contents. This appears to resolve the issue afterwards.
Related
I'm trying to build a basic chat function for a site and am following along with this tutorial...
(https://www.youtube.com/watch?v=tHbCkikFfDE&list=WL&index=4)... but socket.io doesn't seem to be loading on the page. I used the most recent CDN. I have a feeling my file path is off but I'm not quite sure how to repair it. I'm new, be gentle.
<html>
<head>
<title>IO Chat</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.slim.js" integrity="sha256-DrT5NfxfbHvMHux31Lkhxg42LY6of8TaYyK50jnxRnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<style>
body {
margin-top: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="well">
<h3>Online Users</h3>
<ul id="users" class="list-group"></ul>
</div>
</div>
<div class="col-md-8">
<div class="chat" id="chat"></div>
<form id="messageForm">
<div class="form-group">
<label>Enter Message</label>
<textarea class="form-control" id="message">
</textarea>
<br />
<input type="submit" class="btn btn-primary" value="Send Message" />
</div>
</form>
</div>
</div>
</div>
<script>
$(function(){
var socket = io.connect();
var $messageForm = $('#messageForm');
var $message = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $message.val());
$message.val('');
});
socket.on('new message', function(data){
$chat.append('<div class="well">'+data.msg+'</div>')
})
})
</script>
</body>
</html>
I work on Laravel + Vuejs. Something has just happened, since then my script as copied hereunder doesn't work, chrome doesn't detect any vuejs script.
Astonishingly, the same script works well if I copy it into backup directory & run PHP artisan instance from there. Need advise. Actually problem seems with routerview which could not activate due to unknown problem. did i wrongly uninstall something which need to reinstall again ? because seems router doesn't work
kash.blade.php: - Main script
<head>
<link rel="stylesheet" type="text/css" href="{{ asset('css/app.css')}}">
<link href="{{asset('backend/vendor/fontawesome-free/css/all.min.css')}}"
rel="stylesheet" type="text/css">
<link href="{{asset('backend/vendor/bootstrap/css/bootstrap.min.css')}}"
rel="stylesheet" type="text/css">
</head>
<body id="page-top">
<div id="app">
<div id="wrapper">
<div class="container-fluid" id="container-wrapper">
<router-view></router-view>
</div>
</div>
</div>
<script src="{{asset('js/app.js')}}"></script>
<script src="{{asset('backend/vendor/jquery/jquery.min.js')}}"></script>
<script src="{{asset('backend/vendor/bootstrap/js/bootstrap.bundle.min.js')}}"></script>
<script src="{{asset('backend/vendor/jquery-easing/jquery.easing.min.js')}}"></script>
</body>
</html>
route.js: - where I describe the component route as to where login.vue lies
let login = require('./components/auth/login.vue').default;
export const routes = [
{ path: '/', component: login, name:'/' },
]
Login.vue: - Just a simple vue script with two text boxes.
<template>
<div>
<div class="container-login">
<h1 class="h4 text-gray-900 mb-4">Login</h1>
</div>
<form class="user" #submit.prevent="login">
<div class="form-group">
<input type="email" class="form-control" id="exampleInputEmail"
placeholder="Enter Email Address" v-model="form.email">
</div>
<div class="form-group">
<input type="password" class="form-control" id="exampleInputPassword"
placeholder="Password" v-model="form.password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">Login</button>
</div>
<hr>
</form>
<hr>
<div class="text-center">
</div>
</div>
</template>
<script type="text/javascript">
export default {
data(){
return {
form:{
email: null,
password: null
}
}
},
methods:{
}
}
</script>
I am doing POC on login application using angular js. On button click I need to navigate to another page. The code which I have written is only updating the url but the view is not getting loaded. I have used ng-view or ui- view also. And I have used $location.path. But still unable to navigate to other page
Here is my code
index.html:
<html ng-app='myApp'>
<head>
<title>Jasmine</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="routing.js" type="text/javascript"></script>
</head>
<body>
<div id='content' ng-controller='LoginController'>
<div class="container">
<form class="form-signin" role="form" name="myForm" ng-submit="login()">
<h3 class="form-signin-heading">Login Form</h3>
<span>
<b>Username :</b> <input type="text" class="form-control" ng-model="user.name" required>
</span> <br />
<br /> <span>
<b>Password :</b> <input type="password"
class="form-control" ng-model="user.password" required>
</span>
<br><br>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-disabled="myForm.$invalid">
<b>Sign in</b>
</button>
</form>
</div>
{{message}}
</div>
<div ui-view></div>
</body>
</html>
Here I have used ui-view.. when i use this, url is updating but not the view..
when i use ng-view, the script block is happening both in chrome and firefox.
routing.js:
var applog = angular.module('myApp', ['ngRoute']);
applog.controller("LoginController", function ($scope, $location, $window) {
$scope.message = "hi";
$scope.login = function () {
var username = $scope.user.name;
var password = $scope.user.password;
$location.path('/home');
};
});
applog.controller("HomeController", function ($scope, $location) {
$scope.msg = "qwerty";
});
applog.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'index.html',
controller: 'LoginController'
}).when('/home', {
templateUrl: '/home.html',
controller: 'HomeController'
}).otherwise({
redirectTo: 'index.html'
});
});
Here I tried with hash also.. not working
Home.html:
<div ng-controller="HomeController">
Welcome....
</div>
I am learning Laravel 5.2 and vue.js,and not familiar with the grammars,the question is:
How to get all of the values of the form elements below and send them to controller with vue.js?
Including text,select,textarea,file input,radios,checkboxes.
PS:
There is a plugin in the html demo,it's function is compressing a selected image.
lrz.bundle.js,https://github.com/think2011/localResizeIMG
html demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
</head>
<body>
<div class="container">
<form>
<div class="form-group row">
<label for="formGroupExampleInput" class="col-sm-2 form-control-label">Text</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="formGroupExampleInput" placeholder="">
</div>
</div>
<div class="form-group row">
<label for="exampleSelect1" class="col-sm-2 form-control-label">Select</label>
<div class="col-sm-10">
<select class="form-control" id="exampleSelect1">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="exampleTextarea" class="col-sm-2 form-control-label">Textarea</label>
<div class="col-sm-10">
<textarea class="form-control" id="exampleTextarea" rows="3"></textarea>
</div>
</div>
<div class="form-group row">
<label for="exampleInputFile" class="col-sm-2 form-control-label">File input</label>
<div class="col-sm-10">
<input id="exampleInputFile" name="photo" type="file" class="form-control-file" value="Upload" accept="image/*">
preview:
<img id="preview"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2">Radios</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> 2
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3"> 3
</label>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2">Checkboxes</label>
<div class="col-sm-10">
<div class="checkbox">
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox1" value="option1"> 1
</label>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox2" value="option2"> 2
</label>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox3" value="option3"> 3
</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-secondary">Submit</button>
</div>
</div>
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/js/bootstrap.min.js" integrity="sha384-vZ2WRJMwsjRMW/8U7i6PWi6AlO1L79snBrmgiDpgIWJ82z8eA5lenwvxbMV1PAh7" crossorigin="anonymous"></script>
<script src="js/dist/lrz.bundle.js"></script>
<script>
$(function () {
var $preview = $('#preview');
$('#exampleInputFile').on('change', function () {
lrz(this.files[0], {
width: 800
}).then(function (rst) {
$preview.attr('src', rst.base64);
rst.formData.append('fileLen', rst.fileLen);
});
});
});
</script>
</body>
</html>
I've a little bit of uncertainty as to whether or not it's actually a Laravel -> Vue setup you're looking for since you have absolutely no Laravel nor Vue code in your question which is extremely broad, but here's a basic template to get started. I use the following in pretty much every project.
Laravel
Create your route - routes/web.php:
Route::post('/myform', 'FormControntroller#submitForm');
Create your controller and method - app/http/controllers/FormController.php
class FormController extends App\Controllers\Controller {
public function submitForm()
{
var_dump(request->all());
}
}
Create your entry view - resources/views/app.blade.php
<html>
<head>
<title>Minimal Vue Example</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.1/vue.min.js"></script>
<script src="/js/main.js"></script
</body>
</html>
Vue
main.js
import Vue from 'vue'
import Resource from 'vue-resource'
import Router from 'vue-router'
import Root from './components/Root.vue'
Vue.use(Router)
Vue.use(Resource)
var router = new Router({
history: true,
});
router.map({
'/': {
component: Root
},
});
// Start up our app
router.start(Root, '#app');
Create your root component - resources/views/assets/js/components/Root.vue
<template>
<form v-on:submit.prevent="submitForm">
<input type="text" v-model="formData.username"/>
<input type="text" v-model="formData.password"/>
</form>
</template>
<script>
export default {
data: function() {
return {
formData: {
username: null,
password: null
}
}
},
methods: {
submitForm: function() {
this.$http.post('/myform', this.formData).then(function(response) {
alert('Yay, my form was posted!');
});
}
}
}
</script>
At this point you'll need to run webpack on your assets, see the Laravel Documentation on Elixir.
Again, you've asked a very broad question without providing much background, but this will get you going.
Notes: The above code is working code on Vue 1.X, version 2 is slightly different.
For further help on Vue and Laravel, see the Laravel Documentation.
I am trying to use jquery-validate plugin to validate a form inside a bootstrap-dialog. The "required" rule doesn't prevent me from submitting a form with an empty text field. However, "digits" rule works so that means validation is initialized properly. What am I missing here? Thanks.
Here's how I display the bootstrap-dialog and how I initialize validation.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>App Title</title>
<link type="text/css" rel="stylesheet" href="<c:url value="/css/bootstrap/3.0.3/bootstrap.min.css" />"></link>
<script src="<c:url value="/js/jquery/1.10.2/jquery-1.10.2.min.js" />"></script>
<script src="<c:url value="/js/jquery-ui/1.10.4/jquery-ui.min.js" />"></script>
<script src="<c:url value="/js/bootstrap/3.0.3/bootstrap.min.js" />"></script>
<script src="<c:url value="/js/bootstrap-dialog//bootstrap-dialog.min.js" />"></script>
<link type="text/css" rel="stylesheet" href="<c:url value="/css/style.css" />"></link>
<link type="text/css" rel="stylesheet" href="<c:url value="/css/jquery-ui/1.10.4/jquery-ui.min.css" />"></link>
<link type="text/css" rel="stylesheet" href="<c:url value="/css/bootstrap-dialog/bootstrap-dialog.min.css" />"></link>
<script src="<c:url value="/js/jquery-validation/1.11.1/jquery.validate.min.js" />"></script>
<script type="text/javascript">
function wireValidationEvent($form)
{
$form.validate({
errorElement: 'span',
errorClass: 'help-block',
wrapper: "div",
rules: {
name: {
required: true
}
},
messages: {
name: {
required: "Please enter the name properly."
}
},
highlight: function (element) {
$(element).closest('.form-group').addClass('has-error');
},
success: function (element) {
$(element).closest('.form-group').removeClass('has-error');
}
});
}
function showModalDialog(url)
{
var get = $.get(url, '');
get.done(function(data) {
// Note that data contains just a form without any button.
// The form is dynamically injected into the body of the modal dialog. That's why wireValidationEvent() is called each time when a form is injected.
// When Save button is clicked, the form will be submitted using jquery.
BootstrapDialog.show({
title: 'Update Form',
closable: true,
autodestroy: true,
onshow: function(dialogRef){
var $body = dialogRef.getModalBody();
$body.append(data.trim());
var $formObj = $body.find('#formOfReligion');
if ($formObj)
{
// TODO bug: required validation rule doesn't work here
wireValidationEvent($formObj);
}
else
{
alert('formOfReligion is missing');
}
},
buttons: [{
label: 'Save',
action: function(dialog) {
var formObj = $('#formOfReligion');
if (formObj && formObj.length > 0)
{
var form = formObj[0];
var post = $.post(form.action, formObj.serialize());
post.done(function( data ) {
// succeeded
dialog.close();
$('#frmQuery').submit();
});
post.fail(function( data ) {
// failed
});
}
}
}, {
label: 'Cancel',
action: function(dialog) {
dialog.close();
}
}]
});
});
return true;
}
</script>
Here's what the modal dialog looks like.
<div class="modal-backdrop fade in"></div>
<div id="bea044b7-a0cb-48df-8b57-6cbdedac9bdf" class="modal fade bootstrap-dialog type-primary size-normal in" tabindex="-1" style="display: block;" aria-hidden="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<div class="bootstrap-dialog-header">
<div class="bootstrap-dialog-title">Update Form</div>
<div class="bootstrap-dialog-close-button" style="display: block;">
<button class="close">×</button>
</div>
</div>
</div>
<div class="modal-body">
<div class="bootstrap-dialog-body">
<div class="bootstrap-dialog-message"></div>
</div>
<form id="formOfReligion" class="form-horizontal" role="form" method="POST" action="/prs/protected/test" novalidate="novalidate">
<fieldset>
<div class="form-group">
<div>
<label class="control-label" for="name">Name</label>
</div>
<div>
<input id="id" type="hidden" value="6" name="id">
<input id="name" class="form-control" type="text" value="test" autofocus="autofocus" name="name">
</div>
</div>
</fieldset>
</form>
</div>
<div class="modal-footer">
<div class="bootstrap-dialog-footer">
<div class="bootstrap-dialog-footer-buttons">
<button id="667d578f-490e-4d08-a8c1-1013b60c3394" class="btn btn-default">Save</button>
<button id="8b647389-edce-4f64-af8e-64521e865dcf" class="btn btn-default">Cancel</button>
</div>
</div>
<input id="id" type="hidden" value="6" name="id">
<input id="name" class="form-control" type="text" value="test" autofocus="autofocus" name="name">
You have a hard-coded value of "test" on the input so the required rule is already satisfied without the user having to enter anything.
BTW: I don't think you have a good naming system here: id="id", name="id", id="name", and name="name". It's not semantic, not scalable, and potentially confusing.