diff --git a/warehouse/__init__.py b/warehouse/__init__.py
index 11eb99580b6948552cb76c253f786c5d27b1ea74..923d68d4b537bc6e446e863fae9e71a0b48f5d26 100644
--- a/warehouse/__init__.py
+++ b/warehouse/__init__.py
@@ -174,7 +174,19 @@ def item_upload_photo(item_id):
 def item_locate(item_id):
 	item = Item.query.get_or_404(item_id)
 	if request.method == 'GET':
-		return render_template('item/locate.html', item=item, all_locations=Location.query.all())
+		query = Location.query
+		if 'search' in request.values:
+			keywords = request.values['search'].strip().split()
+			for keyword in keywords:
+				query = query.filter(db.or_(Location.name.contains(keyword), Location.description.contains(keyword)))
+		locations = query.all()
+		def include_parents_r(location):
+			if location.parent and location.parent not in locations:
+				locations.append(location.parent)
+				include_parents_r(location.parent)
+		for location in list(locations):
+			include_parents_r(location)
+		return render_template('item/locate.html', item=item, locations=locations)
 	item.location = Location.query.get(request.form['location_id'])
 	db.session.commit()
 	return redirect(url_for('item_view', item_id=item_id))
diff --git a/warehouse/templates/item/locate.html b/warehouse/templates/item/locate.html
index d3bf801b211021d5497b1f5e5bd9d573d862ec40..50000e9613f40638bbc7049488a22a79e911de26 100644
--- a/warehouse/templates/item/locate.html
+++ b/warehouse/templates/item/locate.html
@@ -1,13 +1,47 @@
 {% extends 'layout.html' %}
 
+{% macro location_recursive(location, indent=0) %}
+			<tr>
+				<td>{{ ('&emsp;'*indent)|safe }}{{ location.name }}</td>
+				<td>
+					{% if not location.children %}
+					<button type="submit" name="location_id" value="{{ location.id }}" class="float-end btn btn-sm btn-primary">Select</button>
+					{% else %}
+					<button type="submit" name="location_id" value="{{ location.id }}" class="float-end btn btn-sm btn-secondary">Select</button>
+					{% endif %}
+				</td>
+			</tr>
+			{% for item in locations if item in location.children %}
+				{{ location_recursive(item, indent+1) }}
+			{% endfor %}
+{% endmacro %}
+
 {% block body %}
+<h1>Set location for {{ item.name }}</h1>
+
+<div class="d-flex justify-content-end gap-1">
+	<form class="form-inline">
+		<div class="input-group">
+			<input type="text" class="form-control" name="search" value="{{ request.args.search }}" placeholder="Search" autofocus>
+			<button class="btn btn-outline-secondary" type="submit">Search</button>
+		</div>
+	</form>
+</div>
+
 <form method="POST">
 	<input type="hidden" name="csrf_token" value="{{ request.csrf_token }}">
-	{% for location in all_locations %}
-	<div class="clearfix w-100 my-2">
-		{{ location.name }}
-		<button type="submit" name="location_id" value="{{ location.id }}" class="float-end btn btn-primary">Select</button>
-	</div>
-	{% endfor %}
+	<table class="table table-hover">
+		<thead>
+			<tr>
+				<th scope="col">Location</th>
+				<th scope="col"></th>
+			</tr>
+		</thead>
+		<tbody>
+			{% for location in locations if not location.parent %}
+				{{ location_recursive(location) }}
+			{% endfor %}
+		</tbody>
+	</table>
 </form>
 {% endblock %}