I am using Vuejs cdn. In which I have a Navigation menu. I want to load different layout when a user clicks on Nav menu.
for example
<div class="row" id="mytemplate">
<div class="col-sm-3 sidebar-col">
<div>
<nav class="settings-sidebar">
<h4>Profile settings</h4>
<ul>
<li class="active" v-on:click="Profile()">
<a >Profile picture</a>
</li>
<li class="" v-on:click="Business()">
<a >Business details</a>
</li>
<li class="" v-on:click="Equipments()">
<a >Equipments details</a>
</li>
</ul>
</nav>
</div>
</div>
<div class="col-sm-9 col-xs-12 settings-body">
{{ load_layout_here }}
</div>
Now when user click on "Business Details" option it should run function Business() and load layout from business.html or business.php
the sample code in business.php
<div class="form">
<div class="input-field">
<h5>Business name</h5>
<input type="text" class="textbox" name="primary-phone" value="Perfect choice movers" placeholder="Your business name" maxlength="15">
</div>
<div class="input-field inline-input">
<h5>City</h5>
<input type="text" class="textbox " name="business-city" value="myCity" placeholder="Business address" maxlength="15">
</div>
<button class="btn btn-orange" type="submit">Save</button>
My vue.js code is
var app2 = new Vue({
el: '#mytemplate',
data : {
message : 'hi',
},
methods: {
Profile : function () {
this.message = 'Profile';
},
Business : function () {
// Here I want to call Html Template to load seprate layout
this.message = 'Business';
},
Equipments : function () {
this.message = 'Equipments';
}
}
})
I have seen lots of answers on the internet but they all using vue template engine or .vue files. Which I do not want to use
Note : I am using CodeIgniter as PHP framework. and Vue for frontend.
You can use axios to render the html. What ever data come in response data variable. That should to show.
Profile : function () {
axios.get('profile.php')
.then(function (response) {
console.log(response.data);
// response
this.message = response.data.json;
})
.catch(function (error) {
// handle error
console.log(error);
});
}
and to use axios, you have to include cdn file.
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Related
I have a problem. It's my first Vue.js project and I need help to solve the following problem. First I get a response from my API, then I get a list of projects and I want to find the project with the same ID as the url parameter. When I try to open the view my console logs the following error:
TypeError: Cannot read property 'title' of undefined
However, it then renders the right project into the template.
Code:
<template>
<div id="wrapper">
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"
integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA=="
crossorigin="anonymous"
/>
<Sidebar></Sidebar>
<div id="content">
<Navbar></Navbar>
<div id="headline">
<ul>
<li>
<h1>Projekt Details</h1>
<Popup></Popup>
</li>
</ul>
</div>
<div id="grid" class="module-grid module-grid-2">
<div class="card">
<div class="card-head">
<div>
<h3>Meta Daten</h3>
</div>
<div></div>
</div>
<div class="card-body">
<ul v-if="filtered_projects != null">
<li>
<div class="list-info">
<p>Projektnummer: {{ filtered_projects.id }}</p>
</div>
</li>
<li>
<div class="list-info">
<p>Autor: {{ filtered_projects.author }}</p>
</div>
</li>
<li>
<div class="list-info">
<p>Firma: {{ filtered_projects.company }}</p>
</div>
</li>
<li>
<div class="list-info">
<p>
Erstellt am:
{{
new Date(filtered_projects.created_at)
.toLocaleString()
.split(",")[0]
}}
</p>
</div>
</li>
<li>
<div class="list-info">
<p>
Letzte Änderung am:
{{
new Date(filtered_projects.updated_at)
.toLocaleString()
.split(",")[0]
}}
</p>
</div>
</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-head">
<div>
<h3>Projekt Übersicht</h3>
</div>
<div></div>
</div>
<div class="card-body">
<form class="edit-form" #submit.prevent="submitProject()">
<label for="title">Überschrift*</label>
<input
v-model="filtered_projects.title"
name="title"
id="title"
class="input"
type="text"
required
maxlength="16"
/>
<label for="text">Text*</label>
<textarea
v-model="filtered_projects.text"
name="text"
id="text"
class="input"
type="text"
required
rows="6"
/>
<label for="finish">Abgeschlossen</label>
<input
v-model="filtered_projects.finish"
name="finish"
id="finish"
class="input w-auto"
type="checkbox"
/>
<button v-if="state.user_info.id === filtered_projects.author || state.user_info.admin === true" type="submit" class="second-btn btn">
Aktualisieren
</button>
</form>
<button v-on:click="deleteProject()" v-if="state.user_info.id === filtered_projects.author || state.user_info.admin === true" class="btn delete-btn">Löschen</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { computed, reactive } from "vue";
import { useStore } from "vuex";
import { useRoute, useRouter } from "vue-router";
import Sidebar from "../components/Sidebar.vue";
import Popup from "../components/Popup.vue";
import Navbar from "../components/Navbar.vue";
export default {
name: "ProjectDetails",
components: {
Sidebar,
Popup,
Navbar,
},
setup() {
const store = useStore();
const route = useRoute();
const router = useRouter();
store.dispatch("company_projects/getProjectList");
store.dispatch("user_info/getUserInfo");
store.dispatch("companies/getCompaniesList");
const state = reactive({
query: route.params.id,
company_projects: computed(
() => store.getters["company_projects/getProjectlist"]
),
user_info: computed(
() => store.getters["user_info/getUserInfo"]
),
companies: computed(
() => store.getters["companies/getCompanieslist"]
),
user_auth_data: computed(
() => store.getters["auth/getAuthData"]
),
});
const filtered_projects = computed(() => state.company_projects.find(obj => {
return obj.id == parseInt(state.query)
}))
async function submitProject() {
await store
.dispatch("company_projects/submitProject", {
id: state.company_project.id,
company: state.company_project.company,
author: state.company_project.author,
title: state.company_project.title,
text: state.company_project.text,
finish: state.company_project.finish,
})
.catch((err) => {
console.log(err);
});
}
async function deleteProject() {
await store
.dispatch("company_projects/deleteProject", {
id: state.company_project.id,
})
.catch((err) => {
console.log(err);
});
router.push("/project");
}
return {
state,
submitProject,
deleteProject,
filtered_projects,
route,
};
},
};
</script>
Do you know a way to solve it better than me?
Thank you very much.
Since you are dispatching the company_projects/getProjectList action (which I suppose is responsible for fetching data from the server) directly in the setup, it is very likely that at the moment your component will render for the 1st time, the company_projects/getProjectList getter (and consequently the state.company_projects computed) will return an empty array and thus filtered_projects is undefined (find)
Which means the part of your template which needs filtered_projects to have a value should be protected with v-if
<form class="edit-form" #submit.prevent="submitProject()" v-if="filtered_projects">
so im trying to use an api from pixabay website however i do not have any results , the api doesnt send any results i checked it using console.log
i would like to have a little help from you guys
thank you
here is the code using vuejs
so im trying to use an api from pixabay website however i do not have any results , the api doesnt send any results i checked it using console.log
i would like to have a little help from you guys
thank you
here is the code using vuejs
<template>
<section>
<div class="row">
<form class="form-inline d-flex justify-content-center md-form form-sm mt-0">
<i class="fas fa-search" aria-hidden="true"></i>
<input class="form-control form-control-sm ml-3 w-75" type="text" placeholder="Search"
aria-label="Search" v-model="searchText" v-on:keyup.enter.stop.prevent="search">
</form>
</div>
<!-- Grid row -->
<!-- Grid row -->
<div class="gallery" id="gallery">
<!-- Grid column -->
<div class="mb-3 pics" v-for="image in images" :key="image.id" >
<img class="img-fluid" :src="image.largeImageURL" alt="">
</div>
</div>
</section>
</template>
<script>
// # is an alias to /src
import HelloWorld from "#/components/HelloWorld.vue";
import axios from 'axios'
export default {
name: "Home",
components: {
HelloWorld,
},
data () {
return {
searchText: '',
amount: 15,
apiUrl: 'https://pixabay.com/api/',
apiKey: '19405941-132a0646104b54c8459f0746c',
images: []
}
},
mounted () {
},
methods:{
search:function(event){
axios
.get( `${this.apiUrl}?key=${this.apiKey}&q=${this.searchText}`)
.then(response => (this.images = response.data.hits))
console.log(this.images)
}
}
};
</script>
>
Pressing the enter key is submitting your form. The prevent modifier is on the input but should be on the <form>:
<form #submit.prevent>
And it can be removed from your keypress event listener:
v-on:keyup.enter="search"
First time with vue. I am learning it playing around with some examples from Laracasts. I cannot get external template to render and the console shows cannot find element: #toolbar-chat.
My template is:
<template>
<div id="toolbar-chat">
<div class="toolbar-chat">
<ul v-for="chat in messages">
<li><b>#{{ chat.nickname }} says:</b> #{{ chat.message }}</li>
</ul>
</div>
<div class="input-group input-group-sm">
<input class="form-control" value="" placeholder="Type message..." required="required" maxlength="140" v-model="newMsg">
<div class="input-group-btn">
<button class="btn btn-primary" type="button" #click="press">
<i class="fa fa-paper-plane"></i>
</button>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
},
data() {
return {
nickname: [],
message: ''
}
},
ready() {
Echo.channel(chat_channel)
.listen('ChatMessageWasReceived', (data) => {
// Push data to messages list.
this.messages.push({
message: data.chat.message,
nickname: data.player.nickname
});
});
},
methods: {
press() {
// Send message to backend.
this.$http.post(chat_send_route, {message: this.newMsg})
.then((response) => {
// Clear input field.
this.newMsg = '';
});
}
}
};
</script>
My HTML contains the following tag:
<div class="col-xs-12 col-md-4" id="toolbarChat">
<my-chat></my-chat>
</div>
My vue component call is inside a document ready function like this:
require('./../app/bootstrap');
$(document).ready(function()
{
....
// Set up chat
Vue.component('my-chat', require('./../generic/chat.vue'));
const app = new Vue({
el: '#toolbar-chat'
});
});
And I include vue in my bootstrap file like this, then compile with webpack and no errors.
window.Vue = require('vue');
Why is my HTML template not rendering?
In your HTML you have the following div:
<div class="col-xs-12 col-md-4" id="toolbarChat">
<my-chat></my-chat>
</div>
Change it to
<div class="col-xs-12 col-md-4" id="toolbar-chat">
<my-chat></my-chat>
</div>
Because that is the id that new Vue({el: "#toolbar-chat",...}) is looking for.
I am building an angular application with multiple controllers.
Here is my index page:
<body ng-controller="BaseCtrl">
<div class="wrapper">
<header ng-show="HdrSection.ShowMenu">
<a ng-href="" class="show-list"><i class="fa fa-th-list">Option 1</i></a>
<a ng-href="" class="show-list"><i class="fa fa-th-list">Option 2</i></a>
<a ng-href="" class="show-list"><i class="fa fa-th-list">Option 3</i></a>
<a ng-href="" class="show-list"><i class="fa fa-th-list">Option 4</i></a>
</header>
<div class="container" ui-view>
</div>
</div> <!--wrapper div end-->
</body>
The pages of the application get rendered inside the div container. The first one gets loaded is the login page. I want to hide the header when login page is loaded and only show it whenever the page that is not a login page gets loaded. What's the best way to do that?
Should I hide it in the Login page controller?
Here is my login page:
<div id="login" class="main">
<div class="row">
<div class="col-md-2">
<img src="Images/Logo.gif" />
</div>
</div>
<div class="row">
<div class="col-md-10">
<form id="frmLogin">
<span class="prompt_text">Please enter your ID:</span>
<div class="input-group" style="width: 50%;">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input type="text" class="form-control" id="Username" ng-model="lc.user">
</div>
<br />
<input type="button" class="btn_main" value="Login" ng-click="Login()">
<br />
<span id="lblMsg" class="error_msg">{{lc.UserValidate}}</span>
</form>
</div><!--/.span12-->
</div><!--/.row-fluid-->
and here is a base controller for my index page:
(function () {
var app=angular.module("myApp", ["ui.router"]);
app.controller("BaseCtrl", ["$scope", BaseControllerFunc]);
function BaseControllerFunc($scope) {
//$('header').hide();
console.log($scope.HdrSection.ShowMenu);
$scope.HdrSection = { ShowMenu: false };
$scope.HdrSection.ShowMenu = false;
console.log($scope.HdrSection.ShowMenu);
}
})();
So far I tried 2 things:
using $('header').hide(); which works the first time page is opened but then I have no way to show the header again from any other child controller loaded by the page
and setting ng-show attribute of the header section to false in my base controller did not work as $scope.HdrSection.ShowMenu comes up as undefined
Can anyone help?
I load a number of different pages into the container div and each has its own controller. The only one I do not want header shown for is the login page
Try passing explicit the $scope form the controller injection as follow:
app.controller("BaseCtrl", ["$scope", BaseControllerFunc($scope)]);
function BaseControllerFunc($scope) {
...
}
})
Got it to work by changing my controller code to:
(function () {
var app=angular.module("myApp", ["ui.router"]);
app.controller("BaseCtrl", ["$scope", BaseControllerFunc]);
function BaseControllerFunc($scope) {
$scope = { ShowMenu: false };
}
})();
Now whenever the page loaded, the header is hidden and can be enabled by setting
$scope.parent = { ShowMenu: true };
from all other controllers
I am new to AngularJS and I am trying to incorporate Angular into my already built Rails app. In my rails app have a the ability to post to a feed. I have Angular working so it retrieves the feed and also posts the latest record to the feed.
My issue is that it only post the contents of the form. I am looking to retrieve the user id as well so I can render out the user's name, profile pic, etc. This information shows up when I refresh the page but does not show right after the post happens, only the contents of the post shows.
microposts.js.coffee
app = angular.module('micropostApp', ['ui.router', 'ngResource'])
app.factory 'Micropost', ["$resource", ($resource) ->
return $resource('/')
]
app.factory 'createMicropost', ["$resource", ($resource) ->
return $resource('/microposts')
]
app.factory 'Comments', ["$resource", ($resource) ->
return $resource('/microposts/:id/comments', id: '#id')
]
app.controller 'MicropostsController', [
'$scope'
'Micropost'
'createMicropost'
'Comments'
($scope, Micropost, createMicropost, Comments) ->
Micropost.query (data) ->
$scope.microposts = data
$scope.addPost = ->
if !$scope.newPost or $scope.newPost == ''
return
post = createMicropost.save($scope.newPost)
console.log("POST: " + angular.toJson(post))
$scope.microposts.unshift(post)
$scope.newPost = {}
]
microposts controller
respond_to :json
def create
#micropost = current_user.microposts.create!(micropost_params)
respond_with #micropost
end
view
<div ng-app="micropostApp" ng-controller="MicropostsController">
<div class="row">
<div class="col-md-12">
<form ng-submit="addPost()" style="margin-top:30px;">
<div class="form-group">
<input type="textarea"
class="form-control"
placeholder="Post an update..."
ng-model="newPost.content"></input>
</div>
<button type="submit" class="btn btn-primary pull-right">Post</button>
</form>
</div>
</div>
<div ng-repeat="post in microposts">
<div class="row">
<div class="panel panel-default">
<div class="panel-body">
<li id="{{post.id}}">
<div class="row">
<div class="col-md-12">
<aside>
{{post.user.name}}
</aside>
<aside>
<li id="feed-fat-menu" class="dropdown pull-right feed-dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<b class="glyphicon glyphicon-chevron-down"></b>
</a>
<ul class="dropdown-menu">
<li>Delete</li>
</ul>
</li>
<span class="user"> {{post.user.name}} </span>
<span class="content">{{post.content}}</span>
<hr>
<span class="timestamp pull-right"> Posted {{post.created_at}} ago. </span>
<span class="pull-left" style="padding-right: 5px;"><a>Comment </a>({{post.comments.length}})</span>
<span class="pull-left" style="padding-right: 5px;">
<a>Likes</a> ({{post.likes.length}})
</span>
<br />
</aside>
</div>
</div>
</li>
</div>
</div>
</div>
</div>
I'm not familiar with coffescript. If it's loading in the data on page reload, I would just add a call to whatever function is triggering that in the $scope.addPost call stack.
$scope.addPost = function(){
if(!$scope.newPost || $scope.newPost == ''){
return
}
post = createMicropost.save($scope.newPost);
console.log("POST: " + angular.toJson(post));
$scope.microposts.unshift(post);
$scope.newPost = {};
Micropost.get();
}
app.factory("Micropost", ["$resource", function($resource) {
return $resource("/", {}, {
get: {
method: "GET",
cache: true
}
});
}]);