Online test system asp.net mvc - javascript

I am able to display the questions by id but dont know how to randomly display them for different users and everytime the user logs in a new random combination is initiated.
can someone guide?
My Controller:-
public ActionResult Index()
{
var question = Quiz.Instance.LoadQuiz();
return View(question);
}
[HttpPost]
public ActionResult Index(string Opt)
{
if (Quiz.Instance.IsComplete)
{
return RedirectToAction("ShowResult");
}
Quiz.Instance.SaveAnswers(Opt);
if (Quiz.Instance.MovetoNext())
{
var question = Quiz.Instance.LoadQuiz();
return View(question);
}
Quiz.Instance.IsComplete = true;
return RedirectToAction("ShowResult");
}`
Quiz repository:
public Question_OptionViewModel LoadQuiz()
{
var questions = db.Questions.Find(Q_ID);
var options = from o in db.Options
select o;
options = options.Where(o => o.Q_Id == Q_ID);
var viewmodel = new Question_OptionViewModel()
{
Question = questions,
Options = options
};
return viewmodel;
}
public void SaveAnswers(string answer)
{
Attempt at = new Attempt()
{
Q_Id = Q_ID,
Answer = answer,
Registration_number = 1312153
};
db.Attempts.Add(at);
db.SaveChanges();
var questions = db.Questions.Where(q => q.Q_Id == Q_ID).First();
if (at.Answer == questions.Correct_Ans)
{
result.Score++;
}
}
public bool MovetoNext()
{
int questions = db.Questions.Where(q => q.Test_Id == 1).Count();
bool canmove = false;
if (questions > Q_ID)
{
Q_ID++;
canmove = true;
}
return canmove;
}
My view:-
#model OnlineTestSystem.ViewModels.Question_OptionViewModel
#{
ViewBag.Title = "Quiz";
}
$("#submitButton").live("click", function () {
$.get($(this), function (response) {
$("#quiz").replaceWith($("#quiz", response));
});
return false;
});
});
<div id="quiz" style="text-align:center">
#using (Html.BeginForm("Index", "Test"))
{
<fieldset>
<legend><h2>#Model.Question.QuestionText</h2></legend>
<li>
#foreach (var opt in Model.Options)
{
<ul class="list-inline" style="font-size:17px">
#Html.RadioButton("Opt", #opt.Opt) #opt.Opt
</ul>
}
</li>
<input class="btn btn-default" type="submit" value="Next" id="submitButton" />
</fieldset>
}
</div>
``

You could just simply randomize your question by using a Shuffle algorithm. You can use Fisher-Yates algorithm to randomize your questions.
You could encapsulate the algorithm in an extension method like this:
public static class Extensions
{
private static Random rnd = new Random();
public static void Shuffle<T>(this IList<T> collection)
{
int n = collection.Count;
while (n > 1)
{
n--;
int k = rnd.Next(n + 1);
T value = collection[k];
collection[k] = collection[n];
collection[n] = value;
}
}
}
Then on your LoadQuiz method, you may call the Shuffle extension method.
var questions = db.Questions.Find(Q_ID).ToList().Shuffle();
You may also take a look on this SO post

Related

How to stop running process in c#

I am calling a same function in parallel using Task.WhenAll(); and I was wondering if there is any way we can stop all threads /process if stop button is clicked? Also I do not want browser to be closed. can anyone suggest me what approach I should use?
[HttpPost]
public async Task<IActionResult> Runcase(List<string> products,string runnumber,string button)
{
try
{
if (ModelState.IsValid)
{
var productinfo = products;
List<string> productids = new List<string>(productinfo);
var runnum = runnumber;
string runid = "";
int count = productids.Count();
List<Task> tasks = new List<Task>();
int rawid = 0;
for (int i = 0; i < count; i++)
{
tasks.Add(RunServiceAsync(productids[i], runnum,rawid));
}
await Task.WhenAll(tasks);
ViewBag.completed = "Success";
return View();
}
else
{
ViewBag.productinfo = new MultiSelectList(_context.inputValuesConfigurations, "ProductID", "ProductName");
ModelState.AddModelError(string.Empty, "Please enter a valid data...");
return View();
}
}
catch(Exception ex)
{
return View();
}
}

How to use ActionResult in onkeyup and onkeydown in a input which type is number?

I am trying to use an action result in a input function,here is my code,my goal is that when user Keyup or keydown or type a number in input,Sum of ProductPrice changes.i dont know,which event is proper for my goal,i have used onkeydown & onkeyup events.but nothing changes.
<td><input type="number" onkeyup="#Url.Action("CountUp","ShoppingCart",new { id = #item.ProductId })"
onkeydown="#Url.Action("CountDown","ShoppingCart",new { id = #item.ProductId })"
value="#item.ProductCount" min="0" style="width:70px"></td>
and Here is My controller
// GET: ShoppingCart
public ActionResult Index()
{
List<ShowShoppingCart> shopcart = new List<ShowShoppingCart>();
if (Session["ShoppingCart"] != null)
{
List<ShopCartItem> shop = Session["ShoppingCart"] as List<ShopCartItem>;
foreach (var item in shop)
{
var product = db.Products.Find(item.ProductId);
shopcart.Add(new ShowShoppingCart()
{
ProductCount = item.ProductCount,
ProductId = item.ProductId,
ProductPrice = product.ProductPrice,
ProductTitle = product.ProductTitle,
Sum = item.ProductCount * product.ProductPrice
});
}
}
return View(shopcart);
}
public ActionResult CountUp(int id)
{
List<ShopCartItem> shop = Session["ShoppingCart"] as List<ShopCartItem>;
int index = shop.FindIndex(s => s.ProductId == id);
shop[index].ProductCount += 1;
Session["ShoppingCart"] = shop;
return RedirectToAction("Index");
}
public ActionResult CountDown(int id)
{
List<ShopCartItem> shop = Session["ShoppingCart"] as List<ShopCartItem>;
int index = shop.FindIndex(s => s.ProductId == id);
shop[index].ProductCount -= 1;
if (shop[index].ProductCount == 0)
{
shop.Remove(shop[index]);
}
Session["ShoppingCart"] = shop;
return RedirectToAction("Index");
}
and this is ShopCart
public class ShopCartItem
{
public int ProductId { get; set; }
public int ProductCount { get; set; }
}
and another question?
when user type a number in input which event should i use? onChange()? or another?
Not really sure about your main question, but about the second one, you should really use onChange()

How do I use jquery to validate form fields, that was populated dynamically?

I have a list of 10 questions, used in rating a user, something like this:
The list is gotten dynamically, based on the users Occupation. This is how I am getting the list:
#for (int i = 0; i < Model.AppraisalQuestions.ToList().Count; i++)
{
#Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionId)
#Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionDescription)
<p>
#Html.DisplayFor(m => m.AppraisalQuestions[i].QuestionDescription)
#Html.ValidationMessageFor(m => m.AppraisalQuestions[i].SelectedAnswer, "", new { #class = "text-danger" })
</p>
<div class="row lead evaluation">
<div id="colorstar" class="starrr ratable"></div>
<span id="count">0</span> star(s) - <span id="meaning"> </span>
#foreach (var answer in Model.AppraisalQuestions[i].PossibleAnswers)
{
//var inputId = Model.AppraisalQuestions[i].QuestionId + "-" + answer.ID;
#Html.HiddenFor(m => m.AppraisalQuestions[i].SelectedAnswer, new { id = "SelectedAns", required = "required" })
}
</div>
}
This is the model:
public class AppraisalInputModel
{
public int AppraisalId { get; set; }
public AppraisalInputModel()
{
AppraisalQuestions = new List<AppraisalQuestionInputModel>();
}
public string FullName { get; set; }
public string JobTitle { get; set; }
public int StaffId { get; set; }
public int ScorerId { get; set; }
public int BranchId { get; set; }
public string AppraisalTitle { get; set; }
public IList<AppraisalQuestionInputModel> AppraisalQuestions { get; set; }
}
and this is the AppraisalQuestionInputModel
public class AppraisalQuestionInputModel
{
public int QuestionId { get; set; }
public string QuestionDescription { get; set; }
public bool IsGeneral { get; set; }
[Required]
[Display(Name = "Score")]
public int? SelectedAnswer { get; set; }
public IEnumerable<AnswerVM> PossibleAnswers => new List<AnswerVM>()
{
new AnswerVM {ID = 1, Text = "1 - Poor"},
new AnswerVM {ID = 2, Text = "2 - Below Expectation"},
new AnswerVM {ID = 3, Text = "3 - Meets Expectation"},
new AnswerVM {ID = 4, Text = "4 - Good"},
new AnswerVM {ID = 5, Text = "5 - Excellent"},
};
}
This is the script section code:
#section Scripts{
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
// Starrr plugin (https://github.com/dobtco/starrr)
var __slice = [].slice;
(function($, window) {
var Starrr;
Starrr = (function() {
Starrr.prototype.defaults = {
rating: void 0,
numStars: 5,
change: function(e, value) {}
};
function Starrr($el, options) {
var i,
_,
_ref,
_this = this;
this.options = $.extend({}, this.defaults, options);
this.$el = $el;
_ref = this.defaults;
for (i in _ref) {
_ = _ref[i];
if (this.$el.data(i) != null) {
this.options[i] = this.$el.data(i);
}
}
this.createStars();
this.syncRating();
this.$el.on('mouseover.starrr', 'span', function(e) {
return _this.syncRating(_this.$el.find('span').index(e.currentTarget) + 1);
});
this.$el.on('mouseout.starrr', function() {
return _this.syncRating();
});
this.$el.on('click.starrr', 'span', function(e) {
return _this.setRating(_this.$el.find('span').index(e.currentTarget) + 1);
});
this.$el.on('starrr:change', this.options.change);
}
Starrr.prototype.createStars = function() {
var _i, _ref, _results;
_results = [];
for (_i = 1, _ref = this.options.numStars; 1 <= _ref ? _i <= _ref : _i >= _ref; 1 <= _ref ? _i++ : _i--) {
_results.push(this.$el.append("<span class='glyphicon .glyphicon-star-empty'></span>"));
}
return _results;
};
Starrr.prototype.setRating = function(rating) {
if (this.options.rating === rating) {
rating = void 0;
}
this.options.rating = rating;
this.syncRating();
return this.$el.trigger('starrr:change', rating);
};
Starrr.prototype.syncRating = function(rating) {
var i, _i, _j, _ref;
rating || (rating = this.options.rating);
if (rating) {
for (i = _i = 0, _ref = rating - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
this.$el.find('span').eq(i).removeClass('glyphicon-star-empty').addClass('glyphicon-star');
}
}
if (rating && rating < 5) {
for (i = _j = rating; rating <= 4 ? _j <= 4 : _j >= 4; i = rating <= 4 ? ++_j : --_j) {
this.$el.find('span').eq(i).removeClass('glyphicon-star').addClass('glyphicon-star-empty');
}
}
if (!rating) {
return this.$el.find('span').removeClass('glyphicon-star').addClass('glyphicon-star-empty');
}
};
return Starrr;
})();
return $.fn.extend({
starrr: function() {
var args, option;
option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
return this.each(function() {
var data;
data = $(this).data('star-rating');
if (!data) {
$(this).data('star-rating', (data = new Starrr($(this), option)));
}
if (typeof option === 'string') {
return data[option].apply(data, args);
}
});
}
});
})(window.jQuery, window);
$(function() {
return $(".starrr").starrr();
});
$(document).ready(function () {
var starCount;
var correspondence = ["", "Poor", "Below Expectation", "Above Expectation", "Good", "Excelent"];
$('.ratable').on('starrr:change', function(e, value) {
$(this).closest('.evaluation').children('#count').html(value);
$(this).closest('.evaluation').children('#SelectedAns').val(value);
starCount = $(this).closest('.evaluation').children('#SelectedAns').val(value);
if (starCount === null) {
swal("", "Please Enter First Name", "error");
}
$(this).closest('.evaluation').children('#meaning').html(correspondence[value]);
var currentval = $(this).closest('.evaluation').children('#count').html();
var target = $(this).closest('.evaluation').children('.indicators');
target.css("color", "black");
target.children('.rateval').val(currentval);
target.children('#textwr').html(' ');
});
$('#hearts-existing').on('starrr:change', function(e, value) {
$('#count-existing').html(value);
});
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
});
</script>
}
And all questions must be answered. How Do I validate to make sure that all questions are answered?
I have tried form.Validate() but it is not working.
Your view is generating 5 hidden inputs for the same SelectedAnswer. You need only one (only the value of the first one will be bound by the DefaultModelBinder), and you need to set its value in the starrr:change event.
However, hidden inputs are not validated by default so you also need to configure the $.validator to give you client side validation.
First, modify your view to delete the foreach loop and replace it with a single hidden input. Note also the id attributes have been replaced with class names (duplicate id attributes is invalid html)
#for (int i = 0; i < Model.AppraisalQuestions.ToList().Count; i++)
{
#Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionId)
#Html.HiddenFor(m => m.AppraisalQuestions[i].QuestionDescription)
<p>
#Html.DisplayFor(m => m.AppraisalQuestions[i].QuestionDescription)
#Html.ValidationMessageFor(m => m.AppraisalQuestions[i].SelectedAnswer, "", new { #class = "text-danger" })
</p>
<div class="row lead evaluation">
<div class="starrr ratable"></div> // remove invalid id attribute
<span class="count">0</span> star(s) - <span class="meaning"> </span>
#Html.HiddenFor(m => m.AppraisalQuestions[i].SelectedAnswer, new { #class = "rating" })
</div>
}
Then to set the value of the input so it is posted back when you submit the form
$('.ratable').on('starrr:change', function(e, value) {
var container = $(this).closest('.evaluation'); // cache it
container.children('.count').html(value); // modify
container.children('.rating').val(value); // set value of input
container.children('.meaning').html(correspondence[value]); // modify
....
})
Note the code relating to starCount does not seem necessary, and its not clear what some of the other code in that method is doing or why you have it (for example currentval is just the same value as value)
Finally, to get client side validation, add the following script (but not inside document.ready())
$.validator.setDefaults({
ignore: ":hidden:not('.rating')"
});

SignalR : Send a Message for special user

I have a model that i want to send message for special user when add new item of my model.
I add a hub.
public class VisitHub: Hub
{
public void Update(string user, VisitNotification visit)
{
Clients.User(user).update(visit);
}
}
public class VisitNotification
{
public string Referred { get; set; }
public string VisitType { get; set; }
public int ReferredId { get; set; }
public DateTime VisitedDate { get; set; }
}
and in Controller, when i add item.
var visitHub = GlobalHost.ConnectionManager.GetHubContext<VisitHub>();
visitHub.Clients.User(user.UserName).update(new VisitNotification() { Referred = reff.Name + " " + reff.Family, ReferredId = model.ReferredId, VisitType =type.Title, VisitedDate = visit.VisitDate });
}
and in javascript .
function Visit(data, hub) {
var self = this;
self.hub = hub;
data = data || {};
self.Referred = data.Referred || "";
self.ReferredId = data.Referred || 0;
self.VisitType = data.VisitType || "";
self.VisitedDate = getTimeAgo(data.VisitedDate);
}
function viewModel() {
var self = this;
self.newVisit = ko.observable();
self.error = ko.observable();
//SignalR related
self.newVisits = ko.observableArray();
// Reference the proxy for the hub.
self.hub = $.connection.VisitHub;
self.loadNewVisits = function () {
self.visits(self.newVisit().concat(self.visits()));
self.newPosts([]);
}
//functions called by the Hub
self.hub.client.loadVisits = function (data) {
var mappedVisits = $.map(data, function (item) { return new Visit(item, self.hub); });
self.visits(mappedVisits);
}
self.hub.client.update = function (Visit) {
self.newVisit.splice(0, 0, new Visit(Visit, self.hub));
}
self.hub.client.error = function (err) {
self.error(err);
}
return self;
};
var vmVisit = new viewModel();
ko.applyBindings(vmVisit);
$.connection.hub.start().done(function () {
vmVisit.init();
});
and in view.
<span data-bind=" text: newVisits().length" class="badge bg-important"></span>
But don't show any value.
Is the user authenticated? Signalr will only recognize the user if the connections are mapped to the user. Check this link on how to map signalr connections to users: http://www.google.co.uk/url?q=http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections&sa=U&ei=Tjj-VJuPMsPBOZGGgYgH&ved=0CAsQFjAA&usg=AFQjCNFXoGJOm3mzenAJbz46TUq-Lx2bvA

Get the javascript push object array in a MVC3 controller action

This is my javascript code:
var bankOptions = {};
var playerOptions = [];
bankOptions["BankTotalAmount"] = $("#totalBankAmountID").val();
bankOptions["SinglePlayerAmount"] = $("#singlePlayerAmountID").val();
while (_playerNumber != 0) {
if (_playerNumber == 1) {
var player1Option = {};
player1Option["Name"] = $("#p" + _playerNumber + "Name").val();
player1Option["Color"] = $("#p" + _playerNumber + "Color").val();
playerOptions.push(player1Option);
}
if (_playerNumber == 2) {
var player2Option = {};
player2Option["Name"] = $("#p" + _playerNumber + "Name").val();
player2Option["Color"] = $("#p" + _playerNumber + "Color").val();
playerOptions.push(player2Option);
}
if (_playerNumber == 3) {
var player3Option = {};
player3Option["Name"] = $("#p" + _playerNumber + "Name").val();
player3Option["Color"] = $("#p" + _playerNumber + "Color").val();
playerOptions.push(player3Option);
}
if (_playerNumber == 4) {
var player4Option = {};
player4Option["Name"] = $("#p" + _playerNumber + "Name").val();
player4Option["Color"] = $("#p" + _playerNumber + "Color").val();
playerOptions.push(player4Option);
}
_playerNumber--;
}
alert(playerOptions);
$.ajax({
url: "/StartOption/setOptions/",
contentType: 'application/json',
data: JSON.stringify({ bankOptions: bankOptions, playerOptions: playerOptions }),
type: "POST",
timeout: 10000,
success: function (result) {
}
});
and i have this Controller class
public class StartOptionController : Controller
{
private MonopolyDB db = new MonopolyDB();
//
// GET: /StartOption/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult setOptions(BankOptions bankOptions, Playeroptions[] playerOptions)
{
//int length = (int)playerOptions.GetType().InvokeMember("length", BindingFlags.GetProperty, null, playerOptions, null);
BankAccount bankaccount = new BankAccount();
bankaccount.ID = 1;
bankaccount.TotalAmmount = bankOptions.BankTotalAmount;
db.BankAccount_Table.Add(bankaccount);
db.SaveChanges();
//Here i want to get each (player1Option, player2Option...) object array from that playerOptions object array
//return RedirectToAction("Index");
return View();
}
}
public class BankOptions
{
public int BankTotalAmount { get; set; }
public int SinglePlayerAmount { get; set; }
}
public class Playeroptions
{
public string Name { get; set; }
public string Color { get; set; }
}
My question is how i can get those object array that i push into playerOptions object array in my setOptions action?
as like i want to save each player info in my DB from playerOptions object array where i push each player info in my javascript code.
Well first to make it easy I would like to recommend that changes the sign of your action
from
public ActionResult setOptions(BankOptions bankOptions, Playeroptions[] playerOptions)
To
public ActionResult setOptions(BankOptions bankOptions, List<PlayerOptions> playerOptions)
That's it's going to make it easy the handle of each element of the array, and there's not problem for the framework to serialize this object.
Now to answer your question you could iterate the array like this
[HttpPost]
public ActionResult setOptions(BankOptions bankOptions, Playeroptions[] playerOptions)
{
//int length = (int)playerOptions.GetType().InvokeMember("length", BindingFlags.GetProperty, null, playerOptions, null);
BankAccount bankaccount = new BankAccount();
bankaccount.ID = 1;
bankaccount.TotalAmmount = bankOptions.BankTotalAmount;
db.BankAccount_Table.Add(bankaccount);
db.SaveChanges();
//Here i want to get each (player1Option, player2Option...) object array from that playerOptions object array
for ( int i = 0 ; i< playerOptions.Length, i++)
{
playerOptions[i]; //<-- this give's the specific element
}
//return RedirectToAction("Index");
return View();
}
Nevertheless if you follow my recommendation and changes the sign of your action you could iterate your code like this
[HttpPost]
public ActionResult setOptions(BankOptions bankOptions, List<PlayerOptions> playerOptions)
{
//int length = (int)playerOptions.GetType().InvokeMember("length", BindingFlags.GetProperty, null, playerOptions, null);
BankAccount bankaccount = new BankAccount();
bankaccount.ID = 1;
bankaccount.TotalAmmount = bankOptions.BankTotalAmount;
db.BankAccount_Table.Add(bankaccount);
db.SaveChanges();
//Here i want to get each (player1Option, player2Option...) object array from that playerOptions object array
foreach( var item in playerOptions){
item //<--- in this variable you have the element PlayerOption
}
//return RedirectToAction("Index");
return View();
}

Categories