List.js - clickable links - javascript

My List.js implementation is creating what appear to be links but they're un-clickable. In the image I attached everything appears correct, however the link doesn't work even though when you hover it even underlines like a normal link would. What am I missing here?
I read somewhere that <li> items cannot be assigned href tags? If that is true then how does one get around that little issue?
Javascript:
<script>
var options = {
valueNames: [ 'title', 'description', 'lat', 'lng', 'user_sub', 'location', 'imageurl', 'final_url' ],
item: '<li id="my-list"><h3 class="title"></h3><p class="description"></p><p class="location"></p><p class="user_sub"></p><a class="final_url"></a></li>'
};
var values = JSON.parse('{{ jsonout|safe }}');
var userList = new List('places', options, values);
</script>
HTML:
<div id="places" class="container">
<input class="search" placeholder="Search" />
<button class="Find" data-sort="title">
Search
</button>
<button id="click_me" class="sort" data-sort="location">
Sort by State
</button>
<button id="click_me" class="sort" data-sort="title">
Sort by Name
</button>
<ul class="list"></ul>
</div>

Related

Setting div IDs to dynamic IDs using AngularJS

I am attempting to use Bootstrap accordion to allow a section of text to be expanded upon when a button is clicked. The data is being pulled from a JS file (Angular), however, I cannot seem to figure how how to set the div ID according to the JS file.
HTML:
<li ng-repeat="i in items | searchFor:searchString">
<img ng-src="{{i.image}}" />
<p>{{i.title}}</p>
<button type="button" class="btn btn-desc btn-lg pull-left" data-toggle="collapse" data-target="{{i.id}}">Expand Description/Output</button>
<div id="{{i.id}}" class="collapse">
<p>{{i.desc}}</p>
</div>
</li>
</ul>
Here is the JS:
$scope.items = [
{
id: '1',
url: 'http://google.com',
title: 'Google',
image: 'http://google.com/image.png',
desc: 'Information about Google'
},
{
id: '2',
url: 'http://duckduckgo.com',
title: 'Duck Duck Go',
image: 'http://duckduckgo.com/image.png'
desc: 'Information about Duck Duck Go'
},
I can display properly each entry for url, image, title, but the same application of the {{id}} or {{i.id}} does not seem to work in relation to data-target and div id. I have looked at other Stack items, but cannot seem to work back from them.
firstly:
In your list item you want searchFor to be filter
i.e.
<li ng-repeat="i in items | searchFor:searchString">
should be
<li ng-repeat="i in items | filter:searchText">
secondly:
You can't set an id to an integer, why not try using:
<img ng-src="{{i.image}}" />
This way you have a string which still has your id value. Although your scope sets the int values to string by default, the HTML will render the id as a int not a string, therefore you want to add text into your statement and that way it's more definitive and you avoid the problem of "why isn't my id working?"
Try setting $index of the repeater as the id
<button type="button" class="btn btn-desc btn-lg pull-left" data-toggle="collapse" data-target="{{$index}}">Expand Description/Output</button>
<div id="{{$index}}" class="collapse">

List.JS - Cannot read property 'childNodes' of undefined

I cannot seem to figure this out. I've already tried $(document).ready and still doesn't work for me. I've also tried making a for loop specifically for these two value names to save the results to a var and pass it in that way. I've also tried putting the input with the class and id with search inside of the parent div and outside. Essentially like it in the nav bar. Using list.js & knockout.js btw. Im getting my venues using an ajax request using foursquares api.
JS:
var options = {
valueNames: ['name', 'category']
};
var userList = new List('search', options);
HTML:
<body>
<nav>
<h1 class="formattedH1">Downtown SA,TX</h1>
<span>
<input type="search" placeholder="Search" class="search" id="search">
<input type="button" class="sort searchButton" value="List"></input>
</span>
</nav>
<div id="map" class="map"></div>
<div class="list">
<input type="search" placeholder="Search" class="search" id="search">
<h1>My Top 5</h1>
<!-- Square card -->
<div class="card" id="favViewModel" data-bind="foreach: favList">
<div class="expand">
<h2 class="venueName" data-bind="text:name"></h2>
</div>
<div class="cardSupport" data-bind="attr: {src: image()}">
</div>
<div class="cardSupport" data-bind="text:address">
</div>
<a data-bind="attr: {href: website()}">Website</a>
</div>
<h1>Foursquare Recommended</h1>
<div class="card" id="recViewModel" data-bind="foreach: recommendedSpotList ">
<div class="expand">
<h2 class="venueName" data-bind="text:name"></h2>
</div>
<div class="cardSupport" data-bind="text:location">
</div>
<div class="cardSupport" data-bind="text:category">
</div>
<div class="cardSupport" data-bind="text:rating">
</div>
</div>
<script src="js/tester123.js"></script>
I fixed the same problem with some comments on the github page of the project, just make sure to have the same names as the examples and it will work, everything must be in a <div> and the ul must have the class list
Like this
<div id="hacker-list">
<ul class="list"></ul>
</div>
Link: https://github.com/javve/list.js/issues/9
I found my answer browsing other similar projects, so simple now. Thought it might help someone in case they ran across this. It was that since I was making an ajax call I had to to place the call to ko.applybindings inside the ajax request. The binding was out of scope, if you think about it make's sense especially if your request fails. Why even attempt to still bind the values of the request. HTML as above, and for JS ajax request please see below:
JS:
$.ajax({
url: 'https://api.foursquare.com/v2/venues/explore',
dataType: 'json',
data: 'data',
async: true,
success: function(data) {
venues = data['response']['groups'][0]['items'];
//This is where I had to place the binding to get it to render properly.
ko.applyBindings(new recommendedViewModel(), document.getElementById('recViewModel'));
},
error: function() {
alert("An error occurred.");
}
});
"Hello World" example of this error.
Where?
https://listjs.com/api/#listClass
listClass String, default: "list" What is the class of the
list-container.
Case one (Missing list class):
/* error example */
var options = {
valueNames: [ 'name', 'born' ],
};
var userList = new List('users', options);
<!-- error example -->
<div id="users">
<input class="search" placeholder="Search" />
<button class="sort" data-sort="name">
Sort by name
</button>
<ul data-missing-list-class class="">
<li>
<h3 class="name">John</h3>
<p class="born">1986</p>
</li>
</ul>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
Case two (custom listClass missing):
I declare listClass to be no_such_class. The code trying to read childNodes of undefined.
/* error example */
var options = {
valueNames: [ 'name', 'born' ],
listClass: "no_such_class" /* the error */
};
var userList = new List('users', options);
<!-- error example -->
<div id="users">
<input class="search" placeholder="Search" />
<button class="sort" data-sort="name">
Sort by name
</button>
<ul class="list">
<li>
<h3 class="name">No such class</h3>
<p class="born">1986</p>
</li>
</ul>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
**the error will not throw under stackoverflow snippet
Extra
Remember to not confuse between:
id or element
Id the element in which the list area should be initialized. OR the
actual element itself.
new List(id/element, options, values);
VS:
listClass
What is the class of the list-container?

Click button to copy text to another div with angularjs

I have a list of Items with different button with them. Plunker
Quick View:
I want something like if I click on any of the buttons, related text will be copy to the div above. Also if I click on the button again it will removed from the Div.Same for each of the buttons. [I added manually one to show how it may display ]
I am not sure how to do that in Angular. Any help will be my life saver.
<div ng-repeat="item in csTagGrp">
<ul>
<li ng-repeat="value in item.csTags">
<div class="pull-left">
<button type="button" ng-class='{active: value.active && !value.old}' class="btn btn-default btn-xs">{{value.keys}}</button>
<span>=</span>
</div>
<div class="pull-left cs-tag-item-list">
<span>{{value.tags}}</span>
</div>
</li>
</ul>
</div>
The simplest thing would be to use $scope.tags object to store selected tags and add/remove them with the scope method similar to this:
$scope.tags = {};
$scope.toggleTag = function(tag) {
if (!$scope.tags[tag]) {
$scope.tags[tag] = true;
}
else {
delete $scope.tags[tag];
}
};
Demo: http://plnkr.co/edit/FrifyCrl0yP0T8l8XO4K?p=info
You can use ng-click to put in your scope the selected value, and then display this value instead of "Win".
http://plnkr.co/edit/IzwZFtRBfSiEcHGicc9l?p=preview
<div class="myboard">
<span>{{selected.tags}}</span>
</div>
...
<button type="button" ng-click="select(value)">{{value.keys}}</button>

Need input in another div! #listjs

Anyone in here familiar with LISTJS plugin? If so, I require your assistance.
Reffering to: http://codepen.io/javve/pen/zpuKF.
What I'm trying to achieve is NOT havin the search-input within the same div as the list.
I want the search-input in another div. Is this possible? If so, what do I do, I'm guessing I'm gonna have to edit the source code...?
To sum up - I wan't the input field in another div, not the "users" - as described below.
<div id="THIS IS WHERE I WANT MY INPUT FIELD"></div>
<div id="users">
<input class="search" placeholder="Search" />
<button class="sort" data-sort="name">
Sort by name
</button>
<ul class="list">
<li>
<h3 class="name">Jonny Stromberg</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Jonas Arnklint</h3>
<p class="born">1985</p>
</li>
<li>
<h3 class="name">Martina Elm</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Gustaf Lindqvist</h3>
<p class="born">1983</p>
</li>
</ul>
</div>
<script src="http://listjs.com/no-cdn/list.js"></script>
Probably you figured out a solution or you implemented the one above. I think that it's not OK to modify a plugin if you have alternatives. I had the same problem and I solved it by using the listObj.search from list.js documentation. The code will look something like this:
$("#searchInput").keyup(function () { // #searchInput is your input
var searchString = $(this).val(); // your searching string
searchList.search(searchString); // searchList is your new List
});
You can do it by editing the plugin, only some few lines of code to add some options to the plugin to make it accept sibling search input by id
First go to the init() method in the plugin to add some options and their default values, let say options.searchWithId which is a boolean that indicates if you want sible search input using an id and options.searchId which correspond to the Id of your search input:
// If not provided in the options it takes false by default
self.searchWithId = options.searchWithId || false;
// In case search input with id, initialise the id
self.searchWithId ? self.searchId = options.searchId || false : void 0;
After that you need to modify the input search object retrieval by adding those lines of code, just before the keyup event bind:
var searchInput = null;
if(list.searchWithId === false){
searchInput = getByClass(list.listContainer, list.searchClass);
}
else{
searchInput = $("#"+list.searchId);
}
And finally change the events binding like this:
events.bind(searchInput, 'keyup', function(e) {
var target = e.target || e.srcElement, // IE have srcElement
alreadyCleared = (target.value === "" && !list.searched);
if (!alreadyCleared) { // If oninput already have resetted the list, do nothing
searchMethod(target.value);
}
});
// Used to detect click on HTML5 clear button
events.bind(searchInput, 'input', function(e) {
var target = e.target || e.srcElement;
if (target.value === "") {
searchMethod('');
}
});
You can initialize your plugin this way:
var options = {
valueNames: [ 'name', 'born' ],
searchWithId: true,
searchId: "search-list"
};
var userList = new List('users', options);
and you put your search input where you want (outside, inside, ...)
<input id="search-list" class="search" placeholder="Search" />
<div id="users">
<button class="sort" data-sort="name">
Sort by name
</button>
<ul class="list">
<li>
<h3 class="name">Jonny Stromberg</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Jonas Arnklint</h3>
<p class="born">1985</p>
</li>
<li>
<h3 class="name">Martina Elm</h3>
<p class="born">1986</p>
</li>
<li>
<h3 class="name">Gustaf Lindqvist</h3>
<p class="born">1983</p>
</li>
</ul>
</div>
I tested it and it works, if you want the entire file just let me know.
Update
Fiddle demo
This cannot be done like that, otherwise it wont have relation with your code below, that's the reason why you had to include it in your (Div) users, is there any particular reason you trying to put it in a different (DIV)
Search and sort can be triggered via javascript.
Like For search, suppose search input id is mySearch
$('#mySearch').on('keyup', function() {
var searchString = $(this).val();
userList.search(searchString);
});
To search against specific column :
$('#mySearch').on('keyup', function() {
var searchString = $(this).val();
userList.search(searchString, ['user']);
});
Similarly for sorting use sort function :
$('#mySort').on('click',function() {
userList.sort('user',{
order: "desc"
})
});

How to filter a list in AngularJS using several links

I have been going over a lot of tutorials on how to filter a list and can't find an example for my simple use-case.
I have several buttons such as
Name
Age
Height
I have var persons = {...} object and I display it like
<div ng-repeat="person in persons">
{{person.name...}}
</div>
How do I create a filter so each time I will click on one of the buttons the list will be filtered ?
I have tried addingng-repeat="person in persons | filter:filterPersons"
and on the script side to write:
$scope.filterPersons(person){
if (person.name == "John")
return person;
}
but this is only one use-case (how can I filter by another name?) - in other words - How do I connect the links to the filter?
You can bind your filter to scope variables as you do with any other thing. So all you need is to set the appropriated filter to the scope when the user click and bind it to the ng-repeat filter param. See:
<div ng-app>
<span ng-click="myFilter = {type: 1}">Type 1</span> |
<span ng-click="myFilter = {type: 2}">Type 2</span> |
<span ng-click="myFilter = null">No filter</span>
<ul ng-controller="Test">
<li ng-repeat="person in persons | filter:myFilter">{{person.name}}</li>
</ul>
</div>
function Test($scope) {
$scope.persons = [{type: 1, name: 'Caio'}, {type:2, name: 'Ary'}, {type:1, name: 'Camila'}];
}
Notice that the myFilter is changed when the user clicks the filter, and that it's bound to the ng-repeat filter. Fiddle here. You could also create a new filter, but this solution is far better.
My response is very similar to Caio's. I just wanted to show how to filter out an existing array.
In my ng-repeat I have a search filter that goes through the words. I wanted tabs to look for a string match. So I added a additional filter
<tr class="unEditableDrinks" ng-repeat="drink in unEditableDrinkList | orderBy:'-date'|limitTo:400|filter:search |filter:myFilter">
<td>[[drink.name]]</td>
I only have the top part of my table but this should show the strategy. The second filter called myFilter is attached to the buttons below.
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" ng-click="myFilter={name:'soda'}">Soda</button>
</div>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" ng-click="myFilter={name:'energy'}">Energy Drinks</button>
</div>
On each button I am able to add a ng-click that goes through myFilter and searches the td with drink.name. In each ng-click I can set the value of name to search. So every title containing soda or energy can be filtered through.

Categories