简体   繁体   中英

Click event fires on one tab but not other tabs

I have an loop that generates tabs for each element in the collection. The tabs generate correctly and the content on the tabs generates correctly. Every tab has a DropDownList control with a list of items in it. All seems to be working properly except one thing. The javascript click event for the control on the first tab fires but all other tabs the click event does NOT fire??

I was thinking each tab would have it's own event handler so that code is part of the loop. However the "name/id" of the control is the same on every tab and I wonder if this is my issue.

Is there some sort of difficulty / problem with each tab having the same "named" control? I thought...perhaps incorrectly...that each tab would have it's own context thus there wouldn't be any issues.

Code for the loop:

foreach (var extbrd in Model.ExtBds)
{
    tabstrip.Add()
    .Text(extbrd.ExtName)

    .ImageUrl("~/.../TabIcon.png")
    .Content(@<text>
                <div>
                @Html.Action("Controller", "Action", new { object })
                </div>
               </text>);
 }    

As you can see in the loop the tab code is a partial view. I have snipped out alot of extra code but can post / edit it in if needed. That code is:

....snip
<script type="text/javascript">
   $(function() {
       $("#@Html.FieldIdFor(model => model.ExtFIds)").click(function () 
        {...this code works fine so dropped it....});
   });

</script>
....more snipping....
<tr>
   <td style="width:400px;">           
      @Html.DropDownListFor(model => model.ExtFIds, Model.SelectThreads, new {style = "width:400px;height:400px", @size = 30})
   </td>

So you see the code uses the same name for the control and thus the javascript .click event handler.

Also I think it would be helpful to know that I am using the Telerik mvc tab control object.

Using the F12 debugger I see no errors in the console or similiar....it seems to me that the click event is just not firing on tab 2 and on...?

Any ideas would be greatly appreciated.

Thank You


Edit 1 per a suggestion I did this to add a class:

<td>           
   @Html.DropDownListFor(model => model.ExtFIds, Model.SelectThreads, new {style = "width:400px;height:400px", @size = 30, @Class = "ddlTab_" + Model.ExtFIds.ToString() } )
</td>

and javascript:

$(".ddlTab_@(Model.ExtFIds)").click(function ()

This resulted in every ddl having a uniques class name and a unique event handler but the first tab still only worked???


Edit 2

I slightly modified the proposed answer to this:

<div class="Tab">
   @Html.Action("Controller", "Action", new { object })
</div>

and the javascrip to this:

 $("div.Tab").click(function () 
    {
        alert(this.id);

The result was that I did get an alert to pop when I clicked on the ddl...which makes sense because it is in the div which has a handler on it but the alerts were empty. I also got two alerts so it fired the click event twice even though I only clicked one item in the ddl?


Edit3

Instead of wrapping the outer div which is the loop of the partial view I changed the div to wrap JUST the ddl creation and added an id like so:

<div class="Tab" id="ddlTab_@(Model.ExtFIds.ToString())">          
            @Html.DropDownListFor(model => model.ExtFIds, Model.SelectThreads, new {style = "width:400px;height:400px", @size = 30} )
</div>

My alert now yields the name of the div clicked. Still fires twice but I can live with that for now.

So now that it is firing I suppose what I have to do is drill down to the child object of the div which would be the ddl...get the selected item and proceed as normal from there.


Final Edit--Resolved

So I got it working by using a div wrapped around the ddl but it sure seems to me this is a band-aid / work around...perhaps not though..I just don't know enough to say. For anyone else here is what I ended up doing.

In the razor cshtml I wrapped the ddl in a div as mentioned above in edit 3 and made sure it had a unique id (uniqueness provided by my model ExtFIds).

<div class="Tab" id="ddlTab_@(Model.ExtFIds.ToString())">          
    @Html.DropDownListFor(model => model.ExtFIds, Model.ST, new {style = "...", @size = 30, @Class = "ddlTab_" + Model.ExtFIds.ToString() } )

In the script portion:

$(function() { $("div.Tab").click(function () //so I attach event handler to div instead of ddl { var id = this.id var idLen = id.length;

        id = id.substr(7, idLen);
        //get the div id and then trim off the leading string

        //get our raw html string and load it into an object
        var rawModel = $('#HiddenModel_' + id).html();
        //here I access a control on the tab using the id obtained above...
        //of course in the cshtm I concat the model id to the name as seen for the div


        var jsonModel = jQuery.parseJSON(rawModel) //turn the data into json object

        var selectedItem = $('.ddlTab_' + id).val();
         //here I have to drill down to the correct ddl to find the selected item
         //again the model id provides unique name

        var matchingObj = getObjects(jsonModel, 'ThreadValue', selectedItem);
        //search through my json object to find matching item.

        if(matchingObj.length > 0)
        {
            //update two controls with matched value
            //at this point I think you get the idea...the model id makes for 
            //unique names that can be drilled down to from the wrapping div
            var $FrmDiv = $('#ForumFrame_' + id);
            if ($FrmDiv.length)
            {
                $FrmDiv.empty();
                $FrmDiv.append(matchingObj[0].Link);
            }


            var $prevfram = $('#ForumPreview_' + id);
            if ( $prevfram.length ) {
                $prevfram.val(matchingObj[0].Description);   
            }
        }

    });
});

I welcome any improvements / suggestions / explanations as to this post.

do like this, add a class to tabs:

foreach (var extbrd in Model.ExtBds)
{
    tabstrip.Add()
    .Text(extbrd.ExtName)

    .ImageUrl("~/.../TabIcon.png")
    .Content(@<text>
                <div class="tab">
                @Html.Action("Controller", "Action", new { object })
                </div>
               </text>);
 }    

and do in javascript like this:

<script type="text/javascript">
   $(function() {
       $("div.tab)").click(function () {

        var id = this.id;


        // do whatever here you want to do

       });

  });

    </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM