How to Filter by Category via Modal checkbox using Ionic / Angularjs?

Asked

Viewed 725 times

1

EDITED FOR BETTER EXPLANATION

I have 3 types of filters:

A research:

<div class="bar bar-subheader bar-assertive">
        <label class="item-input-wrapper textbox-search">
            <i class="icon ion-search placeholder-icon"></i>
            <input ng-model="q" placeholder="Procurar" aria-label="filter restaurantess" />
        </label>
    </div>

Where the ng-model filter is: filter:q

One by ordination:

  <!-- ORDENA POR PREÇO -->
                <button class="button button-stable button-block  icon-left ion-android-restaurant" modal-select="" ng-model="someModel" options="selectableNames" option-property="role" modal-title="Ordenar por..." has-search="true">Ordenar
                    <div class="option">
                        <h2>{{option.name}}</h2>
                    </div>
                </button>

Where the filter is: orderby:someModel

I need a filter by Category, that opens a modal listing all categories, but showing only the categories that exist listed (for the user not to waste time selecting a category that does not exist in the listing), where the view of this modal is:

 <ion-modal view-title="cadastrar" hide-nav-bar="false">
    <ion-header-bar>
        <h1 class="title">Escolha as Categorias</h1>
    </ion-header-bar>
    <ion-content>

        <div class="card">
            <div class="item item-text-wrap">
                Estão sendo listadas apenas as categorias existentes em sua localização.
            </div>
        </div>

        <div class="button-bar">
            <button class="button button-stable button-block  icon-left ion-android-funnel" ng-click="closeModal()">Aplicar Filtro</button>
        </div>

        <ion-list>
            <ion-checkbox ng-repeat="item in ofertass | unique:'categoria_comida_nome' track by $index" ng-model="filtro[$index]" ng-true-value="{{item}}" ng-false-value="" ng-checked="check">{{item.categoria_comida_nome}}</ion-checkbox>
        </ion-list>

        <div class="button-bar">
            <button class="button button-stable button-block  icon-left ion-android-funnel" ng-click="closeModal()">Aplicar Filtro</button>
        </div>


    </ion-content>
</ion-modal>

As in the image below, the result of the modal of the code:

inserir a descrição da imagem aqui

The sort and search, are working well.

But I’m not getting a way to filter the categories selected by the user.

