I am trying to make a filter on my ecommerce website. I am taking a data using json from the user and filtering items on the views.py. There are no any errors and I can see the filtered products on the console. However, I can not render products on the template. It is not giving any errors. It's just not showing.
views.py
def Products(request):
data = cartData(request)
cartItems = data['cartItems']
order = data['order']
items = data['items']
products = Product.objects.all()
gender = Gender.objects.all()
categories = Category.objects.all()
product_types = ProductType.objects.all()
try:
data = json.loads(request.body)
productTId = data['productTId']
productVId = data['productVId']
genderId = data['genderId']
genderId = get_object_or_404(Gender, id=genderId)
productVId = get_object_or_404(Category, id=productVId)
productTId = get_object_or_404(ProductType, id=productTId)
filtered_products = Product.objects.filter(typeP=productTId).filter(category=productVId).filter(Gender=genderId)
countFilter=filtered_products.count()
print(filtered_products)
print(countFilter)
return JsonResponse(filtered_products, safe = False)
except:
None
try:
context = {'countFilter':countFilter,'filtered_products':filtered_products,'gender':gender,'categories':categories,'product_types':product_types,'products':products, 'cartItems':cartItems, 'order':order, 'items':items}
except:
context = {'gender':gender,'categories':categories,'product_types':product_types,'products':products, 'cartItems':cartItems, 'order':order, 'items':items}
return render(request, 'product.html', context)
html
{% for product in filtered_products %}
<div class="card">
<div class="card__img">
<picture><source srcset="{{product.imageURL}}" type="image/webp"><img src="{{product.imageURL}}" alt=""></picture>
</div>
<h6 class="card__title">{{product.name}}</h6>
<div class="card__descr">{{product.description}}...
<div class="card__more" onclick="More('{{product.id}}')">подробнее...</div>
</div>
<div class="card__func">
<a class="btn-hover card__button-buy update-cart" data-product="{{product.id}}" data-action="add">В КОРЗИНУ</a>
<div class="card__right">
<div class="card__price" data-product="{{product.id}}">{{product.price}} р</div>
<div class="card__changed-price card__changed-price--card">
<div class="card__changed-btn card__changed-btn--prev card__changed-btn--max increase" data-product="{{product.id}}" data-action="minus"><svg width="8" height="2" viewBox="0 0 8 2" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 1L7 1" stroke="#7ABC51" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<p class="card__changed-thing" id="quantity" class="quantity" data-product="{{product.id}}">1</p>
<div class="card__changed-btn card__changed-btn--next increase" data-product="{{product.id}}" data-action="plus"><svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 7C3 7.41421 3.33579 7.75 3.75 7.75C4.16421 7.75 4.5 7.41421 4.5 7V4.75H6.75C7.16421 4.75 7.5 4.41421 7.5 4C7.5 3.58579 7.16421 3.25 6.75 3.25H4.5V1C4.5 0.585786 4.16421 0.25 3.75 0.25C3.33579 0.25 3 0.585786 3 1V3.25H0.75C0.335786 3.25 0 3.58579 0 4C0 4.41421 0.335786 4.75 0.75 4.75H3V7Z" fill="#7ABC51"/>
</svg>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
As I mentioned it's not returning any errors and I can see result on the console. But, it's only not showing while I tried to render it. Hope for your response.
Related
I'm using HTMX and I have a button inside a form that says 'Send' and when the form is submitted a loading spinner appears next to it. I want the 'Send' to disappear and only the loading spinner to be shown while the request is in progress. How can I do that?
<form hx-post="/test">
<button type="submit">
<span>Send</span>
<svg class="htmx-indicator ml-2 animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="black" fill="transparent" stroke-width="4"></circle>
<path class="opacity-75" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</button>
</div>
</form>
The .htmx-request class should be added to the button that triggered the request, so you can use that with some CSS to hide the text.
https://htmx.org/docs/#request-operations
I want it so that when a user clicks on the heart icon, the heart-icon is hidden and the heart-filled-icon is shown. How do I refer to the other icon within my jQuery function to change it's "display" from "none" to "shown"? I know that this example is really wrong this is just an idea of what I want to do and I can't figure it out.
$('.heart-icon').click(function(){
$('.heart-icon').hide();
$('.heart-filled-icon').show();
});
<svg width="1em" height="1em" viewBox="0 0 16 16" class="heart-icon bi bi-heart" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/>
</svg>
<svg width="1em" height="1em" style ="display:none;" viewBox="0 0 16 16" class="heart-filled-icon bi bi-heart-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
</svg>
There are many different ways you can do this...
One way is to toggle the Bootstrap display classes. Put either d-none or d-block on the SVG's classes initially.
$('.bi').click(function(){
$('.bi').toggleClass('d-none d-block');
})
https://codeply.com/p/FmVXaxOvoA
I want to extract next page url from the following html using css selector for scrapy spider.
<button id="omni-next-click" name="searchnextclick" class="btn btn__blue btn__rounded" aria-label="next" data-reactid="971" omnivalue="1">
<span class="icon icon__arrow-right" data-reactid="972">
<svg aria-hidden="true" data-reactid="973">
<use xlink:href="/images/adaptive/livestyleguide/walgreens.com/v3.0/themes/images/icons/symbol-defs.svg#icon__arrow-right" data-reactid="974">
#shadow-root (closed)
<svg id="icon__arrow-right" viewBox="0 0 32 32">
<title>icon__arrow-right</title>
<path d="M13.312 21.952c-0.144 0-0.288-0.064-0.4-0.176-0.224-0.224-0.224-0.592 0-0.816l4.976-4.976-4.976-4.96c-0.224-0.224-0.224-0.592 0-0.816s0.592-0.224 0.816 0l5.376 5.376c0.224 0.224 0.224 0.592 0 0.816l-5.376 5.376c-0.128 0.112-0.272 0.176-0.416 0.176z">
</path>
</svg>
</use>
</svg>
</span>
</button>
I am new to scraping. Please help me through it. How can I find css so that I can crawl through all the available pages?
So I came across with this awesome Search Form. Demo can be found here.
I was trying to figure how to hide the advanced search box as following:
It does not have to be an error but some button so if the user clicked on it, it will expand the advanced search. I can't seem to figure out how to do it.
The simplified code:
<div class="s009">
<form>
<div class="inner-form">
<div class="basic-search">
<div class="input-field">
<b-form-input v-model="search_text" id="search" placeholder="Type Keywords"></b-form-input>
<div class="icon-wrap">
<svg class="svg-inline--fa fa-search fa-w-16" fill="#ccc" aria-hidden="true" data-prefix="fas" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path>
</svg>
</div>
</div>
</div>
<div class="advance-search">
<span class="desc">ADVANCED SEARCH</span>
</div>
</div>
</form>
</div>
Is it possible to suggest some CSS/HTML solution for that?
Give us more information.
If you want just hide the advanced search box use this below code
.advance-search
{
display: none;
}
With jQuery
You can use jquery.this code works if you use add jQuery in your html file
$('document').ready(() => {
$('button').on('click', function () {
$('.advance-search').css('display', 'none')
})
})
This answer should suffice. They use the adjacent sibling selector to create "buttons" out of spans in focus. For your code it would look like this.
<div class="s009">
<form>
<div class="inner-form">
<div class="basic-search">
<div class="input-field">
<b-form-input v-model="search_text" id="search" placeholder="Type Keywords"></b-form-input>
<div class="icon-wrap">
<svg class="svg-inline--fa fa-search fa-w-16" fill="#ccc" aria-hidden="true" data-prefix="fas" data-icon="search" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path>
</svg>
</div>
</div>
</div>
**** <span class="show">Show</span>
**** <span class="hide">hide</span>
<div class="advance-search">
<span class="desc">ADVANCED SEARCH</span>
</div>
</div>
</form>
</div>
and the css
span.show:focus ~ .advance-search{ display: none;}
span.hide:focus ~ .advance-search{ display: block;}
addition two
Initially I was trying to do this with only html/css as per your question, however you commented about using Vue. So there are three things to note with vue:
you can store component states in data
you can show and hide elements with v-if
you can change component states on events with v-on
So you want to store data show-advanced: false, then set v-if='show-advanced' on the advance-search. With this advance-search won't display unless show-advance is set to true
<div class="advance-search" v-if='show'>...</div>
<script>
new Vue({
...
data: {
'show': false
}
...
})
</script>
To create a toggle you need a button with the attribute v-on:click="show=!show".
<button v-on:click="show=!show">Toggle</button>
Put that button where ever you want and there you go!
edit
I got a fiddle working, changed show-advanced to show, and I fixed a mistake changing v-bind to v-on
My current code to get the content I need looks like this:
#BeautifulSoup
textContent = []
headline = soup.find('a', attrs={"class":"title"}).text
review = soup.find('div', attrs={"class":"text show-more__control"}).text
rating = soup.find('div', attrs={"class":"rating-other-user-rating"})
textContent.append(headline)
print(headline)
textContent.append(review)
print(review)
textContent.append(rating)
print(rating)
I get the title and the text of the review but not the rating because this information is in a different "tag-system" than the other info. On the html code it looks like this:
<span class="rating-other-user-rating">
<svg class="ipl-icon ipl-star-icon " xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">
<path d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path>
<path d="M0 0h24v24H0z" fill="none"></path>
</svg>
<span>6</span><span class="point-scale">/10</span>
</span>
The information I want to get is the "6". Obviously, I can't just go by "soup.find.---.text() because it's a None-Object.
Thanks for the help!
1) Change the 'div' to 'span'
2)
a) then you can get the text
b) strip away the whitespace, to get 6/10
c) Split at the '/'
d) take element in that list at index [0]
Replace:
rating = soup.find('div', attrs={"class":"rating-other-user-rating"})
With:
rating = soup.find('span', attrs={"class":"rating-other-user-rating"}).text.strip().split('/')[0]
Output:
print (rating)
6