Add "items per page" drop down box in SHOPIFY - search

I'm building a web store on shopify. I want to add a drop down box on a page that displays my products where I can select number of items to display per page (i.e. 25, 50, 100).
Any suggestions on where to start with this and if there are any shortcodes in shopify that will help me do this?

Here is the solution for the collection page; try the following code:
<div class="sort-per-page">
<label for="sel1">Show per page:</label>
<select id="sel1" class="num">
<option value="/collections/{{ collection.handle }}?view=9" {% if limit == 9 %}selected="selected"{% endif %}>9</option>
<option value="/collections/{{ collection.handle }}?view=12" {% if limit == 12 %}selected="selected"{% endif %}>12</option>
<option value="/collections/{{ collection.handle }}?view=24" {% if limit == 24 %}selected="selected"{% endif %}>24</option>
<option value="/collections/{{ collection.handle }}?view=36" {% if limit == 36 %}selected="selected"{% endif %}>36</option>
</select>
</div>
<script>
$(document).ready(function(){
jQuery('.sort-per-page select.num').on('change', function(){
window.location.replace(jQuery(this).val());
});
});
</script>

One thing is for sure. You will be dealing with Collections. When you render a collection, you choose the number of Products to show. Further Shopify has Pagination you setup and control.
You can thus render your selection mechanism however you choose by enacapsulating the built-in Liquid Collection rendering variables.
Alternatively, you can render ALL the products in a collection into some client-side data structure (that could take some time depending on the number of products) and then render any number of them using your own algorithms and ideas.

Related

How to paginate my jekyll site using Jekyll-Paginate-v2

Here is the source code of the website with its index.md and config.yml.
The problem
The number of tools (.md files) in _wadcoms directory keeps increasing over time, so I want the main page to be paginated in order to better navigate among plenty of them.
I tried several blogs and followed them all step by step individually, but unfortunately, I couldn't document each one of them here, still, my Jekyll site won't render that pagination.
Just now I found out that Pagination only works within HTML files, despite the solutions and workarounds suggested in that thread, I am unable to follow it up with my website. It renders the main page from the index.md file, I am not able to convert it to index.html which would help my site paginate.
What I wanted
I wanted to have ellipses to paginated the site using Jekyll-Paginate-v2, just like in the answer thread. I am absolutely out of ideas and I have no clue how to proceed with rendering a successful pagination in this case.
NOTE: Those files under _wadcoms are individual webpages, they increase in number over time, that's why I needed pagination on the main site. Imagine 200 of these tools/commands, that would be very difficult to navigate.
Thanks for your help.
Following my comment above, I have tested the plugin.
The result is not a numbered pagination yet but this should be also possible. Note that I converted the paragraphs, logo, and links in the index to HTML tags (p, img and a) but this worked OK:
I have not tested the search ... I hope that this is a trace and helps a bit. You can find my complete test code I comment below in a branch/PR in your repo: https://github.com/WADComs/WADComs.github.io/pull/21
I have replaced the current code in bin_table.html with
<!-- not sure about the reverse, the plugin offers this option, too! -->
{% assign sites = paginator.wadcoms | reverse %}
{% for file in sites %}
<tr>
<td>
<div class="bin-name">
<div style="flex: 0 0 97%"><a href="{{ file.url }}" id="{{ file.url }}"
style="text-decoration: none; color: DarkGreen;">{{ file.command | escape }}</a></div>
<div style="flex: 1;"><a href="javascript:void(0)" onClick="copyFunction('{{ file.url }}')"><img
src="/assets/copy-button.svg" alt="Copy" title="Copy" id="{{ file.url }}_img" /></a>
</div>
</div>
<p style="margin-top: -12px;">{% include filter_list.html bin=file %}</p>
</td>
</tr>
{% endfor %}
Previous page | Next page
{{ paginator.page }}
{{ paginator.total_pages | inspect }}
{% for page in paginator.total_pages %}
{{ page }}
{% endfor %}
I have added these lines to the _config.yml file (as an example config):
paginate:
collection: wadcoms
per_page: 10 # maximum number of items per page
limit: false # Maximum number of pages to paginate (false for unlimited)
permalink: /page:num/ # pagination path (relative to template page)
title_suffix: " - page :num" # Append to template's page title
category: '' # Paginate items in this category
categories: [] # Paginate items in any of these categories
tag: '' # Paginate items tagged with this tag
tags: [] # Paginate items tagged with any of these tags
reversed: true # Reverse the order of the documents