For a better illustration, follows the Full view of my main listing which I want to filter the categories:

    <ion-view side="center" view-title="vovócooks">


    <!-- BOTÃO CARRINHO DE COMPRAS -->
    <ion-nav-buttons side="right" class="has-header">
        <a href="#/nhaac/carrinho" class="button button-clear button-icon icon ion-ios-cart"> {{total}} </a>

        <button class="button button-icon button-clear ion-ios-color-filter-outline" id="menu-popover" ng-click="popover.show($event)"></button>

    </ion-nav-buttons>

    <center>
        <div class="bar bar-subheader bar-assertive">
            <label class="item-input-wrapper textbox-search">
                <i class="icon ion-search placeholder-icon"></i>
                <input ng-model="q" placeholder="Procurar" aria-label="filter restaurantess" />
            </label>
        </div>
    </center>


    <div class="tabs-striped tabs-top tabs-background-assertive tabs-color-light">
        <div class="tabs" style="height:70px;">
            <a class="tab-item active" href="#/nhaac/promocoes">
                <i class="icon ion-home"></i> DELÍCIAS CASEIRAS
            </a>
            <a class="tab-item" href="#/nhaac/restaurantes">
                <i class="icon ion-star"></i> VOVÓS ONLINE
            </a>
        </div>
    </div>



    <div class="tabs-striped tabs-color-assertive" >
        <div class="tabs">
            <a class="tab-item active" ng-click="doRefresh()">
                <i class="icon ion-refresh"></i> Atualizar
            </a>

            <a ng-show="checarPermissoes('logado_usuario')" class="tab-item" href="#/nhaac/perfil">
                <i class="icon ion-person"></i> Meu Perfil
            </a>
        </div>
    </div>

    <ion-content delegate-handle="top" lazy-scroll id="page-promocoes" class="has-header page-promocoes">

        <ion-refresher pulling-text="Puxe para atualizar..." on-refresh="doRefresh()"></ion-refresher>


        <div class="list animate-fade-slide-in-right">

            <div class="spacer" style="width: 300px; height: 65px;"></div>

                <div class="card" >
                      <div class="item" style="white-space:normal;font-size:12px">
                          <center>
                          <b>Sua localização atual é: </b> {{endereco_atual}}
                          </center>
                        </div>  

                         <center>
                              <button class="button button-clear button-assertive" style="font-size:12px" ui-sref="nhaac.localiza">
                                  Mudar Localização
                              </button>
                          </center> 

                 </div>      

            <div class="button-bar">


                <!-- FILTRA POR... -->

                <!-- FILTRA POR... -->
                <button class="button button-stable button-block  icon-left ion-android-funnel" ng-click="abreModal()">
                    Filtrar
                </button>


                <!-- ORDENA POR PREÇO -->
                <button class="button button-stable button-block  icon-left ion-android-restaurant" modal-select="" ng-model="someModel" options="selectableNames" option-property="role" modal-title="Ordenar por..." has-search="true">Ordenar
                    <div class="option">
                        <h2>{{option.name}}</h2>
                    </div>
                </button>

            </div>



            <div class="card" ng-repeat="item in ofertass | filter:q | orderBy:someModel | unique: 'cadastra_oferta_cod_oferta'" ng-init="$last ? fireEvent() : null" href="#/nhaac/ofertas_singles/{{item.cadastra_oferta_cod_oferta}}">



                <div class="item item-thumbnail-top item-text-wrap">
                    <img class="imagemCapa" image-lazy-loader="lines" ng-src="{{item.cadastra_oferta_foto}}" />
                    <div class="promocao"><b>{{item.cadastra_oferta_desconto}}% Off</b></div>
                    <div class="desconto"><b>{{item.cadastra_oferta_valor_com_desconto | currency}}</b></div>

                    <div class="item">
                        <center>
                            <h2 style="white-space:normal; color:#D95B43;"><b>{{item.cadastra_oferta_titulo_promocao}}</b></h2>
                        </center>
                    </div>

                    <div class="spacer" style="width: 300px; height: 8px;"></div>

                    <h3><b>Vovó Cozinheira: </b>{{item.fornecedores_fantasia}}</h3>

                    <div ng-model="item.avaliacao_media">

                        <div ng-show="item.avaliacao_media">
                            <!--                            <h4>Avaliação Média:  {{item.avaliacao_media}} </h4> -->


                            <h4>Avaliação Média

                                <span class="stars alignleft">
                            <span ng-style="{ 'width': getStars(item.avaliacao_media) }">
                        </span></h4>



                        </div>





                        <div class="spacer" style="width: 300px; height: 8px;"></div>

                        <div class="item">
                            <h3>Categoria: {{item.categoria_comida_nome}}</h3>

                            <h3><small><b>Descrição: </b>{{item.cadastra_oferta_descricao}}</small></h3>

                            <h3>
                                Preço Normal: <s style="color:red;"><small class="preco"> {{item.cadastra_oferta_valor_sem_desconto | currency}}</small></s><br> Preço Promocional: <small class="preco"> {{item.cadastra_oferta_valor_com_desconto | currency}} </small><br> Preço do Frete: <small class="preco"> {{item.fornecedor_configura_frete_custo_padrao | currency}} </small>

                            </h3>


                        </div>
                    </div>
                </div>


                <a class="item button button-clear button-assertive ink" href="#nhaac/ofertas_singles/{{item.cadastra_oferta_cod_oferta}}"><b>PEDIR</b></a>
            </div>
        </div>


        <ion-list class="list">
            <ion-infinite-scroll ng-if="!noMoreItemsAvailable" on-infinite="onInfinite()" distance="5px" ng-if="hasMoreData"></ion-infinite-scroll>
        </ion-list>

        <ion-list class="list">
            <div class="item" ng-if="results.length == 0">
                <p>Nenhum resultado encontrado...</p>
            </div>
        </ion-list>


    </ion-content>
    <!-- ./content -->
</ion-view>

In my Controller, what trying filter through ng-clik the stretch is this:

