Bettelbursche
Bettelbursche

Reputation: 443

TypeError: grid is undefined

I have uploaded a page where the error occurs. It´s displayed in the console (please use F12 in Firefox or Chrome Browser). http://preventdefault.lima-city.de/index.php

This line is wrong: "kendo.stringify(grid.getOptions())"

My Question: How must i change this code so that i could store the changed table settings?

I also insert the html code here, Thx for answer !

    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">  
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.common.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.rtl.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.default.min.css"> 
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.default.min.css">

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>       
    <script src="http://cdn.kendostatic.com/2014.3.1411/js/jszip.min.js"></script>
    <script src="http://cdn.kendostatic.com/2014.3.1411/js/kendo.all.min.js"></script>

    <style type="text/css">
        .button-center {
            text-align: center; /* button position in grid */
        }
    </style>
</head>

<body role="document">

    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#">WebSiteName</a>
            </div>
            <div>
                <ul class="nav navbar-nav">
                    <li class="active"><a href="index.php">one</a></li>
                    <li><a href="next.php">two</a></li>
                </ul>
            </div>
        </div>
    </nav>  

    <div class="container theme-showcase" id="main" role="main">

        <div class="container">
            <h1>Page<small> one</small></h1> 
        </div>

        <div class="row-fluid">
            <div id="grid_one"></div>   
        </div> <!-- row -->

        <div class="row-fluid">
            <div id="log"></div>
        </div> <!-- row -->

    </div> <!-- container -->
<script>
<!-- --------------------------------------------------------------------------------- --> 
var firstNames = ["Nancy", "Andrew", "Janet", "Margaret", "Steven", 
                  "Michael", "Robert", "Laura", "Anne", "Nige"],
    lastNames = ["Davolio", "Fuller", "Leverling", "Peacock", "Buchanan", 
                 "Suyama", "King", "Callahan", "Dodsworth", "White"],
    cities = ["Seattle", "Tacoma", "Kirkland", "Redmond", "London", 
              "Philadelphia", "New York", "Seattle", "London", "Boston"],
    titles = ["Accountant", "Vice President, Sales", "Sales Representative", 
              "Technical Support", "Sales Manager", "Web Designer",
              "Software Developer", "Inside Sales Coordinator", "Chief Techical Officer", 
              "Chief Execute Officer"],
    birthDates = [new Date("1948/12/08"), new Date("1952/02/19"), new Date("1963/08/30"), 
                  new Date("1937/09/19"), new Date("1955/03/04"), new Date("1963/07/02"), 
                  new Date("1960/05/29"), new Date("1958/01/09"), new Date("1966/01/27"), 
                  new Date("1966/03/27")];

