0

I have a web page which has four tabs at the top. Clicking one of the tabs displays the appropriate page beneath. The tab selection and display is controlled by a js/jQuery function I've called 'changeTab'. Nothing uusual there.

I want to set up a (different) JS function for each tab, to run when that tab is displayed, similar to the way jQuery 'document.ready' works when the main page itself is loaded. I can put a function call at the bottom of my 'changeTab' function, such as 'tabLoaded()'. But that obviously only calls the same one function each time.

I can name the functions 'tab_1_Loaded', 'tab_2_Loaded' etc. ,but then I need some way of dynamically modifying the function call so that the number of the tab is included (I already have the tab number, I just need to work out how to insert it into the function call).

What I am hoping for is a function call like:

tab_[insert tabNum dynamiclly here]_Loaded();

Is that possible in a few lines of code?

I have read articles on Stackoverflow, but they seem do address a different problem of creating (new?) functions with a dynamically derived name. I can be quite clear what my functions are called. I need a dynamically derived call. I suspect it may be possible with 'eval' but my reading also suggests eval is to be avoided, so I've not pursued it.

My fall-back is a series of conditionals:

    if(tabNum == 1) tab_1_Loaded();
    if(tabNum == 2) tab_2_Loaded();
    etc.

but it seems inelegant (though simple) and it certainly works in this case where the number of possibilities is small. Is there a better way that's also simple?

LATER: I've subsequently realised there's an additional complication for the particular page/tabs I'm working on right now, (though it won't apply to the entire site). This page is for on-line booking. The first tab is the booking form (visitor enters dates, number of people). The second and subsequent tabs aren't populated until the visitor clicks 'Next' and moves on to the next stage. Consequently any function call in the 'changeTabs' function is made before the contents of the tab have actually loaded, so it does't work.

To deal with that I'm going to put the call into a script at the bottom of each tab contents. I expect there are more elegant ways of doing it, but it's only one line of code, whereas all the offered solutions are actually more verbose (and harder for me to understand). I will probably still need the call from 'changeTab' to cope with the visitor flicking through the tabs before finalising the booking.

Tim Dawson
  • 89
  • 2
  • 9
  • Do you have four hard-coded tabs, or an array of tabs, represented by some data structure? – Cobus Kruger Jul 01 '19 at 13:00
  • Take a look here: https://stackoverflow.com/questions/32826789/javascript-call-back-by-function-name-in-data-attribute. You can specifiy your function name in a `data` attribute of your tab link and call it – Lapskaus Jul 01 '19 at 13:05
  • Would this work? https://stackoverflow.com/questions/1225102/jquery-event-to-trigger-action-when-a-div-is-made-visible, alternately, do the callback like @Lapskaus said. – Jeff Jul 01 '19 at 13:06
  • @Cobus Kruger: The tabs are hard coded in the HTML, but the click functions are added with JS/jQ – Tim Dawson Jul 01 '19 at 15:40

2 Answers2

0

When press the tab, the call back function will always be invoked, no matter what how many call back functions all will be invoked. You cannot conditionally invoke a callback function from a key press. Ideal way to implement this would be

i) Have a single call back function for the tab event ii) Identify the id of the element, that is currently on focus when tab is pressed inside that call back function iii) Add conditions based on that element on focus to have your logic of functions for respective elements

Sasi Kumar M
  • 2,440
  • 1
  • 23
  • 23
  • I think because I must cope with both conditions (as in the 'Later' edit to my post) I am doomed to put a relatively simple function call at the bottom of each tab page so that it is called under all circumstances. – Tim Dawson Jul 04 '19 at 11:45
0

Yes it's possible to do what you're asking. All functions and variables declared with global scope are methods and properties of the window object, so you can build the name of the your function as a string and reference it via bracket notation. So assuming you have tabNumber already stored in a variable:

var functionName = "tab_"+tabNumber+"_Loaded";
window[functionName]();

(See https://codepen.io/slynagh/pen/MMVEoE)

But a better approach would be to use callback functions or else use one tab_Loaded() function which accepts the tabNumber as a parameter, eg:

function tab_Loaded(tabNumber){
  if(tabNumber === 1) { do something }
  else if(tabNumber === 2 ) {do something else}
  //etc
}
slynagh
  • 601
  • 4
  • 16
  • The 'do something' would always be a call to a function whose name included the tabNumber, so your first suggestion is less verbose. – Tim Dawson Jul 04 '19 at 11:41
  • @TimDawson my point was that you should handle all cases within a dedicated function. In your particular use case it's probably fine, however for scalability and debuggablity, calling a function via a dynamically generated string doesn't seem to me very good practice. – slynagh Jul 06 '19 at 13:40
  • As explained in a comment to the answer below, I have had to adopt a different method anyway. – Tim Dawson Jul 07 '19 at 17:37