Imagine below MVC parent model:
Model:
Namespace MyProject.SampleModel
{
public class ViewModelExample {
public FirstModel BoolValues { get; set; }
public SecondModel NamesValues { get; set; }
}
}
Namespace MyProject.SampleModel
{
public class FirstModel
{
public bool MyBoolean1 { get; set; }
public bool MyBoolean2 { get; set; }
}
public class SecondModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
View:
#model MyProject.SampleModel.ViewModelExample
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, htmlAttributes: new { id = "Myform" }))
{
(...)
#Html.CheckBoxFor(m => m.BoolValues.MyBoolean1)
(...)
<input id="submitButton" type="button" value="Add" onclick="InitiateSequence();" />
(...)
}
<script type="text/javascript" src="~/Scripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
(...)
function InitiateSequence()
{
// Do some stuff
}
(...)
function ScriptSample() {
if(#(Model.BoolValues.MyBoolean1 ? "true" : "false")
{
// It's true, do some stuff
}
else
{
// It's false, do some stuff
}
}
</script>
Controller:
public ActionResult MyAction(ViewModelExample model)
{
model.FirstModel = new TestsModel(); // I do not instantiate SecondModel as in the view for this controller i do not use it
return View(model);
}
Page is loading correctly, but when I click on the button it says javascript function InitiateSequence is not defined.... what's happening?
That could be because most possibly the function appears where it is not supposed to be. Also don't use inline attributes to bind the handlers, use event binding instead of inline handler.
<input id="submitButton" type="button" value="Add" />
and
<script type="text/javascript">
(...) //whatever code
$(function(){
$('#submitButton').on('click', InitiateSequence);
});
Related
I want to create a Quiz website with Asp. I want to create Quiz, add questions to the quiz, and add answers to the question. Add question button adds a question, but the Addanswer button submits the form instead of adding an answer to the question.
My classes:
public class Answer
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Content { get; set; }
public Guid QuestionId { get; set; }
public class Question
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Content { get; set; }
public Guid QuizId { get; set; }
public ICollection<Answer> Answers { get; set; } = new List<Answer>() {
new Answer() { Content = "Answeeeer" },
new Answer() { Content = "Answeeeer2" },
new Answer() { Content = "Answeeeer3" }
};
public class Quiz
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Name { get; set; }
public ICollection<Question> Questions { get; set; } = new List<Question>() { };
In front side I have Question and Answer Partial views:
Question Partial View:
#model QuizIt_Tests.Entities.Question
<hr style="height: 4px; color: black;" />
<div class="w-100 p-3 px-5 my-3">
<label asp-for="Content" class="control-label">Question</label>
<input asp-for="Content" class="form-control" value="#Model.Content" />
<span asp-validation-for="Content" class="text-danger"></span>
<div id="answerRows #Model.Id" class="w-75">
#Html.EditorFor(model => model.Answers)
<button class="btn btn-primary" id="addAnswer #Model.Id">Add Answer</button>
</div>
</div>
#section Scripts {
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="jquery-3.6.1.min.js"></script>
<script>
$("#addAnswer " + #Model.Id).click(function () {
console.log("clicked");
$.ajax({
url: '#Url.Action("AddBlankQuestion", "Quizes")',
cache: false,
success: function (html) {
$("#answerRows " + #Model.Id").append(html); },
error: function (xhr, status, error) {
console.log(xhr.responseText);
}
});
return false;
});
</script>
}
Answer Partial View:
#model QuizIt_Tests.Entities.Answer
<div class="row" style="background-color:red; margin: 20px;">
<label asp-for="Content" class="control-label">Answer Content</label>
<input asp-for="Content" class="form-control" value="#Model.Content" />
<span asp-validation-for="Content" class="text-danger"></span>
</div>
My Controller:
public class QuizesController : Controller
{
private readonly ApplicationDBContext _context;
public QuizesController(ApplicationDBContext context)
{
_context = context;
}
public IActionResult AddBlankQuestion(Quiz model)
{
Question question = new Question();
return PartialView("EditorTemplates/Question", question);
}
public IActionResult AddBlankAnswer(Question model)
{
return PartialView("EditorTemplates/Answer", new Answer() { QuestionId = model.Id });
}
}
You did not specify the type attribute in the button, which by default is equal to submit which causes the form to be submitted, to change its behavior, change the type value to button as follows.
<button type="button" class="btn btn-primary" id="addAnswer #Model.Id">Add Answer</button>
I have a view inside which there are two checkboxes. On checked I need to save currently assigned value into database table.
Here is the model:
public class RoomHk
{
public int RoomHkId { get; set; }
public int RoomId { get; set; }
public DateTime? DeepCleaning { get; set; }
public DateTime? NewLinen { get; set; }
}
This is the child table of my Room Table. Following is my view, suppose user check on first checkbox then he clicks on save button, then I want to save current datetime in the NewLinen column of the RoomHk table to that respective RoomId. How can I do it with jQuery post method?
<div class="col-6">
#if (item.NewLinen == null)
{
<input type="checkbox" data-nlid="#item.RoomId" class="form-check-input newLinen" />
<label>New Linen</label>
<br />
}
#if (item.DeepCleaning == null)
{
<input type="checkbox" data-dcid="#item.RoomId" class="form-check-input deepClean" />
<label>Deep Cleaning</label>
}
</div>
<button type="button" class="btn btn-default insert" data-rid="#item.RoomId">Save</button>
$(function () {
$('.insert').click(function () {
$.post("#Url.Action("SetCleaningStatus", "HouseKeeping")", { id: $(this).data("id"), });
});
});
You could use Html.BeginForm and place the submit button inside the form. This is important, otherwise you'll need to employ additional scripts to get it working.
If you need to post the state of the two checkboxes (DeepCleaning and NewLinen) I'd suggest having them as Boolean instead of DateTime so you can have their states (checked/unchecked) mapped to the respective properties, because you seem to want to do that.
SetCleaningStatus.cshtml
#model RoomHk;
#Html.BeginForm("SetCleaningStatus", "HouseKeeping")
{
<!-- Will be posted to the controller, no additional Javascript necessary -->
#Html.HiddenFor(m => m.RoomId)
<div class="col-6">
#if (item.NewLinen == null)
{
<input type="checkbox" data-nlid="#item.RoomId" class="form-check-input newLinen" />
<label>New Linen</label>
<br />
}
#if (item.DeepCleaning == null)
{
<input type="checkbox" data-dcid="#item.RoomId" class="form-check-input deepClean" />
<label>Deep Cleaning</label>
}
</div>
<!-- IMPORTANT: the type needs to be `submit` instead of `button` -->
<input type="submit" class="btn btn-default insert" value="Save" />
}
HouseKeeping.cs
public class RoomHk
{
public int RoomHkId { get; set; }
public int RoomId { get; set; }
public DateTime? DeepCleaning { get; set; }
public DateTime? NewLinen { get; set; }
}
[HttpGet]
public ActionResult SetCleaningStatus()
{
var model = new RoomHk();
return View(model);
}
[HttpPost]
public ActionResult SetCleaningStatus(RoomHk arg)
{
bool response = new {
success = true
};
// Here is your RoomId
arg.RoomId;
arg.NewLinen = DateTime.Now;
// Save posted data to DB
// ...
// Return your response here
return Json(response);
}
POSTting the checked state of checkboxes
Use Html.CheckBoxFor and Html.LabelFor and let the compiler render those fields for you, with the right IDs and names properly set.
public class RoomHk
{
// Make them booleans
public bool DeepCleaning { get; set; }
public bool NewLinen { get; set; }
}
<div class="col-6">
<!--
<input type="checkbox" data-nlid="#item.RoomId" class="form-check-input newLinen" />
<label>New Linen</label>
<br />
-->
#Html.LabelFor(m => m.NewLinen, "New Linen")
#Html.CheckBoxFor(m => m.NewLinen, new { #class = "form-check-input" })
</div>
This is our Home Index:
#model ELearning.Data.ELearningEgitimDTO
#{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
#if (TempData["message"] != null)
{
<div class="alert alert-info" role="alert">#TempData["message"]</div>
}
<div>
<div>
#if (Model.EgitimTuru == 5)
{
<h1>Yangın Eğitimi</h1>
}
<table class="table table-responsive">
<tr>
<td width="20%">Şirket Adı:</td>
<td width="80%">#Model.Name</td>
</tr>
<tr>
<td>Eğitimi Veren:</td>
<td>#Model.PersonelAdi</td>
</tr>
<tr>
<td>Eğitim Tarihi:</td>
<td>#Model.Tarih</td>
</tr>
</table>
</div>
<div>
<table class="table table-responsive">
<tr>
<td>Eğitim Konuları:</td>
</tr>
#foreach (var konu in Model.Adi)
{
<tr>
<td><ul><li>#konu</li></ul></td>
</tr>
}
</table>
</div>
</div>
<p class="text-right"><button onclick="getStartDate()" class="btn btn-primary btn-lg ">Eğitime Başla »</button></p>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript">
function getStartDate() {
$.post("/Video/GetStartDate",
{
PerNr: #Model.PerNr,
StartDate: "",
EndDate: "",
EgitimFilesId: #Model.FileId
});
}
</script>
</div>
This is Video Index:
#model WebApplication3.Models.VideoLogsModel
#{
ViewBag.Title = "Video Page";
}
<div class="jumbotron">
<div>Eğitime başlanan zaman:</div>
<div id="startdate"></div>
<div class="col-md-12 text-center">
<video controls controlslist="nodownload" id="videoPlayer" width: 100% height: auto>
<source src="~/Video/GetVideo" type="video/mp4">
</video>
</div>
<br />
<div class="text-right">
<p id="button" onclick="egitimiBitir()" class="btn btn-danger btn-lg ">Eğitimi Bitir</p>
</div>
<script type="text/javascript">
var vid = document.getElementById("videoPlayer");
var button = document.getElementById("button");
if (vid.played) {
setInterval(function () { vid.pause(); }, 30000);
}
vid.addEventListener("ended", function() {
button.className = "btn btn-success btn-lg "
});
function egitimiBitir() {
if (vid.ended) {
$.post("/Video/GetEndDate",
{
PerNr: #Model.PerNr,
StartDate= "",
EndDate: "",
EgitimFile sId: #Model.EgitimFilesId
});
}
else {
document.getElementById("message").innerHTML = "Video tamamlanmadan eğitimi bitiremezsiniz.."
}
}
</script>
</div>
This is our main model:
public class ELearningEgitimDTO
{
public ELearningEgitimDTO() { }
public ELearningEgitimDTO(string PerNr, int ID)
{
this.ID = ID;
this.PerNr = PerNr;
}
public int ID { get; set; }
public string PerNr { get; set; }//katılımcıID
public string Name { get; set; }//şirket adı
public int EgitimTuru { get; set; }
public DateTime Tarih { get; set; }//egitim tarihi
public string PersonelAdi { get; set; } // eğitimi veren
public int FileId { get; set; }
public string FileName { get; set; }
public string[] Adi { get; set; }
}
This is our model:
public class VideoLogsModel
{
public int EgitimFilesId { get; set; }
public int PerNr { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
This is our Home Controller:
public class HomeController : Controller
{
public ActionResult Index(int EgitimId=4, string PerNr="2")
{
ELearningService service = new ELearningService();
ELearningEgitimDTO egitim = new ELearningEgitimDTO(PerNr, EgitimId);
return View(service.getInfo(egitim)); //eğitim bilgileri istenirken egitimId ve egitim kullanıcıdaki eğitmenin perNr si verilmeli!!
}
}
This is our Video Controller:
public class VideoController : Controller
{
public ActionResult Index(VideoLogsModel model)
{
return View(model);
}
public ActionResult GetVideo()
{
var memoryStream = new MemoryStream(System.IO.File.ReadAllBytes(#"C:\Users\cyare\Desktop\videoplayback.mp4"));
//byte[] bytes = System.IO.File.ReadAllBytes(#"C:\Users\melik.DESKTOP-LQQAB68\Desktop\videoplayback.mp4");
//System.IO.File.WriteAllBytes(#"C:\Users\melik.DESKTOP-LQQAB68\Desktop\videoplayback.mp4", bytes);
return new FileStreamResult(memoryStream, "video/mp4");
}
/* [HttpPost]
public ActionResult GetStartEndDate(VideoLogsModel logs)
{
DateTime startDate = logs.StartDate; //database de uygun tabloya yazılır
return RedirectToAction("Index", "Video");
}*/
[HttpPost]
public ActionResult GetStartDate(VideoLogsModel model)
{
model.StartDate = System.DateTime.Now;
ELearningDosyaKullaniciDTO user = new ELearningDosyaKullaniciDTO();
user.egitimFileID = model.EgitimFilesId;
user.egitimKullanıcı = model.PerNr;
user.startDate = model.StartDate;
ELearningService service = new ELearningService();
//service.CreateLogs(user);
//return RedirectToAction("Index","Video",model);*/
return RedirectToAction("Index", model);
}
[HttpPost]
public ActionResult GetEndDate(VideoLogsModel model)
{
model.EndDate = System.DateTime.Now;
ELearningDosyaKullaniciDTO user = new ELearningDosyaKullaniciDTO();
user.egitimFileID = model.EgitimFilesId;
user.egitimKullanıcı = model.PerNr;
user.endDate = model.EndDate;
ELearningService service = new ELearningService();
service.UpdateLogs(user);
TempData.Add("message", String.Format("Eğitiminiz Tamamlanmıştır!"));
return RedirectToAction("Index", "Home");
}
}
My question is how can i pass the model from home index to video controller and then to video index?
Video Index doesn't run. It goes to video index but then it runs home index again.
Also it runs egitimibitir() function before button's onclick function.
You send an ajax request to your service. (endpoint => GetEndDate) I think you can change your code like that,
$.ajax({
type: "POST",
url: "/Video/GetEndDate", //your reqeust url
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
// your data here
}),
success: function (data) {
// check state of data
// after check window.location = // redirect url
},
error: function (data) {
// handle exception
}
});
You can change your controller method to a data controller. (not an ActionResult. create a custom result object which include your data and your success state. you can use this custom result object every ajax requests for return state and data). If an exception occurs while executing "GetEndDate" method, you need to handle exception and you need to show it to client. You send exception or your success complete response to to client(view). (you can handle your exception data in ajax error: function)
I have JS function that is basically
<script type="text/javascript">
function doSomething() {
var s = 'some data'
return s; }
</script>
and
#using (Html.BeginForm(new { data_to_send = x))
{
//some form controls that are sent to controller via model
}
Is it possible, and how, to assign value returned by doSomething function to x variable in form?
I don't need x in my model, because it won't go to database. It's just some additional info from user, how to manipulate data in model before saving to database.
edit: Controller action is
public actionresult MyController(string data_to_Send, model) {}
In the View:
#using (Html.BeginForm())
{
#Html.HiddenFor(model => model.X1)
#Html.HiddenFor(model => model.X2)
}
In the Model:
public class YourModel
{
public string X1 { get; set; }
public string X2 { get; set; }
}
In the Controller:
[HttpPost]
public ActionResult Index(YourModel model)
{
string x1 = model.X1;
string x2 = model.X2;
return View(model);
}
The form has to be posted in order to do what you are looking for.
You can post the model along with PostedDateValue
#using (Html.BeginForm("ActionMethod", "Controller", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-field required">
<label for="Posted Data">Posted Data</label>
<input id="txtPostedData" name="PostedDateValue" >
<input type="submit" class="gradient" value="SUBMIT" />
</div>
}
)
Controller
public ActionResult ActionMethod(string PostedDateValue)
{
}
My JavaScript will not run. I've been struggling with this for a while (2 days) Here's my current setup:
Created a new MVC 4 project. I intend to try out some AJAX, so named it AjaxTest.
Added a model (Vehicle.cs) consisting of three classes OdometerInfo, VehicleMinInfo, and Vehicle. Here they are:
public class OdometerInfo
{
public virtual string VIN { get; set; }
public virtual int Odometer { get; set; }
}
public class VehicleMinInfo : OdometerInfo
{
public virtual Nullable<int> VehicleYear { get; set; }
public virtual string Make { get; set; }
public virtual string Model { get; set; }
}
public class Vehicle : VehicleMinInfo
{
// default constructor
public Vehicle()
{
VIN = "MyFakeVin";
Odometer = 0;
VehicleYear = 2012;
Make = "Porsche";
Model = "911";
}
public override string VIN { get; set; }
public override int Odometer { get; set; }
public override Nullable<int> VehicleYear { get; set; }
public override string Make { get; set; }
public override string Model { get; set; }
// other fields
}
Then I replaced the contents of the template Index.cshtml with:
#model AjaxTest.Models.VehicleMinInfo
#{
ViewBag.Title = "Index";
}
<h2>Enter your odometer reading</h2>
#using (Html.BeginForm("Odometer", "Home", FormMethod.Post))
{
<h4>For the following vehicle.</h4>
#Html.DisplayFor(model => model.VIN) <br />
#Html.DisplayFor(model => model.VehicleYear) <br />
#Html.DisplayFor(model => model.Make) <br />
#Html.DisplayFor(model => model.Model) <br />
<h1>Enter Odometer</h1>
#Html.DisplayNameFor(model => model.Odometer)
#Html.EditorFor(model => model.Odometer)
#Html.HiddenFor(model => model.VIN);
<input type="submit" value="Odometer reading is correct" id="OdometerForm" />
}
Then I made a strongly typed view (Odometer.cshtml):
#model AjaxTest.Models.OdometerInfo
#{
ViewBag.Title = "Odometer";
}
<h2>Odometer</h2>
Your odometer has been entered. It is
#Html.DisplayFor(model => model.Odometer)
. (
#Html.DisplayFor(model => model.VIN)
)
And added to the controller:
public ActionResult Index()
{
VehicleMinInfo OdomObj = new Vehicle();
return View(OdomObj);
}
[HttpPost]
public ActionResult Odometer(OdometerInfo oi)
{
return View(oi);
}
All of that works. I can fill in an odometer reading and both the odometer and the VIN are passed back to the controller and displayed on the Odometer page. Now, it's time to start adding some JavaScript. So I created OdometerList.js with the eventual goal of passing back a list of odometer readings instead of just one, and in it I placed:
$("#OdometerForm").click(function () {
alert("Hello world!");
});
window.onload = function () {
if (window.jQuery) {
// jQuery is loaded
alert("Yeah!");
} else {
// jQuery is not loaded
alert("Doesn't Work");
}
}
$(document).ready(function () {
alert("!!!");
});
Then I added in _Layout.cshtml
#Scripts.Render("~/Scripts/jquery-1.3.2.min.js")
#Scripts.Render("~/Scripts/OdometerList.js")
And I double checked Web.config to be sure compilation debug was true:
<system.web>
<compilation debug="true" targetFramework="4.5" />
...
None of my alerts are triggered, not one. Is my setup wrong? I moved my JavaScript from OdometerList.js to the bottom of Odometer.cshtml and put it all between script tags, but there was no change. I am new to JavaScript, so have I made a mistake there?
This is really stumping me. Any help you can give will be much appreciated!
The version of jQuery had been updated. Once I put the correct version number in, I was able to use #Scripts.Render("~/Scripts/jquery-1.8.2.min.js") and everything works!