Cheerio JS Can I check if an attribute is included in an element I already selected in cheerio JS

I am wondering if I can check if an element has a certain attribute after locating it, and if it has that attribute, avoid it and get a new one.
Here is the html I am using:
<option
value="19438389624960">
1
</option>
<option
disabled="disabled"
value="19438389657728">
2
</option>
<option
value="19438389690496">
3
</option>
<option
disabled="disabled"
value="19438389723264">
4
</option>
As you can see, 2 of the 4 options have a disabled="disabled" attribute that I want to avoid, is there anyway I can do that ?
I currently have this code that chooses a random value out of all the options:
var list = [];
$('select[name=id]').find('option').each(function (index, element) {
list.push($(element).attr('value'));
});
const randomVar = list[Math.random() * list.length | 0]
variant = randomVar
But this code still will choose the ones that have the disabled="disabled" attr
You can use this:
$('select[name=id]').find('option[disabled!="disabled"]').each(...)
to skip the options that have disabled=disabled. Then, you will be picking a random one from only the non-disabled items. Since cheerio uses the same selector engine as jQuery, you can find this kind of stuff in the relevant page of the jQuery doc.
:not is a regular css pseudo, which means it works everywhere:
$('option:not([disabled="disabled"])')
or probably just:
$('option:not([disabled])')

Capture values from multiple select form and POST via Flask [duplicate]

This question already has answers here:
Converting Flask form data to JSON only gets first value
(2 answers)
Closed 4 years ago.
I need to capture multiple select form vlaue (generated from a MongoDB collection ) and POST via a Flask route to another MongoDB collection: recipes
Below is the relevant form div:
<form action="{{ url_for('insert_recipe') }}" method="POST" class="col s12">
...
<div class="input-field col s6 l6">
<i class="material-icons prefix">warning</i>
<select multiple id="allergen_name" name="allergenlist">
<option value="" disabled selected>Choose allergens</option>
{% for allergen in allergens %}
<option value="{{allergen.allergen_name}}">{{allergen.allergen_name}}</option>
{% endfor %}
</select>
</div>
</div>
...
</form>
I want to capture the selected options and POST them via Flask:
# Get all recipes
#app.route('/get_recipes')
def get_recipes():
return render_template("recipes.html",
recipes=mongo.db.recipes.find())
# Render HTML form
#app.route('/add_recipe')
def add_recipe():
return render_template('addrecipe.html',
users=mongo.db.users.find(),
allergens=mongo.db.allergens.find(),
cuisines=mongo.db.cuisine.find(),)
# Send the form
#app.route('/insert_recipe', methods=['POST'])
def insert_recipe():
recipes = mongo.db.recipes
recipes.insert(request.form.to_dict())
return redirect(url_for('get_recipes'))
However, only the first selected option is being captured and sent.
Any help would be appreciated.
EDIT:
When looking at: http://werkzeug.pocoo.org/docs/0.12/datastructures/#werkzeug.datastructures.MultiDict.to_dict
... relaised that I need to set to_dict(flat=false) in order to have all values of dict returned.
See EDIT above, the correct way is to:
# Send the form
#app.route('/insert_recipe', methods=['POST'])
def insert_recipe():
recipes = mongo.db.recipes
recipes.insert_one(request.form.to_dict(flat=False))
return redirect(url_for('get_recipes'))
Also, just found a duplicate as notified by #davidism :
Converting Flask form data to JSON only gets first value

How to make dropdown list change a table data with Jinja2 + Flask

