Reputation: 4132
I'm using Polymer 1.8 (Starter Kit template). I want to know how to create a search filter custom element like the one in https://codelabs.developers.google.com/
As you can see, it filters out the cards below it, with each keystroke typed in the search bar, leaving only the cards that are containing desirable search words.
I'd like for it to find the words in both:
<paper-card>
(text in the heading
) divs
(description of a <paper-card>
)The only examples of the search box I found are this page from 2015 and this page of the Polymer Element Catalog, which is using a similar search box, but I couldn't adapt them to my custom elements.
my-preview-cards
custom element:It contains the cards themselves:
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="shared-styles.html">
<dom-module id="my-preview-cards">
<template>
<style>
/* local DOM styles go here */
:host {
display: inline-block;
}
</style>
<div>
<paper-card heading="Color picture" image="http://lorempixel.com/300/200">
<div class="card-content">An RGB picture</div>
<div class="card-actions">
<paper-button>Button</paper-button>
</div>
</paper-card>
<paper-card heading="Grey image" image="http://lorempixel.com/g/300/200">
<div class="card-content">That's a grey picture</div>
<div class="card-actions">
<paper-button>Button</paper-button>
</div>
</paper-card>
</div>
</template>
<script>
Polymer({
is: 'my-preview-cards',
});
</script>
</dom-module>
my-search-bar
for the search bar:It contains the search bar:
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="shared-styles.html">
<dom-module id="my-search-bar">
<template>
<style>
/* local DOM styles go here */
:host {
display: inline-block;
}
</style>
<form on-submit="performSearch" class="flex">
<paper-input id="query" value="{{query::keyup}}" type="search" placeholder="search"></paper-input>
</form>
</template>
<script>
Polymer({
is: 'my-search-bar',
});
</script>
</dom-module>
my-homepage
as:<div>
<my-search-bar></my-search-bar>
</div>
<div>...</div>
<div>
<my-preview-cards></my-preview-cards>
</div>
I understand this is a complicated question. As soon as I get 75 rep, I will assign bounty of 50 to this question, and whoever provides the working solution gets it.
Upvotes: 4
Views: 1006
Reputation: 377
I think it's about manipulating the data. I doubt that you would want to manually create all those <paper-card>
s if you have so much data, so I suggest using <dom-repeat>
for that and filtering your data from the Array
. You can see an example demo here.
.search-box {
display: flex;
display: -webkit-flex;
background-color: #fff;
border: 1px solid #eee;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
height: 40px;
width: 100%;
align-items: center;
}
.search-box iron-icon {
color: var(--google-grey-700);
fill: var(--google-grey-700);
margin-left: auto;
right: 0;
}
.search-box input {
font-size: 20px;
outline: 0;
border: none;
padding-left: 10px;
width: 86%;
}
.search-box {
@apply(--layout-flex);
@apply(--layout-center);
@apply(--layout-horizontal);
}
.search-box input {
@apply(--layout-flex);
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="polymer-search">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Polymer Search</title>
<base href="https://polygit.org/polymer+1.6.0/components/">
<link rel="import" href="iron-icon/iron-icon.html">
<link rel="import" href="iron-icons/iron-icons.html">
<link rel="import" href="iron-icons/av-icons.html">
<link rel="import" href="paper-toolbar/paper-toolbar.html">
<link rel="import" href="paper-input/paper-input.html">
</head>
<body>
<dom-module id="my-app">
<template>
<style>
ul {
padding:20px 10px;
list-style: none;
display:flex;
flex-flow:row;
justify-content:space-between;
}
.item {
width:25%;
background-color: whitesmoke;
padding:5px;
margin:5px;
display:flex;
flex-flow:column;
}
</style>
<paper-toolbar>
<div class="search-box bottom">
<input id="search" />
<iron-icon icon="av:mic"></iron-icon>
</div>
</paper-toolbar>
<ul>
<template is="dom-repeat" items="[[data]]">
<li class="item">
<span>[[item.title]]</span>
<p>[[item.description]]</p>
</li>
</template>
</ul>
</template>
<script>
Polymer({
is: 'my-app',
properties: {
defaultData: {
type: Array,
value: [{
title: 'Color picture',
description: 'An RGB picture'
},
{
title: 'Grey image',
description: 'That\'s a grey picture'
},
{
title: '3',
description: 'this is content 3'
}
]
},
data: {
type: Array
}
},
ready: function() {
this.data = this.defaultData;
this.$.search.addEventListener('keyup', this.searchChanged.bind(this));
},
searchChanged: function(e) {
var querySearch = this.$.search.value.toLowerCase();
if (querySearch == '') {
this.data = this.defaultData;
} else {
this.data = this.defaultData.filter(function(item) {
return item.title.toLowerCase().indexOf(querySearch) !== -1 || item.description.toLowerCase().indexOf(querySearch) !== -1;
});
}
}
})
</script>
</dom-module>
<my-app></my-app>
</body>
</html>
Upvotes: 5