metafizzy / isotope

:revolving_hearts: Filter & sort magical layouts
https://isotope.metafizzy.co
11.06k stars 1.42k forks source link

Filter with angular and scope variable #943

Closed Seiifer closed 9 years ago

Seiifer commented 9 years ago

Hi, first of all, great work.

I have found a few examples on codepen doing what I am trying to achieve (http://codepen.io/desandro/pen/btFfG and http://codepen.io/desandro/pen/wfaGu), but they are all using css classes to filter, and I'm not quite sure how to achieve what I'm trying to do :

I want to filter some tile I display depending on a search input and on some checkboxes. I have the searchInput value and my checkboxes states in my scope.

But I don't know what should go in my controller.

Here is the concerned HTML :

<md-grid-list md-cols-sm="2" md-cols-md="4" md-cols-lg="6" md-cols-gt-lg="8"
 md-row-height-gt-md="1.2:1" md-row-height="1:1" md-gutter="10px" 
 md-gutter-gt-sm="10px" class="isotope">

    <md-grid-tile class="gray"  ng-repeat="carto in cartoList">
        <md-button ng-click="changeSVG(carto.fileName)" aria-label="carto.displayName">
            <img src="style/images/thumbnails/{{carto.fileName}}.png" width="100%" height="100%"
            </img>
        </md-button>
        <md-grid-tile-footer><h3 align="center">{{carto.displayName}}</h3> </md-grid-tile-footer>
     </md-grid-tile>

</md-grid-list>

Some CSS :

md-grid-list {
    margin: 8px;
}

.gray {
    background: #f5f5f5;
}

md-grid-tile {
    -webkit-transition: all 500ms ease-out 100ms;
    -moz-transition: all 500ms ease-out 100ms;
    -o-transition: all 500ms ease-out 100ms;
    transition: all 500ms ease-out 100ms;
}

md-grid-tile md-grid-tile-footer {
    background:  rgba(0,0,0,.68);
    height: 6px; !important;

}

md-grid-tile-footer figcaption  {
    width:100%;
}

md-grid-tile-footer figcaption h3 {
    margin:0px;
    font-weight:200;
    width:100%;
    text-align:center;
}

So basically, I want to display only the tiles for which the displayName contains the searchInput and for which some other fields (from carto just like displayName) have a certain value depending on the checkboxes states.

Here is what a carto looks like :

{
"fileName": "AT_Collateral",
"type": "AT",
"level": "block",
"informationSystem": "Group",
"area": "Middle Office",
"block": "Collateral management",
"fullDisplayName": "Technical architecture collateral",
"displayName": "TA collateral",
"defaultZoom": "1",

}

So ideally, I guess a function should check the value of my searchInput and my checkboxes in order to do the proper filter.

How do I filter my display on this variables ? How do I even compare this variable to the field from my ng-repeat

desandro commented 9 years ago

I guess a function should check the value of my searchInput and my checkboxes in order to do the proper filter.

Yes, you have the right idea.

How do I filter my display on this variables ? How do I even compare this variable to the field from my ng-repeat

Sorry, but I won't be able to produce a solution for you. Generally, I recommend avoiding this kind of UI which relies on multiple parts that are combined together. It's confusing for users and complex to maintain for developers.

Seiifer commented 9 years ago

Could you point me into the right direction ? Additionally to the code I provided above, there is :

The search input :

<form action="javascript:void(0)" method="get" class="sidebar-form">
     <div class="input-group">
          <input type="text" ng-model="searchInput" name="q" class="form-control"
                     placeholder="Search..." id="sInput"/>
          <span class="input-group-btn">
               <button type='submit' name='search' id='search-btn' class="btn btn-flat"><i class="fa fa-search"></i>
               </button>
         </span>
    </div>
</form>

And i try to add this as the filter handler :

$( function() {
    // init Isotope
    var $container = $('.isotope').isotope({
        itemSelector: 'md-grid-tile',
        filter: function() {
            var isMatched = true;
            var $this = $(this);
            console.log($(this));

            return isMatched;
        }
    });

    $('#sInput').keyup(function() {
        console.log("changed");
        var $this = $(this);
        // get group key

        // arrange, and use filter fn
        $container.isotope('arrange');
    });
});

So, the logic is : For each element targetted by itemSelector, the element will be displayed if isMatched is set to true right ? So I'll need to set isMatched depending on my input ?

So, how do I call my filter function from my keyup event ? I need to add some filter or data-filter class somewhere in my html ? If I add a filter property to my input, for example <input ... filter="sFilter"/>, how do I add the sFilter function ?

Also is there any example where the filter is applied to a tag instead of a class ?