This is a migrated thread and some comments may be shown as answers.

Grid is double firing in Ipad / Safari

5 Answers 118 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Davin
Top achievements
Rank 1
Davin asked on 03 Jun 2013, 09:44 PM
I am making a C# Razor MVC web app that is geared for Ipad. I am using JQuery mobile and Kendo UI. Kendo has presented me with some tough bugs that I cannot seem to fix.

My Kendo grid is double firing in Ipad (Safari). This is unnoticeable in desktop apps such as Google Chrome or Firefox but in Safari it is showing up. Is this a known issue or is my code wrong? I have 2 input forms that use Kendo grid that sit in a JQuery popup window.

Are there any known issues running JQuery Mobile and Kendo UI. The reason I ask is that I have have to comment out either the JQuery scripts that comes with Kendo or Vice versa to make everything play nice. This has come at a cost where JQuery pluggins such as Fittext which needs JQuery to run does not work.

attached are 2 pics of the problem forms (waste and downtime) and below is my _Layout.cshtml and Ham.cshtml (which is my view) code. Any help is greatly appreciated!

_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    @{

        if (Session["currentDate"] == null)
        {
            HttpContext.Current.Session["currentDate"] = DateTime.Today.ToString("yyyy-MM-dd");
        }

        if (Session["currentShift"] == null)
        {
            HttpContext.Current.Session["currentShift"] = 1;
        }

        if (Session["ReportType"] == null)
        {
            HttpContext.Current.Session["ReportType"] = "Daily";
        }
            
    }

    <title>@ViewBag.Title</title>
    <meta name="viewport" content="initial-scale = 1.0, maximum-scale = 1.0, user-scalable = no, width=device-width" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <link href="~/Resources/Triangle.ico" rel="shortcut icon" type="image/x-icon" />

    @Styles.Render("~/Content/mobileCss", "~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")

    <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.common.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.silver.min.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/kendo/2013.1.319/kendo.dataviz.silver.min.css")" rel="stylesheet" type="text/css" />

    @*<script src="@Url.Content("~/Scripts/kendo/2013.1.319/jquery.min.js")"></script>*@
    <script src="@Url.Content("~/Scripts/kendo/2013.1.319/kendo.all.min.js")"></script>
    <script src="@Url.Content("~/Scripts/kendo/2013.1.319/kendo.aspnetmvc.min.js")"></script>
    @*<script src="@Url.Content("~/Scripts/kendo.modernizr.custom.js")"></script>*@
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

    <script type="text/javascript">


        //prevents ipad vertical bounce scrolling
        document.ontouchmove = function (event) {
            event.preventDefault();
        }

        function UpdateDate() {
            UpdateSessionDate();
            UpdateSessionShift();
            UpdateSessionReportType();

            //$('#datepick').val('AT(Session["currentDate"])');

            var DatePageType = '@(ViewBag.DatePageType)';

                if (DatePageType == "Reporting") {

                    UpdateCharts();
                }
                if (DatePageType == "LiveView") {
                    UpdateViews($('#hoursaver').val());
                    UpdateLineViews($('#hoursaver').val());
                    UpdateOverallInfoBox($('#linesaver').val());
                    UpdateOverviewOfLabourChart()
                }
                if (DatePageType == "LabourEntry") {
                    // UpdateViews($('#hoursaver').val());
                    refreshLabourEntry();
                }

            }

            function UpdateShift() {
                UpdateSessionDate();
                UpdateSessionShift();

                //$('#datepick').val('AT(Session["currentDate"])');

                var DatePageType = '@(ViewBag.DatePageType)';

                if (DatePageType == "Reporting") {
                    UpdateCharts();
                }
                if (DatePageType == "LiveView") {
                    UpdateViews($('#hoursaver').val());
                    UpdateLineViews($('#hoursaver').val());
                    UpdateOverallInfoBox($('#linesaver').val());
                }
                if (DatePageType == "LabourEntry") {
                    refreshLabourEntry();

                }
            }

            function pullfrompeviousLoad(objThis) {
                var url = $(objThis).data('url') + '?hour=' + $(objThis).data('hour') + '&Shift=' + $(objThis).data('shift') + '&LineName=' + $(objThis).data('line');
                window.location.href = url;
            }

            function menuLoad(objThis) {
                var url = $(objThis).data('url');
                window.location.href = url;
            }

            function buttonLoad(objThis) {
                var url = $(objThis).data('url') + '?hour=' + $(objThis).data('time');
                window.location.href = url;
            }

            function saveLoad(objThis) {

                $('#labourform').submit();
                var url = $(objThis).data('url') + '?hour=' + $(objThis).data('time');
                window.location.href = url;
                return false;
            }

            // update date session data
            function UpdateSessionDate() {

                $.post('/SetSession/SetVariable',
                       {
                           key: "currentDate",
                           value: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd")
                       });

            };

            // update shift session data
            function UpdateSessionShift() {

                $.post('/SetSession/SetVariable',
                       {
                           key: "currentShift",
                           value: $('#shift').val()
                       });

            };


            // update report type session data
            function UpdateSessionReportType() {

                $.post('/SetSession/SetVariable',
                       {
                           key: "ReportType",
                           value: $('#ReportType').val()
                       });

            };

            function UpdateButtons(h) {
                var arrayToModify = [];
                var i = 0, j, k, buttonsToCreate, buttonContainer, newButton;
                var buttonsToCreate = [];
                var now = parseInt(h);

                for (var j = (now - 7) ; j <= (now + 7) ; j++) {

                    if (j >= 0 && j <= 23) {
                        buttonsToCreate[i] = j;
                        i++;
                    }
                }

                buttonContainer = document.getElementById('ddShift');

                for (k = 0; k < buttonsToCreate.length; k++) {

                    if (buttonsToCreate[k] == parseInt(h) + 1) {
                        newButton.style.cssText = 'background-color: red;';
                    }

                    newButton = document.createElement('input');
                    newButton.type = 'button';
                    newButton.value = buttonsToCreate[k];
                    newButton.id = buttonsToCreate[k];
                    newButton.onclick = function () {
                        arrayToModify[arrayToModify.length] = this.id;
                        $('#hoursaver').val(this.id);
                        UpdateViews(this.id);
                        UpdateLineViews(this.id);
                    };

                    buttonContainer.appendChild(newButton);
                }
            };

            kendo.culture("en-US");

    </script>

