Aurelia: templating. Include a template in another - layout

I would like to use two layouts for my Aurelia app.
Home - FAQ - Login page don't contain a sidebar;
But everything else do contain this sidebar.
My architecture, with a sidebar is pretty complicated in HTML and is like:
div.container
div.sidebar
div.sidebar_content
div.site_content
So i can't just enable or disable the sidebar because it contains the view.
I have to make two pages like "app.html", defined in main.js, but how tell to Aurelia "Choose app.html for this page, and app2.html for this other page"?
I have found the setRoot function but i have bugs with it (the routes does not work properly when i change setroot)
Thank you for your answers

The router supports the concept of "layouts." This is documented here: http://aurelia.io/hub.html#/doc/article/aurelia/router/latest/router-configuration/10
Basically, you specify a layout for each route (you can specify a default layout on the router-view custom element:
app.html
<router-view layout-view="./layout-with-sidebar.html"></router-view>
app.js
export class App {
configureRouter(config, router) {
config.title = 'Aurelia';
var model = {
id: 1
};
config.map([
{ route: ['home', ''], name: 'home', title: "Home", moduleId: 'home', nav: true },
{ route: 'no-sidebar', name: 'no-sidebar', title: "No Sidebar", moduleId: 'no-sidebar', nav: true, layoutView: 'layout-without-sidebar.html' }
]);
this.router = router;
}
}
layout-with-sidebar.html
<template>
<div class="container">
<div class="row">
<div class="col-sm-2">
<slot name="sidebar"></slot>
</div>
<div class="col-sm-10">
<slot name="main-content"></slot>
</div>
</div>
</div>
</template>
layout-without-sidebar.html
<template>
<div class="container">
<div class="row">
<div class="col-sm-12">
<slot name="main-content"></slot>
</div>
</div>
</div>
</template>
home.html
<template>
<div slot="sidebar">
<p>I'm content that will show up on the right.</p>
</div>
<div slot="main-content">
<p>I'm content that will show up on the left.</p>
</div>
</template>
no-sidebar.html
<template>
<div slot="main-content">
<p>Look ma! No sidebar!</p>
</div>
</template>

Related

Laravel + JS Vue

Just start a tutorial about Laravel 5.8 (from 0) and trying to add some JS to the project. Installed NodeJS: npm -v: 6.10.1; node -v: 12.6.0; Then install npm in the project and use npm run watch. After all change ExampleComponent.vue to MyButton.vue:
<template>
<div>
<button type="submit" class="my-button" v-text="test.name">My Button</button>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
axios.post('api/vue', {})
.then(response => {
this.test = response.data
});
},
data: function () {
return {
test: null,
}
},
props: [
'text'
]
}
</script>
<style>
.my-button{
background-color: #333333;
}
</style>
Register it in app.js:
require('./bootstrap');
window.Vue = require('vue');
Vue.component('my-button', require('./components/MyButton.vue').default);
let app;
app = new Vue({
el: '#app',
});
then in my view add:
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Dashboard</div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
<div id="app">
<my-button text="My new test button"></my-button>
</div>
</div>
</div>
</div>
</div>
</div>
#endsection
app.js component error
After all, I got the report from Laravel mix that build success:
DONE Compiled successfully in 16733ms 4:51:01 PM
But in the browser, I didn't see my button. I've tried cleaning the cache. But it doesn't help. Someone any suggestions?

EJS: Failed to load resource: the server responded with a status of 500 (Internal Server Error) using loop