I'm using Jinja2 Template to change dynamically a result table for my Motor Racing webapp. It's not perfect, but I'm making my way with patience.
I have a template that is rendered by the URL 'webapp.com/driver/' that's supposed to show the results of a Race where the driver was present inside a table. To make it clear:
The user selects a Driver and goes to webapp.com/driver/someDriver
The someDriver page has a dropdown list with ALL Races the someDriver has been through
User selects someRace from dropdown list
Table is fed by someRace's results
The python flask route I wrote for it:
#app.route('/driver/<driverid>')
def driver(driverid):
driver = db.Drivers.find_one({'_id': ObjectId(driverid)})
races = db.Races.find({'finalresult.driver':driver['unique_name']}).sort([('timestamp', -1)])
racesList = []
for race in races:
raceItem = {
'filename':race['filename'],
'date':datetime.datetime.fromtimestamp(float(race['timestamp'])).strftime('%d-%m-%Y'),
'finalresult':race['finalresult'],
'id':str(race['_id'])}
racesList.append(raceItem)
return render_template('user.html', driver=driver, racesList=racesList)
Now I'm trying to make a dynamic template that changes the Result table everytime the user change the selection.
<div class="row">
<form name="racesForm">
<label for="selRace">Escolha uma corrida!</label>
<select class="form-control" id="selRace">
{% for race in racesList %}
<option value="{{race.filename}}">
{{race.filename}}
</option>
{% endfor %}
</select>
</form>
<hr>
</div>
<div class="row">
<table>
<thead>
<th>Position</th>
<th>Driver</th>
</thead>
<tbody>
<tr>
{% position, drivername in race.finalresult %}
<th>{{position}}</th>
<td>{{drivername}}</td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
But now I'm receiving a error:
Encountered unknown tag 'position'.
And that's it..I'm not sure of how to make this dropdown list change the table dynamically. Any insights 'd be aprecciated.
UPDATE//Giving more info:
Driver is a very simples dict/json that has two keys ['name'] and ['_id']
racesList is an array of many "raceItem"s.
Each "raceItem" has a key anmed 'finalresult' that has data of the positions each driver has finished.
this array is filled with many objects it may seem like the example below:
'finalresult': [
{'position': 1,
'drivername': 'John Doe'},
'position': 2,
'drivername': 'Foo Bazz', etc
}]
As I told before, I want this data to be displayed in a table, depending on what RACE has been selected from the "raceList" dropdown list.
As a solution, I'm thinking of creating a new routing...but I wanted this routing to be displayed in the same page. I don't want the user to be directed to a new window.
First of all, you are getting Encountered unknown tag 'position' as you are using a different data structure. As you mentioned finalresult is a list of dicts. So you need to iterate through it when populating your table.
{% for driver_stat in race.finalresult %}
<td>{{driver_stat.position}}</td>
<td>{{driver_stat.drivername}}</td>
{% endfor %}
But with your approach, this table will not be updated dynamically as you select different race from your dropdown. Instead I suggest to use jquery. So you don't have to nevigate to another page to display the driver stats. I found several useful SO question that have been already answered on this. Follow them.
Ref:
Populate table based in select
Populate HTML table based on second dropdown selection

Is it possible to send an advanced query to Shopify /search url

I am customizing a Shopify template has a form like this.
<form action="/search" method="get" class="search-bar" role="search">
<input type="hidden" name="type" value="product">
<input type="search" name="q" class="text" placeholder="{{ 'general.search.placeholder' | t }}" value="{{ search.terms }}">
<input type="hidden" class="btn" value="Search">
</form>
Which returns an array of objects search.results it is not possible to remove elements from that array in Liquid (ex. remove products which has a price of 0)
I want to remove elements from that array because even though i can filter those elements and choose them to show in the page or not, i cant effect {% paginate %} function because it is paginating the unfiltered version of search.results for example {% paginate search.results by 12 %}.
So my question is can i send an advanced query from the very start and only get the result for ex. products which have not a price of 0 ?
Thanks in advance.
I googled about this a lot but couldn't find a solution.
`
Nope you can't. Price is not a valid field in Shopify's search fields - https://help.shopify.com/manual/sell-online/online-store/storefront-search
Alternatively you can tag the products with 0 price and add "-tag" as a field to exclude those items. Refer to the link for detailed description on search on Shopify.

Resources