function createRandomData(count) {
    var data = [], now = new Date();

    for (var i = 0; i < count; i++) {
        var firstName = firstNames[Math.floor(Math.random() * firstNames.length)],
            lastName = lastNames[Math.floor(Math.random() * lastNames.length)],
            city = cities[Math.floor(Math.random() * cities.length)],
            title = titles[Math.floor(Math.random() * titles.length)],
            birthDate = birthDates[Math.floor(Math.random() * birthDates.length)],
            age = now.getFullYear() - birthDate.getFullYear();

        data.push({
            Id: i + 1,
            FirstName: firstName,
            LastName: lastName,
            City: city,
            Title: title,
            BirthDate: birthDate,
            Age: age
        });
    }
    return data;
}
<!-- --------------------------------------------------------------------------------- --> 
function onChangeSelection() {
    var selectedItem = this.dataItem(this.select());
    var Text = '<h1><small>row name=</small>' + selectedItem.FirstName + " " + selectedItem.LastName + "</h1>";
    console.log(Text);
    $("#log").html(Text);
    $("#ordernumber").val(selectedItem.ordernumber);
}
<!-- --------------------------------------------------------------------------------- --> 
function startbuttonclick(e) {      
    var data = this.dataItem($(e.currentTarget).closest("tr"));
    var Text = "<h1><small>Button click name=</small> " + data.FirstName + " " + data.LastName + "</h1>";       
    console.log(Text); 
    $("#log").html(Text);
    e.preventDefault();                         
}
<!-- --------------------------------------------------------------------------------- --> 
$(document).ready(function() {
    $("#grid_one").kendoGrid({
        dataSource: {
            data: createRandomData(10),
            schema: {
                model: {
                    fields: {
                        FirstName: { type: "string" },
                        LastName: { type: "string" },
                        City: { type: "string" },
                        Title: { type: "string" },
                        BirthDate: { type: "date" },
                        Age: { type: "number" }
                    }
                }
            },
            pageSize: 10
        },
        height: 500,
        dataBound: saveState,
        columnResize: saveState,
        columnShow: saveState,
        columnHide: saveState,
        columnReorder: saveState,
        columnLock: saveState,
        columnUnlock: saveState,        
        selectable: true,
        resizable: true,
        columnMenu: true,
        scrollable: true,
        sortable: true,
        filterable: true,
        change: onChangeSelection,            
        pageable: {
            refresh: true,
            pageSizes: true,
            buttonCount: 5,
            pageSizes: [5, 10, 20, 250]
        },
        columns: [
            {
                field: "FirstName",
                title: "First Name",
                width: "150px",
            },
            {
                field: "LastName",
                title: "Last Name",
                width: "150px",
            },
            {
                field: "City",
                hidden: true
            },
            {
                field: "Title",
                hidden: true
            },
            {
                field: "BirthDate",
                title: "Birth Date",
                template: '#= kendo.toString(BirthDate,"MM/dd/yyyy") #',
                width: "175px",
            },
            {
                field: "Age",
                width: "150px",
            },
            {
                command: { 
                    text: "Start", 
                    click: startbuttonclick }, 
                        title: "Start", 
                        width: "65px",
                    attributes:{
                        "class":"button-center"}            
            }
        ]
    });
    <!-- ------------------------------------------------------------------------------ -->     
    var grid = $("#grid_one").data("kendoGrid");

    function saveState(e) {
        e.preventDefault();
        localStorage["kendo-grid-one"] = kendo.stringify(grid.getOptions());
    };

    $(function (e) {
        var options = localStorage["kendo-grid-one"];
        if (options) {
            grid.setOptions(JSON.parse(options));
        } else {
          grid.dataSource.read();
        }
    }); 
});
<!-- --------------------------------------------------------------------------------- --> 
</script>
</body>
</html>

Upvotes: 1

Views: 6931

Answers (3)

fuyushimoya
fuyushimoya

Reputation: 9813

Edited for:

  1. Your var grid = $("#grid_one").data("kendoGrid"); only defined once, and it may not have data upon defined, it maybe insert by your kendogrid after.
  2. Domready Part should also need to have reference to it, you can either put it at origin location or move it into the function

  3. From your and dfsq's replies, the problem is that json CANNOT store a function, so you have to add it back to when retrieved from the localstorage

  4. In your current code, saveState will always be called before the setOptions one, which means the saveState just erased by your saveState function, so you have to move the setoptions code forward.

Changes a lot

$(document).ready(function() {
  // Get options first
  var options = localStorage["kendo-grid-one"];
  if (options) {
    options = JSON.parse(options);
    // Workaround to addback event
    options.columns[6].command.click = startbuttonclick;
  }

  $("#grid_one").kendoGrid({
        dataSource: {
            data: createRandomData(10),
            schema: {
            .....
    });
  if (options) {
    $("#grid_one").data("kendoGrid").setOptions(options);  
  }
  <!-- ------------------------------------------------------------------------------ -->     

  function saveState(e) {
    var grid = $("#grid_one").data("kendoGrid");
    e.preventDefault();
    localStorage["kendo-grid-one"] = kendo.stringify(grid.getOptions());
  };

See Demo Here, now it works.

  1. saveState part use dfsq's may be better
  2. options.columns[6].command.click = startbuttonclick; may be can write in a more elegant style, but here I just want to show why the issues come out and how to apply a basic solution.

Upvotes: 1

dfsq
dfsq

Reputation: 193301

The problem is that saveState function is called before grid is initialzed. you cantually don't need grid reference since saveState s called in grid context so you can simply use this instead:

function saveState(e) {
    e.preventDefault();
    localStorage["kendo-grid-one"] = kendo.stringify(this.getOptions());
};

Upvotes: 0

Sebastian Nette
Sebastian Nette

Reputation: 7842

I don't know kendo but the issue must be that the saveState function is called before the grid is declared.

JSFiddle: http://jsfiddle.net/8x7v7mga/1/

So somewhere in the construction of the kendo object, one of the saveState handlers is called.

You can avoid this by declaring the grid variable first and then in the saveState simply check if grid is defined or not:

var grid = null;

$("#grid_one").kendoGrid({ ... });

grid = $("#grid_one").data("kendoGrid");

function saveState(e) {
    e.preventDefault();
    grid && localStorage["kendo-grid-one"] = kendo.stringify(grid.getOptions());
};

Upvotes: 0

Related Questions