// PEGA OS ITENS SELECIONADOS NA MODAL E COLOCA NUM ARRAY
    $scope.checkItems = {};

    $scope.print = function () {
        console.log($scope.checkItems);

    }

    // APLICANDO FILTRO CATEGORIA
//    $scope.userCategoria = function (checkItems) {
//        console.log("entra na chamada");
        //          $scope.userCategoria = $scope.checkItems(function(element) {
//        $scope.checkItems;

//        console.log("Imprime array");
//        console.log($scope.checkItems);
        //          };
        //            console.log("Imprime array");
        //          console.log($scope.userCategoria);
//        $scope.modal.hide();
//        var role = array
//        $state.go("nhaac.promocoes");
//    };

    $scope.save = function () {
        console.log("Chamou o save");
        var array = [];
        for (i in $scope.checkItems) {
            console.log($scope.checkItems[i]);
            if ($scope.checkItems[i] == true) {
                array.push(i);           

            }
        }
        console.log(array);

        $state.go("nhaac.promocoes");
    }


    // INICIA FILTRO POR CATEGORIA    
    $ionicModal.fromTemplateUrl('/templates/filters/side-filter.html', {
        scope: $scope,
        animation: 'slide-in-up'
    }).then(function (modal) {
        $scope.modal = modal;
    });
    $scope.abreModal = function () {
        $scope.modal.show();
    };
    $scope.closeModal = function () {
        $scope.modal.hide();


    };  

    // FIM FILTRO POR CATEGORIA

This one’s pretty messed up from all the tests I’ve done...

But you can see that I take the data, and store it locally separated by comma:

inserir a descrição da imagem aqui

That is to say, I am suffering with the turn (unawareness)...

Place | groupBy: 'mais_campo' makes a mistake.

I’m not getting this filter by categories, and I need help.

Or I need to change my logic? I don’t know if for lack of a better logic (or knowledge). I’d really appreciate it...

