Add a second function to this jquery? - javascript

The following jQuery function filters my table columns by letter. There is an <a> for each letter. I'm not sure how to add another function though to filter column 1 using a different dropdown on the html side.
JavaScript:
function fil(rexp)
{
$('#tablestyle').dataTable().fnFilter(rexp, 0, true, false);
}
HTML:
<div style="float:left;" class="sortalpha">
ALL
| A
| B
<!-- [...] -->
| Z
</div>
What I have tried to do is copy the top part and change fil to fil2 then copy the HTML part and change those to fil2. Is that the correct way?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Just to give everyone a bit more info, I am using datatables {www.datatables.net} which is a jquery script that presents tables in a nice looking ui with various differnt functions to it like search, filter records per page etc.
I have implemented this mod that someone has listed here >> http://www.datatables.net/forums/discussion/6641/filtering-with-first-letter/p1
It works fine and when I select each letter it filters column 0 using whatever letter I have clicked on. What I am trying to do is have two different filters, one to filter column 0 which is the name of the person, and also another filter that does exaclty the same thing, but for column 1 which is business name, I just wasnt sure how to add the same piece of code twice?.

I don't really know your context, but I would suggest you try using event handlers instead of JavaScript URLs.
So instead of this:
ALL
You could do this:
$('.sortalpha a').on('click', function() {
fil('');
});
Of course, this would make all links filter on ''. To fix that, you could get the text from the <a> that was clicked and use that to call fil(), like so:
function fil(rexp) {
if (rexp.length > 0) {
rexp = '^' + rexp;
}
//$('#tablestyle').dataTable().fnFilter(rexp, 0, true, false);
alert('Filter on: "' + rexp + '"');
}
$('.sortalpha a').on('click', function(event) {
var letter = $(this).text().toLowerCase();
if (letter === 'all') {
fil('');
} else {
fil(letter);
}
});
Here's a working example: http://jsfiddle.net/uzGat/2/
Edit: I updated the answer to account for capital letter and the ^ in the regular expressions.

if the plugin is well written, it must maintain chainbilty so you can do like:
function fil(rexp)
{
$('#tablestyle').dataTable().fnFilter(rexp, 0, true, false).fnFilter(rexp2, 0, true, false);
}

Related

How to write a neat JS if else statement to dynamically add a nested Rails simple_form via Cocoon?

I am building a nested simple_form_for in rails using cocoon to dynamically add and remove nested elements. The main model object is a quote and a quote has many employees. I've reached the limit of my amateur code skills and would like some guidance on writing a neat js script so to achieve the following:
if nested_object.count <= 2 then remove_empee_link.hide
if nested_object.count > 2 then remove_empee_link.show, but not on the first two nested_objects.
if nested_object.count > 10 then add_empee_link.hide, otherwise always add_empee_link.show
Adapted from a really helpful post here courtesy of #nathanvda I've got to here;
$(document).ready(function() {
function check_to_hide_or_show_add_empee_link() {
if ($('#empee-form .nested-fields:visible').length == 5) {
$('#empee-form .links a').hide();
} else {
$('#empee-form .links a').show();
}
}
$('#empee-form').on('cocoon:after-insert', function() {
check_to_hide_or_show_add_empee_link();
});
$('#empee-form').on('cocoon:after-remove', function() {
check_to_hide_or_show_add_empee_link();
});
check_to_hide_or_show_add_empee_link();
});
$(document).ready(function() {
function check_to_hide_or_show_remove_empee_link() {
if ($('#empee-form .nested-fields:visible').length <= 2) {
$('.remove_fields').hide();
} else {
$('.remove_fields').show();
}
}
$('#empee-form').on('cocoon:after-insert', function() {
check_to_hide_or_show_remove_empee_link();
});
$('#empee-form').on('cocoon:after-remove', function() {
check_to_hide_or_show_add_remove_empee_link();
});
check_to_hide_or_show_add_remove_empee_link();
});
But I'm struggling to put a strategy together on how I can I achieve what I outlined in my biullets above in a neat solution, any guidance would be really appreciated after starting and playing with this for hours. Thanks
The updated code that I've now written, but the behavior is unexpected;
If 1, 2 or 3 nested elements on page, then all remove_links hidden.
If 4 nested elements on page then 1st, 2nd & 4th have remove_link hidden
If 5 nested elements on page then 1st, 2nd & 3rd have remove_link hidden
Intended behaviour, 1st and 2nd remove_links hidden always, anoy others shown:
// Hiding the 1st 'remove employee' link for the first two employee fields.
$(document).ready(function() {
function hide_first_and_second_remove_empee_links() {
var remove_links = $('.remove_fields')
$(remove_links[0]).hide();
$(remove_links[1]).hide();
// $('a.remove_fields:first-child').hide();
// $('a.remove_fields:nth-child(2)').hide();
}
$('#empee-form').on('cocoon:after-insert', function() {
hide_first_and_second_remove_empee_links();
});
$('#empee-form').on('cocoon:before-insert', function() {
hide_first_and_second_remove_empee_links();
});
hide_first_and_second_remove_empee_links();
});
How can this be? There's one method, it collects all .remove_fields' into the remove_links var, then wraps the[0]element of that collection in a jQuery object and callshideon it. Then the same to the1element. That method is called on page ready and then again oncocoon:before-insertandafter-insert. I don't see how the definition of the[0]and the1` elements changes?
Your logic becomes easier when you write:
always hide the first two remove links
hide the add association link if there are more than 10 employees
The second is already covered in your answer.
The first one is actually pretty easy using jquery:
$('.remove-fields:first-child').hide()
$('.remove-fields:nth-child(2)').hide()

