I am new to mvc and am trying to do something like in the below image (im not using partial views).
I have an IEnumerable property on Model
Like in this image, (i have not enough reputation to show image directly)
but on controller if i put FormCollection as parameter to accepting post method when i process same name fields i get an extra character ',', which might be also used by user...
Any idea....
[EDIT]
My view
#model Models.Question
#{
ViewBag.Title = "Add";
}
<h2>Add</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Question</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.SurveyId)
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.QuestionTypeId, "Question type", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.QuestionTypeId, new SelectList(ViewBag.QuestionTypes, "QuestionTypeId", "Name"), new { #class = "form-control col-md-10" })
<button type="button" class="btn btn-default addAnswer hide"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
#Html.ValidationMessageFor(model => model.QuestionTypeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group hide">
#Html.LabelFor(model => model.Answers, "Options", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10" id="allAnswers">
#Html.ValidationMessageFor(model => model.Answers, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Sort, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Sort, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Sort, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Mandatory, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Mandatory)
#Html.ValidationMessageFor(model => model.Mandatory, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Question", "Survey", new { id = Model.SurveyId }, null)
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval", "~/Scripts/QuestionAdd.js")
}
Controller
[HttpGet]
public ActionResult Add(long id)
{
var question = new Models.Question();
question.SurveyId = id;
ViewBag.QuestionTypes = BLL.Questions.GetQuestionTypes();
return View(question);
}
[HttpPost]
public ActionResult Add(FormCollection coll)
{
if (ModelState.IsValid)
{
var question = new Models.Question();
question.Name = coll["Name"];
byte qid = 0, sort = 0;
bool mandatory = false;
byte.TryParse(coll["QuestionTypeId"], out qid);
byte.TryParse(coll["Sort"], out sort);
bool.TryParse(coll["Mandatory"], out mandatory);
question.QuestionTypeId = qid;
question.Sort = sort;
question.Mandatory = mandatory;
foreach (var answer in coll["Answers"])
question.Answers.Add(new Models.Answer() { Value = answer + "" });
if (question != null)
{
if (BLL.Questions.Insert(question) != null)
ViewBag.Message = "Successfully inserted";
else
ViewBag.Message = "Insert could not be done";
return RedirectToAction("Index", "Question", new { questionId = question.QuestionId });
}
}
return View();
}
When (+) clicked
$('#allAnswers').append(
'<div class="input-group col-lg-4">' +
'<input class="form-control" name="Answers"> ' +
'<div class="input-group-btn">' +
' <button type="button" class="btn btn-default removeAnswer"><span class="glyphicon glyphicon glyphicon-trash" aria-hidden="true"></span></button>' +
'</div> </div>');
As discussed.. here is how i would approach this.
I have a view model to hold the questions and answers and the selected question to which we will be adding answers.
public class CurrentViewModel
{
public string QuestionSelected { get; set; }
public List<SelectListItem> Questions { get; set; }
public List<string> Answers { get; set; }
}
Then in your controller we have an action to return the view, an action to get the answers for the selected question, an action to add a new answer for the selected question and also a save method which just demonstrates the final model content posted.
public class TestController : Controller
{
public ActionResult Test()
{
var model = new CurrentViewModel()
{
Questions = new List<SelectListItem>()
{
new SelectListItem()
{
Text = "Question 1",
Value = "Question 1"
},
new SelectListItem()
{
Text = "Question 2",
Value = "Question 2"
}
},
Answers = new List<string>()
};
return View("Test", model);
}
public PartialViewResult GetAnswers(CurrentViewModel model)
{
model.Answers = new List<string>();
//model.Answers = Get Answers from some service based on QuestionSelected?!
model.Answers.Add("Answer 1");
model.Answers.Add("Answer 2"); //Add manuall for example
return PartialView("_Answers", model);
}
public PartialViewResult AddAnswer(CurrentViewModel model)
{
model.Answers.Add("Add answer here...");
return PartialView("_Answers", model);
}
public ActionResult SaveQuestionsAndAnswers(CurrentViewModel model)
{
if (model.Questions.Count == 0)
{
}
return View("Test", model);
}
}
Then we have a main view for showing the questions dropdown and a partial view that will show us the answers.
Main View
#model TestMVC.Models.CurrentViewModel
#{
ViewBag.Title = "Test";
}
<link href="~/Content/StyleSheets/jquery-ui.css" rel="stylesheet" />
<script src="~/Content/Scripts/jquery-2.2.3.js"></script>
<script src="~/Content/Scripts/jquery-ui-1.11.4.js"></script>
<div id="divBodyContent">
<div>
<h3>Q & A</h3>
</div>
#using (Html.BeginForm("SaveQuestionsAndAnswers", "Test", FormMethod.Post, new { id = "frmQandA" }))
{
#Html.Label("lblQ", "Questions", new { #class = "form-control inline" })
#Html.DropDownListFor(model => model.QuestionSelected, Model.Questions, "Select--", new { #class = "form-control inline", id="ddQuestions" })
<div id="divAnswers">
#Html.Partial("_Answers")
</div>
<div style="margin-top: 1%;">
<button id="btnSave" type="submit" class="btn btn-primary" style="margin-left: 4px; margin-bottom: 10px; width: 7%">save</button>
</div>
}
</div>
<script>
$("#ddQuestions").on("change", function() {
var myData = $('#frmQandA').serialize();
$.ajax({
type: "POST",
url: "#Url.Action("GetAnswers", "Test")",
data: myData,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function(data) {
$("#divAnswers").html(data);
}
})});
</script>
Partial View
#model TestMVC.Models.CurrentViewModel
<link href="~/Content/StyleSheets/jquery-ui.css" rel="stylesheet" />
<script src="~/Content/Scripts/jquery-2.2.3.js"></script>
<script src="~/Content/Scripts/jquery-ui-1.11.4.js"></script>
<div>
#for (var counter = 0; counter <= (Model.Answers.Count - 1); counter++)
{
#Html.TextBoxFor(model => model.Answers[counter], new {#class = "form-control inline"})
}
<div style="margin-top: 1%;">
<button id="btnAddAnswer" type="button" class="btn btn-primary" style="margin-left: 4px; margin-bottom: 10px; width: 7%">Add</button>
</div>
</div>
<script>
$("#btnAddAnswer").on("click", function() {
var myData = $('#frmQandA').serialize();
$.ajax({
type: "POST",
url: "#Url.Action("AddAnswer", "Test")",
data: myData,
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function (data) {
$("#divAnswers").html(data);
}
})});
</script>
I've tested this locally and it works. In a nutshell, when we need a new answer adding to the model, we add it in server side so we can then bind to the model in the browser. We do this via an Ajax call on the change event of the questions drop down. The partial view iterates through each answer via a counter which generates a unique id and textbox for each answer. Adding a new answer is also achieved via ajax. These can then all be posted back.
Hope that helps.
Related
I want to retrieve data from textbox, when I but Id in the textbox it will retrieve rest of data in in other textbox here is my code:
controller:
[HttpPost]
public ActionResult Contact(int id)
{
testEntities db = new testEntities();
List<Table_1> tb = db.Table_1.ToList();
var c = tb.Find(m => m.id == id);
return View(c);
}
view
<div class="form-horizontal">
<h4>Table_1</h4>
<hr />
<form id="myForm">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.id, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.id, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.id, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.depart, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.depart, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.depart, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" value="Create" class="btn btn-default" id="btnSubmit">press here</button>
</div>
</div>
</form>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#btnSubmit").click(function () {
debugger
var data = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "/Home/Contact",
data: data,
success: function (response) {
},
});
});
});
</script>
I use almost the same codes:
#model FormSubmitWebApplication.Models.Student
#{
ViewBag.Title = "Contact";
}
<div class="form-horizontal">
<h4>Table_1</h4>
<hr />
<form id="myForm">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Id, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Id, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Id, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="button" value="Create" class="btn btn-default" id="btnSubmit">press here</button>
</div>
</div>
</form>
</div>
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
$("#btnSubmit").click(function () {
debugger
var data = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "/Home/Contact",
data: data,
success: function (response) {
},
});
});
});
</script>
}
The id could be passed to the controller.
Could you show the debug view in the controller?
I'm developing an administration page and I'm having trouble receiving my data from json.
I have a Create view and inside it I created a script to show my partial views when selecting a certain type. But when I select the Hotel type, my controller is not receiving the data. When I select the other types, it works well.
Can anyone tell me what the problem is?
My Code:
Create.cshtml
#model ProjetoFinal.Models.Item
#{
ViewBag.Title = "";
}
<h2>#Resource.Criar</h2>
Português |
Inglês
<br />
#using (Html.BeginForm("Create", "Trans", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="form-group">
#Html.LabelFor(model => model.Titulo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Titulo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Titulo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Descricao, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Descricao, new { #class = "form-control", #id = "Descricao" })
#Html.ValidationMessageFor(model => model.Descricao, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Main_Image, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="col-md-10">
<input type="file" name="imagem_principal" id="createimageinput" />
#Html.ValidationMessageFor(model => model.Main_Image, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Localidade, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Localidade, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Localidade, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Endereco, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Endereco, new { htmlAttributes = new { #id = "Endereco", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Endereco, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Latitude, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Latitude, new { htmlAttributes = new { #id = "Latitude", #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.Latitude, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Longitude, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Longitude, new { htmlAttributes = new { #id = "Longitude", #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.Longitude, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tipo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<!--Ao escolher o tipo vai aparecer os campos respetivos dessa categoria
atraves da funcao ddldropdown-->
#Html.DropDownListFor(model => model.Tipo, new SelectList(Model.tipos, "ID", "Tipo"), Resource.Selecionar_Tipo, htmlAttributes: new { #id = "ddldropdown", #class = "form-control" })
</div>
</div>
<div id="partialDiv">
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="btnsave" value="#Resource.Criar" class="btn btn-default" />
</div>
</div>
</div>
#section Scripts
{
<!--Script to add Views from the Others folder in the "partialDiv"-->
<script type="text/javascript">
$("#ddldropdown").change(function () {
var txt = $("#ddldropdown option:selected").text();
if (txt == null || txt == "Selecionar Tipo")
$('#partialDiv').html('');
else if (txt == "Teatro" || txt == "Feira" || txt == "Exposição" || txt == "Hotel" || txt == "Cinema" || txt == "Musica") {
$.ajax({
type: 'get',
url: '/Outros/Create_' + txt,
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
}
else if (txt == "Parques/Percursos Pedestres") {
$.ajax({
type: 'get',
url: '/Outros/Create_Percurso',
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
}
else {
$.ajax({
type: 'get',
url: '/Outros/Create_Other',
dataType: 'html',
success: function (html) {
$('#partialDiv').html(html);
}
});
}
});
</script>
<!--Script to submit partialDiv data-->
<script type="text/javascript">
window.jQuery(document).ready(function () {
$('#btnsave').click(function () {
var txt = $("#ddldropdown option:selected").text();
var frm = $("form");
var data = new FormData($("form")[0]);
if (txt == "Teatro" || txt == "Feira" || txt == "Exposição" || txt == "Hotel" || txt == "Cinema" || txt == "Musica") {
var files = $("#createimageinput").get(0).files;
// Add the uploaded file to the form data collection
if (files.length > 0) {
for (f = 0; f < files.length; f++) {
data.append("imgfile", files[f]);
}
}
$.ajax({
url: '/Outros/Create_' + txt,
method: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
else if (txt == "Parques/Percursos Pedestres")
{
$.ajax({
url: '/Outros/Create_Percurso',
method: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
else
{
if (txt != null || txt != "Selecionar Tipo")
{
$.ajax({
url: '/Outros/Create_Other',
method: "POST",
processData: false,
data: data,
dataType: 'html',
contentType: false,
});
}
}
});
});
</script>
<!--Script to place the Autocomplete at the Address-->
<script>
// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCvSxmjQNuUVyhYFJ8SmXHa0sQKgpiLBLA&libraries=places">
function initMap() {
google.maps.event.addDomListener(window, 'load', function () {
var options = {
types: ['geocode'],
componentRestrictions: { country: "pt" }
};
var input = document.getElementById('Endereco');
var autocomplete = new google.maps.places.Autocomplete(input, options);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var near_place = autocomplete.getPlace();
document.getElementById('Latitude').value = near_place.geometry.location.lat();
document.getElementById('Longitude').value = near_place.geometry.location.lng();
});
});
}
$("#Endereco").change(function () {
document.getElementById('Latitude').value = '';
document.getElementById('Longitude').value = '';
});
</script>
<!--Google API-->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCvSxmjQNuUVyhYFJ8SmXHa0sQKgpiLBLA&libraries=places&callback=initMap"
async defer></script>
<script type="text/javascript">
$('#btnsave').click(function () {
var form = $("#formH");
var url = form.attr("action");
var formData = form.serialize();
$.post(url, formData, function (data) {
$("#msg").html(data);
});
})
</script>
}
<div>
#Html.ActionLink(Resource.Voltar, "Index")
</div>
}
Create_Hotel.cshtml
#model ProjetoFinal.Models.Hotel
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#using (Html.BeginForm("Create_Hotel", "Outros", FormMethod.Post))
{
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Outras_Imagens, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="col-md-10">
<input type="file" name="images" multiple="multiple" id="imagens"/>
#Html.ValidationMessageFor(model => model.Outras_Imagens, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Preco, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Preco, new { htmlAttributes = new { #type = "number", #min = "0", #step = "0.01", #value = "0", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Preco, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tipo_Hotel, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tipo_Hotel, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Tipo_Hotel, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group" id="div_comodidades">
#Html.LabelFor(model => model.Comodidades, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10" id="divCom">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => model.Comodidades, new { htmlAttributes = new { #id = "comodidades", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comodidades, "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" id="com" value="+" onclick="addComodidades()" />
</span>
</div>
</div>
</div>
<div class="form-group" id="div_condicoes">
#Html.LabelFor(model => model.Condicoes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10" id="divCon">
<div class="input-group">
<span class="input-group-btn">
#Html.EditorFor(model => model.Condicoes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Condicoes, "", new { #class = "text-danger" })
<input type="button" class="btn btn-primary" value="+" onclick="addCondicoes()" />
</span>
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Telefone1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Telefone1, new { htmlAttributes = new { #type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Telefone1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Telefone2, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Telefone2, new { htmlAttributes = new { #type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Telefone2, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Avaliacao, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Avaliacao, new { htmlAttributes = new { #type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Avaliacao, "", new { #class = "text-danger" })
</div>
</div>
</div>
#section Scripts
{
<script type="text/javascript">
var cont = 0;
var cont1 = 0;
//function to add more fields for the user to enter more comodidades
function addComodidades() {
cont++;
$("#div_comodidades").append(`<div class="col-md-10" id="campo` + cont + `" style="margin-left:16.7%">
<div class="input-group">
<span class="input-group-btn">
<input class="form-control text-box single-line" name="Comodidades" placeholder="Comodidades" type="text" value="" id="input_comodidades` + cont + `"/>
<span class="field-validation-valid text-danger" data-valmsg-for="Comodidades" data-valmsg-replace="true"></span>
<input type="button" id="` + cont + `" class="btn btn-primary" value="-" style="padding-left:15px;"/>
</span>
</div>
</div>`);
}
//function to add more fields for the user to enter more condicoes
function addCondicoes() {
cont1++;
$('#div_condicoes').append(`<div class="col-md-10" id="campo1` + cont1 + `" style="margin-left:16.7%">
<div class="input-group">
<span class="input-group-btn">
<input class="form-control text-box single-line" name="Condicoes" placeholder="Condicoes" type="text" value="" id="input_condicoes` + cont1 + `" />
<span class="field-validation-valid text-danger" data-valmsg-for="Condicoes" data-valmsg-replace="true"></span>
<input type="button" id="` + cont1 + `" class="btn btn-primary" value="-" style="padding-left:15px;"/>
</span>
</div>
</div>`);
}
//function to remove the comodidades field that the user added
$('#div_comodidades').on('click', '.btn-primary', function () {
var button_id = $(this).attr("id");
$('#campo' + button_id + '').remove();
});
//function to remove the condicoes field that the user added
$('#div_condicoes').on('click', '.btn-primary', function () {
var button_id = $(this).attr("id");
$('#campo1' + button_id + '').remove();
});
</script>
}
}
#{
Layout = null;
}
TransController.cs
public class TransController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FormCollection formCollection)
{
Item item = new Item();
//add the database
}
}
OutrosController.cs
public class OutrosController : Controller
{
[HttpGet]
public ActionResult Create_Hotel()
{
Hotel hotel = new Hotel();
return View(hotel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create_Hotel(Hotel hotel, HttpPostedFileBase[] images)
{
//add the database
return View(hotel);
}
}
(Model) Hotel.cs
public class Hotel
{
public int ID { get; set; }
public String Preco { get; set; }
public String Comodidades { get; set; }
public List<String> array_comodidades { get; set; }
public String Condicoes { get; set; }
public List<String> array_condicoes{ get; set; }
[Display(Name = "Telefone")]
public int? Telefone1 { get; set; }
[Display(Name = "Telemovel/Fax")]
public int? Telefone2 { get; set; }
public String Email { get; set; }
public String Tipo_Hotel { get; set; }
[Range(0, 5)]
public String Avaliacao { get; set; }
public List<Imagem> Imagens { get; set; }
[Display(Name = "Imagens_Secundárias", ResourceType = typeof(Resource))]
public String Outras_Imagens { get; set; }
public class TransmontanosDBContext : DbContext
{
public DbSet<Hotel> Transmontanos { get; set; }
}
}
Problem:
Your ajax request specifies type, url, dataType and a callback success function but it never actually sends any of the form data with it (not sure why these fields are in a form any way if youre not using the form to submit the data to the server- but that's a different problem than your posting about.
To fix your issue, you should change your ajax request to a POST instead of GET and include your model data with it as follows:
var model = { Id = $("#Id").val(),
Preco = $("#Preco").val(),
//populate the rest of your fields here just like Id
};
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: '/Outros/Create_Percurso',
contentType: "application/json",
success: function (html) {
$('#partialDiv').html(html);
}
})
I have a ajax.beginform that I have to upload a file and then in the view I have hidden for the path of the file that have been
saved in the server.
The problem is that the value of the path doesn't return to the view after the the post call.
I am returning new partial view with the errors and the value don't
coming
please help me
post method from controller that return partial view
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveSocioDetails(SpSocio socio) // ajax for 1 step in socio
{
bool sociook = false;
socio.StudentId = sStudentId; // bind student id to socio model
socio = SocioDetValid(ref sociook,socio);
// add validation
if (ModelState.IsValid && sociook)
{
socio = SaveSocioModel(socio);
Response.StatusCode = 200;
}
else
Response.StatusCode = 300; // return error to client the model is not valid
return PartialView("~/Views/Student/Socio/SocioDetails.cshtml", socio); // return the partial view of the forn with validation messages
}
Sociodetvalid function that saves the file and add the path to path field:
// bank account validation and save
if (socio.FileBankAccount == null) // if there is no file
{
if (socio.PathBankAccount == null) // check if he upload file already - if not add error message
{
ModelState.AddModelError("FileBankAccount", "חובה לצרף קובץ");
ok = false;
}
}
else // upload new the file
socio.PathBankAccount = Files.SaveFileInServer(socio.FileBankAccount, "BankAccount", sStudentId, socio.PathBankAccount);
the section in view for upload and the hidden for the path string:
<div class="row">
<div class="col-xl-3 col-lg-3 col-md-4 col-12 ">
#Html.LabelFor(model => model.BankStatus, htmlAttributes: new { #class = "control-label col-12" })
#Html.EditorFor(model => model.BankStatus, new { htmlAttributes = new { #class = "form-control must m-1 mt-0" } })
#Html.ValidationMessageFor(model => model.BankStatus, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.PathBankAccount)
</div>
<div class="col-xl-3 col-lg-3 col-md-4 col-12">
#Html.LabelFor(model => model.FileBankAccount, htmlAttributes: new { #class = "control-label col-12 must-sign", #for = "" })
<div class="chose-file m-1 mt-0">
#Html.TextBoxFor(model => model.FileBankAccount, new { #class = "form-control must", #type = "file", #accept = "image/jpeg,image/jpg,image/png,application/pdf", #style = "display:none;" })
<label for="FileBankAccount">
<i class="ml-1 material-icons">add_photo_alternate</i>
בחר קובץ
</label>
</div>
#Html.ValidationMessageFor(model => model.FileBankAccount, "", new { #class = "text-danger" })
</div>
#*
<div class="col-xl-3 col-lg-3 col-md-4 col-12" style="display:#(Model.PathBankAccount != null ? "" : "none")">
<label class="control-label col-12" for="">קובץ שמור</label>
<a name="#Model.PathBankAccount" class="btn btn-light btn-file m-1 mt-0">צפייה בקובץ שמור</a>
</div>*#
Thanks for help
Update:
Ajax form code : this is the part of the ajax that in a big view
<fieldset>
#using (Ajax.BeginForm("SaveSocioDetails", "Student", new AjaxOptions { HttpMethod = "POST", OnSuccess = "firstsuccess",OnFailure = "sociodetailsfail", UpdateTargetId="partialsocio" ,LoadingElementId = "div_loading" }, new { #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div id="partialsocio">
#Html.Action("PartialSocioDetails", "Student", new { SpId = ViewBag.SpId })
</div>
<div id="div_loading" style="display:none;">
<img src="#Url.Content("~/Content/Pic/Spinner.gif")" alt="" />
</div>
<button class="btn btn-primary" type="submit">המשך</button>
}
<input type="button" name="next" class="next action-button bg-primary" hidden value="Next" id="sociodetnext" />
</fieldset>
this is the function of fail and success ajax:
<script>
$(document).ready(function ()
{
});
function firstsuccess() {
console.log('this is ajaxSuccess');
$("#sociodetnext").click();
}
function sociodetailsfail(bdata) {
console.log('this is ajaxfail');
console.log(bdata.responseText);
$('#partialsocio').html(bdata.responseText);
}
</script>
In the script that Have returned to the client the value of the string doesn't appear..
Thanks for help
I tried to clear the form controller and using ModelState.Clear(); but don't work. I want to clear the form after the form is saved to database. Is there any possibility to refresh the view and clear the form jquery.
<td>
#Ajax.ActionLink("Show Post Order", "_ListPost", new { idOrder = #item.IdOrder }, new AjaxOptions()
{
HttpMethod = "GET",
LoadingElementId = "divLoading",
UpdateTargetId = "divPosition",
InsertionMode = InsertionMode.Replace
}, new { #class = "btn btn-primary" })
</td>
<td>
#Ajax.ActionLink("Add Answer", "_AddPost", new { idZlecenia = #item.IdZlecenia }, new AjaxOptions()
{
HttpMethod = "GET",
LoadingElementId = "divLoadingForm",
UpdateTargetId = "divAddPozycje",
InsertionMode = InsertionMode.Replace
}, new { #class = "btn btn-primary" })
</td>
</tr>
...
<tr id="divAddPozycje"></tr>
}
[HttpPost]
[ValidateAntiForgeryToken]
public PartialViewResult _AddPost(int idOrder, AddPositionViewModel viewModel)
{
var findOrder = db.Order.Find(idOrder);
if (ModelState.IsValid)
{
OrderPosition position = new OrderPosition { Description = viewModel.Description };
db.OrderPosition.Add(position);
findOrder.OrderPositionList.Add(position);
db.SaveChanges();
ViewBag.Information = position;
}
Thread.Sleep(2000);
ModelState.Clear();
return PartialView();
}
And View _AddPost - Paritial View. This partialView add position to
orders. The item is added using Html Ajax that adds an item without
page refresh
#model AplikacjaHelpDesk.ViewModels.AddPositionViewModel
#{
ViewBag.Title = "Add Post";
Layout = null;
}
<link href="~/Content/font-awesome.min.css" rel="stylesheet" />
<script src="~/Scripts/tinymce/tinymce.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/jquery-2.2.3.min.js"></script>
<div class="container-fluid">
#using (Ajax.BeginForm(new AjaxOptions()
{
UpdateTargetId = "divformResult",
HttpMethod = "Post"
}))
{
#Html.AntiForgeryToken()
#Html.Hidden("IdOrder")
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-md-10">
#Html.TextAreaFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10 ">
<input type="submit" value="Save" class="btn btn-danger" />
</div>
</div>
</div>
}
</div>
...
We've got a page which currently contains a four or five partial views, but is something that could grow. At the moment, there's two POST actions, for two entirely different database functions.
If we try doing the create function on another, the redirect then results in an "Object reference not set to an instance of an object." error, which is then relating to the other POST partial view.
Is there a way to stop this? Essentially, it seems to me that the post for one partial view is trying to interact with the other. Any ideas?
Thanks
Bulletins Controller for Creating:
[HttpPost]
public ActionResult CreateMain(BulletinsViewModel viewModel)
{
if (ModelState.IsValid)
{
BulletinsContext.tblBulletins.Add(new tblBulletin
{
ID = viewModel.BulletinID,
BulletinDisplayDate = viewModel.BulletinDisplayDate,
BulletinFilename = viewModel.MainBulletinName,
IsSixthForm = viewModel.IsSixthForm
});
//For loop to delete bulletins
//If bulletin folder has more than 10 files in
//Delete the oldest file, itererate till only 10 remain
{
DirectoryInfo dir = new DirectoryInfo(#"D:\Inetpub\WWWroot\intranet\Dashboard\Dashboard\Files\Bulletins");
List<FileInfo> filePaths = dir.GetFiles().OrderByDescending(p => p.CreationTime).ToList();
for (int index = filePaths.Count() - 1; index > 9; index--)
{
var fileNames = filePaths[index].Name;
//Delete from directory
filePaths[index].Delete();
//Remove from collection to restart the loop
filePaths.RemoveAt(index);
}
}
//Save changes to database
BulletinsContext.SaveChanges();
//Return to main bulletins index page
return RedirectToAction("~/Home/Index");
}
return View(viewModel);
}
Bulletins Create View:
#model Dashboard.Viewmodels.BulletinsViewModel
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.BulletinDisplayDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.BulletinDisplayDate, new { htmlAttributes = new { #class = "form-control", #id = "datepicker-basic", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.BulletinDisplayDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MainBulletinName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group">
#Html.EditorFor(model => model.MainBulletinName, new { htmlAttributes = new { #class = "form-control", #Value = "Select File...", #readonly="readonly" } })
<span class="input-group-addon" href="javascript:;" onclick="moxman.browse({ fields: 'MainBulletinName', extensions: 'pdf', path: 'D:/Inetpub/WWWroot/intranet/Dashboard/Dashboard/Files/Bulletins' });" style="cursor: pointer;"><i class="fa fa-upload"></i></span>
#Html.ValidationMessageFor(model => model.MainBulletinName, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
<script type="text/javascript" src="~/Scripts/tinymce/plugins/moxiemanager/js/moxman.loader.min.js"></script>
Printer Credits Create Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PrinterCredits(PrinterCreditsViewModel viewModel)
{
if (ModelState.IsValid)
{
//Send the email if credits are added..
//Create a bunch of variables for the email
//Create the email body etc
var fromAddress = "";
string toName = Request.Form["Username"].ToUpper();
string AmountOfCredits = Request.Form["AmountAdded"];
string Plural = "";
string Title = "";
string AddedByWho = User.Identity.Name.Split('\\')[1];
System.DateTime AddedWhen = DateTime.Now;
if (AmountOfCredits == "1")
{
Plural = " printer credit has ";
Title = "Printer Credit Added!";
}
else
{
Plural = " printer credits have ";
Title = "Printer Credits Added!";
}
var toEmail = toName + "";
var subject = AmountOfCredits + Plural + "been added to your account, " + toName;
string body = "";
//Create an SMTP client for sending an email
var smtp = new SmtpClient
{
Host = "",
Port = 25,
EnableSsl = false,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = true,
};
//Populate the SMTP client and encode the body for the HTML
using (var message = new MailMessage(fromAddress, toEmail)
{
Subject = subject,
Body = body,
IsBodyHtml = true,
BodyEncoding = System.Text.Encoding.UTF8
})
//Try to send the email. If sent, insert data.
//Redirect back to original page
//Take current printer credit from and update with fund + cost
try
{
//Link the viewmodel and the database together
PartialViewContext.tblPrinterCredits.Add(new tblPrinterCredit
{
Username = viewModel.Username,
AmountAdded = viewModel.AmountAdded,
AddedBy = AddedByWho,
AddedWhen = viewModel.AddedWhen,
Money = viewModel.AmountAdded * 0.02
});
Nullable<double> cost = viewModel.AmountAdded * 0.02;
//Update the printer credit fund and insert into tblOption
tblOption fund = (
from n in PartialViewContext.tblOptions
where n.ID == 1
select n).First();
fund.PrinterCreditFund = fund.PrinterCreditFund + cost;
PartialViewContext.SaveChanges();
message.CC.Add("");
smtp.Send(message);
Response.Redirect("~/Home/Index");
}
//If it fails, go chicken oriental (only a redirect, will eventually become a crazy message)
catch
{
smtp.Send(message);
Response.Redirect("~/Home/Index");
}
}
return View(viewModel);
Printer Credits View:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="panel">
<div class="panel-heading">
<span class="panel-icon">
<i class="fa fa-print"></i>
</span>
Add Printer Credits - #Costings
</div>
<div class="panel-body">
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label class="control-label col-md-3">User:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", #id = "Username", #name = "Username", #maxlength = "6" } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Amount:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.AmountAdded, new { htmlAttributes = new { #class = "form-control", #id = "AmountAdded", #onkeyup = "Update()", #Value = 0 } })
#Html.ValidationMessageFor(model => model.AmountAdded, "", new { #class = "text-danger", #type="number" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3">Cost:</label>
<div class="col-xs-8">
#Html.EditorFor(model => model.TotalCost, new { htmlAttributes = new { #class = "form-control", #id = "TotalCost", #readonly = "readonly", #Value = "0" } })
#Html.ValidationMessageFor(model => model.TotalCost, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1 col-md-10">
<input type="submit" value="Add Printer Credits" class="btn btn-primary btn-gradient dark btn-block" />
#Html.EditorFor(model => model.AddedBy, new { htmlAttributes = new { #class = "form-control", #Value = User.Identity.Name.Split('\\')[1], #Style = "display: none;" } })
#Html.ValidationMessageFor(model => model.AddedBy, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
}
<script type="text/javascript">
$(document).ready(
function () {
Update();
$('#AmountAdded, #TotalCost')
.keyup(function () {
Update();
})
}
);
function Update() {
var cost = 2
var one = $('#AmountAdded'),
two = $('#TotalCost');
two.val(parseInt(one.val()) * cost / 100);
}
</script>
<script type="text/javascript">
document.getElementById('Username').focus()
</script>
Just figured out that I need to tell the form which action and controller to use, despite the fact two different controllers are running the views. But anyway, an example is:
#using (Html.BeginForm("CreateMain", "Bulletins", FormMethod.Post, new { }))