1

Okay so last time I asked a question on MVC3 it got extremely down voted and I have no idea why, so if this goes the same way, please give me the reason so I can fix it. Anyway, I'm try to take a string from a model and put it into Javascript. The Javascript manipulates the string. I already have the Javascript working with static strings in an array, however I wish to have these strings in a SQL database and load it into a model and from there put it into my Javascript that is already doing the bulk of the work.

Here is My javascript:

function questionViewModel() {
    this.questions = new Array("Whats the difference between axial leads and radial leads?", "What is the difference between AC and DC current?", "Is Nikola Telsa known for his work with AC current or DC current.", "What is a semiconductor?");
    this.answers = new Array();
    this.answers[0] = new Array("Radial leads point in the same direction, while axial leads point in oppossite directions", "Radial leads are round, while Axial leads are square", "There is no difference");
    this.answers[1] = new Array("DC has current flowing constantly in one direction, while AC has the flow of current changing.", "AC has current flowing constantly in one direction, while DC has the flow of current changing.", "AC is weaker than DC");
    this.answers[2] = new Array("AC", "DC", "Both");
    this.answers[3] = new Array("A material which has electrical conductivity between that of a metal and an insulator.", "Something that reduces the flow of current", "A large wire");
    this.right = new Array("Radial leads point in the same direction, while axial leads point in oppossite directions", "DC has current flowing constantly in one direction, while AC has the flow of current changing.", "AC", "A material which has electrical conductivity between that of a metal and an insulator.");
    this.i = Math.floor(Math.random() * this.questions.length);
    this.a = Math.floor(Math.random() * this.answers[0].length);
    var iAns1 = this.i;
    var iAns2 = this.i;
    var iAns3 = this.i;
    this.currentQuestion = this.questions[this.i];
    this.nextQuestion = "";
    this.answer1 = ko.observable(this.answers[this.i][0]);
    this.answer2 = ko.observable(this.answers[this.i][1]);
    this.answer3 = ko.observable(this.answers[this.i][2]);
}

So what I'm hoping to do is load the strings into the questions and answers arrays from a model, I imagine this would be done in the controller for the most part, then the script would append it to the view.

If anyone can help my it would be extremely appreciated, and by the way, I'm very new to .Net and MVC3 so I need all the help I can get. Thank you.

tereško
  • 58,060
  • 25
  • 98
  • 150
Christian Grabowski
  • 2,782
  • 3
  • 32
  • 57
  • 1
    You can access the model properties directly from the javascript: see: http://stackoverflow.com/questions/4599169/using-razor-within-javascript?rq=1 – markpsmith Jul 12 '13 at 13:27
  • Thanks, but this is in a separate JS file that is being loaded asynchronously, and that seems to only address static in-line JS – Christian Grabowski Jul 12 '13 at 13:53
  • How about assigning your model properties to hidden fields @Html.Hidden? Then access them from the javascript via an id or class selector. – markpsmith Jul 12 '13 at 13:59
  • I was just thinking that hahaha. could you give me some sample code though? I'm extremely new to MVC and asp.net. – Christian Grabowski Jul 12 '13 at 14:30

3 Answers3

1

I did this last Friday, so it'll be hard to describe being it's monday and I just got to work, anyway here's the solution I ended up using:

controller:

public ViewResult Questionare()
    {
        Goldienator.Models.QuestionnaireModel model = new Models.QuestionnaireModel();
        model.question1 = "Whats the difference between axial leads and radial leads?";
        model.question2 = "What is the difference between AC and DC current?";
        model.question3 = "Is Nikola Telsa known for his work with AC current or DC current?";
        model.question4 = "What is a semiconductor?";
        model.answer11 = "Radial leads point in the same direction, while axial leads point in oppossite directions";
        model.answer12 = "Radial leads are round, while Axial leads are square";
        model.answer13 = "There is no difference";
        model.answer21 = "DC has current flowing constantly in one direction, while AC has the flow of current changing.";
        model.answer22 = "AC has current flowing constantly in one direction, while DC has the flow of current changing.";
        model.answer23 = "AC is weaker than DC";
        model.answer31 = "AC";
        model.answer32 = "DC";
        model.answer33 = "Both";
        model.answer41 = "A material which has electrical conductivity between that of a metal and an insulator.";
        model.answer42 = "Something that reduces the flow of current";
        model.answer43 = "A large wire";
        return View(model);
    }

model:

public class QuestionnaireModel
{
    public string question1;
    public string question2;
    public string question3;
    public string question4;
    public string answer11;
    public string answer12;
    public string answer13;
    public string answer21;
    public string answer22;
    public string answer23;
    public string answer31;
    public string answer32;
    public string answer33;
    public string answer41;
    public string answer42;
    public string answer43;
}

view:

