Vue component data between pages - javascript

I have a Vue component, that I call in 2 pages, in which I am storing a variable I need to evaluate on the second page.
I am successfully setting the variable's value on the first page, but, on the next page, the value I set is lost.
I thought once you store variable in component data, it stays the same between pages, I don't know why the variable doesn't show up in Vue devtools, even though it is declared and initialized.
Any help is appreciated, and I can provide the resources you need if you need more.
Component code:
cartTotal = new Vue({
el: '#totalPrices',
data: {
delivery_today : true,
totalPrice : 0,
minimalOrder : 0,
totalPriceFormat : "",
deliveryPriceFormated : "",
delivery : true,
},
methods: {
getItemsDelivery() {
axios.get('/cart-getContent')
.then(function (response) {
if (response.data.status) {
let foo = JSON.stringify(response.data.data);
let a = foo.replace(/"/g,'');
if (a.includes('delivers_today:0')) {
this.data.delivery_today = false;
console.log('tomorrow delivery');
}
else console.log('today delivery');
}
else notify(response.data.errMsg);
})
}
}
})
First page HTML markup:
<div id="totalPrices" v-cloak>
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<!--<h6 class="card-title text-uppercase text-muted mb-0">Sales Volume ( 30 days )</h6>
<span class="h5 font-weight-bold mb-0">SD</span>-->
<span v-if="totalPrice==0">{{ __('Cart is empty') }}!</span>
<span v-if="totalPrice"><strong>{{ __('Subtotal') }}:</strong></span>
<span v-if="totalPrice" class="amount"><strong>#{{ totalPriceFormat }}</strong></span>
<input hidden id="delivery_final_state" :value="delivery_today">
</div>
</div>
</div>
</div>
<br/>
<div v-if="totalPrice" v-cloak>
{{ __('Checkout') }}
</div>
</div>
Next page HTML markup:
<div id="totalPrices" v-cloak>
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<!--<h6 class="card-title text-uppercase text-muted mb-0">Sales Volume ( 30 days )</h6>
<span class="h5 font-weight-bold mb-0">SD</span>-->
<span v-if="totalPrice==0">{{ __('Cart is empty') }}!</span>
<span v-if="totalPrice"><strong>{{ __('Subtotal') }}:</strong></span>
<span v-if="totalPrice" class="amount"><strong>#{{ totalPriceFormat }}</strong></span>
<span v-if="totalPrice&&delivery"><br /><strong>{{ __('Delivery') }}:</strong></span>
<span v-if="totalPrice&&delivery" class="amount"><strong>#{{ deliveryPriceFormated }}</strong></span><br /><br />
<span v-if="totalPrice"><strong>{{ __('TOTAL') }}:</strong></span>
<span v-if="totalPrice" class="amount"><strong>#{{ withDeliveryFormat }}</strong></span>
<input v-if="totalPrice" type="hidden" id="tootalPricewithDeliveryRaw" :value="withDelivery" />
<span v-if="delivery_today">Delivery For today</span>
</div>
</div>
</div>
</div>
</div>

Related

Create a dynamic div with JavaScript

I have created a page of feeds in which a new post should be created and shown in the user's feed. Lets say the div will look like this
In the textarea the data is entered and then on click of the post button the lower div is created
I have done this in javascript but the name, image, all data is simply entered by me but it should come from the controller I cant use the simple approach like I have done in HTML page how can it be done in javascript?
<body>
<textarea class="form-control border-0 p-0 fs-xl" rows="4" id="input" placeholder="What's on your mind Codex?..."></textarea>
<button class="btn btn-info shadow-0 ml-auto " id="submit" onclick="addCode()">Post</button>
<div id="add_after_me">
<div class="test " >
</div>
</div>
<script>
$('#submit').click(function () {
var text = $('#input').val();
$('#newDivs').append('<div class="test">' + text + '</div>');
});
function addCode() {
document.getElementById("add_after_me").insertAdjacentHTML("afterend",
'<div class="card mb-g"> < div class= "card-body pb-0 px-4" ><div class="d-flex flex-row pb-3 pt-2 border-top-0 border-left-0 border-right-0"><div class="d-inline-block align-middle status status-success mr-3"> <span class="profile-image rounded-circle d-block" style="background-image:url(); background-size: cover;"></span> </div> <h5 class="mb-0 flex-1 text-dark fw-500"> Dr. John Cook PhD <small class="m-0 l-h-n">Human Resources & Psychiatry Division</small></h5><span class="text-muted fs-xs opacity-70"> 3 hours </span> </div> <div class="pb-3 pt-2 border-top-0 border-left-0 border-right-0 text-muted " id="newDivs"> </div> </div ></div > ');
}
</script>
</body>
here is my code
I'm assuming that you have a Controller that can receive POST data, will handle it, then will respond an JSON with all the processed data that you want your Javascript to display.
We will use simple Ajax with jQuery here. We will start by sending the form via post to your controller when you submit the form, then we will assume that your controller respond a json with the same data once it's done. Then javascript will read the Json responded, and update the DOM.
Here is your code :
<body>
<textarea class="form-control border-0 p-0 fs-xl" rows="4" id="input" placeholder="What's on your mind Codex?..."></textarea>
<button class="btn btn-info shadow-0 ml-auto " id="submit" onclick="addCode()">Post</button>
<div id="add_after_me"></div>
<script>
$('#submit').click(function () {
$.post('/your-controller', {
text: $('#input').val()
}, function(data) {
const json = jQuery.parseJSON(data)
addCode(json)
})
});
function addCode(data) {
const addAfterMe = $("#add_after_me")
const template = `
<div class="card mb-g">
<div class= "card-body pb-0 px-4">
<div class="d-flex flex-row pb-3 pt-2 border-top-0 border-left-0 border-right-0">
<div class="d-inline-block align-middle status status-success mr-3">
<span class="profile-image rounded-circle d-block" style="background-image:url('${data.image}'); background-size: cover;"></span>
</div>
<h5 class="mb-0 flex-1 text-dark fw-500">
${data.fullname}
<small class="m-0 l-h-n">${data.department}</small>
</h5>
<span class="text-muted fs-xs opacity-70">
${data.time}
</span>
</div>
<div class="pb-3 pt-2 border-top-0 border-left-0 border-right-0 text-muted" id="newDivs">${data.text}</div>
</div>
</div>`
addAfterMe.append(template)
}
</script>
</body>
To create your "card", I use "Template Literals" javascript standard. But feel free to use whatever strategy you want.
So, each time that you will submit your form, the text will be sent to the Controller. Assuming that your controller will response this JSON :
{
'text': "Lorem Ipsum",
'image': "https://url-to-your-profile-image.com/image.png",
'fullname': 'Dr. John Cook PhD',
'department': 'Human Resources & Psychiatry Division',
'time': '3 hours'
}
And voila :)
I hope it helps !

