Table Sorting with Javascript - javascript

I'm working on a table with filtering, I can get it to kind of function in fiddle but when I pop it back into DW and test the page it loses functionality. I have tried with the script on the page and inserted into the page, I'm at a loss of where to turn next so any help will be appreciated. I realize it's not complete and all the checkboxes arent set up properly but I really want to know (at this point) is why I lose functionality in dreamweaver - Correction when I test in a browser through Dreamweaver,I've also uploaded to a test server and still no functionality.
fiddle
$("input[name='filterStatus'], select.filter").change(function () {
var classes = [];
var stateClass = ""
$("input[name='filterStatus']").each(function() {
if ($(this).is(":checked")) {
classes.push('.'+$(this).val());
}
});
$("select.filter").each(function() {
if ($(this).val() != 'ZZ') {
stateClass += "." + $(this).val();
}
});
if (classes == "" && stateClass == "") {
// if no filters selected, show all items
$("#StatusTable tbody tr").show();
} else {
// otherwise, hide everything...
$("#StatusTable tbody tr").hide();
// then show only the matching items
rows = $("#StatusTable tr" + stateClass).filter(classes.length ? classes.join(',') : '*');
if (rows.size() > 0) {
rows.show();
}
}

I am sure JTable will solve your problem.
You need to pass the data in the given example's format and it will allow to filter, search and paginate the data.
http://jtable.org/GettingStarted

Related

Adding to local storage only working after refreshing the page after button navigation to another page

I am developing an app that allows user to search for fishing lakes in their area. To do this they can type in their location which then displays fisheries near them that i have identified in the Json data. The search works perfectly with the code below i have written (i know it maybe a little flaky as i am not the best programmer).
//search
$(document).ready(function(){
$('#exampleSearch').keyup(function() {
var searchVal = $('#exampleSearch').val();
$('#results').empty();
console.log(searchVal);
var results = [];
$.getJSON("/data/locations.json",function(locations) {
for (var i = 0; i < locations.length; i++) {
if (locations[i].location.match(searchVal)) {
results.push(locations[i]);
}
}
$.each(results, function(index,result) {
var $resultsLi = $(
'<div class="row">'+
'<div class="twelve columns profile-information ">'+
'<div class="profile-title">'+
'<h6>'+result.name+'</h6>'+
'</div> ' +
' <img class= "favourites-pic" src="'+ result.image +'" alt="Fishery">'+
'<a class="view" href="'+ result.url + '" >View</a>'+
'</div>'+
' </div>'
)
$("#results").append($resultsLi);
});
});
});
});
I have now added a feature where users can now add their search results to their favourites page, by click a Add to favorites button on the page of the fishery they found from their search with the following code:
Javascript:
//Add to Favourites
$(function() {
$( ".addFavourites" ).on("click", function() {
try {
$(this).attr('disabled', true);
var locIdToAdd = $(this).closest("p").attr("id");
var myFavouriteLoc=JSON.parse(localStorage.getItem("favLoc"));
if (myFavouriteLoc == null) {
myFavouriteLoc = [];
}
if (myFavouriteLoc != null) {
for ( var j = 0; j < myFavouriteLoc.length; j++) {
if ( locIdToAdd == myFavouriteLoc[j]) {
alert("This property is already in your favourites");
myFavouriteLoc = [];
}
}
}
myFavouriteLoc.push(locIdToAdd);
localStorage.setItem("favLoc", JSON.stringify(myFavouriteLoc));
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
console.log("Error: Local storage limit exceeds");
} else {
console.log("ERROR: Saving to local storge.");
}
}
});
});
Html:
<p id="loc 1">
<input class="button-primary green addFavourites" type="submit" value="Add to Favourites">
</p>
THE PROBLEM
Upon clicking the 'view' button on the search page results, and navigating to a fishery page. I have a problem where i have to then refresh the page again before the add to favourites button will add anything to the local storage, it is clickable, but nothing happens. once i refresh the page it works fine.
Can anyone help with why i have to refresh the page first? any help is a appreciated :)
Try this jquery code to add favorites, it should work on each click:
$( document ).on("click", ".addFavourites", function(e) {
e.preventDefault();
try {
$(this).attr('disabled', true);
var locIdToAdd = $(this).closest("p").attr("id");
var myFavouriteLoc=JSON.parse(localStorage.getItem("favLoc"));
if (myFavouriteLoc == null) {
myFavouriteLoc = [];
}
if (myFavouriteLoc != null) {
for ( var j = 0; j < myFavouriteLoc.length; j++) {
if ( locIdToAdd == myFavouriteLoc[j]) {
alert("This property is already in your favourites");
myFavouriteLoc = [];
}
}
}
myFavouriteLoc.push(locIdToAdd);
localStorage.setItem("favLoc", JSON.stringify(myFavouriteLoc));
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
console.log("Error: Local storage limit exceeds");
} else {
console.log("ERROR: Saving to local storge.");
}
}
});
Just make sure you are not putting this jquery function inside $(document).ready(function(){}) or $(function(){}) because it is not required
I can't see any code relating to loading the list of favourites, but I think it's fair to assume to that when the page loads you're loading the items from storage and placing them in, and then the pages where you add favourites and view favourites don't involve any loading between them. Therefore, of course, loading the items for the favourites list will only be performed on load, and so placing new items into the localStorage without reloading will not add them. So I'm going to cover a few things.
Firstly, don't use == and !=. They perform type coercion, (numbers to strings, strings to numbers, null to undefined, etc.), the rules for which are unintuitive and unmemorable and are best simply avoided, lest they cause difficult to diagnose problems in your code. Use === and !== instead, these behave just like == and != does in other languages. If you want to perform type coercion I'd do so explicitly (e.g. Number('5')).
Secondly, and just as a suggestion, if you implement the local storage as an object, you won't need to loop and can simply use property names. So you can replace
if (myFavouriteLoc != null) {
for ( var j = 0; j < myFavouriteLoc.length; j++) {
if ( locIdToAdd == myFavouriteLoc[j]) {
With simply
if (myFavouriteLoc && myFavouriteLoc[locIdToAdd]) {
// ...
}
The object && object.property idiom will perform a truthy check on both the object and the property, only passing if they are both truthy (not falsy). Here's a list of falsy values.
So, to answer your actual question. I'd say you have two options:
Reload the page on each addition, or
AJAXily add the entry to your views when favourites are added. Favourites will then, of course, need be removed
Going with my assumption in the first paragraph, I'd say that the second option is your best bet, as the constant page refreshes would provide a bad user experience.
So here's the jsfiddle
(function bindBtns() {
$('.Table-btn--add').click(function () {
addBinding($(this));
});
$('.Table-btn--remove').click(function () {
removeBinding($(this));
});
})();
Here is an immediately invoked function, meaning it's run straight away. This will bind the existing buttons' behaviour, depending on whether they are add or remove buttons.
function addBinding($btn) {
$btn.parent()
.detach()
.appendTo($('#favourites'));
// add to local storage here
modifyAttributes($btn);
}
Here's the behaviour for the binding, fairly straight forward, but:
Select the buttons parent, i.e. the row
Detach it from the DOM, i.e. the current table
Attach it to the other table
Rebind the button to perform the opposite behaviour, shown below
Place your behaviour for adding or removing from local storage where I've placed the comments.
removeBinding is exactly the same except it appends to the other table.
function modifyAttributes($btn) {
if ($btn.hasClass('Table-btn--add')) {
$btn.text('Remove')
.removeClass('Table-btn--add')
.addClass('Table-btn--remove')
.off('click')
.click(removeBinding.bind(null, $btn));
} else if ($btn.hasClass('Table-btn--remove')) {
$btn.text('Add')
.removeClass('Table-btn--remove')
.addClass('Table-btn--add')
.off('click')
.click(addBinding.bind(null, $btn));
}
}
Split on whether this is an adding button, or a removing button. (The next steps will be for both versions.)
Update the text to be the opposite, (add -> remove, remove -> add)
Remove the current class
Add the new class
Remove the old click binding
Bind the new click binding. Read about .bind here
In your version you would replace .Table-btn--add with .addFavourites, and place addBinding($(this)) in your try block, and then you can just copy over the other functiona verbatim (I think).
Good luck! Sorry that got so long, and let me know how it goes.

Parent siblings not showing after hiding/showing

I have a simple in-page search function which shows only topics which contain words searched for.
Each section has a heading, a <h2> - I want the headings for the blocks which are not hidden, to show.
The problem: The h2 header does not always show after the search
This is a fiddle to test the issue
Fail/success examples:
One of the headings is Complaints and cancellations - sub section titled: How do I cancel
If you search for how do then you'll see the first block show, with header... the second block titled Guides disappears. This is correct.
If you search for I cancel - again, the second block disappears, which is correct, but, the heading for the first block hides too, which it shouldn't.
This is the javascript:
$("#faq_search").on("input", function () {
var v = $(this).val().toLowerCase();
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v != "" && eachPlace.search(v) == -1) {
$(this).parent().parent().parent().siblings('h2').hide();
$(this).fadeOut();
} else {
$(this).fadeIn('fast', function(){
$(this).parent().parent().parent().siblings('h2').show();
});
}
});
});
Is there a better way to do this?
The problem is that a hide of the h2 can occur after a show for the same section, depending on the order of matches in the section.
The quick solution is to do all the hides first, then the shows:
$("#faq_search").on("input", function () {
var v = $(this).val().toLowerCase();
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v != "" && eachPlace.search(v) == -1) {
$(this).closest('.vc_tta').siblings('h2').hide();
$(this).fadeOut();
}
});
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v == "" || eachPlace.search(v) > -1) {
$(this).fadeIn('fast', function(){
$(this).closest('.vc_tta').siblings('h2').show();
});
}
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/L0m3z98y/2/
Notes:
parent().parent().parent() is a not a maintainable solution. Any change to the DOM structure will break the code. Instead use closest() with an appropriate target selector. This is shorter and safer

