Click handler for link

Click handler for link

tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
edited May 2009 in General
Allen, as I indicated in my email, DT is the bomb! Thank you again for such a cool plugin. I don't know how I missed the forums.. I must have sailed right over the link last night before I sent the email.

What I'd like to do is somehow bind a click event for each row that will open a javascript window. The content that will be loaded into this new window will be specific to the row clicked. Each row will have a unique id from the database and will somhow have the id hidden and only will be used to load the content of the new window.

Now, I have to say that I am newer than new to js and jquery so any code samples would be greatly appriciated. I already found a couple of posts where jquery's doubleclick even handler can be used but I don't understand it. Can someone please help?

Thanks!
«1

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Hi Tom,

    Thanks for the compliments! Great to hear that DataTables is nice to work with :-)

    Regarding your question - have a look at my two event handler examples:

    http://datatables.net/examples/example_events_pre_init.html
    http://datatables.net/examples/example_events_post_init.html

    The first is for adding the event handlers prior to DataTables initialisation (ideal for when the DataTable is created from data in the DOM due to speed), and the second if for adding event handlers after DataTables initialisation (suitable for Ajax loading of data etc).

    Both of these examples use a tooltip plugin for jQuery, but you can hopefully see how this could be readily utalised for a click event. Something like this:

    [code]
    /* Apply the events */
    $('#example tbody tr').click( function() {
    window.location.href = "whatever-the-link-is";
    } );

    /* Init DataTables */
    $('#example').dataTable();
    [/code]

    Hope this helps,
    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    edited May 2009
    Hi Allen,

    Thanks for the quick response. Well, I tried to get this working but I can't seem to get it. This is my code so far.

    $(document).ready(function() {
    $('#search tbody tr').click( function() {
    alert('Hello');
    } );
    $('#search').dataTable( {
    "sPaginationType": "full_numbers",
    "bProcessing": true,
    "iDisplayLength": 15,
    "sAjaxSource": 'json.php'
    } );
    } );

    When I added the click event and tested it, nothing happens. I'm sorry that I'm so new to this and need everything spelled out for me. I looked at your examples of the post and pre initialisation but honestly, I'm not sure which one I should use.

    Also, another area of concern for me is how will DataTables know what row is clicked and what the database id is?
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Well, I have some good news to report. I was able to make it as far as echoing an alert but this is what I had to use:

    $('#search').click(function(){
    alert("Test");
    });

    For some reason, it will not alert when I include the tbody and tr tags in the function. I am still perplexed on how to pass to the function, each row's value.. :/
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Funny that it didn't working with the tbody tr selector. Does your table conform to the structure that DataTables requires: http://datatables.net/usage ?

    Regardless, once inside the event handler you can use the 'this' variable to get information about the row. For example:

    [code]
    var nTds = this.getElementsByTagName('td');
    var tmp = nTds[1].innerHTML; // value of the second column in this row
    [/code]

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    I thought it was strange myself. Here is my exact table structure I am using. I believe that I took this from your original sample grid provided in the source download. What is even stranger is that I am working with a guy on an application right now and he was the one that turned me onto DataTables. The grid he is using is exibiting the exact same behavior; he also cannot get a row to fire with .click.






    Last
    First
    Address
    Suite
    City
    State
    Zip
    Phone
    Cell
    Office







     






    Ok, thanks for the advice on using "this". I can give that a whirl. Just to understand, will I import the row_id using json and then call that using the code that you provided? I'm sorry to have to ask such noobish questions.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    I think I might see what is going on... Are you loading your data via json rather than reading it from the DOM? If that is the case, then you need to use the example shown in the post-initialisation example! The selector didn't work because there are no rows in the DOM which match that selector - until you initialise DataTables :-)

    Try that and see if that works. Then we can tackle the next bit :-)

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    edited May 2009
    :) Thanks Allan!.. Yes, I'm loading the data with json. I will try that and come back. I'm glad that I mentioned json.
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    I just looked at the post initialization example and I see a line:
    /* Init DataTables */
    oTable = $('#example').dataTable();

    Now, you say that I have to initialize DataTables first but I believe that I'm already doing that. Here is what I have.
    oTable = $('#search').dataTable( {
    "sPaginationType": "full_numbers",
    "bProcessing": true,
    "iDisplayLength": 15,
    "sAjaxSource": 'json.php'
    } );

    Isn't this the same thing?
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Allan,

    I found this while reading over the example page again:
    "Rather then queriing the DOM to get all rows (since they aren't there) you need to use the fnGetNodes() API function. This is shown in this example."

    In your example, you have this:
    $( oTable.fnGetNodes() ).tooltip( {
    "delay": 0,
    "track": true,
    "fade": 250
    } );

    Does this mean that I must use tooltips to use the .click event? I was kind of hoping not to have to use the tips. In place of the .tooltip, maybe I can try #search. I don't know.. I'm just digging. :)
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    edited May 2009
    Hi Tom,

    Try something like this:

    [code]
    oTable = $('#search').dataTable( {
    "sPaginationType": "full_numbers",
    "bProcessing": true,
    "iDisplayLength": 15,
    "sAjaxSource": 'json.php'
    "fnInitCallback": function () {
    $( oTable.fnGetNodes() ).click( function () {
    /* Link or whatever */
    }
    } );
    } );
    [/code]

    Because the Ajax call to get the data is asynchronous you need to use fnInitCallback() to get the nodes once they have been added by DataTables. Then they will be available to you thought the fnGetNodes() API function.

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    edited May 2009
    Hi Allan,

    Thanks again for the help. Unfortunately it still isn't working. The error I am getting is: "missing } after property list". I'll see what I can do to work through it and let you know what the outcome is. I've already spent 45 minutes on it but I am not used to the (){}{{}})() that javascript uses so I really don't know where the issue is.

    Anyhow, it seems to me that there is still a lot of work left to do because I still have to get the row_id for the event even if I am successful at getting this to work.

    Thanks,
    Tom
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Well, I have been at it since I posted my last post and have also been to JQuery's site with no luck. I have also posted the question on a public forum and nobody else seems to know either. Do you offer paid support by chance? I don't think I'm up to another day of trying to get this working. :)

    Thanks,
    Tom
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Oops - sorry - I had a syntax error in my code (missed a trailing bracket) which was causing the error you describe.

    So to now get the row id for the event, you'll need to use the 'this' property that I was talking about earlier. "this.id" will likely do it - alert that to the screen and see if it meets what you expected.

    Regarding paid support - yes I can offer this. Please contact me directly through www.datatables.net/contact with further details (and example data) of what you need :-)

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    edited May 2009
    Yeah, I just found the error myself after about 6 hours. If I use this.#search... Where should it go? I'm thinking that maybe in fnGetNodes() like fnGetNodes(this.#search).. Is this right Allen?

    Actually, let me post what I currently have so we are on the same page

    var oTable;
    $(document).ready(function() {
    oTable = $('#search').dataTable(
    {
    "sPaginationType": "full_numbers",
    "bProcessing": true,
    "iDisplayLength": 15,
    "sAjaxSource": 'json.php',
    "fnInitCallback": function ()
    {
    $(oTable.fnGetNodes(this.search) ).click(function ()
    {
    alert('sdsdsd');
    });
    }
    });
    });

    Thanks
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Allen, by the way.. if you look at your code you posted on your line "sAjaxSource": 'json.php' you use no comma afterward. I tried your code and it still won't compile. My code does as it uses the comma. Also, it may be worth noting that in my code, I have no selectors as you suggested that I use (#search tbody tr). Just thought I would mention it.

    Thanks!
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    I've just experimented with this a little bit, and I'm sorry to say that I've lead you down the garden path a little with the use of fnGetNodes() - that's only suitable for when you have the full table data on the client-side. It's not particularly suited for server-side processing. What is needed here is fnDrawCallback()...

    [code]
    $(document).ready(function() {
    $('#example').dataTable( {
    "bProcessing": true,
    "bServerSide": true,
    "sAjaxSource": "../examples_support/server_processing.php",
    "fnDrawCallback": function() {
    $("#example tbody tr").click(function () {
    alert('blah');
    } );
    }
    } );
    } );
    [/code]

    This should now work as expected (I've just tried it locally).

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Allen, I am happy to say that fnDrawCallback() did the trick for me. No worries.. The garden path made me read a lot about jquery and datatables so its all good. :)

    I'm terrified to ask what it will take to get the row_id into the alert. Is there a lot involved in this?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Did you try 'this.id (or this.getAttribute('id') - same thing, the second is more "correct")'?

    I just tried it with this.className and it worked perfectly. :-)

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Well, back to my real noobish glow again.. If I'm totally incorrect on this then I will really be giving myself away on just how little I know about javascript but what I tried was this: alert(this.getAttribute('col_id')) but I got "null" returned.

    Just so that we are both on the same page. I have a primary key that is returned in the json array. The name is col_id. What I was hoping for was to get that value passed into a query string so that I could forward the user to a new page based on that value. You said that you tried it with class name but I'm not sure that a class is what I need in this case.

    I promise to do some serious reading on javascript this weekend. :)
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    this.getAttribute('col_id') would suggest that you have ''. If you don't have a col_id attribute like this then it will indeed return null.

    With the data that you are passing to DataTables, are you passing the information as a straight array something like this?:

    [code]
    {
    aaData: [
    [ 1, "a", "b" ],
    [ 2, "c", "d" ],
    [ 3, "e", "f" ]
    ]
    }
    [/code]

    Here I've got three columns and three rows. The first column is the id. This can be hidden from the user by setting bVisible ( http://datatables.net/usage#bVisible - remove to add an extra TD/column for this if you need to add this).

    Then we can look at the DataTables initialisation again. I'm not entirely sure where I got the server-side processing part from (brain not engaged properly this morning) so in fact fnInitComplete() is actually where we are looking for here. I've put together a working example below:

    [code]
    var oTable;
    $(document).ready(function() {
    oTable = $('#search').dataTable( {
    "sPaginationType": "full_numbers",
    "bProcessing": true,
    "iDisplayLength": 15,
    "sAjaxSource": 'json.php',
    "fnInitComplete": function ( oSettings ) {
    $(oTable.fnGetNodes()).click( function () {
    var iPos = oTable.fnGetPosition( this );
    var aData = oSettings.aoData[ iPos ]._aData;
    alert('Data at index 0: '+aData[0]);
    } );
    },
    "aoColumns": [
    { "bVisible": false },
    null,
    null,
    null,
    null
    ]
    } );
    } );
    [/code]

    Hopefully this will do the trick for you.

    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Wow.. Thanks Allan. I will give that a try. Now it is starting to make a little sense to me. Each tr must have the col_id as the class? All of my tr tags are empty. :)

    Based on the fact that I have not yet placed the col_id in the tags, should I still use the most recent example you provided or just stay with what we currently have and put the col_id into them?

    You are correct, my json array looks exactly what you posted.
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Allan, it worked peeeerfectly. Thank you very much! You've made my day!! :)

    I am absolutely exhausted so I'm going to call it a night but if it would be ok with you, I'd like to ask a couple of questions tomorrow about a couple of the functions you are using.

    Thanks again!!
    Tom
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Feel free to fire away :-)
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Hello Allan,

    Thank you very much for the invitation. I am home now from work and can focus a bit on this code. Let me again thank you for taking the time to help me as I'm certain that this will also help other noobs as well. :)

    If you think this should be in its own thread, feel free to move it.

    As I was trying to find answers away from this site to the questions I was asking you... I went to the JQuery site and had a look at their daunting documentation. One of the things that immediately struck me was the experience level that the JQuery authors assume that the reader is at. I tried to read through some of it but was quickly discouraged. I want to understand what is happening within these code snippets so that I can build my own modules or add onto an existing plugin, like your grid.

    I was hoping that you would be able to direct me and others that have no javascript experience whatsoever to a site or to some material that might help us. Maybe a good place for a noob to begin; a starting point so to speak.

    Now, on your code. I was wondering if you could please explain the use of the brackets. I am not used to the way JQuery uses these. Such so that almost every closing block has a closing ")" with it. Is there a certain point when I have to use or not use them? I figured that having a block of code like this would be a good start.

    $(oTable.fnGetNodes()).click( function () {
    } );

    If I am reading this right, the closing ")" is for the click function but I'm not 100% certain on this. Why are these needed? Why couldn't these functions just open and close with curly braces?

    Another question I have is the "oTables" variable. Why is this needed? I see where this was declared at the top of the script. Could I have used something else other than oTables? You mentioned a "callback" in one of my other posts and I was wondering if you could please explain what that is and what it does.

    I have other questions but I will wait. I don't want to bombard you with too much. :)

    Thank you for the help and direction, Allan!
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Hi Tom,

    As I've noted in the forum information, I don't particularly want to encourage non-Javascript related questions here, and would prefer that this forum is used for DataTables related questions only - there are a number of better places to ask:

    jQuery mailing lists - http://docs.jquery.com/Discussion
    SitePoint forums - http://www.sitepoint.com/forums/
    Flashkit forums - http://board.flashkit.com/board/forumdisplay.php?f=103
    and many others.

    However, I can perhaps point you in the direction of a few materials that you might want to read up on:

    http://15daysofjquery.com
    http://www.noupe.com/tutorial/51-best-of-jquery-tutorials-and-examples.html
    http://tinyurl.com/o3wy4g - DOM Scripting book

    And finally for now - regarding this ststement:

    $(oTable.fnGetNodes()).click( function () { ... } );

    It's actually a fairly complex statement when you look at it. What is happening is that the $() function (which is an alias for jQuery) is being passed an array of TR elements (the return from the oTable.fnGetNodes() function). This initialises a jQuery object with this information available to it. One of the methods which jQuery makes available is the click function, which takes a function as it's parameters. The closing bracket is needed in order to close the function call (i.e. click() ). The following does exactly the same as the above:

    function fnClickHandler () {
    ...
    }
    var anTRs = oTable.fnGetNodes();
    var jqTRs = $(anTrs);
    jqTRs.click( fnClickHandler );

    The example you posted is just a short hand way of doing this - no need to define all those variables if they are not going to be used again.

    Regarding oTable - this is just a variable name - it can be whatever you want. If you need to reference the recreated DataTables object (i.e. if you want to call any of the API functions) then you will indeed need to store the return from your $().dataTable() call in some variable. It doesn't matter what it is called.

    If you are interesting in learning more about Javascript, it might be worth seeing is a local college (further education) offers a night class in programming (specifically Javascript, but the rules from many other programming languages can be applied as well - the syntax is just a bit different).

    Hope this helps,
    Allan
  • tomjohnsontomjohnson Posts: 20Questions: 0Answers: 0
    Allan,

    Thanks again for the explanation and the help. The other question that I wanted to ask you is about this:

    function ( oSettings ) {

    Is oSettings yours or JQuery's? Is this a variable or what? I don't see it defined above so I'm curious as to where it came from.

    I am going to use the links you provided and see how much I can learn about javascript. I am making the assumption that JQuery is 100% javascript and that if I invest my time and enegry to learning javascript that it will be useful in writing JQuery code as well. Am I right about this?

    Thanks again,
    Tom
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    What is happening with the "function(oSettings){ ... }" statement is that I have defined the parameter "fnInitComplete" as a function - that function accepts one parameter, in this case the DataTables settings object. Whatever part of the program calls the defined fnInitComplete function, it should pass this parameter. It can be called anything you like here.

    If you look through the DataTables code you will see "oSettings.fnInitComplete( oSettings );". That is my call to this function, and it's passing my settings object (I just so happen to stick to the same naming). That make sense?

    Regarding jQuery - it is a Javascript library which provides easy access to common methods for Javascript developers. For example, events can be a massive pain in the neck to get right across all browsers, but with jQuery you just you $().click( function() {...} ); - nice and easy. So it could almost be viewed as an abstraction layer from that perspective...

    If you know Javascript, then you will have no problem writing code for jQuery or any other Javascript library available (YUI, MooTools etc etc - they are all quite excellent). Personally I'd recommend learning Javascript without the use of a library first as you will learn a lot about the language itself and then not have any dependancies on any one library - but as I say, watch out for this - there are a lot of nasty gotchas in cross-platform Javascript!

    Good luck :-)

    Allan
  • jonathanjonathan Posts: 2Questions: 0Answers: 0
    edited May 2010
    Allan,

    thanks for this.

    This thread was very useful in providing a way to make the rows in tables link to a URL based on the data in that row. Took a lot of searching on the forum though - could use a more descriptive title than Click handler for link, although the title makes sense (hindsight is 20/20) - I think my search queries like 'adding links to rows', 'Link URL', hyperlink were my enemy. Anyway, should show up now that I've added this comment.

    The example code addresses throwing an alert on click, here's the code I ended up using to open a window passing a parm to php script... I'm passing the city name in my table, which is in the second column [1].

    [code]
    "fnInitComplete": function ( oSettings ) {
    $(oTable.fnGetNodes()).click( function () {
    var iPos = oTable.fnGetPosition( this );
    var aData = oSettings.aoData[ iPos ]._aData;
    window.open('script.php?city='+aData[1],'cityreport','width=1020,height=700,resizable=0');
    } );
    }
    [/code]
  • slaterslater Posts: 5Questions: 0Answers: 0
    This was a very useful topic..Can you please tell me how i can change the mouse pointer to a hand shaped one(Usually for hyperlinks we have this right??)
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Worth Googling that one: http://www.google.com/search?q=css+hand+cursor .

    Allan
This discussion has been closed.