Pergunta

I've been trying to find an example on how to filter a container of divs based on a search text box using RactiveJS.

I know how to get the key pressed events using Ractive but unsure on how to filter the model the RactiveJS way. Keeping copies / history of the data during key press event seems like a bad idea. What am I missing here?

Foi útil?

Solução

You can let Ractive manage it (http://jsfiddle.net/nnbww/):

<div id="container">
  <input name="search" type="text" value="{{searchTerm}}"/>
  {{#items}}
     {{#(..indexOf(searchTerm)===0)}}
         <div>{{.}}</div>
     {{/}}
 {{/items}}
</div>

You can use this instead of . if you prefer:

{{# this.indexOf(searchTerm)===0 }}

And put the function on your data, rather than inline:

{{# filter(this) }}

This would allow you to change the filter as well. Check out http://examples.ractivejs.org/todos for a good example of this.

If you need to track other info about the filtered list (for example display a count of matched items), it's a bit more difficult to use a purely reactive approach (see version /1/ of above jsfiddle), which probably makes it simpler to use an observer:

 <input name="search" type="text" value="{{searchTerm}}"/>
 {{#filtered}}
     <div>{{.}}</div>
 {{/filtered}}
 Matching {{filtered.length}} of {{items.length}}

set in complete method:

var ractive = new Ractive({
    el: 'container',
    template: '#container',
    data: { 
        searchTerm: 'foo',
        items: [ 'foo', 'bar', 'biz', 'bah' ]
    },
    complete: function(){
        var r = this
        r.observe('searchTerm', function(search){
            var filtered = r.get('items').filter(function(item){
                return item.indexOf(search)===0
            })
            r.set('filtered', filtered)
        })
    }
})

(see version /2/ of jsfiddle link)

Outras dicas

If your searchable div's are static, then you can put an observer on your search term: http://jsfiddle.net/fLd86/10/

ractive = new Ractive({
el: 'container',
template: '#container',
data: { searchTerm: 'foo' }
});

observer = ractive.observe( 'searchTerm', function ( newValue, oldValue, keypath ) {
    $( 'div.searchable:contains("' + newValue +'")').show();
    $( 'div.searchable:not(:contains("' + newValue +'"))').hide();
});

If the divs are part of your model, you'll need to put something in the template to inject them into the html, but the same sort of logic should work.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top