Well, to finalize, I make all my Main View Controller available:

    .controller("promocoesCtrl", function ($scope, $rootScope, $state, $ionicScrollDelegate, $http, $httpParamSerializer, $stateParams, $timeout, $ionicLoading, $ionicPopup, $ionicPopover, $ionicSlideBoxDelegate, $ionicHistory, ionicMaterialInk, ionicMaterialMotion, $ionicModal, sharedCartService, sharedFilterService) {

         $ionicHistory.nextViewOptions({
                disableBack: false,
                historyRoot: true
            });

//            $ionicHistory.clearCache();
//            $ionicHistory.clearHistory();


        //put cart after menu
        var cart = sharedCartService.cart;

        $scope.endereco_atual = window.localStorage.getItem("endereco_atual");

        if (window.localStorage.getItem("user_des") === undefined) {
            console.log("Usuário logado, setar como logado");



        } else {

            console.log("Usuário deslogado, setar como deslogado");
            var setar = "user_des";
            window.localStorage.setItem("user_des", setar)
        };


        $scope.getStars = function (avalia) {
            // Get the value
            var val = parseFloat(avalia);
            // Turn value into number/100
            var size = val / 6 * 100;
            return size + '%';
        }

        $scope.cadastra_oferta_cod_fornecedor = $stateParams.cadastra_oferta_cod_fornecedor;

        $scope.endereco_atual = window.localStorage.getItem("endereco_atual");


        // ORDENA POR...
        $scope.selectableNames = [

            {
                name: "Por preço: Do Menor para o Maior",
                role: "+cadastra_oferta_valor_com_desconto"
        },

            {
                name: "Por preço: Do Maior para o Menor",
                role: "-cadastra_oferta_valor_com_desconto"
        },

            {
                name: "Por Maior Desconto (%)",
                role: "-cadastra_oferta_desconto"
        },

            {
                name: "Menor Prazo de Entrega",
                role: "+fornecedor_configura_frete_prazo_entrega_min"
        },

            {
                name: "Maior Prazo de Entrega",
                role: "-fornecedor_configura_frete_prazo_entrega_min"
        },

            {
                name: "Oferta em Ordem Alfabética",
                role: "+cadastra_oferta_titulo_promocao"
        },

            {
                name: "Por Categoria",
                role: "+categoria_comida_nome"
        },



//        {
//            name: "Por Menor valor de Frete",
//            role: "+fornecedor_configura_frete_custo_padrao"
//        },

    ];


        $scope.getOpt = function (option) {
            return option.name + ":" + option.role;
            console.log(option);
            window.localstorage.setItem("OrdenaPor", option.role);
        };
        // FIM DE ORDENA POR

        $scope.filtro = [];

        //função utilizada no filter do ng-repeat
        $scope.devListFilter = function () {
            return $scope.devList.filter(function (item) {
                return $scope.filtro.indexOf(item.categoria_comida_nome) !== -1;
            });
        };
        $scope.pushNotificationChange = function () {
            console.log('Push Notification Change', $scope.pushNotification.checked);
        };

        $scope.pushNotification = {
            checked: true
        };
        $scope.emailNotification = 'Subscribed';

        $scope.save = function () {
            console.log("clicado");
            $state.go("nhaac.promocoes");
        };




        // PEGA OS ITENS SELECIONADOS NA MODAL E COLOCA NUM ARRAY
        $scope.checkItems = {};

        $scope.print = function () {
            console.log($scope.checkItems);
        }

        // APLICANDO FILTRO CATEGORIA
        //    $scope.userCategoria = function (checkItems) {
        //        console.log("entra na chamada");
        //          $scope.userCategoria = $scope.checkItems(function(element) {
        //        $scope.checkItems;

        //        console.log("Imprime array");
        //        console.log($scope.checkItems);
        //          };
        //            console.log("Imprime array");
        //          console.log($scope.userCategoria);
        //        $scope.modal.hide();
        //        var role = array
        //        $state.go("nhaac.promocoes");
        //    };

        //    $scope.save = function (item) {
        //        console.log("Chamou o save");
        //        var array = [];
        //        for (i in $scope.checkItems) {
        //            console.log($scope.checkItems[i]);
        //            if ($scope.checkItems[i] == true) {
        //                array.push(i);

        //            }
        //        }
        //        console.log(array);
        //        window.localStorage.setItem("q", array);
        //
        //        $scope.q = window.localStorage.getItem("q");
        //
        //        $scope.modal.hide();
        //    }


        // INICIA FILTRO POR CATEGORIA    
        $ionicModal.fromTemplateUrl('/templates/filters/side-filter.html', {
            scope: $scope,
            animation: 'slide-in-up'
        }).then(function (modal) {
            $scope.modal = modal;
        });
        $scope.abreModal = function () {
            $scope.modal.show();
        };
        $scope.closeModal = function () {
            $scope.modal.hide();


        };

        // FIM FILTRO POR CATEGORIA



        $rootScope.page_id = "promocoes";

        $scope.endereco_atual = window.localStorage.getItem("endereco_atual");


        $scope.scrollTop = function () {
            $ionicScrollDelegate.$getByHandle("top").scrollTop();
        };
        // open external browser 
        $scope.openURL = function ($url) {
            window.open($url, "_system", "location=yes");
        };
        // open AppBrowser
        $scope.openAppBrowser = function ($url) {
            window.open($url, "_blank", "closebuttoncaption=Done");
        };
        // open WebView
        $scope.openWebView = function ($url) {
            window.open($url, "_self");
        };

        // Set Motion
        $timeout(function () {
            ionicMaterialMotion.slideUp({
                selector: ".slide-up"
            });
        }, 300);


        var targetQuery = ""; //default param
        var raplaceWithQuery = "";
        // TODO: Dinamics Promoções

        $scope.endereco_atual = window.localStorage.getItem("endereco_atual");

        targetQuery = "json=promocao"; //default param
        raplaceWithQuery = "json=promocao";


        var fetch_per_scroll = 1;
        // animation loading 
        $ionicLoading.show({
            template: '<div class="loader"><svg class="circular"><circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/></svg></div>'
        });


        $scope.noMoreItemsAvailable = false; //readmore status
        var lastPush = 0;
        var data_ofertass = [];

        if (window.localStorage.getItem("data_ofertass") !== "undefined") {
            data_ofertass = JSON.parse(window.localStorage.getItem("data_ofertass"));
            if (data_ofertass !== null) {
                $scope.ofertass = [];
                for (lastPush = 0; lastPush < 10; lastPush++) {
                    if (angular.isObject(data_ofertass[lastPush])) {
                        $scope.ofertass.push(data_ofertass[lastPush]);
                    };
                }

                $timeout(function () {
                    $ionicLoading.hide();
                }, 500);


            }
        }
        if (!angular.isObject(data_ofertass)) {
            $timeout(function () {
                // retry retrieving data
                $http.get("http://vovocooks.com.br/admin/apis/api_listagem/lista_oferta_api.php?json=promocao".replace(targetQuery, raplaceWithQuery)).then(function (response) {
                    data_ofertass = response.data;
                    if (typeof (Storage) != "undefined") {
                        try {
                            window.localStorage.setItem("data_ofertass", JSON.stringify(data_ofertass));
                        } catch (e) {
                            window.localStorage.clear();
                            window.localStorage.setItem("data_ofertass", JSON.stringify(data_ofertass));
                            //         $ionicHistory.removeBackView();
                            //            $ionicHistory.clearCache();
                            //            $ionicHistory.clearHistory();

                            $state.reload();
                            $scope.$state = $state;
                        }
                    }
                    $scope.ofertass = [];
                    for (lastPush = 0; lastPush < 100; lastPush++) {
                        if (angular.isObject(data_ofertass[lastPush])) {
                            $scope.ofertass.push(data_ofertass[lastPush]);
                        };
                    }
                }, function (response) {
                    // error message
                    var alertPopup = $ionicPopup.alert({
                        title: "error " + response.status,
                        template: response.statusText + "<br/>problem: table ofertas",
                    });
                }).finally(function () {
                    $scope.$broadcast("scroll.refreshComplete");
                    // event done, hidden animation loading
                    $timeout(function () {
                        $ionicLoading.hide();
                    }, 1000);
                });

            }, 1000);
        }




        $scope.doRefresh = function () {
            // retry retrieving data
            //  window.localStorage.clear();
            $http.get("http://vovocooks.com.br/admin/apis/api_listagem/lista_oferta_api.php?json=promocao".replace(targetQuery, raplaceWithQuery)).then(function (response) {
                data_ofertass = response.data;
                if (typeof (Storage) != "undefined") {
                    try {
                        window.localStorage.setItem("data_ofertass", JSON.stringify(data_ofertass));
                    } catch (e) {
                        window.localStorage.clear();
                        window.localStorage.setItem("data_ofertass", JSON.stringify(data_ofertass));
                        //   $ionicHistory.removeBackView();
                        $ionicHistory.clearCache();
                        //    $ionicHistory.clearHistory();
                        $state.reload();
                        $scope.$state = $state;


                    }
                }
                $scope.ofertass = [];
                for (lastPush = 0; lastPush < 100; lastPush++) {
                    if (angular.isObject(data_ofertass[lastPush])) {
                        $scope.ofertass.push(data_ofertass[lastPush]);
                    };
                }
            }, function (response) {
                // error message
                var alertPopup = $ionicPopup.alert({
                    title: "error " + response.status,
                    template: response.statusText + "<br/>Problema: com a tabela de ofertas",
                });
            }).finally(function () {
                $scope.$broadcast("scroll.refreshComplete");
                // event done, hidden animation loading
                $timeout(function () {
                    $ionicLoading.hide();
                }, 500);
            });



        };


        if (data_ofertass === null) {
            data_ofertass = [];
        };

        //Coloca produto em destaque
        $scope.addToStar = function (id, image, name, price, supply_id, deliver) {

            console.log(id);
            console.log(name);
            console.log(price);
            console.log(supply_id);




        };


        //add to cart function
        $scope.addToCart = function (id, image, name, price, supply_id, deliver, entrega) {
            // CHAMA CART.ADD DE SERVICES 
            window.localStorage.setItem("fonecedor_carrinho", supply_id);
            window.localStorage.setItem("tipos_pagamentos", tipopag);
            window.localStorage.setItem("frete", deliver);
            window.localStorage.setItem("faz_entrega", entrega);
            cart.add(id, image, name, price, 1, supply_id, deliver);
            $state.go('nhaac.carrinho');

        };

        // animation readmore
        var fetchItems = function () {
            for (var z = 0; z < fetch_per_scroll; z++) {
                if (angular.isObject(data_ofertass[lastPush])) {
                    $scope.ofertass.push(data_ofertass[lastPush]);
                    lastPush++;
                } else {;
                    $scope.noMoreItemsAvailable = true;
                }
            }
            $scope.$broadcast("scroll.infiniteScrollComplete");
        };



        var tipo = '';

        // $scope.checarPermissoes();

        $scope.checarPermissoes = function (tipo) {
            var permitido;

            if (tipo === 'logado_usuario' && window.localStorage.getItem("user_log") !== null) {
                permitido = true;            
            } else {
                permitido = false;
            }

            return permitido;
        };




        // event readmore
        $scope.onInfinite = function () {
            $timeout(fetchItems, 500);
        };

        // create animation fade slide in right (ionic-material)
        $scope.fireEvent = function () {
            ionicMaterialMotion.fadeSlideInRight();
            ionicMaterialInk.displayEffect();
        };


        // animation ink (ionic-material)
        ionicMaterialInk.displayEffect();
        $scope.rating = {};
        $scope.rating.max = 5;
    })
  • 1

    To offer bonus you need to reach the 75 reputation points, here will appear an option below for you vvvvvv

  • Thanks @Math that this solution of mine is not what I want.

  • 1

    Just to illustrate: https://i.stack.Imgur.com/Ihvtf.png

