1

Hi I have two functions one with one parameter and the other called 'goToMatchDetailPage' with two parameter. I'm trying to get the two variables to the second function but it end up only going to the first parameter and leaving the second one empty and it says 'undefined'.

match.Home and match.Away are the two dynamic variable I want to pass through 'goToMatchDetailPage'. It puts match.Home and match.Away as one variable and I would like them separate.

Here is the code

  function generateMatchLink(match){
  //<li data-role="list-divider">Divider</li>

    var currentDate = match.Date;
    var time = match.Time.replace(":00", "");

    if(oldDate != currentDate){
    //debugger
    oldDate = match.Date;
return '<li data-role="list-divider" data-theme="b">\ ' + oldDate + '\ </li><li  data-icon="false"><a href="javascript:void(0)'
    + '" onclick="goToMatchDetailPage(\''
    + match.Home + ',' + match.Away +'\')">'
        + ' <div class="ui-grid-a" data-theme="none" style="height:20px">'
        + ' <div class="ui-block-a" style="width:40%">' + match.Home + '</div>'
        + ' <div class="ui-block-b" style="width:20%">' + time + '</div>'
        + ' <div class="ui-block-c" style="width:40%">' + match.Away + '</div></div></a></li>';

    }else{

    return '<li data-icon="false"><a href="javascript:void(0)'
    + '" onclick="goToMatchDetailPage(\''
    + match.Home + ',' + match.Away +'\')">'
        + ' <div class="ui-grid-a" data-theme="none">'
        + ' <div class="ui-block-a" style="width:40%">' + match.Home + '</div>'
        + ' <div class="ui-block-b" style="width:20%">' + time + '</div>'
        + ' <div class="ui-block-c" style="width:40%">' + match.Away + '</div></div></a></li>';

    }

}

Here is the second function

function goToMatchDetailPage(matchHome, matchAway){

    //create the html template
    var matchPage = $("<div data-role='page' data-url=dummyUrl><div data-role='header'><h1>"
      + matchHome + "</h1></div><div data-role='content'><div data-role='tabs'>"
  + "<div data-role='navbar'>"
  +  "<ul>"
  +    "<li><a href='#fragment-1'>" + matchHome + "</a></li>"
  +   "<li><a href='#fragment-2'>" + matchAway + "</a></li>"
  +  "</ul>"
  + "</div>"
  + "<div id='fragment-1'>"
  +  "<p>This is the content of the tab 'One', with the id fragment-1.</p>"
  + "</div>"
  + "<div id='fragment-2'>"
  +  "<p>This is the content of the tab 'Two', with the id fragment-2.</p>"
  + "</div></div></div>");

    //append the new page to the page contanier
    matchPage.appendTo($.mobile.pageContainer);

    //go to the newly created page
    $.mobile.changePage(matchPage);
}
user3210416
  • 794
  • 1
  • 10
  • 20

2 Answers2

2

As an example of doing this with templates (and avoiding quote problems):

Define a dummy script block of unknown type (so it is not run):

<script id="homeTemplate" type="text/template">
    <li data-role="list-divider" data-theme="b">{oldDate}</li>
    <li data-icon="false">
        <a href="javascript:void(0)" onclick="goToMatchDetailPage('{home}','{away}')">
            <div class="ui-grid-a" data-theme="none" style="height:20px">
                <div class="ui-block-a" style="width:40%">{home}</div>
                <div class="ui-block-b" style="width:20%">{time}</div>
                <div class="ui-block-c" style="width:40%">{away}</div>
            </div>
        </a>
    </li>
</script>

This keeps the HTML much cleaner and easier to maintain. Just create one per required template.

Note: I only use {placeholder} as braces do not normally appear in HTML. it can be any delimiter you want or just match on a unique name in the template. The braces actually make the matching Regex replace a bit uglier as they need to be escaped as \{ and \}, so you may want to go the simpler route of using names only.

Reference the template by id:

var homeTemplate = $('#homeTemplate');

Replace the placeholders you define with the actual value:

homeTemplate = homeTemplate.replace(/\{home\}/g, match.Home);
homeTemplate = homeTemplate.replace(/\{away\}/g, match.Away);
homeTemplate = homeTemplate.replace(/\{time\}/g, time);
homeTemplate = homeTemplate.replace(/\{oldDate\}/g, oldDate);

// Now insert the template
$.mobile.pageContainer.append(homeTemplate);

The replaces can obviously be concatenated to shorten the code, but going for readable here.

The replaces use the /g "global" options of regex as replace only replaces the first match by default