</head>

<body>

    <div data-role="page" data-theme="b" id="index">

        <div data-role="header" data-position="fixed">
            <h1>@ViewBag.Title</h1>
            <a href="#nav-panel" data-icon="bars" data-iconpos="notext" class="ui-btn-left">Menu</a>

            @if (Request.IsAuthenticated)
            {
                @Html.ActionLink("My Account", "Index", "Account", routeValues: null, htmlAttributes: new { data_icon = "gear" })
            }
            else
            {
                @Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { data_icon = "gear" })
            }


            <div class="datepickerbtn" style="width: 212.5px;">

                @(Html.Kendo().DatePicker()
                      .Name("datepicker")
                      .Events(e =>
                          {
                              e.Change("UpdateDate");
                          })
                  .Format("yyyy-MM-dd")
                  .Value((String)Session["currentDate"])
                )
            </div>

            <div class="shiftpickerbtn" id="btnshift">
                <select id="shift" name="shift" onchange="UpdateShift()">
                    <option value="1">Shift 1</option>
                    <option value="2">Shift 2</option>
                </select>
            </div>


        </div>
        <div data-role="content">

            @RenderBody()
        </div>
        <div data-role="footer" style="text-align: center" data-position="fixed">
            @RenderSection("footer", false)
        </div>
        <div data-role="panel" data-position-fixed="true" data-theme="b" data-content-theme="d" id="nav-panel">
            <ul data-role="listview" data-theme="a" class="nav-search">
                <li data-icon="delete"><a href="#" data-rel="close">Close menu</a></li>
                <li><a data-url="@Url.Action("Index", "Home")" onclick="menuLoad(this)">Home</a></li>
                <li><a data-url="@Url.Action("Index", "LabourEntry")" onclick="menuLoad(this)">Labour Entry</a></li>
                <li><a data-url="@Url.Action("Index", "LiveView")" onclick="menuLoad(this)">Live View</a></li>
                <li><a data-url="@Url.Action("Index", "Report")" onclick="menuLoad(this)">Reporting</a></li>
                <li><a data-url="@Url.Action("Loin", "ScheduleBuilder")" onclick="menuLoad(this)">Schedule Builder</a></li>
                <li><a data-url="@Url.Action("About", "Home")" onclick="menuLoad(this)">About</a></li>
                <li><a data-url="@Url.Action("Contact", "Home")" onclick="menuLoad(this)">Contact</a></li>
            </ul>

        </div>

    </div>

    @RenderSection("scripts", required: false)