1 answer

0


I made a solution WELL TABAJARA.

I took the | filter:q of the result.

I changed my Checkbox modal (It’s not ideal, nor what I wanted. The ideal was to select more than one category) for a Radio:

 <ion-modal-view  view-title="cadastrar" hide-nav-bar="false">
    <ion-header-bar>
        <h1 class="title">Escolha as Categorias</h1>
    </ion-header-bar>
    <ion-content>

        <div class="card">
            <div class="item item-text-wrap">
                Estão sendo listadas apenas as categorias existentes em sua localização.
            </div>
        </div>

       <div id="home-button-bar5" class="button-bar">
            <button id="home-button72" class="button button-assertive  button-block" ng-click="save()">Filtrar</button>

            <button id="home-button73" class="button button-balanced  button-block" ng-click="limpaFiltro()">Limpar</button>

            <button id="home-button74" class="button button-dark  button-block" ng-click="limpaFiltro()">Cancelar</button>

        </div>

        <ion-list>
            <ion-radio ng-repeat="item in ofertass | unique:'categoria_comida_nome'" ng-model="checkItems[item.categoria_comida_nome]" ng-change="print()" ng-value="item.categoria_comida_nome">{{item.categoria_comida_nome}}</ion-radio>

        </ion-list>


        <div id="home-button-bar5" class="button-bar">
            <button id="home-button72" class="button button-assertive  button-block" ng-click="save()">Filtrar</button>

            <button id="home-button73" class="button button-balanced  button-block" ng-click="limpaFiltro()">Limpar</button>

            <button id="home-button74" class="button button-dark  button-block" ng-click="limpaFiltro()">Cancelar</button>

        </div>

 <!--       <div class="button-bar">
            <button class="button button-stable button-block  icon-left ion-android-funnel" ng-click="save()">Aplicar Filtro</button>
        </div> -->



    </ion-content>
</ion-modal-view>

And in Controller it says these calls:

// APLICANDO FILTRO CATEGORIA
        $scope.userCategoria = function (checkItems) {
            console.log("entra na chamada");

            $scope.modal.hide();


        };

        $scope.save = function (checkItems) {
            console.log("Chamou o save");
            var array = [];
            for (i in $scope.checkItems) {
                console.log($scope.checkItems[i]);              
                if ($scope.checkItems[i] == true) {
                    array.push(i);

                }
            }
            console.log(array);

            window.localStorage.setItem("q",$scope.checkItems[i]);

            $scope.q = window.localStorage.getItem("q");

            $scope.modal.hide();
        }

        $scope.limpaFiltro = function(){

            var limpa = '';

            window.localStorage.setItem("q",limpa);

            $scope.q = window.localStorage.getItem("q");

            $scope.modal.hide();

            $scope.doRefresh();

        };

Ready! Tabajara pro MVP. Who knows in the future with the ideal solution.

But what? Gives me some solution to the true goal?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.