Using Javascript to implement Live Django Search - javascript

I am adding a Search functionality to my E-commerce Project using Javascript, I have followed a tutorial that explains that when writing the title in the search bar only the items with the same letter appears. In my project, it was working fine for basic HTML but I am trying to make it a little more complex to include a complete card with some details such as price, not just the title.
Here is the model.py
class Item(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(blank=False, upload_to=upload_design_to)
price = models.DecimalField(decimal_places=2, max_digits=100)
discount_price = models.DecimalField(decimal_places=2, max_digits=100, blank=True, null=True)
timestamp = models.DateTimeField(default=timezone.now)
Here is the views.py
class ItemListView(ListView):
model = Item
paginate_by = 12
template_name = "store/product_list.html"
ordering = ['-timestamp']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["qs_json"] = json.dumps(list(Item.objects.values()),cls=DjangoJSONEncoder)
return context
Here is the scripts.py
<script>
const data = '{{qs_json}}'
const rdata = JSON.parse(data.replace(/"/g, '"'))
console.log(rdata)
const input = document.getElementById('search_here')
console.log(input)
let filteredArr = []
input.addEventListener('keyup', (e)=>{
box.innerHTML = ""
filteredArr = rdata.filter(store=> store['title'].includes(e.target.value))
console.log(filteredArr)
if (filteredArr.length > 0){
filteredArr.map(store=>{
box.innerHTML += `<b>${store['title']}</b><br>`
})
} else {
box.innerHTML = "<b>No results found...</b>"
}
})
</script>
Here is the template.html
<input id="search_here" class="mb-2 form-control" placeholder="Type to search...">
<!--Card-->
<div id="box" class='row card-group'>
{% for item in object_list %}
<div class="col-4 mb-3">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<embed src="{{ item.image.url }}" class="card-img-top" alt="..."/>
</a>
<div class="card-body">
<h5 class="card-title">{{ item.title }}</h5>
<p class="card-text">
{% if item.description %}
{{ item.description }}
{% endif %}
</p>
</div>
<div class="card-footer">
<small class="text-muted">{{ item.timestamp }}</small>
</div>
</div>
</div>
{% endfor %}
</div>
<!--Card-->
My Question: How do I replace the simple <b>${store['title']}</b><br> with the below in the scripts with the whole card div with all its information related to it?
If any more information or clarifications required let me know
<div class="col-4 mb-3">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<embed src="{{ item.image.url }}" class="card-img-top" alt="..."/>
</a>
<div class="card-body">
<h5 class="card-title">{{ item.title }}</h5>
<p class="card-text">
{% if item.description %}
{{ item.description }}
{% endif %}
</p>
</div>
<div class="card-footer">
<small class="text-muted">{{ item.timestamp }}</small>
</div>
</div>
</div>

from django.db.models import Q
name = request.POST['name']
price = request.POST['price']
Item.objects.filter(Q(title __icontains=name) | Q(price __icontains=price))
Try This

Your template.html page already have all htmls generated using for-loop so you don't need to generate them again .Instead , when user type you can loop through all div and check if card-title div has that input if it has simply show that div or else hide it.
Demo Code :
const input = document.getElementById('search_here')
input.addEventListener('keyup', (e) => {
var inputs = e.target.value.toLowerCase(); //do lowercase
//loop through outer div and hide it
document.querySelectorAll('.outers').forEach(function(el) {
el.style.display = 'none';
});
//loop through outer ->card-title
document.querySelectorAll('.outers .card-title').forEach(function(el) {
//compare
if (el.textContent.toLowerCase().indexOf(inputs) > -1) {
el.closest('.outers').style.display = "block"; //if match show that div
}
})
})
.outers {
border: 1px solid blue;
width: 150px;
height: 150px;
margin-bottom: 5px
}
<input id="search_here" class="mb-2 form-control" placeholder="Type to search...">
<div id="box" class='row card-group'>
<!--just added one extra class-->
<div class="col-4 mb-3 outers">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<img src="{{ item.image.url }}" class="card-img-top" alt="..." />
</a>
<div class="card-body">
<h5 class="card-title">Somethings</h5>
<p class="card-text">
some things ...
</p>
</div>
<div class="card-footer">
<small class="text-muted">12:30:00</small>
</div>
</div>
</div>
<div class="col-4 mb-3 outers">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<img src="{{ item.image.url }}" class="card-img-top" alt="..." />
</a>
<div class="card-body">
<h5 class="card-title">Abc</h5>
<p class="card-text">
some things ...
</p>
</div>
<div class="card-footer">
<small class="text-muted">12:30:00</small>
</div>
</div>
</div>
<div class="col-4 mb-3 outers">
<div class="card h-100">
<a href="{{item.get_absolute_url}}">
<img src="{{ item.image.url }}" class="card-img-top" alt="..." />
</a>
<div class="card-body">
<h5 class="card-title">def</h5>
<p class="card-text">
some things ...
</p>
</div>
<div class="card-footer">
<small class="text-muted">12:30:00</small>
</div>
</div>
</div>
</div>

I think that you can change the script by following code.
const data = '{{qs_json}}'
const rdata = JSON.parse(data.replace(/"/g, '"'))
console.log(rdata)
const input = document.getElementById('search_here')
console.log(input)
let filteredArr = []
input.addEventListener('keyup', (e) => {
box.innerHTML = ""
filteredArr = rdata.filter(store => store['title'].includes(e.target.value))
console.log(filteredArr)
if (filteredArr.length > 0) {
filteredArr.map(store => {
box.innerHTML += `
<div class="col-4 mb-3">
<div class="card h-100">
<a href="${store['get_absolute_url']}">
<embed src="${store['image']['url']}" class="card-img-top" alt="..."/>
</a>
<div class="card-body">
<h5 class="card-title">${store['title']}</h5>
<p class="card-text">
${store['description'] ?? ''}
</p>
</div>
<div class="card-footer">
<small class="text-muted">${store['timestamp']}</small>
</div>
</div>
</div>`;
})
} else {
box.innerHTML = "<b>No results found...</b>"
}
})

Related

How do i add items to my cart using javascript?

When I click on a product in the store section I want it to go in the cart. For some reason nothing is showing up in the cart but empty space. `//show cart
(function(){
const cartInfo = document.getElementById('cart-info');
const cart = document.getElementById('cart');
cartInfo.addEventListener('click', function(){
cart.classList.toggle('show-cart')
})
})();
//add items to cart
(function() {
const cartBtn = document.querySelectorAll('.store-item-icon');
cartBtn.forEach(function(btn) {
btn.addEventListener('click', function(event) {
if (event.target.parentElement.classList.contains('store-item-icon'))
{
let fullPath =
event.target.parentElement.previousElementSibling.src;
let pos = fullPath.indexOf('img') + 3;
let partPath = fullPath.slice(pos);
const item = {};
item.img = `
img - cart$ {
partPath
}
`;
let name =
event.target.parentElement.parentElement.nextElementSibling
.children[0].children[0].textContent;
item.name = name;
let price =
event.target.parentElement.parentElement.nextElementSibling
.children[0].children[1].textContent;
let finalPrice = price.slice(1).trim();
item.price = finalPrice;
console.log(finalPrice);
console.log(item);
const cartItem = document.createElement('div')
cartItem.classList.add('cart-item', 'd-flex', 'justify-content-between',
'text-capitalize', 'my-3');
cartItem.innerHtML = ` < img
src = "${item.img}"
class = "img-fluid rounded-circle"
id = "item-img"
alt = "" /
>
<
div class = "item-text" >
<
p id = "cart-item-title"
class = "font-weight-bold mb-0" >
$ {
item.name
} <
/p> <
span > £ < /span> <
span id = "cart-item-price"
class = "cart-item-price mb-0" >
$ {
item.price
} < /span >
<
/div> <
a href = "#"
id = "cart-item-remove"
class = "cart-item-remove" >
<
i class = "fas fa-trash" > < /i> <
/a> <
/div> *
/
`;
//select cart
const cart = document.getElementById('cart');
const total = document.querySelector('.cart-total-container');
cart.insertBefore(cartItem, total);
alert('item added to the cart')
}
});
});
})();
<!--cart-->
<div class="cart" id="cart">
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon2.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--total-->
<div class="cart-total-container d-flex justify-content-around text-capitalize mt-5">
<h5>total</h5>
<h5>£ <strong id="cart-total" class="font-weight-bold">21.99</strong></h5>
</div>
<!--end of total-->
<!--buttons-->
<div class="cart-buttons-container mt-3 d-flex justify-content-between">
clear cart
checkout
</div>
</div>
</div>
</div>
<!--store items-->
<div class="row store-items" id="store-items">
<!-- single item-->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card single-item">
<div class="img-container">
<img src="img/bodybutter.jpg" class="card-img-top store-img" />
<span class="store-item-icon"><i class="fas fa-shopping-cart"></i> </span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">body butter</h5>
<h5 class="store-item-value">£ <strong id="store-item-price" class="font-weight-bold">10.99</strong></h5>
</div>
</div>
</div>
</div>
<!--singles item end -->
There are more then one errors in your code starting with innerHtML instead of innerHTML and incorrectly formatted template literal and incorrect bindings inside it ... so I have decided to just post a working code. Keep in mind that incorrect HTML will be treated as text only, so check the correctness of the HTML block you want to place inside innerHTML, because there was as an extra closing div also.
(function(){
const cartInfo = document.getElementById('cart-info');
const cart = document.getElementById('cart');
cartInfo.addEventListener('click', function(){
cart.classList.toggle('show-cart')
})
})();
//add items to cart
(function() {
const cartBtn = document.querySelectorAll('.store-item-icon');
cartBtn.forEach(function(btn) {
btn.addEventListener('click', function(event) {
if (event.target.parentElement.classList.contains('store-item-icon'))
{
let fullPath =
event.target.parentElement.previousElementSibling.src;
let pos = fullPath.indexOf('img') + 3;
let partPath = fullPath.slice(pos);
const item = {};
item.img = `img - cart${partPath}`;
let name = event.target.parentElement.parentElement.nextElementSibling
.children[0].children[0].textContent;
item.name = name;
let price =
event.target.parentElement.parentElement.nextElementSibling
.children[0].children[1].textContent;
let finalPrice = price.slice(1).trim();
item.price = finalPrice;
console.log(finalPrice);
console.log(item);
const cartItem = document.createElement('div')
cartItem.classList.add('cart-item', 'd-flex', 'justify-content-between', 'text-capitalize', 'my-3');
cartItem.innerHTML =
`<img src = "${item.img}" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">${item.name}</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">${item.price}</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i></a>`;
//select cart
const cart = document.getElementById('cart');
const total = document.querySelector('.cart-total-container');
cart.insertBefore(cartItem, total);
alert('item added to the cart')
}
});
});
})();
.cart.show-cart{display:block}
.cart{display:none; border: 1px solid #000; padding: 20px}
.store-items{margin:20px 0;border:1px solid #000;padding: 20px}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta2/css/all.min.css" integrity="sha512-YWzhKL2whUzgiheMoBFwW8CKV4qpHQAEuvilg9FAn5VJUDwKZZxkJNuGM4XkWuk94WCrrwslk8yWNGmY1EduTA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<a id="cart-info" href="javascript:;">Toggle Cart</a>
<!--cart-->
<div class="cart" id="cart">
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--cart item-->
<div class="cart-item d-flex justify-content-between text-capitalize my-3">
<img src="img-cart/creamicon2.jpg" class="img-fluid rounded-circle" id="item-img" alt="" />
<div class="item-text">
<p id="cart-item-title" class="font-weight-bold mb-0">cart item</p>
<span>£ </span>
<span id="cart-item-price" class="cart-item-price mb-0">10.99</span>
</div>
<a href="#" id="cart-item-remove" class="cart-item-remove">
<i class="fas fa-trash"></i>
</a>
</div>
<!--cart item end-->
<!--total-->
<div class="cart-total-container d-flex justify-content-around text-capitalize mt-5">
<h5>total</h5>
<h5>£ <strong id="cart-total" class="font-weight-bold">21.99</strong></h5>
</div>
<!--end of total-->
<!--buttons-->
<div class="cart-buttons-container mt-3 d-flex justify-content-between">
clear cart
checkout
</div>
</div>
</div>
</div>
<!--store items-->
<div class="row store-items" id="store-items">
<!-- single item-->
<div class="col-10 col-sm-6 col-lg-4 mx-auto my-3 store-item sweets" data-item="sweets">
<div class="card single-item">
<div class="img-container">
<img src="img/bodybutter.jpg" class="card-img-top store-img" />
<span class="store-item-icon"><i class="fas fa-shopping-cart"></i></span>
</div>
<div class="card-body">
<div class="card-text d-flex justify-content-between text-capitalize">
<h5 id="store-item-name">body butter</h5>
<h5 class="store-item-value">£ <strong id="store-item-price" class="font-weight-bold">10.99</strong></h5>
</div>
</div>
</div>
</div>
<!--singles item end -->

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 retain the border of selected bootstrap cards even on page refresh?

I am having 6 bootstrap cards now I wrote code for storing the every card details in the local storage and also on click the card will get a border now I want is on page refresh I should retain the border of the card
My html code is:
<div class="row">
<div class="col-4" onclick="getGoal(1)">
<div class="card4 mt-3" id="room_1" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_1"><b>I am redecorating</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(2)">
<div class="card4 mt-3" id="room_2" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_2"><b>I am Moving</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(3)">
<div class="card4 mt-3" id="room_3" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_3"><b>I need help with a layout</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(4)">
<div class="card4 mt-3" id="room_4" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_4"><b>I am looking for a species</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(5)">
<div class="card4 mt-3" id="room_5" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_5"><b>I am moving with someone</b></p>
</div>
</center>
</div>
</div>
<div class="col-4" onclick="getGoal(6)">
<div class="card4 mt-3" id="room_6" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_6"><b>Other</b></p>
</div>
</center>
</div>
</div>
</div>
<!--Loop ends-->
<a class="link mt-3"><u>Dont see your room?</u></a>
<div class="row mb-3">
<div class="col-4 mr-5">
« Home
</div>
<div class="col-4 ml-5">
Next »
</div>
</div>
My JS code:
$(document).ready(function(){
// goals
$("#room_1").click(function(){
$("#room_1").toggleClass("blue");
});
$("#room_2").click(function(){
$("#room_2").toggleClass("blue");
});
$("#room_3").click(function(){
$("#room_3").toggleClass("blue");
});
$("#room_4").click(function(){
$("#room_4").toggleClass("blue");
});
$("#room_5").click(function(){
$("#room_5").toggleClass("blue");
});
$("#room_6").click(function(){
$("#room_6").toggleClass("blue");
});
$("#room_7").click(function(){
$("#room_7").toggleClass("blue");
});
$("#room_8").click(function(){
$("#room_8").toggleClass("blue");
});
$("#room_9").click(function(){
$("#room_9").toggleClass("blue");
});
});
var goal = [];
var goalIds = [];
function getGoal(id) {
if (goal.length > 0) {
var data = {
id: id,
content: $("#cont_" + id).text()
}
var x = JSON.stringify(data)
var index = goal.indexOf(x)
if (index == -1) {
goal.push(x);
} else {
goal.splice(index, 1);
}
} else {
var data = {
id: id,
content: $("#cont_" + id).text()
}
var x = JSON.stringify(data);
goal.push(x);
}
localStorage.setItem("goal", JSON.stringify(goal));
goalIds = goal.map(element => JSON.parse(element).id);
console.log(goalIds);
issample();
}
function issample() {
$("#goal").val(goalIds);
console.log(goalIds);
}
function initGoals() {
var storedNames = JSON.parse(localStorage.getItem("goal") || '[]');
goalIds = storedNames.map(element => JSON.parse(element).id);
}
My codepen link is: https://codepen.io/lakshmi123__/pen/xxbzwNP
function initGoals() {
goal = JSON.parse(localStorage.getItem("goal") || '[]');
goalIds = goal.map(element => JSON.parse(element).id);
goalIds.forEach(function(i){$("#room_"+i).addClass('blue');});
}
initGoals();
but event then, you are filling your goalIds variable right with that function,but you are forgetting to fill the goal variable too ;)

Categories