</body>
</html>


Ham.cshtml (my view)

@model IEnumerable<OPS.Models.LabourSchedule>

@{
    ViewBag.Title = "Ham";
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.DatePageType = "LabourEntry";
}

<script>

    $(document).ready(function () {

        //set the value of the datepicker and Shift via session variables
        $('#datepicker').val('@(Session["currentDate"])');
        $('#shift').val('@(Session["currentShift"])');
        $('#shift').selectmenu('refresh');

        $('#lblWasteFormDate').html('@(Session["currentDate"])');

    });

        function Update_Data() {
            return {
                CurDate: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd")
            };
        }

        function Read_Data() {
            return {
                LineName: "Ham",
                CurDate: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd"),
                ShiftName: @(Session["currentShift"]) + ""
            };
        }

        function Read_DT_Data() {
            return {
                LineName: "Ham",
                CurDate: kendo.toString($("#datepicker").data("kendoDatePicker").value(), "yyyy-MM-dd"),
                ShiftName: $("#shift").val() + ""
            };
        }

</script>


@section footer
            {
    <div data-inline="true">

        <div data-inline="true">
            @if (ViewBag.curHour > 0)
            {                                    
                <a data-role="button" href="#" data-url="@Url.Action("Ham", "LabourEntry")" onclick="buttonLoad(this)"  data-icon="arrow-l" data-iconpos="notext" data-theme="c" data-inline="true" data-time="@ViewBag.prevHour"></a>                  
            }
            @for (var i = ViewBag.curHour - 7; i <= ViewBag.curHour + 7; i++)
            {

                if (ViewBag.curHour == i)
                {                            
                <a data-role="button" href="#" data-theme="b" data-inline="true">@i</a>                                
                }
                else if (@i >= 0 && @i <= 23)
                {                             
                <a data-role="button" href="#" data-url="@Url.Action("Ham", "LabourEntry")" onclick="buttonLoad(this)" data-theme="c" data-inline="true" data-time="@i">@i</a>                                          
                            
                }

            }
            @if (ViewBag.curHour < 23)
            {                                                          
                <a data-role="button" href="#" data-url="@Url.Action("Ham", "LabourEntry")" onclick="buttonLoad(this)"  data-icon="arrow-r" data-iconpos="notext" data-theme="c" data-inline="true" data-time="@ViewBag.nextHour">Arrow right</a>                    
            }
            <a href="#popupMenu" data-rel="popup" data-role="button" data-inline="true" data-transition="slideup" data-icon="grid" data-iconpos="notext" data-theme="b">Options</a>
        </div>

    </div>
    <div data-role="popup" id="popupDownTime" class="ui-content" data-theme="d" data-overlay-theme="a" data-dismissible="false" style="width: 80%; position: relative; margin: 20px auto;">
        <a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>

        <div id="update-message"></div>
        @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "DTForm" }))
        {
                
            <input type="hidden" name="LineName" value="Ham" />
            <table>
                <tr>
                    <td colspan="3">
                        <label for="categories">Downtime Reason:</label>
                        @(Html.Kendo().DropDownList()
                                    .Name("DTCatId")
                                    .OptionLabel("Select downtime...")
                                    .HtmlAttributes(new { style = "width:90%;" })
                                    .DataTextField("Name")
                                    .DataValueField("ID")
                                    .DataSource(source =>
                                    {
                                        source.Read(read =>
                                        {
                                            read.Action("GetDowntimeCategories", "LabourEntry");
                                        });
                                    })
                            )
                    </td>
                </tr>
                <tr>
                    <td>
                        <label for="txt_DT_Duration">Duration (minutes):</label>
                        <input type="number" name="DT_Duration" pattern="[0-9]*" id="txt_DT_Duration" value="" />
                    </td>
                    <td>
                        <label for="txt_DT_People"># of People:</label>
                        <input type="number" name="DT_People" pattern="[0-9]*" id="txt_DT_People" value="" />
                    </td>
                    <td>
                        <label for="sl_Hrs_Type">Hours Type:</label>
                        <select name="Hrs_Type" id="sl_Hrs_Type" data-role="slider">
                            <option value="OT">OT</option>
                            <option value="REG" selected="selected">Reg</option>
                        </select>
                    </td>

                </tr>
                <tr>
                    <td colspan="3">
                        <label for="txt_DT_Desc">Description Detail:</label>
                        <textarea rows="12" name="DT_Desc" id="txt_DT_Desc"></textarea>
                    </td>
                </tr>
                <tr>
                    <td colspan="3">
                        <input type="submit" name="submit" value="Add Downtime" />
                    </td>

                </tr>
                <tr>
                    <td colspan="3">
                        @(Html.Kendo().Grid<OPS.Models.DownTime>()
                                .Name("DTGrid")
                                .Columns(columns =>
                                {
                                    columns.Bound(p => p.ID).Hidden(true);
                                    columns.Bound(p => p.DT_ID).Hidden(true);
                                    columns.Bound(p => p.HR_TYPE).Hidden(true);
                                    columns.Bound(p => p.LINE_ID).Hidden(true);
                                    columns.Bound(p => p.SHIFT).Hidden(true);
                                    columns.Bound(p => p.USER_ID).Hidden(true);
                                    columns.Bound(p => p.DT_REASON).Title("Reason");
                                    columns.Bound(p => p.DT_DETAIL).Title("Details");
                                    columns.Bound(p => p.DURATION).Title("Duration (mins)");
                                    columns.Bound(p => p.NUM_EFFECTED).Title("# of People");
                                })
                                 .ToolBar(toolbar =>
                                    {
                                        toolbar.Save();
                                    })
                                .Editable(editable => editable.Mode(GridEditMode.InCell))
                                .Sortable()
                                .Scrollable()
                                .Resizable(resize => resize.Columns(true))
                                .DataSource(dataSource => dataSource
                                    .Ajax()
                                    .Model(model =>
                                    {
                                        model.Id(p => p.ID);
                                    })
                                    .Batch(true)
                                    .ServerOperation(false)
                                    .Events(events => events.Error("error"))              
                                    .Read(read => read.Action("DT_Read", "LabourEntry")
                                                        .Data("Read_DT_Data"))
                                    .Update(update => update.Action("DT_Update", "LabourEntry"))
                                )
                            )
                    </td>
                </tr>
            </table>
            
        }
    </div>

    <div data-role="popup" id="popupWaste" class="ui-content" data-theme="d" data-overlay-theme="a" data-dismissible="false" style="width: 90%; position: relative; margin: 20px auto;">
        <a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>

        <div style="width: 100%;">

                <h3>Date: <label id="lblWasteFormDate"></label>
                    </h3>


            @(Html.Kendo().Grid<OPS.Models.LineProductWasteEntry>()
            .Name("WasteGrid")
            .Columns(columns =>
            {

                columns.Bound(p => p.Id).Hidden(true);
                columns.Bound(p => p.BucketWeight).Hidden(true);
                columns.Bound(p => p.LineCategoryId).Hidden(true);
                columns.Bound(p => p.LineCategoryProduct).Hidden(true);
                columns.Bound(p => p.LineProductId).Hidden(true);
                columns.Bound(p => p.ShiftId).Hidden(true);
                columns.Bound(p => p.SourceId).Hidden(true);
                columns.Bound(p => p.UserId).Hidden(true);
                columns.Bound(p => p.CategoryName);
                columns.Bound(p => p.ProductName);
                columns.Bound(p => p.Value);
                columns.Bound(p => p.SourceName);
                columns.Bound(p => p.Source);
                columns.Bound(p => p.Weight);
                columns.Bound(p => p.Weight2);
                columns.Bound(p => p.Weight3);
            })
            .ToolBar(toolbar =>
            {
                toolbar.Save();
            })
            .Editable(editable => editable.Mode(GridEditMode.InCell))
            .Sortable()
            .Scrollable()
            .Resizable(resize => resize.Columns(true))
            .DataSource(dataSource => dataSource
                .Ajax()
                .Model(model =>
                {
                    model.Id(p => p.Id);
                    model.Field(p => p.SourceName).Editable(false);
                    model.Field(p => p.CategoryName).Editable(false);
                    model.Field(p => p.ProductName).Editable(false);
                    model.Field(p => p.Value).Editable(false);
                })
                .Batch(true)
                .ServerOperation(false)
                .Events(events => events.Error("error"))        
                .Read(read => read.Action("Waste_Read", "LabourEntry")
                                    .Data("Read_Data"))
                .Update(update => update.Action("Waste_Update", "LabourEntry")
                                    .Data("Update_Data"))

            )

        )

        </div>
    </div>
    <div data-role="popup" id="popupMenu" data-theme="a">
        <ul data-role="listview" data-inset="true" style="min-width: 270px;" data-theme="a" class="nav-search">
            <li><a href="#popupWaste" data-rel="popup" data-position-to="window" data-transition="pop">Add Waste</a></li>
            <li><a href="#popupDownTime" data-rel="popup" data-position-to="window" data-transition="pop">Add Downtime</a></li>

        </ul>
    </div>

}










