I have a JS function which takes a value from a textbox based on the Radio button selected.
Example: If RadioButton No is Selected, values is teken from TextBox A, else if RadioButton Yes is selected, Value is taken from TextBox B. The following script is in my view
$('#btnVolunteerSaveBtn').on('click', function() { // on click of save button
if (document.getElementById('RadioNo').checked) { //ID of radio button NO
var checking = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
if (checking == "") {
//if nothing is entered, stop from saving in DB
} else {
x = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
$.ajax({
url: '#Url.Action("DonationValue","VolunteerInfo")',
data: {
name: x
},
type: "POST"
});
}
} else {
x = $('#GetNames').val(); //ID of textbox from where the value is to be taken if RadioButton Yes is selected
$.ajax({
url: '#Url.Action("DonationValue","VolunteerInfo")',
data: {
name: x
},
type: "POST"
});
}
});
Till here it seems to work fine. Now coming to the controller, I have a function DonationValue
My Question:
How can I pass the name parameter above?
If nothing is filled in TextBox with id #Donation, how do I stop
from saving the form in the DB?
My Attempt:
I tried doing
public string DonationValue(string name = null)
{
return name; //Trying to pass this value above
}
This didn't help. It resolved the error but the passed value was always null. I also tried a couple of other things but none helped.
Edited:
[HttpPost]
public ActionResult AddVolunteer(VolunteerInfo viewModel)
{
if (!ModelState.IsValid)
{
return View("AddVolunteer", viewModel);
}
var volunteer = new VolunteerInfo()
{
Name = viewModel.Name,
BirthdayDateTime = viewModel.BirthdayDateTime,
Address = viewModel.Address,
PhoneNumber = viewModel.PhoneNumber,
EmailAddress = viewModel.EmailAddress,
OccasionsID = viewModel.OccasionsID,
DonationForWhom = _DonationValue
};
if (!string.IsNullOrEmpty(volunteer.DonationForWhom))
{
_context.VolunteerInfos.Add(volunteer);
_context.SaveChanges();
return RedirectToAction("Index", "Home");
}
return //something to save state so that user doesnt have to enter all the values again
}
[HttpPost]
public void DonationValue(string name)
{
_DonationValue = name;
}
#Daisy Shipton.
Is this a better solution?
<script>
$(function() {
$('#btnVolunteerSaveBtn').on('click', function() { // on click of save button
debugger;
if (document.getElementById('RadioNo').checked) { //ID of radio button NO
var checking = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
if (checking == "") {
//if nothing is entered, stop from saving in DB
}
else {
var x = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
var jsonObject = {
"textValue": x,
"isRadioSelected": "true" // show the radio is selected
};
$.ajax({
url: '#Url.Action("AddVolunteer", "VolunteerInfo")',
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
}
}
else {
var jsonObject2 = {
"textValue": $('#GetNames').val(),
"isRadioSelected": "false" // show the radio is not selected
};
$.ajax({
url: '#Url.Action("AddVolunteer", "VolunteerInfo")',
data: JSON.stringify(jsonObject2),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
}
});
})
</script>
In my controller:
[HttpPost]
public ActionResult AddVolunteer(VolunteerInfo volunteerInfo)
{
if (volunteerInfo.isRadioSelected)
{
//something
}
else
{
//something
return View();
}
1) Client calls to DonationValue post method with name paramter
e.g. name="abc"
[HttpPost]
public string DonationValue(string name = null) // name = "abc"
{
return name; //Trying to pass this value above
}
This returned value to be stored in client side say variable retunedDonationValue
If you don't pass any name parameter then above post method does return empty string then just set retunedDonationValue = ''
2) Now you have to pass above retunedDonationValue to your post method in posted json object like
var jsonObject =
{
"Name" = "YourName",
"BirthdayDateTime" = "YourBirthdayDateTime",
"Address" = "YourAddress",
"PhoneNumber" = "YourPhoneNumber",
"EmailAddress" = "YourEmailAddress",
"OccasionsID" = "YourOccasionsID",
"DonationForWhom" = retunedDonationValue //Note here
}
3) And pass this post data to http call to AddVolunteer
$.ajax({
url: '#Url.Action("AddVolunteer", "VolunteerInfo")',
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
4) And your action method is look like
[HttpPost]
public ActionResult AddVolunteer(VolunteerInfo viewModel)
{
if (!ModelState.IsValid)
{
return View("AddVolunteer", viewModel);
}
var volunteer = new VolunteerInfo()
{
Name = viewModel.Name,
BirthdayDateTime = viewModel.BirthdayDateTime,
Address = viewModel.Address,
PhoneNumber = viewModel.PhoneNumber,
EmailAddress = viewModel.EmailAddress,
OccasionsID = viewModel.OccasionsID,
DonationForWhom = viewModel.DonationForWhom
};
if (!string.IsNullOrEmpty(volunteer.DonationForWhom))
{
_context.VolunteerInfos.Add(volunteer);
_context.SaveChanges();
}
return View(viewModel);
}
Related
Description of the situation:
I have selectbox, I choose a person there (there, I download the entire list of employees from the database). I have two more fields (I would like to enter values from other columns (same row) (data of this employee))
Controller
using AppEcp.Models;
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
namespace AppEcp.Controllers
{
public class UzytkownicyController : Controller
{
private readonly UzytkownicyDbContext _uzytkownicyContext;
public UzytkownicyController(UzytkownicyDbContext uzytkownicyContext)
{
_uzytkownicyContext = uzytkownicyContext;
}
public IActionResult GetItems(DataSourceLoadOptions loadOptions)
{
var GetMethod = _uzytkownicyContext.Uzytkownicy.Where(i => i.Firma == "Pekao Leasing").Select(i => new
{
i.Id,
i.Nazwa,
i.Departament,
i.Login
});
return Json(DataSourceLoader.Load(GetMethod, loadOptions));
}
[HttpGet]
public ActionResult GetDepartmentAndManager(string nazwaValue)
{
var danePracownika = _uzytkownicyContext.Uzytkownicy.Where(x => x.Nazwa == nazwaValue).Select(s => new
{
UserDepartament = s.Departament,
UserManager = s.Manager
});
return Json(danePracownika);
}
}
}
I tried:
cshtml page
#(Html
.DevExtreme()
.SelectBox()
.ID("Id_name")
.DataSource(d => d
.Mvc()
.Controller("Uzytkownicy")
.Key("Id")
.LoadAction("GetItems")
)
.DisplayExpr("Nazwa")
.ValueExpr("Id")
.SearchEnabled(true)
.OnValueChanged("getDepAndMan")
)
#(Html.DevExtreme().TextBox()
.ID("Id_department"))
#(Html.DevExtreme().TextBox()
.ID("Id_manager"))
<script type="text/javascript">
function getDepAndMan() {
var nazwaValue = document.getElementById("Id_name").value;
$.ajax({
type: "GET",
url: '#Url.Action("GetDepartmentAndManager", "Uzytkownicy")',
contentType: 'application/json; charset=utf-8',
data: { nazwaValue : nazwaValue},
dataType: "json",
success: function (data) {
document.getElementById("Id_department").value = (data.UserDepartament);
document.getElementById("Id_manager").value = (data.UserManager);
},
error: function () {
alert("bad code noob");
}
});
}
</script>```
Do not work:
The code does not throw an error, but does not enter the downloaded data into text boxes
Access the required widget using its "options" api (refer to this demo), for example:
success: function (data) {
alert(data.UserDepartament + " " + data.UserManager);
//document.getElementById("Id_department").value = (data.UserDepartament);
//document.getElementById("Id_manager").value = (data.UserManager);
$("#Id_department").dxTextBox("instance").option("value", data.UserDepartament);
$("#Id_manager").dxTextBox("instance").option("value", data.UserManager);
}
I have a problem when I try to save some data to the database. I can see the ID and Date returning me appropriate values in the JS function... However, the parameter for the Process function inside the controller class remains null. I don't know why is that happening. There is a linq query that is also included in the Hello Model, but I didn't include it because there is no need for it.
Model:
public class Hello
{
List<string> Ids { get; set; }
List<string> Dates { get; set; }
}
Controller:
[HttpPost]
public ActionResult Process(string ids, string dates)
{
Hello model = new Hello();
if (ModelState.IsValid)
{
using (db = new DB())
{
rp = new RequestProcess();
//var c = rp.getHello(model, dates);
var c = rp.getStuff();
if (c != null)
{
foreach (var i in c)
{
if (i != null)
{
ids = i.ID;
dates = i.Date.ToString();
}
db.SaveChanges();
}
}
}
ViewBag.Message = "Success";
return View(model);
}
else
{
ViewBag.Message = "Failed";
return View(model);
}
}
View:
<td><input class="id" type="checkbox" id=#item.ID /></td>
<td>#Html.DisplayFor(x => #item.ID)</td>
<td><input class="date" id=date#item.ID type="text" value='#item.Date'/></td>
$(document).ready(function () {
var ids = "";
var dates = "";
$("#btnSubmit").bind("click", function () {
createUpdateArrays();
var url = "/Sample/Process";
$.ajax({
type: "POST",
url: url,
data: { ids: ids, dates: dates },
contentType: 'application/json; charset=utf-8',
success: function (success) {
if (success === true) {
alert("HERE WE ARE");
}
else {
alert("eror");
}
}
});
ids = "";
dates = "";
});
function createUpdateArrays() {
var i = 0;
$('input.remedy-id:checkbox').each(function () {
if ($(this).is(':checked')) {
var rid = $(this).attr("id");
$('.planned-date').each(function () {
var did = $(this).attr("id");
if (did === rid) {
var date = $(this).val();
ids += rid + ",";
dates += date + ",";
}
});
};
});
};
Any help would be appreciated!
I think you need contentType: 'application/json' in your $.ajax({});
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(list),
contentType: 'application/json'
});
Also, try adding [FromBody]Hello model in your controller action.
There are several issues in your code:
1) You're passing JSON string containing viewmodel properties, it is necessary to set contentType: 'application/json; charset=utf-8' option in AJAX callback to ensure model binder recognize it as viewmodel parameter.
2) return View() is not applicable for AJAX response, use return PartialView() instead and put html() to render response in target element.
Therefore, you should use AJAX setup as provided below:
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(list),
contentType: 'application/json; charset=utf-8',
success: function (result) {
$('#targetElement').html(result);
},
error: function (xhr, status, err) {
// error handling
}
});
Controller Action
[HttpPost]
public ActionResult Process(Hello model)
{
if (ModelState.IsValid)
{
using (db = new DB())
{
// save data
}
ViewBag.Message = "Success";
return PartialView("_PartialViewName", model);
}
else
{
ViewBag.Message = "Failed";
return PartialView("_PartialViewName", model);
}
}
Remember that AJAX callback intended to update certain HTML element without reloading entire view page. If you want to reload the page with submitted results, use normal form submit instead (with Html.BeginForm()).
i have a modal with input, i digit some emails and add to a list, later i want to pass this list of emails to my function that send emails.
var listEmails = [];
document.getElementById("addEmail").onclick = function () {
var text = document.getElementById("recipient-email").value;
$("#Listmail").append('<li>' + text + '</li>');
listEmails.push(text);
}
document.getElementById("sendEmail").onclick = function () {
#*location.href = '#Url.Action("TestSendReport", "ProductMarketplace")?emails='+listEmails;
}
that is my function in Controller that receive a list of email to send
public void TestSendReport(List<string> ListMails)
Please try below code and try to call controller method using jQuery Ajax
var list= [];
document.getElementById("addEmail").onclick = function () {
var text = document.getElementById("recipient-email").value;
$("#Listmail").append('<li>' + text + '</li>');
list.push(text);
}
document.getElementById("sendEmail").onclick = function () {
var jsonText = JSON.stringify({ list: list});
$.ajax({
type: "POST",
url: "ProductMarketplace/TestSendReport",
data: jsonText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function() { alert("success"); },
failure: function() { alert("failed"); }
});
}
And use controller method like this,
[WebMethod]
public void TestSendReport(List<string> list)
{
}
document.getElementById("sendEmail").onclick = function () {
location.href = '#Url.Action("TestSendReport", "ProductMarketplace")?emails=' +
encodeURI(JSON.stringify(listEmails));
}
public void TestSendReport(List<string> emails)
{
}
I am working with a custom workflow solution that I am creating. I would like to create a postback that has the model, and two integer values that represent the action and step that I have completed. I don't want to add them to the model because they are only used in this one place. The signature for this postback would be something like this.
[HttpPost]
public void ProcessWorkflowAction(EditScreenModelValidation model, int stepActionId, int stepNumber)
{
//Some work on model and actions
}
I would really like to do this through JS because that is currently how I am getting StepActionId and StepId. Is there a way to package up the model to send through JS?
var modelObj = CreateModelData();
var postObj = JSON.stringify(modelObj);
$.ajax({
type: "POST",
traditional: true,
dataType: "json",
url: "url",
data: { model: modelObj, stepActionId: stepId, stepNumber: 3 }
cache: false,
complete: function (data) {
}});
CreateModelData = function () {
var modelObj = {};
var modelArray = $('#frm').serializeArray()
$.each(modelArray, function (index, value) {
assign(modelObj, value.name, value.value);
})
return modelObj;
};
function assign(obj, prop, value) {
if (prop != undefined) {
if (typeof prop === "string")
prop = prop.split(".");
if (prop.length > 1) {
var e = prop.shift();
assign(obj[e] =
Object.prototype.toString.call(obj[e]) === "[object Object]"
? obj[e]
: {},
prop,
value);
} else
obj[prop[0]] = value;
}
}
The model comes back as null in the controller. I have also tried the following code with the same result.
$.ajax({
type: "POST",
traditional: true,
dataType: "json",
url: "url",
data: { model: $('#frm').serializeArray(), stepActionId: stepId, stepNumber: 3 }
cache: false,
complete: function (data) {
}});
You need to build up the object, assign the properties (make sure it matches any model validation and the field names are the same as your model) and use JSON.stringify to make the conversion:
var modelObj = {};
modelObj.prop1 = $('#txtField1').val();
modelObj.prop2 = $('#txtField2').val();
// etc... make sure the properties of this model match EditScreenModelValidation
var postObj = JSON.stringify(modelObj); // convert object to json
$.ajax({
type: "POST",
traditional: true,
dataType: "json",
url: "/Workflow/Home/ProcessWorkflowAction",
data: { model: postObj, stepActionId: stepId, stepNumber: 3 }
cache: false,
complete: function (data) {
if (data.responseText.length > 0) {
var values = $.parseJSON(data.responseText)
$('#ActionErrors').html(values.message)
}
else {
location.reload();
}
}});
It's possible and pretty easy to do. MVC is nice about packaging up what you send it.
So if your model looks like:
public class TestModel
{
public string Name { get; set; }
public int Age { get; set; }
}
And your post method looks like:
[HttpPost]
public void TestMethod(TestModel model, int num1, int num2)
{
// Stuff
}
Your javascript POST would look like:
function doPost(){
$.post("/Home/TestMethod",
{
model: {
Name: "Joe",
Age: 29
},
num1 : 5,
num2 : 10
},
function (data, status) {
//Handle status if you decide to return something
});
}
Hope that helps!
So here is how I got it to work. The CreateModelData uses the (frm).serializeArray() method, but I found that if the item was disabled or not on the page, then it didn't create that property.
var modelObj = CreateModelData();
var postObj = JSON.stringify(modelObj);
$.ajax({
type: "POST",
traditional: true,
dataType: "json",
url: "url",
data: { modelString: postObj, stepActionId: stepId, stepNumber: 3 },
cache: false,
complete: function (data) {
}});
});
CreateModelData = function () {
var modelObj = {};
var modelArray = $('#frm').serializeArray();
$.each(modelArray, function (index, value) {
assign(modelObj, value.name, value.value);
})
return modelObj;
};
function assign(obj, prop, value) {
if (prop != undefined) {
if (typeof prop === "string")
prop = prop.split(".");
if (prop.length > 1) {
var e = prop.shift();
assign(obj[e] =
Object.prototype.toString.call(obj[e]) === "[object Object]"
? obj[e]
: {},
prop,
value);
} else
obj[prop[0]] = value;
}
}
On the controller side, I changed the signature to be all string values like so.
[HttpPost]
public void ProcessWorkflow(string modelString, int stepActionId, int stepNumber)
{
}
To make the modelString value the actual model object, I did this.
using (Stream s = GenerateStreamFromString(json))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(modelObj));
return (modelObj)serializer.ReadObject(s);
}
In the end, this worked for me. All the fields were there and I got no errors. When i tried to have the first variable in the controller method to be the model object, it always came back as null for me no matter what I did.
The fastest and easiest way to get all the fields in the Model is to serialize the Form which is bound with Model.
Update
The problem that you were receiving null in properties is because serializeArray() create key value format json. you just need to get re-build the json from key value to Property value that can be mapped to the model.
var modelObj = $('#formId').serializeArray()
.reduce(function (a, x) { a[x.name] = x.value; return a; }, {});
A little tweak in you ajax call instead of datatype use contentType. This is another reason you were getting null in controller's model object parameter.
$.ajax({
type: "post",
url: "/Account/RegisterSome",
data: { model: modelobj, id: 3 },
contentType: 'application/json',
cache: false,
complete: function (data) {
}
});
I resolved the issue by removing the JSON.stringify() and just posting my javascript object.
I am submitting a form of data via an Ajax call (I think?) to my controller to process. Once the row is saved, I am hoping to redirect to the original HttpGet action in my controller that initially loaded the form.
What I am finding is that the ajax call works, the controller action fires, and the data is saved to the database. However, the screen never refreshes after the View is reloaded.
I have a breakpoint on the 'return View(model)' on the action in my controller, which fires - but the screen doesn't refresh. If I use firebug and look at the html, I see the new row should display in my view. But, the screen doesn't seem to reload at all.
My Javascript:
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmitNewCard').click(function () {
var data = { cardNumber: $('.txtNewCardNumber').val(), cardHolder: $('.txtNewCardHolder').val(), expiryMonth: $('.txtNewExpiryMonth').val(), expiryYear: $('.txtNewExpiryYear').val(), active: $('.txtNewActive').val(), accountId: $('.Id').val() };
$.ajax({
url: '#Url.Action("SaveBankCard", "BankAccount")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result.Success == 'true') {
alert('Redirecting...');
window.location = '#Url.Action("EditBankAccount", "BankAccount", new {accountId = Model.Id})';
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
The controller method called by the javascript above (Successfully):
public ActionResult SaveBankCard(string cardNumber, string cardHolder, int expiryMonth, int expiryYear, string active, int accountId)
{
var card = new AccountCardDto
{
Id = 0,
AccountId = accountId,
Active = active == "on",
CardHolderName = cardHolder,
CardNumber = cardNumber,
ExpiryDate = new DateTime(2000 + expiryYear, expiryMonth, 1)
};
int id = new BankAccountService().SaveCard(card);
return RedirectToAction("EditBankAccount", new { bankAccountId = accountId });
}
And then the Controller Action that gets called from the 'RedirectToAction' call:
[HttpGet]
[Authorize]
[OutputCache(Location = System.Web.UI.OutputCacheLocation.None)]
public ActionResult EditBankAccount(int? bankAccountId)
{
var model = new BankAccountModel();
if (bankAccountId != null)
{
....
}
return View(model);
}
That last line, 'return View(model)' does get called. If I check the 'model', I see the new row that was persisted to the database. But, as I say, the screen doesn't refresh.
Can anyone tell me why, and how I can fix/improve my situation?
Try this...your method SaveBankCard calling EditBankAccount in controller and ajax also then do one thing call it only in ajax or in controller
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmitNewCard').click(function () {
var data = { cardNumber: $('.txtNewCardNumber').val(), cardHolder: $('.txtNewCardHolder').val(), expiryMonth: $('.txtNewExpiryMonth').val(), expiryYear: $('.txtNewExpiryYear').val(), active: $('.txtNewActive').val(), accountId: $('.Id').val() };
$.ajax({
url: '#Url.Action("SaveBankCard", "BankAccount")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result != 0) **//if your method return int else check it null if your method return string**
{
alert('Redirecting...');
window.location = '#Url.Action("EditBankAccount", "BankAccount", new {bankAccountId= Model.Id})'; **//change name of parameters**
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
Controller
public int SaveBankCard(string cardNumber, string cardHolder, int expiryMonth, int expiryYear, string active, int accountId)
{
var card = new AccountCardDto
{
Id = 0,
AccountId = accountId,
Active = active == "on",
CardHolderName = cardHolder,
CardNumber = cardNumber,
ExpiryDate = new DateTime(2000 + expiryYear, expiryMonth, 1)
};
int id = new BankAccountService().SaveCard(card);
int bankAccountId = accountId;
return bankAccountId ;
}