hide/display filter for tablesorter

I d like to be able to hide/display the filters while using tablesorter.
Using table sorter just went fine but when i added a button to execute :
function display_hide_filter() {
var filters = document.getElementsByClassName('tablesorter-filter-row');
for (var i = 0; i < filters.length; i++) {
var filter = filters[i];
if (filter.style.display == 'none') {
filter.style.display='inline';
} else {
filter.style.display='none';
}
}
}
I then get a weird answer. Hiding the filter is fine but re displaying turn into having all filter cells under the first header cell.
Since i got poor english and css/js skills, I just hope I didnt miss something about it in the documentation but i tried to get trough it a thousant times with no success.
Thanks for any help
There is a filter_hideFilters option that minimizes the filter row until the user hovers over it. It is also accessible friendly in that the user can use the tab key gain access the filter inputs (demo).
If you just want to hide/show the filter row, then this basic code would work (demo):
HTML
<button type="button">Toggle Filter Row</button>
Script
$(function () {
$('table').tablesorter({
theme: 'blue',
widthFixed: true,
widgets: ['zebra', 'filter']
});
$('button').click(function(){
$('.tablesorter-filter-row').toggle();
});
});
As Andreas pointed out, I used 'inline' where i should have used ''

Split values from table into different text inputs?

I have a table that is populated by user input. For example, there is a text input for First Name, and Last Name. John in one input and Smith in the next, will add the the table under the Name column as John Smith, one string of 2 values. This is working correctly, along with the Address column... but getting the values FROM the table TO the inputs is the issue. Clicking the corresponding row populates the inputs, but I need to split these values to populate the correct inputs (so that John Smith is split up again to first and last name for example). Any ideas? Thanks in advance.
http://jsfiddle.net/Z85QC/6/
jQuery
/* Add a click handler to the rows - this could be used as a callback */
$("#example tbody tr").click(function (e) {
if ($(this).hasClass('rowSelected')) {
$(this).removeClass('rowSelected');
} else {
oTable.$('tr.rowSelected').removeClass('rowSelected');
$(this).addClass('rowSelected');
}
var properties; // all td from .row_selected
properties = fnGetSelected(oTable).find("td");
$("#fName").val(properties.eq(0).text());
$("#email").val(properties.eq(1).text());
$("#company").val(properties.eq(2).text());
});
I advise you to wrap your data row elements in span with corresponding class names. Example given for first name and last name,
js
$('#addRow').click(function () {
var row =$('#example').dataTable().fnAddData([
'<span class="fname">'+$("#fName").val()+'</span> <span class="lname">' + $("#lName").val()+'</span>',
$("#email").val(),
html of the fiddle
<td><span class='fname'>John</span> <span class='lname'>Smith</span></td>
Then it is straighforward and clear to retrieve the values independent from their textual format.
http://jsfiddle.net/Z85QC/10/
In the fiddle you will also find code for associating click function logic to new added rows so that they can be selected.
$('#addRow').click(function () {
var row =$('#example').dataTable().fnAddData([
'<span class="fname">'+$("#fName").val()+'</span> <span class="lname">' + $("#lName").val()+'</span>',
$("#email").val(),
$("#company").val() + '<br>' + $('#address').val()]);
$(oTable.fnGetNodes(row)).click( function( e ) {
if ($(this).hasClass('rowSelected')) {
$(this).removeClass('rowSelected');
} else {
oTable.$('tr.rowSelected').removeClass('rowSelected');
$(this).addClass('rowSelected');
}
var properties; // all td from .row_selected
properties = fnGetSelected(oTable).find("td");
$("#fName").val(properties.eq(0).find('.fname').text());
$("#lName").val(properties.eq(0).find('.lname').text());
$("#email").val(properties.eq(1).text());
$("#company").val(properties.eq(2).text());
});
In order to keep your code DRY it is best to place the click function logic inside a function and call that directly, instead of copying the code.
If you are 100% sure that the last name and first name are seperated by a space, you can use this code :
$("#fName").val(properties.eq(0).text().split(' ')[0]);
$("#lName").val(properties.eq(0).text().split(' ')[1]);
For address :
$("#company").val(properties.eq(2).html().split('<br>')[0].trim());
$("#address").val(properties.eq(2).html().split('<br>').splice(1).join('\n').trim());
Fiddle : http://jsfiddle.net/Z85QC/11/
You can do a simple change like:
var properties; // all td from .row_selected
properties = fnGetSelected(oTable).find("td");
var names = properties.eq(0).text().split(' ');
$("#fName").val(names[0]);
$("#lName").val(names[1]);
$("#email").val(properties.eq(1).text());
$("#company").val(properties.eq(2).text());
JSFiddle Demo
But only if you're sure the First and Last name are separated by a constant single space, otherwise you'd have to change it a little bit more...

jQuery, selecting just number from id like "article-23"

All right, I have a div tag which got a class="blog-post" and id like id="article-23" (where "23" could be any number, as it is id of blog post in a database). I need to somehow get just a number from that id and than apply some rules to that div tag. So say:
if number from id % 2 == 0 {
set text colour black to associated div tag with class of blog-post
} else {
set text colour white to associated div tag with class of blog-post
}
Thats just a "pseudo" code to show logic that I wan't to apply dependent if number from id is even or odd, but the question remains same, how do I just get number from id like "article-23" ?
As simple as
var number = "article-23".match(/\d+/)[0];
But you have to be sure that any digit exists in the string, otherwise you'd get a error.
You can actually apply rules via function, which makes this the cleanest solution (in my opinion):
$(".blog-post").css('color', function () {
return +this.id.replace('article-', '') % 2 ? 'blue' : 'red';
});
http://jsfiddle.net/ExplosionPIlls/Jrc5u/
Try this:
$('.blog-post[id^="article-"]').each(function () {
if (parseInt(this.id.replace('article-', '')) % 2 === 0) {
$('#' + this.id).css('color', 'black');
} else {
$('#' + this.id).css('color', 'white');
}
});
jsFiddle Demo
As an alternative, HTML5 supports these things called "data attributes", which are specifically meant for attaching data to your DOM without abusing things like the "class" or "id" attributes. jQuery provides a handy .data method for reading these attributes in a more obvious way.
You can add your own numeric ID attribute using something like "data-id":
<div class="blog-post" data-id="23" />
$("#blog-post").each(function () {
console.log($(this).data("id")); // Look up the data-id attribute
});
If I'm understanding correctly, you want the number after the hyphen of the id tag of your .blog-post class.
var article = $(".blog-post").attr('id'); //get the id
var article = article.split("-"); // split it on hyphens
return article = article[article.length-1]; // return the last element

Jquery Isotope Checkbox filtering

I'm using jQuery isotope. Everything is ok but I have problem with filtering. I want to use multiple categories I have 5 checkboxes and I can't use them at the same time. What can I do?
$("#classic").click(function() {
if($("#classic").is(":checked")) {
$('#box').isotope({ filter: '.classic' });
} else {
$('#box').isotope({ filter: '' });
}
});
Example
my items = a,b,c,d,e,f,g,h
categories = x ( a,b,e) y (c,h) z(d,f,g)
now if I choose the x and z checkbox it only show the a,b,e,d,f,g
but I can't do that. How can I do ?
Here is a solution for checkbox filtering:
http://jsfiddle.net/3nY9V/6/
Looks like you have a js error in the code(missing single quote) and also at one place classic is used as an id and at another place as a class. Just wanted to find if thats not the issue. Try this.
function checkIsoTope(){
var ids = [];
$("#classic, #den, #wer").filter(":checked").each(function(){
ids.push("." + this.id);
});
$('#box').isotope({ filter: ids.join(',')});
}
$("#classic, #den, #wer, #allCheckboxId").click(checkIsoTope);

Categories

Resources