Like Count button + Card layout not working properly

enter image description here
I am supposed to have three cards on large screens, 2 in tablets, 1 in mobile and all without hard coded html. Only through javascript. However, when I try to add three cards in the same row, it takes the same movie for the entire row and then the next one for the second row and so on..
Also the button only works for the first card...
There must be smth wrong in my loop..
This is my code so far:
var parsedMovies = JSON.parse(movies);
for (let i = 0; i < parsedMovies.length; i++) {
document.getElementById("cards").innerHTML += `
<div class="card-group">
<div class="card mb-3 bg-dark text-light" style="max-width: 540px;">
<div class="row g-0 ">
<div class="col-md-4 ">
<img src="${parsedMovies[i].image}" class="img-fluid rounded-start" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">${parsedMovies[i].title}</h5>
<p class="card-text">${parsedMovies[i].plot}</p>
<p class="card-text"><small class="text-muted"> Year: ${parsedMovies[i].year} <br> Director: ${parsedMovies[i].director} <br> Actors: ${parsedMovies[i].actors}</small>
<div class="voting">
<button id="likebtn">
<i>👍</i>
</button>
<input type="number" id="input1" value="${parsedMovies[i].likes}">
<button id="dislikebtn">
<i>👎</i>
</button>
<input type="number" id="input2" value="${parsedMovies[i].dislikes}">
</div>
</p>
</div>
</div>
</div>
</div>
<div class="card mb-3 bg-dark text-light" style="max-width: 540px;">
<div class="row g-0 ">
<div class="col-md-4 ">
<img src="${parsedMovies[i].image}" class="img-fluid rounded-start" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">${parsedMovies[i].title}</h5>
<p class="card-text">${parsedMovies[i].plot}</p>
<p class="card-text"><small class="text-muted"> Year: ${parsedMovies[i].year} <br> Director: ${parsedMovies[i].director} <br> Actors: ${parsedMovies[i].actors}</small>
<div class="voting">
<button id="likebtn">
<i>👍</i>
</button>
<input type="number" id="input1" value="${parsedMovies[i].likes}">
<button id="dislikebtn">
<i>👎</i>
</button>
<input type="number" id="input2" value="${parsedMovies[i].dislikes}">
</div>
</p>
</div>
</div>
</div>
</div>
<div class="card mb-3 bg-dark text-light" style="max-width: 540px;">
<div class="row g-0 ">
<div class="col-md-4 ">
<img src="${parsedMovies[i].image}" class="img-fluid rounded-start" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">${parsedMovies[i].title}</h5>
<p class="card-text">${parsedMovies[i].plot}</p>
<p class="card-text"><small class="text-muted"> Year: ${parsedMovies[i].year} <br> Director: ${parsedMovies[i].director} <br> Actors: ${parsedMovies[i].actors}</small>
<div class="voting">
<button id="likebtn">
<i>👍</i>
</button>
<input type="number" id="input1" value="${parsedMovies[i].likes}">
<button id="dislikebtn">
<i>👎</i>
</button>
<input type="number" id="input2" value="${parsedMovies[i].dislikes}">
</div>
</p>
</div>
</div>
</div>
</div>
</div>
`;
let likebtn = document.querySelector("#likebtn");
let dislikebtn = document.querySelector("#dislikebtn");
let input1 = document.querySelector("#input1");
let input2 = document.querySelector("#input2");
likebtn.addEventListener("click", () => {
input1.value = parseInt(input1.value) + 1;
});
dislikebtn.addEventListener("click", () => {
input2.value = parseInt(input2.value) + 1;
});
Your loop is creating multiple time the same ids... An id must be unique.
So, remove all id in the HTML "template" and use a class (I used like-action below) on both the like and dislike buttons.
Then, set ONE event handler for those button, since the action is the same (increment by one). See below:
let likebtns = document.querySelectorAll(".like-action");
likebtns.forEach((button)=>{
button.addEventListener("click", (element) => {
input = element.nextElementSibling
input.value = parseInt(input.value) + 1;
});
});
Have a look at nextElementSibling.

How to display the results based on their parent selection in angular 8

I am trying to display only the corresponding items on selection of its parent (similar to if country is selected then its corresponding states should display) for that i have this below code but the problem is i am not able to apply the filtering. Can anybody help me resolve in this?
See the code below: (The below code is for first tile on selection of this i am showing below its corresponding account related data)
<div class="col mb-3" *ngFor="let account of cloudAccounts1">
<a href="javascript:;" class="item-card text-dark mat-elevation-z8">
<div class="text-center" (click)="getInstances($event, account)"
[ngClass]="{'bg-info text-white': entry.account == account}">
<div class="card-header py-3">
<div *ngIf="account.accountType === 'AZURE'">
<img class="img-responsive h-25 w-25" src="assets/images/azure.png" />
</div>
<div *ngIf="account.accountType === 'AWS'">
<img class="img-responsive h-25 w-25" src="assets/images/aws.png" />
</div>
<div *ngIf="account.accountType === 'GCP'">
<img class="img-responsive h-25 w-25" src="assets/images/gcp.png" />
</div>
<div class="mt-2"> {{account.accountType}}</div>
</div>
<div class="card-footer no-border py-3">
<div class="text-truncate">{{account.name}}</div>
</div>
</div>
</a>
</div>
The below code is for which when i select any of the above account say AWS or AZURE or GCP then only its corresponding tile should display. The below code.
<div class="col-md-2" *ngIf="showRegion">
<br />
<div class="h6">Instance Type</div>
<div class="row">
<div class="col mb-3" *ngFor="let account of cloudAccounts2">
<a href="javascript:;" class="item-card text-dark mat-elevation-z8">
<div class="text-center">
<div class="card-header py-3">
<div *ngIf="account.accountType === 'AWS'">
<img class="img-responsive h-25 w-25" title="{{account.name}}"
src="assets/images/aws.png">
<div>{{account.accountType}}</div>
</div>
<div *ngIf="account.accountType === 'AZURE'">
<img class="img-responsive h-25 w-25" title="{{account.name}}"
src="assets/images/azure.png">
<div>{{account.accountType}}</div>
</div>
<div *ngIf="account.accountType === 'GCP'">
<img class="img-responsive h-25 w-25" title="{{account.name}}"
src="assets/images/gcp.png">
<div>{{account.accountType}}</div>
</div>
</div>
<div class="card-footer py-3 no-border text-truncate">{{account.name}} <i class="fa fa-external-link" aria-hidden="true"></i></div>
</div>
</a>
</div>
</div>
In cloudAccounts2 array, i have this data, i need to show only one tile on selection of its parent account. But instead its showing all 3 tiles which i dont want.
cloudAccounts1 = [{ "id": "8a8080fc710cdc140171104216c2002b", "accountType": "AWS" },
{ "id": "8a8080fc710cdc140171104216c2002b", "accountType": "AZURE" },
{ "id": "8a8080fc710cdc140171104216c2002b", "accountType": "GCP" }]
Based on the above selection i need to display only its corresponding below data.
cloudAccounts2 = [{"accountType":"AWS", "name":"T2.micro", "link":"https://aws.amazon.com/ec2/pricing/on-demand/"},
{"accountType":"AZURE", "name":"STANDARD_A1", "link":"https://azure.microsoft.com/en-us/pricing/details/virtual-machines/linux/"},
{"accountType":"GCP", "name":"n1-standard-1", "link":"https://cloud.google.com/compute/vm-instance-pricing"}
];
This is the method where i am handling the logic to display only the selected values to display in the template. Can anybody let me know what is my mistake?
getInstances(event, instanceSelected) {
this.classToggled = false;
this.entry.account = instanceSelected;
if(this.entry.account.accountType === instanceSelected.accountType){
this.showInstance = true;
// this.cloudAccounts2 = [];
// this.cloudAccounts2 = [instanceSelected];
if(instanceSelected.accountType === this.cloudAccounts2[1].accountType){
this.cloudAccounts2[1].accountType = instanceSelected.accountType;
}
}
}
It looks like you are trying to do an NgIf within a loop to select your item. Instead of doing that you can create new objects for your selected account (see component) and instead of getInstances() on click do selectAccount1()
Html:
<div *ngFor="let account of cloudAccounts1">
<a (click)="selectAccount1(account)">
...
</a>
</div>
<div *ngFor="let account of cloudAccounts2">
<a (click)="selectAccount2(account)">
...
</a>
</div>
<div *ngIf="selectedAccount1">
<ul>
<li>id: {{ selectedAccount1.id }}</li>
<li>accountType: {{ selectedAccount1.accountType }}</li>
</ul>
</div>
<div *ngIf="selectedAccount2">
<ul>
<li>accountType : {{ selectedAccount2.accountType }} </li>:
<li>name: {{ selectedAccount2.name }}</li>
<li>link: {{ selectedAccount2.link }}</li>
</ul>
</div>
Component:
public selectedAccount1: any;
public selectedAccount2: any;
public selectAccount1(account: any): void {
this.selectedAccount1 = account;
}
public selectAccount2(account: any): void {
this.selectedAccount2 = account;
}

Neet help in creating the parent/child structure in Jquery

I have the following HTML :
I'm trying to send the <p>{{ $comment->comment }}</p> to a Jquery function, upon clicking on the Edit button. I need help in completing the below structure :
Comment = event.target.parentNode.childNodes[1];
<div class=" p-3 border-top border-bottom bg-light">
<div class="d-flex align-items-center osahan-post-header">
<div class="dropdown-list-image mr-3 mb-auto"><img class="rounded-circle" src="img/p8.png" alt=""></div>
<div class="mr-1">
<div class="text-truncate h6 mb-3">{{ $comment->user->first_name }} {{ $comment->user->last_name }}</div>
<p>{{ $comment->comment }}</p>
</div>
<span class="ml-auto mb-auto">
<div class="text-right text-muted pt-1 small">{{ $comment->created_at}}</div>
</span>
</div>
<div class="post" align="right" data-postid="{{ $comment->id }}">
Edit
</div>
</div>
</div>
If you would fix your invalid HTML (as already mentioned in a comment, a <div> can't be inside a <span>), you could get the comment as follows:
document.getElementById("eid").onclick = function(e) {
let comment = e.target.closest(".p-3").getElementsByTagName("p")[0].innerHTML;
console.log(comment);
};
or, if you would use jQuery:
$("#eid").on("click", function(){
let comment = $(this).closest(".p-3").find("p").text();
console.log(comment);
});

How to make a v-for loop of DIVs and show them by part (Vue.js)

I have the following code:
<div class="container-fluid" id="networdapp" style="display:none;">
<div class="row" >
<div v-for="(result,i) in results" :key="i" class="col-sm-6" >
<div class="card m-3 h-240 bg-light" >
<div class="card-header text-center" > {{ result.title }} </div>
<div class="card-body" style="height:200px" >
<p class="card-text" v-html="result.prevDesc" ></p>
</div>
<div class="card-footer bg-transparent border-info">
<a href="/details" class="btn btn-info" #click="getData(i)" >Details</a>
</div>
</div>
</div>
</div>
</div>
And I want to parse these col-sm-6 divs generated by a v-for loop (Vue.js).The goal is to make them visible 5 by 5.First they have to be all invisible -> event handler -> 5 visible -> event handler -> 10 visible and so on...
And I think I need to parse them.The {{result.title}} and result.prevDesc are perfectly working,no worries about that.
You could keep your results array and create another one called shownResults that doesn't contain initially any result, but when you click showMore button you will have 5 results pushed to that array and shown, if you click again you'll have 10 results shown and so on,
new Vue({
el: '#app',
data() {
return {
bound:0,
results:[
{
title:"title1",
prevDesc:"desc1"
},
{
title:"title2",
prevDesc:"desc2"
},
{
title:"title3",
prevDesc:"desc3"
},
{
title:"title4",
prevDesc:"desc4"
},
{
title:"title5",
prevDesc:"desc5"
},
{
title:"title7",
prevDesc:"desc7"
},
{
title:"title8",
prevDesc:"desc8"
}
],
shownResults:[]
}
},
methods:{
showMore(){
this.bound+=5;
this.shownResults=this.results.slice(0,this.bound);
},
getData(i){
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" >
<div id="app">
<div class="container-fluid" id="networdapp" >
<div class="row" >
<div v-for="(result,i) in shownResults" :key="i" class="col-sm-6" >
<div class="card m-3 h-240 bg-light" >
<div class="card-header text-center" > {{ result.title }} </div>
<div class="card-body" style="height:200px" >
<p class="card-text" v-html="result.prevDesc" ></p>
</div>
<div class="card-footer bg-transparent border-info">
<a href="/details" class="btn btn-info" #click="getData(i)" >Details</a>
</div>
</div>
</div>
<a class="btn btn-info" style="height:40px" #click="showMore" >Show more</a>
</div>
</div>
</div>

Categories