I am trying to create a blog page and I chose WordPress over AngularJS so Google can index the page ( or at least that's what i think it works). So for now I have a list which looks like this
<ul>
<li id="1">
<h2>My first Post</h2>
<p>The Message...</p>
</li>
<li id="2">
<h2>My second Post</h2>
<p>The Message...</p>
</li>
<li id="3">
<h2>My third Post</h2>
<p>The Message...</p>
</li>
</ul>
but PHP is pretty static so I want to create a angular filter to filter posts by title, but I don't really know how to do this.
I was thinking to create a hide class for <li>
items and somehow if a post should be deleted because of the filter, to add the hide class to it. I try to mix this angular so I can have a dynamic search instad loading the page again after searching.
You could create a directive to wrap the html content you receive from php, pass the filter term and which element of the list you want to check).
Here is a plunker: http://plnkr.co/edit/Bv2opi5CHfJa0pQyFrBc?p=preview
(this require jquery to hide and show, but you can use css({'display':'none|block'}) too)
(maybe you could modify the directive to apply the filter term to ignore the case of the words)
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.model = {
filter: ''
};
});
app.directive('myHtmlFilter', [function() {
return {
restrict: 'A',
scope: {
filter: '=myHtmlFilter',
element: '@'
},
link: function(scope, elem, attrs) {
scope.$watch('filter', function(newval, oldval) {
elem
.find('ul>li')
.hide()
.find(scope.element)
.filter(':contains("'+scope.filter+'")')
.parent()
.show();
})
}
}
}]);
index.html
<input type="text" ng-model="model.filter" />
<div my-html-filter="model.filter" element="h2">
<ul>
<li id="1">
<h2>My first Post</h2>
<p>The Message...</p>
</li>
<li id="2">
<h2>My second Post</h2>
<p>The Message...</p>
</li>
<li id="3">
<h2>My third Post</h2>
<p>The Message...</p>
</li>
</ul>
</div>
Edit I updated the plunker with a more complete example than the code shown here.
If you can have the JSON approach, then Angular automatically does that for you.
Just go with a simple filter solution:
<input ng-model="criteria"/>
<ul>
<li ng-repeat="entry in entries | filter:{title: criteria}" id="{{entry.id}}">
<h2>{{entry.title}}</h2>
<p>{{entry.body}}</p>
</li>
</ul>
In your controller (or any JS with access to the container scope):
app.controller('MainCtrl', function($scope) {
$scope.criteria = "Title";
$scope.entries = [
{
id: 1,
title: 'My title',
body: 'contents...'
},
{
id: 2,
title: 'The other content',
body: 'contents...'
},
{
id: 3,
title: 'Another title',
body: 'contents...'
},
{
id: 4,
title: 'Something completely different',
body: 'contents...'
}
];
});
You can even use $http
service to retrieve the JSON file:
app.controller('MainCtrl', function($scope) {
$scope.criteria = "Title";
$scope.entries = $http.get('path/to/entries.json');
});
Considering you don't have a service that will return only the JSON formatted items, the best approach would be creating a directive that remove the li
, parse their contents to an object and use ng-repeat
in a template. Something like this:
var app = angular.module('plunker', []);
app.directive('filtered', function() {
return {
scope: {
criteria: '=filtered'
},
compile: function(elm, attr) {
var entries = [];
elm.find('li').each(function(index, item) {
var entry;
$item = angular.element(item);
entries.push({
id: $item.attr('id'),
title: $item.find('h2').text(),
body: $item.find('p').text()
});
}).remove();
elm.append(
'<li ng-repeat="entry in entries | filter:{title: criteria}" id={{entry.id}}>' +
'<h2>{{entry.title}}</h2>' +
'<p>{{entry.body}}</p>' +
'</li>'
);
return function(scope) {
scope.entries = entries;
};
}
};
});
And in your HTML you just decorate the list with the directive:
<input ng-model="userCriteria">
<ul filtered="userCriteria">
<li id="1">
<h2>My first Post</h2>
<p>The Message...</p>
</li>
<li id="2">
<h2>My second Post</h2>
<p>The Message 2...</p>
</li>
<li id="3">
<h2>My third Post</h2>
<p>The Message 3...</p>
</li>
</ul>
I've put together a Plnkr here. Go ahead and change the HTML list and it will automatically include that items.