<div style="margin:0 20px 0 20px;" >
    <input type="text" id="question1" style="display: none;" value="@Model.question1">
    <input type="text" id="question2" style="display: none;" value="@Model.question2">
    <input type="text" id="question3" style="display: none;" value="@Model.question3">
    <input type="text" id="question4" style="display: none;" value="@Model.question4">
    <input type="text" id="answer11" style="display: none;" value="@Model.answer11">
    <input type="text" id="answer12" style="display: none;" value="@Model.answer12">
    <input type="text" id="answer13" style="display: none;" value="@Model.answer13">
    <input type="text" id="answer21" style="display: none;" value="@Model.answer21">
    <input type="text" id="answer22" style="display: none;" value="@Model.answer22">
    <input type="text" id="answer23" style="display: none;" value="@Model.answer23">
    <input type="text" id="answer31" style="display: none;" value="@Model.answer31">
    <input type="text" id="answer32" style="display: none;" value="@Model.answer32">
    <input type="text" id="answer33" style="display: none;" value="@Model.answer33">
    <input type="text" id="answer41" style="display: none;" value="@Model.answer41">
    <input type="text" id="answer42" style="display: none;" value="@Model.answer42">
    <input type="text" id="answer43" style="display: none;" value="@Model.answer43">
    Click start to be asked a question, if you get enough right, you will recieve a discount!
    <button id="start" value="start" onclick="start()">start</button>
    <p data-bind="text: currentQuestion"></p>
    <label>Answer:</label>
    <div>
        <input type="radio" id="answer1" name="ans" style="margin: 10px;" data-bind="value: answer1()"><span data-bind="text: answer1()"></span><br>
        <input type="radio" id="answer2" name="ans" style="margin: 10px;" data-bind="value: answer2()"><span data-bind="text: answer2()"></span><br>
        <input type="radio" id="answer3" name="ans" style="margin: 10px;" data-bind="value: answer3()"><span data-bind="text: answer3()"></span><br>
    </div>
    <button id="answerSubmit" value="submit" onclick="questionare()" style="margin: 10px;">submit</button>
    <p id="message"></p>
    <p id="message2"></p>
    <p style="float: right;">Question <span id="counter"></span></p>
</div>

Javascript:

