Search code examples
javascriptangularjsangularjs-scopeangular-ngmodelangularjs-ng-click

Apply $scope ng-click event to hidden element after it is displayed


Please ask me for better explanation. I have built a global search function into the header of my site. I want to display a separate input box for mobile search that uses the same ng-click event but the input isn't displayed when the page loads. I am having trouble getting the hidden input value on the mobile ng-click once it is displayed.

The areas of concentration are the search click function is not finding the correct ng-model when the function is triggered. I think it is because since the hidden elements are not available on load the ng-model="searchQueryStringMobile" isn't applied to the scope somehow.

My question is how do I get ng-model="searchQueryStringMobile" applied in the scope after it has been displayed posthumously or post-click ng-click="flipNav('search')" so that it does not return undefined when you activate the ng-click="loadSearchResults"?

Here is the code:

HTML:

<div ng-controller="HeaderCtrl as header" class="container">
    <div id="jesusSearchTop">
        <input ng-model="searchQueryString" class="jesusSearchInput autoCompSearch" type="search" placeholder="Search..." autocomplete="off" />
        <select ng-model="searchDDL.item" class="jesusSearchSelect" ng-options="item.name for item in searchDDL track by item.id"></select>
        <div class="jesusSearchHolder">
            <img class="goSearch" ng-model="jesusSearch" ng-click="loadSearchResults('norm')" src="/EMR4/img/gui_icons/searchIcon.png" alt="Search EMR" />
        </div>
    </div>
    <div id="siteControls">
        <div id="siteSearch" class="siteControl" ng-click="flipNav('search')"></div>    
    </div>
    <div ng-switch="dd" class="dropDown">
        <div ng-switch-when="none" style="display:none"></div>
        <div ng-switch-when="search" class="dropMenu listStyle4" id="Search">
            <input ng-model="searchQueryStringMobile" class="jesusSearchInput" type="text" placeholder="Search..." autocomplete="off" />
            <select ng-model="searchDDL.item" class="jesusSearchSelect" ng-options="item.name for item in searchDDL track by item.id"></select>
            <div class="jesusSearchHolder">
                <img class="goSearch" ng-model="jesusSearchMobile" ng-click="loadSearchResults('mob')" src="/EMR4/img/gui_icons/searchIcon.png" alt="Search EMR" />
            </div>
        </div>
    </div>
    <div class="clr"></div>
</div>

Controller:

app.controller('HeaderCtrl', function ($scope, $http, $location, populateDDL) {
            $http.get(badge.credentials[7].home+'data.JSON')
            .success(function(data, status, headers, config) {
                $scope.header = data.header;
                $scope.searchOptions = new populateDDL('tblWebMenuItems',badge.credentials[1].key).
                then(function(response) {
                    $scope.searchDDL = response.tblWebMenuItems
                    $scope.searchDDL.item = $scope.searchDDL[0];
                });
            })
            .error(function(data, status, headers, config) {
                console.log(data+', '+status+', '+headers+', '+config);
            });
            $scope.flipNav = function(choice){
                if ($scope.dd === choice) {
                    console.log(choice);
                    $scope.dd = "none";
                }else {
                    $scope.dd = choice;
                }
            };
            $scope.loadSearchResults = function(uv) {
                var loader;
                if (uv === "mob") {
                    loader = $scope.searchQueryStringMobile;
                }else if (uv === "norm") {
                    loader = $scope.searchQueryString;
                }
                console.log(uv+' - '+loader);
                if (loader == null || loader < 2) {
                    alert('Please refine your search and continue, Thank you!');
                }else {
                    $location.path("/search/"+$scope.searchDDL.item.name.toLowerCase()+"/");
                    $location.search("type",$scope.searchDDL.item.name.toLowerCase());
                    $location.search("query", loader);
                }
            };
        });

Solution

  • i have tested your code and found that it is because of the ng-switch.As ng-switch creates its own new scope which is child scope of its parent's, so if you use ng-model=$parent.searchQueryStringMobile , then it will work fine or If you use ng-show instead of ng-swtich ,it will work because ng-show doesnt create new child scope, it just sets the markup's css property display to noneand $parent allows you to access items of parent scope from child scope.In your example, $scope.searchQueryStringMobile is in the parent scope of ng-switch's scope. Here is the working plunk click

    you can change your ng-switch markup to this

    <div ng-switch="dd" class="dropDown" >
        <div ng-switch-when="none" style="display:none"></div>
        <div  ng-switch-when="search" class="dropMenu listStyle4" id="Search">
            <input ng-model="$parent.searchQueryStringMobile" class="jesusSearchInput" type="text" placeholder="Search..." autocomplete="off" />
            <select ng-model="searchDDL.item" class="jesusSearchSelect" ng-options="item.name for item in searchDDL track by item.id"></select>
            <div class="jesusSearchHolder">
                <img class="goSearch" ng-model="jesusSearchMobile" ng-click="loadSearchResults('mob')" src="/EMR4/img/gui_icons/searchIcon.png" alt="Search EMR" />
            </div>
        </div>
    </div>
    

    Notice the ng-model for the input element in the above code.