-1

People seriously downvoted this because they don't have an answer? Wow.

So I have a partial view with a script inside that's loading into the parent page through AJAX, this script needs to be in here as I'm passing Modal variables through razor to the script.

Here's a shortened version of the script, where it's not picking up.

$(document).ready(function () {

    //add rule if there is a subtype to select
    if (Calendar.CalEventSubTypeListCount > 0)
    {
        console.log($('#CalEventBO_CalEventSubType_ID').data("name"));
        $('#CalEventBO_CalEventSubType_ID').rules('add', { required: true, messages: { required: Calendar.RawMessage } });
    }

    if ($('#CalEventBO_AllDay').prop('checked')) {
        $(".timeOptions").hide();
    }
    else 
    {
        $(".timeOptions").show();
    }

    if (Calendar.BookForUser == 'True') {
        $('.mngUsers').show();
        //Check if the selected user has a colour day
        checkColDay();
    }
    else {
        $('.mngUsers').hide();
        //Check if the logged in user has a colour day
        checkColDay();
    }

    //On page load hide school options and mng user list for hols
    $('.SchAdd').hide();
    $('.AddCon').hide();

    var eventTypeID = $('#CalEventBO_TypeID').val();
    showHideTitleInput();

    if (eventTypeID == Calendar.CalEventType) {
        checkColDay();
    }

So the problem is, that it's saying '#CalEventBO_CalEventSubType_ID' is undefined. The element is in the same view as the script but it seems the script runs before the view is loaded, even though in IE, the view is there when it pauses on break.

I've tried using bind("load") to the element, (window).load, putting the script in the parent view, calling the whole script from another view and also calling the script from the OnSuccess of the AJAX load.

At a complete loss and starting to think that this just isn't possible and I'll need to rewrite this whole page.

TL;DR: Is there any way to tell jQuery to run after the partial view that it resides in loads?

Partial view:

<div class="modal" id="CalAddEventModal">
  <div class="window">

  @using (Ajax.BeginForm("AddEvent", "Calendar", null, new AjaxOptions { UpdateTargetId = "addpanel" }, new { id = "fm_addev" }))
  {

    <fieldset>
        <legend>Add New Event</legend>
        <br />

        @Html.HiddenFor(model => model.CalEventBO.SelectedMonth)
        @Html.HiddenFor(model => model.CalEventBO.SelectedYear)
        @Html.HiddenFor(model => model.CalEventBO.SchRequired)
        @Html.HiddenFor(model => model.CalEventBO.TypeID)


        <span class="blk_w">Category:</span>@Html.DropDownListFor(model => model.CalEventBO.TypeID, Model.TypeList, new { @class = "CatDDL" })

        @* If there is at least 1 sub event type then show the choice *@
        @if (Model.CalEventSubTypeList.Count() > 0)
        {
            <div class="subtype">
            <span class="blk_w">@((CalEventType)Model.CalEventBO.TypeID == CalEventType.Meeting ? "Room:" : "Event Type:")</span> @Html.DropDownListFor(model => model.CalEventBO.CalEventSubType_ID, new SelectList(Model.CalEventSubTypeList, "ID", "Text"))
            </div>
        }

        @if (Model.CalEventBO.TypeID == (int)CalEventType.Roadshow || Model.CalEventBO.TypeID == (int)CalEventType.OnSiteTraining)
        {
            <br />
            <span class="blk_w">Venue:</span>   @Html.DropDownListFor(model => model.CalEventBO.LAID, Model.LAList, "Please Select an LA") <br />
            <div class="SchAdd" style="display:none;">
            <span class="blk_w"></span>         <div class="line">@Html.DropDownListFor(model => model.CalEventBO.SchID, Model.SchList)</div>
            <div class="AddCon" style="display:none;">
            <span class="blk_w">Venue Address:</span> <div class="address line"></div>
            <br />
            <span class="blk_w"></span> @Html.CheckBoxFor(model => model.AddressConfirmed) <strong class="num">I confirm the address above is correct</strong> 
            </div>
            </div>
        }



        @switch (Model.CalEventBO.TypeID)
        {
            case (int)CalEventType.Meeting:
            case (int)CalEventType.Other:
            case (int)CalEventType.Exhibition:
            case (int)CalEventType.OnlineTraining:
            case (int)CalEventType.OutOfOffice:
            case (int)CalEventType.OnlineDemo:
                <div class="titleInput" style="display: none;">
                    <span class="blk_w">Title:</span> @Html.EditorFor(model => model.CalEventBO.Title)
                </div>
                break;
            default:
                break;
        }

        @if (Model.CalEventBO.TypeID == (int)CalEventType.OnlineDemo || Model.CalEventBO.TypeID == (int)CalEventType.Roadshow || Model.CalEventBO.TypeID == (int)CalEventType.OnlineTraining)
        {
            <br />
            <span class="blk_w">Max Attendees:</span> @Html.DropDownListFor(model => model.CalEventBO.MaxAttendees, Model.MaxAttend)
        }

        <br />
        <span class="blk_w">Start Date:</span> <div class="dateselect line">@Html.EditorFor(model => model.CalEventBO.StartDate)</div>

        @if (Model.CalEventBO.TypeID != (int)CalEventType.Holiday && Model.CalEventBO.TypeID != (int)CalEventType.BankHoliday && Model.CalEventBO.TypeID != (int)CalEventType.ColourDay)
        {
            <div class="timeOptions line">
            <span class="blk_w">Start Time:</span> @Html.DropDownListFor(model => model.CalEventBO.StartHour, Model.HourList) : @Html.DropDownListFor(model => model.CalEventBO.StartMin, Model.MinList)
            </div>
        }

        <br />
        <span class="blk_w">End Date:</span> <div class="dateselect line">@Html.EditorFor(model => model.CalEventBO.EndDate)</div>

        @if (Model.CalEventBO.TypeID != (int)CalEventType.Holiday && Model.CalEventBO.TypeID != (int)CalEventType.BankHoliday && Model.CalEventBO.TypeID != (int)CalEventType.ColourDay)
        {
            <div class="timeOptions line">
            <span class="blk_w">End Time:</span> @Html.DropDownListFor(model => model.CalEventBO.EndHour, Model.HourList) : @Html.DropDownListFor(model => model.CalEventBO.EndMin, Model.MinList)
            </div>
        }

        @switch (Model.CalEventBO.TypeID)
        {
            case (int)CalEventType.OnlineDemo:
            case (int)CalEventType.BankHoliday:
            case (int)CalEventType.ColourDay:
            case (int)CalEventType.Roadshow:
                //Do not show the day range options or All Day CheckBox
                break;
            case (int)CalEventType.Holiday:
                <br />
                <span class="blk_w">Day Range:</span> @Html.DropDownListFor(model => model.CalEventBO.DayRange, Model.DayRangeList)  

                //Alert will appear here if colour day for user within selected dates
                <span class="blk_w"></span><span class="colAlert"></span>


                if (Model.MngUserList != null)
                {
                    <br />
                    <span class="blk_w">Book for Managed User:</span> @Html.CheckBoxFor(model => model.BookForUser)
                    <div class="mngUsers">
                    <span class="blk_w">Select User:</span> @Html.DropDownListFor(model => model.MngUserID, Model.MngUserList)
                    </div>
                }
                break;
            default:
                    <br />
                    <span class="blk_w">All Day:</span> @Html.CheckBoxFor(model => model.CalEventBO.AllDay)
                break;

        }

        @if (Model.CalEventBO.TypeID == (int)CalEventType.ColourDay)
        {
            <br />
            <span class="blk_w">Colour:</span>
            for (int i = 0; i < Model.Colours.Count; i++)
            { 
                <div class="blk_wn line">
                @{string radioID = "colID+" + i;} 
                @Html.RadioButton("Colour", Model.Colours[i].Colour, Model.Colours[i].Include, new { @id = radioID })
                <label for="colID+@i" class="@Model.Colours[i].Colour CalDaySelect" title="">@Model.Colours[i].Colour</label>
                </div>
            }

            <div class="line"><br /><br />
                  <img src="/Content/Images/help.png" class ="popup" alt="info" />
                    <div class="popupinfo">

                        Red - No holidays are allowed to be taken<br />
                        Amber - The holiday allowance has been reached<br />
                        Green - Holidays can be booked
                    </div>
                 </div>

            <br />
            <br />

            <fieldset>
                <legend>Included Access Groups</legend>
                <br />
            <div>
                <div class="scrollCalModal">
                    @Html.CheckBox("All") <label for="All">All</label>
                    <br />
                        <div id="groupSelect">
                            @for (int i = 0; i < Model.AuthGroupList.Count; i++)
                            {
                                <div class="blk_vw line">
                                @Html.CheckBoxFor(modelItem => Model.AuthGroupList[i].Include, new { id = Model.AuthGroupList[i].ID, @class = "grpcbx" })
                                <label for="@Model.AuthGroupList[i].ID">@Model.AuthGroupList[i].Name</label>
                                @Html.HiddenFor(modelItem => Model.AuthGroupList[i].ID)
                                @Html.HiddenFor(modelItem => Model.AuthGroupList[i].Name)
                                @Html.HiddenFor(modelItem => Model.AuthGroupList[i].Desc)
                                </div>
                            }
                        </div>
                </div>
                <br />
                <div class="userChanges"></div>
            </div>
            </fieldset>
        }

        @Html.HiddenFor(model => model.CalEventBO.ModeratorID)

        @if (Model.CalEventBO.TypeID == (int)CalEventType.BankHoliday || Model.CalEventBO.TypeID == (int)CalEventType.ColourDay || Model.CalEventBO.TypeID == (int)CalEventType.Holiday)
        {
            //Do not show any users

        }
        else
        {
            //Allow multiple selections for users 
            <br />
            <br />
            <fieldset class="modalFieldset">
                <legend>Moderator(s)</legend>
                <br />
            <div class="scrollCalModal">
            @{  int currentTeamID = -1;
                for (int i = 0; i < Model.MultiModList.Count; i++)
                {

                    // If the current team ID is not the same then make it the same
                    if (currentTeamID != Model.MultiModList[i].Team_ID)
                    {

                        currentTeamID = Model.MultiModList[i].Team_ID;

                        // if the item isn't the first close the div
                        if (i != 0)
                        {
                            @:</div>
                        }
                        @:<div style="margin-bottom:10px;">
                        // display the team name
                        <span class="floatR">
                            <a href="javascript:void(0)" class="teamcbx line" data-teamid="@Model.MultiModList[i].Team_ID" data-selecttype="all">All</a>
                            <a href="javascript:void(0)" class="teamcbx line" data-teamid="@Model.MultiModList[i].Team_ID" data-selecttype="none">None</a>
                        </span>
                        <strong style="display:block; margin-left:3px; margin-bottom:3px; background-color: #eee;">@(Model.MultiModList[i].Team_Name == null ? "Other" : Model.MultiModList[i].Team_Name)</strong>
                    }

                    <div class="blk_wn line">
                    @Html.CheckBoxFor(modelItem => Model.MultiModList[i].Include, new { id = "modID+" + i, @class = "addmodcbx team" + Model.MultiModList[i].Team_ID })
                    <label for="modID+@i">@Model.MultiModList[i].ModName</label>
                    @Html.HiddenFor(modelItem => Model.MultiModList[i].ModID)
                    <br />
                    </div>

                    // If this is the last entry close off the div
                    if (i == Model.MultiModList.Count - 1)
                    {
                        @:</div>
                    }
                }
            }
            </div>
            </fieldset>
        }

    </fieldset>
    @Html.ValidationSummary()
    <div class="searchcol_page"> 
    <span class="legendAction">[ <a href="javascript:void(0);" class="cancelBtn">Cancel</a> ]</span>
            <input type="submit" class="btn sav" value="Add Event" />
    </div>
  }
  </div>
   </div>

Script begins here, after the HTML.

  • are you loading partial view through ajax or you are prerendering it on server? – Alex Art. Nov 13 '15 at 11:48
  • Through ajax @AlexArt. – Exception_i Nov 13 '15 at 11:49
  • @StephenMuecke I'm passing razor variables to the script from the Model that's given to the partial view. It can not be in the main view. Have also tried on("load") and on("change") – Exception_i Nov 13 '15 at 11:51
  • if you load the partial view trough ajax $(document).ready will no fire – Alex Art. Nov 13 '15 at 11:52
  • @AlexArt. Hmm, that's weird because it actually is firing at the moment. That's not the problem. Problem is jQuery is not selecting elements, it's returning undefined. – Exception_i Nov 13 '15 at 11:53
  • @StephenMuecke The partial is given a model with variables according to what the user clicked. The script uses these variables. I cannot use variables that do not exist yet. – Exception_i Nov 13 '15 at 11:54
  • The partial view uses variables that are inside the model that is given to the partial. Have updated question with entire HTML. The script isn't actually in the partial view, it's bundled and being called by a function. – Exception_i Nov 13 '15 at 12:10

2 Answers2

0

While it is not considered to be a good practice to place scripts in partial view, if you absolutely need it there you can put a script an the bottom of your partial, without wrapping it with $(document).ready. You can use Immediately-Invoked Function Expression (IIFE) so it will be executed immediately when the script rendered on client. Placing the script at the bottom of your view will insure that all view content is already on the page:

Partial view should be something like this:

///You view content
<script>
 (function(){
    //your script goes here
 })()
</script>
Alex Art.
  • 8,711
  • 3
  • 29
  • 47
  • Thanks Alex. I've already tried this and I thought it would work but it doesn't. Script is after all HTML in the view, using (function() {}) and still is selecting undefined. – Exception_i Nov 13 '15 at 12:08
  • After your page is fully loaded (including partial), if you run this in console: `console.log($('#CalEventBO_CalEventSubType_ID').length)` is a result 1? – Alex Art. Nov 13 '15 at 12:14
  • Hmmm. Yes. It prints '1', then 'undefined'. What the hell? – Exception_i Nov 13 '15 at 12:21
  • In order to get name attribute you need to use `$('#CalEventBO_CalEventSubType_ID').attr('name')` instead of `$('#CalEventBO_CalEventSubType_ID').data("name")` – Alex Art. Nov 13 '15 at 19:09
0

I think you call wrong control. Maybe similar this:

@using (Ajax.BeginForm("Index", "CALL WRONG HERE",<-----