if this input has value doesn't work in IE 9

I am using this simple code to filter through a search form with many text inputs and see if they have a value and then add a class.
Works perfectly in Chrome, safari and Firefox but not in IE9.
$('input[type="text"]').filter(function() {
if ($(this).val() !== '') {
$(this).addClass('used');
}
});
Please advice, thanks in advance!
EDIT
Change to each but doesn't solve the issue... Here it is with the event that triggers the function...
$(document).on('event-ajax-form-is-loaded', function() {
$('input[type="text"]').each(function() {
if ($(this).val() !== '') {
$(this).addClass('used');
}
});
});
From the limited information you shared, this is how you should be doing this:
$('input[type="text"]').filter(function() {
return $(this).val() !== '';
}).addClass('used');
.filter() is supposed to reduce a set of matched elements so its filter function should always return a bool instead of manipulating the DOM.
Edit: Based on your updated code snippet and the page link you shared in the comments, if you are using jQuery in WordPress, then its always safer to wrap the code like so:
(function($) {
/* jQuery Code using $ object */
})(jQuery);
enter code hereIn JS you can check the element value by getting their tag name
for (var i = 0; i < document.getElementsByTagName('input').length; i++){
if (document.getElementsByTagName('input')[i].value == "")
{
alert("The value of textbox at " + i + " is empty");
}
}
Working Demo
Or like what other people suggest, use a .each in JQuery
$('input[type="text"]').each(function(i){
if ($(this).val() == "") {
alert("The value of textbox at " + i + " is empty");
}
});
anohter Working Demo
If you insist to use filter and here you go
$('input[type="text"]').filter(function()
{ return $( this ).val() != ""; }).addClass("used");
Last Working Demo
and jquery filter reference

Header is not highlighted in type to filter

I am using a type to filter textbox,where in yser type the data they want to highlight. The data entered in the textbox is then checked against the row in html table.
Row containing the typed data is shown and other rows are hidden.
My problem is that this works as expected but the trouble is that it hides the header.Is there any way that it shows the header along with the highlighted row?
Below is the Script I am using :
function Search() {
var value = $('input[id$="txtSearch"]').val();
if (value) {
$('#table-2 tr:not(:first:hidden)').each(function () {
var index = -1;
//$(this).children('td.hiddencls').each(function () {
$(this).children('td').each(function () {
var text = $(this).text();
if (text.toLowerCase().indexOf(value.toLowerCase()) != -1) {
index = 0;
return false;
}
});
if (index == 0) {
$(this).show();
}
else {
$(this).hide();
}
});
}
else
$('#table-2 tr').show();
}
Kindly provide your valuable suggestions..
Putting this at the end of the Search() definition should work
$('#table-2 tr>th').parent().show();
(I'm assuming the header row has th tags, instead of td)
Otherwise try this
$('#table-2 tr:first').show();

How to check all text boxes are empty before clicking calculate

Hi all im new to jscipt,,, well, programming in general to be honest, but learning slowly for personal use.
I seek guidence on how i could place all the textboxes(inputs) in my index file into a list container, loop through them to check if they are empty or not before clicking the calculate button. If they are empty then inform the user of which one is empty.
Also, is there a way of preventing users from entering text into the textboxes and numbers only.
Background: im creating a form that requires all fields to be populate with numbers(in hours), a graph will then be generated from those values.
ive placed the file in skydrive for folks to download with the link below.
Index file
I did try the following but this alerts me regardless of weather the texboxes are populate or not.
function checkInputsGenerateGraph()
{
if( $('#hutz-hoursInput').val() == ""||$('#hutz-weeksPerYearInput').val() == ""||$('#hutz-jobsPerWeekInput').val() == ""||$('#hutz-hourlyMachineRateInput').val() == ""||$('#hutz-maintneneceDowntimeInput').val() == ""||$('#hutz-scrapRateInput').val() == ""||$('#hutz-toolsPerJobInput').val() == ""||$('#hutz-timeToLoadToolInput').val() == ""||$('#hutz-timeToSetPartsInput').val() == "")
{
alert('One them is empty!!');
}
else
{
$("#hutz-graph").slideDown();
$("#hutz-lblImproveMyProcess").slideUp();
$("#hutz-hoursInput").slideUp();
$("#hutz-weeksPerYearInput").slideUp();
$("#hutz-jobsPerWeekInput").slideUp();
$("#hutz-ourlyMachineRateInput").slideUp();
$("#hutz-ntneneceDowntimeInput").slideUp();
$("#hutz-scrapRateInput").slideUp();
$("#hutz-toolsPerJobInput").slideUp();
$("#hutz-timeToLoadToolInput").slideUp();
$("#hutz-timeToSetPartsInput").slideUp();
$("#hutz-lblMachineDetails").slideUp();
$("#hutz-lblPartSetting").slideUp();
$("#hutzcurrencyPreferenceInput").slideUp();
createChart();
}
}
First off, give all the required elements a common class, for examples sake we'll call this required:
<input type="text" class="required" id="hutz-hoursInput" />
Then, when your checkInputsGenerateGraph() function is called, you can loop over the required elements and check them:
$('.required').each(function() {
if (this.value.length == 0) {
alert(this.id + ' is empty!');
}
});
You could also do something like the following to remove all non-digits from your inputs:
$('.required').change(function() {
this.value = this.value.replace(/[^\d]+/, '');
});
See it in action
Hope that points you in the right direction!
edit
Here's a complete example:-
function checkInputsGenerateGraph() {
var isValid = true;
$('.example').each(function() {
if (this.value.length == 0) {
alert(this.id + ' is empty!');
isValid = false;
}
});
if (isValid) {
alert('do calculations!');
}
}
So, loop over all of the elements first, and make sure they are all populated. If not, set isValid to false so that once the loop completes, the calculations are not performed.

Categories