function questionViewModel() {
    this.questions = new Array(document.getElementById('question1').value, document.getElementById('question2').value, document.getElementById('question3').value, document.getElementById('question4').value);
    this.answers = new Array();
    this.answers[0] = new Array(document.getElementById('answer11').value, document.getElementById('answer12').value, document.getElementById('answer13').value);
    this.answers[1] = new Array(document.getElementById('answer21').value, document.getElementById('answer22').value, document.getElementById('answer23').value);
    this.answers[2] = new Array(document.getElementById('answer31').value, document.getElementById('answer32').value, document.getElementById('answer33').value);
    this.answers[3] = new Array(document.getElementById('answer41').value, document.getElementById('answer42').value, document.getElementById('answer43').value);
    this.right = new Array(document.getElementById('answer11').value, document.getElementById('answer21').value, document.getElementById('answer31').value, document.getElementById('answer41').value);
    this.i = Math.floor(Math.random() * this.questions.length);
    this.a = Math.floor(Math.random() * this.answers[0].length);
    var iAns1 = this.i;
    var iAns2 = this.i;
    var iAns3 = this.i;
    this.currentQuestion = this.questions[this.i];
    this.nextQuestion = "";
    this.answer1 = ko.observable(this.answers[this.i][0]);
    this.answer2 = ko.observable(this.answers[this.i][1]);
    this.answer3 = ko.observable(this.answers[this.i][2]);
    this.nAns1 = "";
    this.nAns2 = "";
    this.nAns3 = "";
    if (this.i + 1 < this.questions.length && this.a + 2 < this.answers[0].length) {
        this.nextQuestion = this.questions[this.i + 1];
        this.nAns1 = ko.observable(this.answers[this.i + 1][this.a]);
        this.nAns2 = ko.observable(this.answers[this.i + 1][this.a + 1]);
        this.nAns3 = ko.observable(this.answers[this.i + 1][this.a + 2]);
        iAns1++;
        iAns2++;
        iAns3++;
    }
    else if (this.i + 1 < this.questions.length && this.a + 2 == this.answers[0].length) {
        this.nextQuestion = this.questions[this.i + 1];
        this.nAns1 = ko.observable(this.answers[this.i + 1][this.a]);
        this.nAns2 = ko.observable(this.answers[this.i + 1][this.a + 1]);
        this.nAns3 = ko.observable(this.answers[this.i + 1][0]);
        iAns1++;
        iAns2++;
        iAns3++;
    }
    else if (this.i + 1 < this.questions.length && this.a + 2 > this.answers[0].length) {
        this.nextQuestion = this.questions[this.i + 1];
        this.nAns1 = ko.observable(this.answers[this.i + 1][1]);
        this.nAns2 = ko.observable(this.answers[this.i + 1][this.a]);
        this.nAns3 = ko.observable(this.answers[this.i + 1][0]);
        iAns1++;
        iAns2++;
        iAns3++;
    }
    else if (this.i + 1 == this.questions.length && this.a + 2 < this.answers[0].length) {
        this.nextQuestion = this.questions[0];
        this.nAns1 = ko.observable(this.answers[0][this.a]);
        this.nAns2 = ko.observable(this.answers[0][this.a+1]);
        this.nAns3 = ko.observable(this.answers[0][this.a + 2]);
        iAns1=0;
        iAns2=0;
        iAns3=0;
    }
    else if (this.i + 1 == this.questions.length && this.a + 2 == this.answers[0].length) {
        this.nextQuestion = this.questions[0];
        this.nAns1 = ko.observable(this.answers[0][this.a]);
        this.nAns2 = ko.observable(this.answers[0][this.a + 1]);
        this.nAns3 = ko.observable(this.answers[0][0]);
        iAns1 = 0;
        iAns2 = 0;
        iAns3 = 0;
    }
    else if (this.i + 1 == this.questions.length && this.a + 2 > this.answers[0].length) {
        this.nextQuestion = this.questions[0];
        this.nAns1 = ko.observable(this.answers[0][1]);
        this.nAns2 = ko.observable(this.answers[0][this.a]);
        this.nAns3 = ko.observable(this.answers[0][0]);
        iAns1 = 0;
        iAns2 = 0;
        iAns3 = 0;
    }
    else {
        this.nextQuestion = this.questions[0];
        this.nAns1 = ko.observable(this.answers[0][0]);
        this.nAns2 = ko.observable(this.answers[0][1]);
        this.nAns3 = ko.observable(this.answers[0][2]);
    }
    this.getI = function () { return this.i; };
    this.getA = function () { return this.a; };
    this.getRight = function () { return this.right[this.i]; };
    this.getAns1 = function () {
        return this.answer1();
    };
    this.getAns2 = function () {
        return this.answer2();
    };
    this.getAns3 = function () {
        return this.answer3();
    };
    this.setAns1 = function () {
        this.answer1 = this.nAns1;
        if (iAns1 + 1 < this.answers.length) {
            this.nAns1 = ko.observable(this.answers[iAns1 + 1][0]);
            iAns1++;
        } else {
            this.nAns1 = ko.observable(this.answers[0][0]);
            iAns1 = 0;
        }
    };
    this.setAns2 = function () {
        this.answer2 = this.nAns2;
        if (iAns2 + 1 < this.answers.length) {
            this.nAns2 = ko.observable(this.answers[iAns2 + 1][1]);
            iAns2++;
        } else {
            this.nAns2 = ko.observable(this.answers[0][1]);
            iAns2 = 0;
        }
    };
    this.setAns3 = function () {
        this.answer3 = this.nAns3;
        if (iAns3 + 1 < this.answers.length) {
            this.nAns3 = ko.observable(this.answers[iAns3 + 1][2]);
            iAns3++;
        } else {
            this.nAns3 = ko.observable(this.answers[0][2]);
            iAns3 = 0;
        }
    };
    this.getList = function () {
        return this.questions;
    };
    this.getCurrent = function () {
        return this.currentQuestion;
    };
    this.getNext = function () {
        return this.nextQuestion;
    };
    this.getLength = function () {
        return this.questions.length;
    };
    this.setQuestion = function (x) {
        if (this.i + 1 <= this.questions.length - 1) {
            this.nextQuestion = this.questions[this.i + 1];
            this.i++;
        } else {
            this.nextQuestion = this.questions[0];
            this.i = 0;
        }
        this.currentQuestion = this.nextQuestion;
    };
 }

So this is still just a test, so it's not loading the questions from the database yet, however now it's using MVC and that makes everything else for it easy. I had to use invisible inputs to store the strings in the view to have the javascript get the values.

Christian Grabowski
  • 2,782
  • 3
  • 32
  • 57
0

There is probably a better way to do this, but you could try something like this:

In your controller

   public ViewResult Index()
   {
       MyViewModel model;
       model.questions = "Question1";
       ...
       return View( model );
   }

In your models class

public class MyViewModel
{
   public string questions;
   ...
}

in your .cshtml

@model MyViewModel

<script type="text/javascript">
   MyData = @(( new System.Web.Script.Serialization.JavaScriptSerializer() ).Serialize( Model ));
</script>

then, in your .js you should be able to access

MyData.questions
Brandon
  • 983
  • 6
  • 15
  • Well this makes sense that it should work to me, however the javascript didn't execute because it is saying that MyData.questions is undefined. – Christian Grabowski Jul 11 '13 at 18:29
  • You can test this by looking at the source and see if the line is being written out correcting, and then by using the javascript debugger console. The script tag might be inserted after your javascript file is being included, or you could have an issue with the Serialize – Brandon Jul 11 '13 at 18:38
  • <---- this is what my source says – Christian Grabowski Jul 11 '13 at 18:49
0

Assign your model property to a hidden field in the view:

@Html.Hidden("HiddenName",Model.PropertyName, new { @class = "hiddenselector" })

Then you can access the property in your javascript:

var hidden_val = document.getElementsByClassName("hiddenselector");

Obviously this is a simplified version of what you'd use in reality but it gives you a idea of the approach. It's not as tidy as Brandon's solution but it might get you started.

markpsmith
  • 4,860
  • 2
  • 33
  • 62