5 Answers, 1 is accepted

Sort by
0
Petur Subev
Telerik team
answered on 05 Jun 2013, 11:24 AM
Hello Davin,

What do  you mean by 'My Kendo grid is double firing'. Do you mean that your requests are executed twice or some of its events are fired twice?

Basically nothing should be triggered twice - even on desktop browsers. Does this behavior exist on our online demos?

If not can you reproduce this in a jsbin?

Kind Regards,
Petur Subev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Davin
Top achievements
Rank 1
answered on 11 Jun 2013, 01:23 PM
I am unable to recreate the bug in desktop applications. It only shows up on Ipad in both Safari and Chrome. What I mean by double firing is that the grid appears twice, once where it is supposed to and a ghost version that appears below it (see picture). Can you run my code in an ipad?
0
Petur Subev
Telerik team
answered on 13 Jun 2013, 10:18 AM
Hello Davin,

I am not able to run your code. Could you please send us small & runnable project which we can run on iPad and see the exact reason for that behavior?

Regards,
Petur Subev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Davin
Top achievements
Rank 1
answered on 18 Jun 2013, 01:05 AM
Hi Peter, we may not need to run it on ipad to figure out the problem, I relaized that the controller  action called Waste_Read (which loads the grid with the data) is being called twice. So the grid is populated twice. Ipad shows the second set of data while desktops dont. From looking at my code do you have any idea why that is happening?

thanks
0
Petur Subev
Telerik team
answered on 19 Jun 2013, 10:45 AM
Hello Davin,

I am not sure what exactly might be behind this. Try commenting some of the code, put a breakpoint in one of the events of the Grid such as dataBinding and go up the call stack to see what exactly triggered the request.


Kind Regards,
Petur Subev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Grid
Asked by
Davin
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
Davin
Top achievements
Rank 1
Share this question
or