I am trying to loop through my portfolio sections while inputting it with ejs. But it is throwing a 500 error. I created the loop to code less. The other pages work fine, but the title can't be found or the path is lost. It worked before I added the loop.
const express = require('express');
const router = express.Router();
/* GET portfolio page. */
router.get('/portfolio', (req, res, next) => {
let recentProjects = [{
title: 'ASL Logo',
paragraph: 'Re-branding of ASL Water Solutions'
},
{
title: 'Siva Creative Business Card',
paragraph: 'Re-branding of Siva Creative'
},
{
title: 'Encore Renovations',
paragraph: 'Website design for Encore'
}
]
res.render('portfolio', {
projects: recentProjects
});
});
module.exports = router;
<% include partials/header %>
<section class="content-section" id="portfolio">
<div class="container">
<div class="content-section-heading text-center">
<h3 class="text-secondary mb-0">
<%= title %>
</h3>
<h2 class="mb-5">Recent Projects</h2>
</div>
<div class="row no-gutters">
<% for(let i = 0; i < projects.length; i++) { %>
<div class="col-lg-6">
<a class="portfolio-item">
<span class="caption">
<span class="caption-content">
<h2><%= projects[i].title %></h2>
<p class="mb-0"><%= projects[i].paragraph %></p>
</span>
</span>
<img class="img-fluid" src="img/portfolio-1.jpg" alt="">
</a>
</div>
<% } %>
</div>
</div>
</section>
<% include partials/footer %>
In your view, the variable title is not defined, you should pass it to the view just as you do for the recentProjects object:
res.render('portfolio', {
projects: recentProjects,
title: 'portfolio'
});

Vue.js - Working with Components

I am new to Vue.js. Very new so this question might sound a lot like a first graders. Forgive me.
I have the App.vue and Character.vue setup. I wanted to create characters on the fly and add them to an array (in App.vue) and let the rendering of the look/feel of the characters be done using Character.vue. The characters are created and added to the array and can be retrieved properly. Only thing is...Character.vue doesn't render them properly because for some reason, the character it retrieves from the array is undefined.
Help me?
Attaching files
App.vue
<template>
<div>
<div class='gameHeader'>
<h1>{{ gameHeader }}</h1>
</div>
<div class='gameMessages'>
<div class='gameMessage' v-for="msg in gameMessages">
{{ msg }}
</div>
</div>
<div class='gameMain'>
<button #click="rollNewCharacter">Roll New</button>
<div class="playerParty">
<character v-for="p in playerParty"></character>
</div>
<div class="computerParty">
<character v-for="c in computerParty"></character>
</div>
</div>
<div class='gameFooter'>
{{ gameFooter }}
</div>
</div>
</template>
<script>
import Character from "./assets/components/Character.vue";
export default {
components: { 'character': Character },
data: function(){ return { gameHeader: 'Monster Attack', gameMessages:[], playerParty: [], computerParty: [], gameFooter: '' }; },
methods: {
rollNewCharacter() {
var c = Character;
c.name = 'Usman';
c.type = 'Warrior';
c.mana = 100;
c.health = 100;
c.totalHealth = 100;
c.totalMana = 100;
console.log(c.name);
this.playerParty.push(c);
console.log(this.playerParty[0].name);
//this.computerParty.push(chr2);
}
}
}
</script>
Character.vue
<template>
<div class="character">
<span class='name'>{{ name }}</span><span class='type'>({{ type }})</span>
<div class='health'><div class='total' :class="totalHealth"><div class='health' :class="health"></div></div></div>
<div class='mana'><div class='total' :class="totalMana"><div class='mana' :class="mana"></div></div></div>
<span class='damage'>{{ damage }}</span>
<div class="actions">
<button #click="attack">Attack</button>
<button #click="specialAttack">Special Attack</button>
<button #click="heal">Heal</button>
</div>
</div>
</template>
<script>
export default {
props: [ 'name', 'type', 'mana', 'health', 'damage' , 'totalHealth', 'totalMana' ],
methods: {
attack: function(){},
specialAttack: function(){},
heal: function(){ alert(this.name); console.log(this);}
}
}
</script>
<style>
</style>
You should pass a prop when using the character component:
<character :character="p" v-for="p in playerParty"></character>
I have updated the character to receive only one prop:
export default {
props: [ 'character' ],
methods: {
attack: function(){},
specialAttack: function(){},
heal: function(){ alert(this.name); console.log(this);}
}
}
And this is the character component template with the new prop:
<template>
<div class="character">
<span class='name'>{{ character.name }}</span><span class='type'>({{ character.type }})</span>
<div class='health'><div class='total' :class="character.totalHealth"><div class='health' :class="character.health"></div></div></div>
<div class='mana'><div class='total' :class="character.totalMana"><div class='mana' :class="character.mana"></div></div></div>
<span class='damage'>{{ character.damage }}</span>
<div class="actions">
<button #click="attack">Attack</button>
<button #click="specialAttack">Special Attack</button>
<button #click="heal">Heal</button>
</div>
</div>
</template>

How to replace Aurelia components?

I'm newbie with Aurelia and frontend frameworks generally.
I have page with List
list.html
<template>
<require from="services/list-item"></require>
<div class="container-fluid">
<div class="row row-centered container-top-space">
<div repeat.for="item of items">
<list-item item.bind="item"></list-item>
</div>
</div>
</div>
</template>
list.js
import { inject } from 'aurelia-framework';
import { HttpClient, json } from 'aurelia-fetch-client';
#inject(HttpClient)
export class ListItem{
constructor(httpClient) {
this.items= [];
httpClient.configure(...);
}
}
and ListItem
list-item.html
<template>
<div class="row">
<div class="list-item">
<div class="form-control-inline" style="width:33%">
<span>${item.name}  </span>
</div>
<div class="form-control-inline" style="width:54%">
<span>${item.value}</span>
</div>
<div class="pull-right" style="width:100px">
<button class="btn btn-list-item" type="submit" name="submit" click.delegate="edit($event.target.parentElement)">Edit</button>
</div>
</div>
</div>
</template>
list-item.js
import { bindable } from 'aurelia-framework';
export class ListItem{
#bindable item;
edit(element){
//I'd like to replace view component with update component here
}
}
I'd like to change template of list-item on list-item-edit when edit function will be called, but completely don't know how to make it.

How to dynamically change view in angularjs using ui-router

I have a named view called myView in which I have two div elements that I want to show conditionally using ng-show based on whether the value of $scope.states['currentState'] is 'A' or 'B'. The value of $scope.states['currentState'] is changed when an anchor tag is clicked which calls the doStuff function on the myController controller.
The issue I am having is when the anchor tag is clicked and the doStuff function is clicked, it shows on the console that the value of $scope.states['currentState'] has been modified, but its not updating the myView named view accordingly.
Following is the code for app.js, myView.html and index.html files. The index.html file is being used as a <div ui-view></div> in an index.ejs file that I am rendering using Express with Node.js.
app.js
var app = angular.module("app", ['ui.router']).
config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
views: {
'': { templateUrl: 'partials/index.html' },
'myView#home': {
templateUrl: 'partials/myView.html',
controller: 'myController'
},
'myOtherView#home': {
templateUrl: 'partials/myOtherView.html',
controller: 'myController'
}
}
});
}])
app.controller("myController", ['$scope', function($scope){
var states = ['A', 'B'];
$scope.states = states;
$scope.states['currentState'] = states['currentState'] || 'A';
$scope.doStuff = function(toState) {
//doing stuff
$scope.states['currentState'] = toState;
console.log($scope.states['currentState']);
};
} ]);
index.html
<div class="main">
<div class="container">
<div class="row margin-bottom-40">
<div class="col-md-12 col-sm-12">
<div class="content-page">
<div class="row">
<div ui-view="myView"></div>
<div ui-view="myOtherView"></div>
</div>
</div>
</div>
</div>
</div>
</div>
myView.html
<div ng-controller='myController'>
<div ng-show="states['currentState'] == 'A'">
//displaying this div if the currentState is A
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="states['currentState'] == 'B'">
//displaying this div if the currentState is B
</div>
</div>
Could somebody help me understand that why am not getting the div with states['currentState'] == 'B' shown, even when I see the value of console.log($scope.states['currentState']) changed from 'A' to 'B' when the doStuff function is called in myController?
Edit:
Here is the demo of the issue I am facing.
Okay So I was mistaken in my comment.
The real issue was that you used {{}} in your ng-show which is not needed as these expect to take angular expressions.Also I would make current state a property of your scope as at the moment you are trying to make it a property of an array inside your scope.
Hope that helps! Below is the modified code for your view:
<div ng-controller='MainCtrl'>
<div ng-show="currentState === 'A'">
<a ng-click="doStuff('B')">Do stuff and show B</a>
</div>
<div ng-show="currentState === 'B'">
<a ng-click="doStuff('A')">Do stuff and show A</a>
</div>
</div>
EDIT: Working plunker http://plnkr.co/edit/1llQMQEdxIwu65MNoorx?p=preview

Resources