Run code when tab loads

edited June 26 in Questions
I have a page where I do not want to use a queue... because I want the user to be able to add to the list of programs on the left. When you click on the calendar icon for a program the list of "program years" for that program displays (using a condition) in the table on the right
imageimage
the issue is that when the user click on the tab, i would like to run the filter and display the program years for the first program in the list... to do that i need to run a snippet when the tab is clicked on.... is there a skuid way to do that... or do i have to do some sort of jquery thing ?

this is a very generic thing for applications i build... i will need to do it on many, many forms

I can set an ID on the program tab using skuid... but that id is not for the text in the tab itself... but only for the body of the tab... so to get the tab link it looks like I'll have to attach to the onclick of the LI element
image

Comments

  • edited June 26
    I found another way around this. I put the page title and table for program year in a panel control and gave it an id... then i added some inline css to not display that panel

    so when the tab opens nothing shows for program year

    then i added a line of javascript to the snippet that runs when you click on the calendar icon for a program change the class of the panel to a class that had display set to block... so when you click on a program... then you can see its program years..... but when the panel opens you don't see anything

    the whole goal is to prevent users from adding program years when there is actually no program selected


    I'd still like to be able to get at the event when a tab is selected in javascript... the editor component gives me hooks for when models change... something similar for tabs would be great
  • edited June 26
    Here's my solution


    The tab opens showing nothing for "program years" because the title and table are in a div whose class is set to "display:none"
    When you click on a calendar icon in a program row the program years are displayed.
    In order to change the header for program years to reflect the program selected I had to use a template... insert a div and then change the content in javascript

    var params = arguments[0], row = params.item.row,
       $ = skuid.$;
    var program = row.Id;
    var program_name = row.Name;
    console.log(program + ' ' + program_name);
    var program_years = skuid.model.getModel('Cal_Program_Year');
    var program_years_condition = program_years.getConditionByName('Cal_Program__c');
    //console.log(args.item.row.Id);
    program_years.setCondition(program_years_condition,program,true);
    console.log('condition set');
    skuid.model.updateData([program_years]);
    document.getElementById("program_year_panel").className = "program_year_program_selected";
    document.getElementById("program_years_title").innerHTML = "Program Years for " + program_name;


    here's the inline css



    .program_year_no_program_selected { display: none;}
    .program_year_program_selected {display: block;}
    .custom_title {font-size:18px; font-weight:bold;}


  • edited March 2017
    The Tab Set component triggers a tabshow JavaScript event whenever a Tab is selected / activated. Any event handlers bound to the tabshow event are passed a jQuery event object that allows you to know which Tab was selected.

    Here is some example code that will spit out the Id of the Tab that was shown (technically the Id of the Tab Panel, not the Tab Nav, but this is). Tabs are given auto-generated Ids by default, but if you give your Tabs Unique Ids, then you could use this to reliably run different code based on the Tab Id that was shown.

    This should be added to your Skuid Page as a JavaScript Resource of type Inline (NOT Snippet, NOT Component)
    (function(skuid){   
       var $ = skuid.$;
       $(function(){
          $('body').on('tabshow',function(event){
              var tabShown = $(event.target);
              var tabId = tabShown.attr('id');
              console.log(tabId);
          });
       });
    })(skuid);
    One point to note here: we bound this event generically to the whole document's body element. We could have been more specific, and bound it just to TabSet elements, or to a particular TabSet, for instance one that we gave the Unique Id "Level1Nav". This is a good idea if you have multiple TabSets on the same page and you want to bind separate handlers to each of them.

    Here is what this alternate syntax would look like:
    $('#Level1Nav').on('tabshow',function(event){
        var tabShown = $(event.target);
        var tabId = tabShown.attr('id');
        console.log('showed a tab in Level1Nav: ' + tabId);
    });



  • edited June 2019
    Zach, I have a very similar situation. I need some javascript to run on a page when it loads as an include in a popup. The page functions fine when I run it by it self - the code below runs when the page loads:
    $j(document).load (     function()     {         var models = skuid.model;         var $ = skuid.$;         var workshopRow = models.getModel('WorkshopDetail').getFirstRow(); ...  
    However, when I have a popup (from a calendar) that includes this page, the code seems to execute before the models load. I get an error on the getModel() line when I click to load the popup saying that there is no such model yet. How can I modify this to get the code to execute after the included page's models load?
  • edited December 2016
    Hi Peter, for your situation, you need to wrap your code in an event handler that gets fired when the Skuid popup finishes loading:
    (function(skuid){
    var $ = skuid.$;
    $(function(){
       $(document.body).one('pageload',function(){
          var models = skuid.model.map();
       });
    });
    })(skuid);
  • edited November 2015
    Works - thanks!

    FYI for readers, this approach (my code below) works when the page is used as an include, but doesn't work when the page is used by itself. For that use my code example above, I guess.
    (function(skuid){ var $ = skuid.$; $(function(){    $(document.body).one('pageload',function(){         var models = skuid.model;         var workshopRow = models.getModel('WorkshopDetail').getFirstRow(); ...
  • edited March 2017
    Okay I stand corrected by Ben --- you do NOT want to do what I just said above, as this code is less portable --- it will only work if the page is loaded via a Page Include, but will not work if the page is run on its own.

    The best strategy is to not wrap your code in a jQuery ready block at all, but to JUST listen for the 'pageload' event to be fired on the document body. This event will be fired both on initial page load, AND when a Page is loaded via a Page Include.

    Be careful though -- check to make sure your code is only getting run when you really want it to.
    • If you just want your code to run the first time that a page is loaded, wrap it in a jQuery ready.
    • If you ONLY want it to be run when a Page Include is loaded, wrap it in a jQuery ready AND a 'pageload' one listener.
    • If you want your code to be run any time that a page is loaded, whether your page is run as a top-level page OR as an included page, then use JUST the 'pageload' one listener method.
    See this post for a further explanation:

    https://community.skuidify.com/skuid/topics/how_do_i_wait_for_the_dom_to_load_within_a_skuid_page_in...


  • Matt SonesMatt Sones ✭✭
    edited May 2017
    Quick question on the 'tabshow' event: Does it trigger on pageload?
  • edited December 2016
    Currently no, the tabshow event is only fired when subsequent tabs are loaded, but not on initial load of the default tab. In the next major release of Skuid, it the tabshow event will be fired for all tab loads, including the load of the default tab. Also, sneak preview, in the next release it will be possible to run a sequence of actions when a tab is first loaded and/or whenever a tab is shown.
  • Matt SonesMatt Sones ✭✭
    edited December 2016
    Love it!
  • edited May 2017
    So is there anywhere in the documentation that explains all the javascript events we can hook into  events for Skuid components? The use of .on('tabshow') is great but now I'm trying to hook into the events from table filters and table row actions. Is there a .on('tableshow') event?


    I'd rather use events to add functionality instead of adding click event handlers for each one.
  • edited December 2016
    Joseph, there isn't good documentation yet on all events for all Skuid components -- and there aren't many events you can hook into yet for the Table component. What exactly are you trying to listen for?

    - To listen for Table filter changes, the best way would be to use a Model Action so that whenever the Model is re-queried, you can run some actions.
    - To listen for clicks on Table Row Actions, you could do a couple of things:
    (a) Recomended: Have each Row Action "Run Multiple Actions", and have one of the actions be to "Publish Event" or "Run Skuid JavaScript Snippet" --- this way is recommended if you want to run different logic depending on which Row Action was clicked. If you just want to run generic logic for clicks on any row action in a table, the jQuery approach (b) of binding event listeners would be fine, but otherwise I would do (a) because it's less brittle, it won't break if you rearrange the Row Actions, for instance.
    (b) Use jQuery to bind event listeners to clicks on the particular row actions.
  • Matt SonesMatt Sones ✭✭
    edited December 2016
    'tabshow' doesn't seem to be firing on pageload. Can someone confirm that it should be?
  • edited April 2016
    It would be nice. Right now, we have code called twice. Once for page load and once for tabshow.
  • edited April 2016
    Thanks Zach, I ended up going down the "Run Multiple Actions" approach.
  • edited February 2017
    This no longer appear to wrok
Sign In or Register to comment.