javascriptjqueryasp.netrepeater

javascript function in ASP.NET Repeater


I have a repeater in an ASP.NET UpdatePanel as follows;

<asp:UpdatePanel ID="rptGalleries" runat="server">
<ContentTemplate>
    <asp:Repeater ID="rptAddPhotoGalleries" runat="server">
        <ItemTemplate>
            <div>
                 <input type="checkbox" id="chkNews" data-newsid='<%# Eval("NewsID") %>' runat="server" onclick="javascript:markNews($(this).data('newsid'));" />
            </div>
        </ItemTemplate>
     </asp:Repeater>
</ContentTemplate>

And I use the following javascript within the element of the HTML;

<script type="text/javascript">
    $(document).ready(function () {
        function markNews(nID) {
          var $span = $('span[data-newsid="' + nID + '"]')
          $span.hide('slow');
        }
    });
</script>   

when I click on the resulting checkbox, I get an error in the console as follows;

ReferenceError: markNews is not defined
javascript:markNews($(this).data('newsid'));

Anyone have any ideas?


Solution

  • You should define your function outside like in this demo:

    <script type="text/javascript">
        function markNews(nID) {
            var $span = $('span[data-newsid="' + nID + '"]');
            $span.hide('slow');
        }
    </script>
    

    The jQuery $(document).ready(function () { defines an inner scope, so your function is only accessible inside.


    An alternative would be writing an extension:

    $(document).ready(function () {
        $.fn.markNews = function (nID) {
            var $span = $('span[data-newsid="' + nID + '"]');
            $span.hide('slow');
        }
    });
    

    You can call that function directly on the element like in

    <input type="checkbox" id="chkNews" data-newsid='1' runat="server"
           onclick="javascript:$(this).markNews($(this).data('newsid'));" />
    

    Here is a demo.


    With that said, this could even be improved by reading the id inside the function (demo):

    $.fn.markNews = function () {
        var nID = $(this).data('newsid'),
            $span = $('span[data-newsid="' + nID + '"]');
        $span.hide('slow');
    }
    

    My suggestion for a final solution

    To avoid unnecessary code, I would use the function in outer (global) scope and call it within a jQuery event:

    function markNews() {
        var nID = $(this).data('newsid'),
            $span = $('span[data-newsid="' + nID + '"]');
        $span.hide('slow');
    }
    
    $(document).ready(function () {
        $('#Ctl_rptAddPhotoGalleries > input').on('click', markNews);
    });
    

    Of course #Ctl_rptAddPhotoGalleries has to be replaced with the rendered id (e.g. '#<%=rptAddPhotoGalleries.ClientID%> > input').

    With that, your <input/>s can be as clean as

    <input type="checkbox" data-newsid='<%# Eval("NewsID") %>' runat="server" />
    

    Here is a demo.