1

I am developing a system at ASP.NET MVC4. I have a code written at javascript, and which executes when the page starts, to display a graph about the performance of some students.

The code of the graph is the following

<script>
    window.onload = function () {
        var r = Raphael("holder"),
            txtattr = { font: "20px sans-serif" };

        var lines = r.linechart(30, 30, 600, 440,<%= Json.Encode(ViewBag.dates) %>,<%= Json.Encode(ViewBag.Grades)%>, {axisxstep : 6,nostroke: false, axis: "0 0 1 1", symbol: "circle", smooth: false }).hoverColumn(function () {
            this.tags = r.set();
            for (var i = 0, ii = this.y.length; i < ii; i++) {
                this.tags.push(r.tag(this.x, this.y[i], Number(this.values[i]).toFixed(5), 160, 10).insertBefore(this).attr([{ fill: "#fff" }, { fill: this.symbols[i].attr("fill") }]));
            }
        });
</script>

The data of the graph, come from the function of the controller DisplayGraph. The code of the controller is shown below.

public ActionResult DisplayGraph(String InputStudent = "IP11")
{
    var query = (from b in db.gradesPerStudent
                 where b.Student.Equals(InputStudent)
                 orderby b.Date
                 select b);

    ViewBag.ChartEmpty = "No";
    if (query.ToList().Count == 0)
    {
        ViewBag.ChartEmpty = "Yes";
        ViewBag.Title = "No results for Student " + InputStudent;
        ViewBag.dates = null;
        ViewBag.grades = null;
        DateTime aminDate = new DateTime();
        ViewBag.minDate = aminDate.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
        return View();
    }

    DateTime minDate = query.Min(y => y.Date);
    DateTime maxDate = query.Max(y => y.Date);
    var dates = query.Select(x => EntityFunctions.DiffDays(query.Min(y => y.Date), x.Date));
    var grades = query.Select(x => x.grades);
    var datestable = dates.ToArray();
    var gradestable = grades.ToArray();
    List<int?> dateslist = new List<int?>();
    List<double> gradeslist = new List<double>();
    double result = dates.Count() * 1.0 / 70.0;
    int pointStep = (int)Math.Ceiling(result);
    for (int i = 0; i < dates.Count(); i = i + pointStep)
    {
            dateslist.Add(datestable.ElementAt(i));
            gradeslist.Add(gradestable.ElementAt(i));
    }
    ViewBag.dates = dateslist;
    ViewBag.grades = gradeslist;

    ViewBag.minDate = minDate.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;

    return View(query.ToList());

}

Now, at when the student is new at a school, I do not want to display a graph, but a message that the student is new, and there are no statistics yet for that student.

So my question is. How do I say from my controller when a javascript should be executed and when not?

Thanks a lot

1
  • @ekad Thanks a lot. this is a very nice idea. I think Tim has already updated his answer. Commented Feb 1, 2014 at 4:57

2 Answers 2

2

How do I say from my controller when a javascript should be executed and when not?

Via a view model. A view model should contain all the information needed to render the view, and the view should contain your script (or a link to it).

Try to minimize using ViewBag, and prefer strongly-typed models.

Model

public class MyViewModel {
    public bool ShowGraph { get; set; }

    public List<object> Data { get; set; }

    public List<int?> Dates { get; set; }

    public List<double> Grades { get; set; }
}

Controller

public ActionResult Index(){

    var model = new MyViewModel();
    model.ShowGraph = !IsStudentNew();

    // set your other properties here, instead of using the ViewBag

    return View( model );
}

View

@model MyViewModel

@if( Model.ShowGraph ){
    <script>
        // javascript to render graph goes here
    </script>
}else{
    <div>No statistics yet.</div>
}
Sign up to request clarification or add additional context in comments.

2 Comments

This seems really nice. Thanks. I will try that now. But creating a model is the easiest way? Because my view is also connected with an other model already...
Creating a model is nearly always the correct approach. It looks like query.ToList() is your current model? You can set that value as a property of your new view model (e.g. the Data property).
0

I would just have a GraphText property of your model. Display it over the top of the graph. If there's statistics, then leave this property empty. If there isn't.. give it a value:

public class YourModel {
    public IList<Statistic> StudentStatistics { get; set; }
    public string GraphText {
        get {
            return StudentStatistics.Any() ? "" : "No statistics yet";
        }
    }
}

Then in your view, just render the GraphText property over the top of the graph.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.