Continuing on (thanks to comments from ezanker):

One of the beauties of jQuery is that you do not need to have code (e.g. onclick handlers) in your HTML at all.

If your elements are being created dynamically you can use the delegated version of [on][1] to filter the elements at event time.

This time the template has no code, just some extra data in data-attributes and a class to identify the elements:

e.g. <a href="#" class="hotlink" data-home="{home}" data-away="{away}">

<script id="homeTemplate" type="text/template">
    <li data-role="list-divider" data-theme="b">{oldDate}</li>
    <li data-icon="false">
        <a href="#" class="hotlink" data-home="{home}" data-away="{away}">
            <div class="ui-grid-a" data-theme="none" style="height:20px">
                <div class="ui-block-a" style="width:40%">{home}</div>
                <div class="ui-block-b" style="width:20%">{time}</div>
                <div class="ui-block-c" style="width:40%">{away}</div>
            </div>
        </a>
    </li>
</script>

The home and away values are stored in data- attributes instead of being passed to your function call.

You hook up the events using delegated on like this:

$(document).on('click', 'a.hotlink', function(e){
    e.preventdefault();   // This stops the click of the link navigating
    var $link = $(this);
    var home = $link.data('home');
    var away = $link.data('away');
    goToMatchDetailPage(home, away);
});

This basically listens for click at the document level (can be any element above the target(s) that will not dynamically change, but document is common). When the click event occurs it then applies the jQuery selector in the second parameter (all anchors with a class of hotlink in this case) to work out what element was clicked and then runs the function in the third parameter against that element. This allows for dynamically added elements to generate clicks (where a simple click() would not work).

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • Good of you to take the time (+1)!!! OP should also probably use unobtrusive javascript and event delegation instead of inline onClick as it is much easier to maintain the code. He/She could assign a class to the anchor and store home and away team in data attributes to be retrieved in the click event delegated to that class. – ezanker Apr 03 '14 at 14:05
  • This is really helpful and thanks for showing me the proper way – user3210416 Apr 03 '14 at 14:09
  • Don't know about "proper", but certainly easier to work with (in my experience). Also look into the other suggestions `ezanker` mentions in comment. Enjoy :) – iCollect.it Ltd Apr 03 '14 at 14:10
  • Sorry to bother you once more, do you know where to get the documentation about dummy script? I have been searching no results regarding this. I just want to amend my whole code in this way – user3210416 Apr 03 '14 at 14:39
  • @user3210416: I do not recall where I first saw it, probably on SO, but a search of "text/template jquery" on Google will find you loads of info. – iCollect.it Ltd Apr 03 '14 at 15:15
  • 1
    Added some of the comments `ezanker` suggested as they are all pretty standard, and good, ideas for cleaner code. @ezanker: thanks again. – iCollect.it Ltd Apr 03 '14 at 15:28
  • @TrueBlueAussie, you very nicely explained the data attributes and delegated event for the dynamic items. It is exactly what I was thinking. I wish I could vote you up more than once :) – ezanker Apr 03 '14 at 17:38
  • @ezanker: More votes... Try this underrated one: http://stackoverflow.com/questions/6801546/silverlight-rotate-scale-a-bitmap-image-to-fit-within-rectangle-without-croppi/6802332#6802332 :) – iCollect.it Ltd Apr 03 '14 at 18:40
  • @TrueBlueAussie, that is underrated! I added a vote :) – ezanker Apr 03 '14 at 18:46
1

I think you are just missing some quotes:

onclick="goToMatchDetailPage(\'' + match.Home + ',' + match.Away +'\')

will resolve to a single parameter with a comma in it:

onclick="goToMatchDetailPage('match.Home, match.Away')

You need this:

onclick="goToMatchDetailPage(\'' + match.Home + '\', \'' + match.Away +'\')
ezanker
  • 24,628
  • 1
  • 20
  • 35
  • +1: Good catch. Of course none of this would occur if it was not just strung together HTML and code generation instead of a template :) – iCollect.it Ltd Apr 03 '14 at 13:37
  • @TrueBlueAussie, agreed ;) – ezanker Apr 03 '14 at 13:38
  • Can you explain what happen here please, I very new to dummy script and would like to know how to avoid this type of problems – user3210416 Apr 03 '14 at 13:42
  • Well you ended up with quotes within quotes and you got a little lost... Instead of using inline onClick, you should probably handle the click event via jQuery and just assign match.Home and match.Away as data attributes of the anchor. This is too much to explain in comments, read about unobtrusive javascript and event delegation in jQuery. – ezanker Apr 03 '14 at 14:01