Add item to Model.List<item> with JavaScript - javascript

My Model has fields which are displayed on the screen, as well as a List which is displayed in a grid on the screen. I have an Add button, which shows a modal popup (without a postback), that allows the user to enter a few fields, and then clicks 'Save'. At the moment, I use a JSON call back to my controller to save the data. I then reload the screen, and the new item appears in the grid, as it was saved to the database, and the Model reloaded.
Problem is, if the user has made any changes to the main details in the model, they're lost, because all the JSON call did was save a new item to the database, and redirect to the main screen which reloads.
What I need to rather do is somehow, add the new item from the popup, to the main Model, and then reload the grid, without saving to the database at all, and without a postback.
My javascript for posting the data from the view looks like this:
<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) {
if (result.Success == 'true') {
window.location = '#Url.Action("EditBankAccount", "BankAccount", new { bankAccountId = Model.Id })';
} else {
alert(result.Message);
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
And then the controller method that handles this, looks like this:
public JsonResult 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)
};
var id = new BankAccountService().SaveCard(card);
var result = new { Success = "true", Message = "Saved", NewId = id };
var r = new JsonResult
{
Data = result
};
return r;
}
So, the data is saved in the controller, and then the Javascript redirects to roload the whole screen. Can this be changed to rather save the data to the models' List client side, and then the whole model with changes and additions get saved via the one Save button on my screen? Is it possible to add to the Model's List client side?

try json script like this
$('#ddlCompany').change(function () {
//var URL = $('#Enrollform').data('fetchproduct');
$.getJSON('/EnrollmentForm/fetchproduct/' + $('#ddlCompany').val(), function (data) {
var items = '<option>Select a Product</option>';
$.each(data, function (i, product) {
items += "<option value='" + product.Value + "'>" + product.Text + "_" + product.Value + "</option>";
});
$('#ddlProduct').html(items);
});
});

Related

Asynchronous AJAX calls (multiple)

I posted this yesterday but i may not have explained my situation well.
I have 3 grids on a page that are built dynamically through JavaScript.
I then have 3 separate JavaScript methods to set a session when a row is clicked in a certain grid.
Once the session is set i would like it to navigate to the next page.
Here is what i have
OnClick event
$('#clinician-planned').on('click', 'tbody>tr>td:not(:last-child):not(:first-child)', function () {
var ID = $(this).closest("tr").children("td.grid__col--id").find("[name=patient-link]").text().trim();
var Location = '#Url.Action("SetPASession", "Clinician")';
AjaxCall(Location, ID);
});
$('#clinician-recent').on('click', 'tbody>tr>td:not(:last-child):not(:first-child)', function () {
var ID = $(this).closest("tr").children("td.grid__col--id").find("[name=patient-link]").text().trim();
var Location = '#Url.Action("SetRDSession", "Clinician")';
AjaxCall(Location, ID);
});
$('#clinician-theatre').on('click', 'tbody>tr>td:not(:last-child):not(:first-child)', function () {
var ID = $(this).closest("tr").children("td.grid__col--id").find("[name=patient-link]").text().trim();
var Location = '#Url.Action("SetTESession", "Clinician")';
AjaxCall(Location, ID);
});
AJAX Post To Controller
function AjaxCall(Location, ID) {
alert('1');
$.ajax({
type: 'POST',
url: Location,
dataType: 'text',
async: false,
contentType: 'application/json; charset=utf-8',
error: function (response) { alert(JSON.stringify(response)); }
}).done(function (response) {
alert('2');
location.href = "#Url.Action("Summary", "Patient")" + "/" + ID;
});
}
Here are the controller methods
public ActionResult SetPASession()
{
Session.Remove("Clinician");
Session["Clinician"] = "pa";
return Json(null);
}
public ActionResult SetRDSession()
{
Session.Remove("Clinician");
Session["Clinician"] = "rd";
return Json(null);
}
public ActionResult SetTESession()
{
Session.Remove("Clinician");
Session["Clinician"] = "te";
return Json(null);
}
The problem i have is when the row is clicked "alert('1'); shows instantly, however it seems like it takes a while and waits for all grids to be populated before the 2nd alert appears. I have tried putting async: false, but this doesnt seem to work.
Any ideas would be much appreciated.

Url action parameters using Ajax

I am trying to pass data from a view to a controller using parameters.
Now I am running a few difficulities. I am trying to pass those parameters once I select a row from a table and press on a button which has a onclick method to ShowTasks()
The C# controller:
[Route("/service/delivery/{id}/{shopdoccode}/{regdate}")]
public ActionResult Delivery(string id, string shopdoccode, string regdate)
{
//do stuf
}
The Javascript function when user clicks on button:
function ShowTasks() {
//Dear Stackoverflow > This works, this is for selecting a row in the table
var $selectedRow = $(".highlight");
if ($selectedRow.length == 1) {
var dcColumn = 0;
var rdColumn = 1;
var shopdoccodeColumn = 3;
//assigning name to the colomn value
var id = $selectedRow[0].children[dcColumn].innerText.trim();
var regdate = $selectedRow[0].children[rdColumn].innerText.trim();
var shopdoccode = $selectedRow[0].children[shopdoccodeColumn].innerText.trim();
//ajax
if (id && regdate && shopdoccode) {
$.ajax({
type: 'POST',
url: '#Url.Action("service", "delivery" ,new { id = "id", shopdoccode = "shopdoccode", regdate = "regdate" })',
data: { id, regdate, shopdoccode },
success: function (data) {
if (data.success) {
console.log("Succes");
}
},
error: function (data) {
console.log("Error");
}
});
}
}
}
What have I done so far? Sitting for hours trying to find a way to give the parameters to my controller so I can invoke a SQL stored procedure.
Unforntunately I can not simply use a hidden form for this.
Also this was quite helpful:
Url.Action parameters?
#sleeyuen
Looks to me like your Url.Action has its parameters in the wrong order. Change it to:
url: '#Url.Action("delivery", "service", new { id = "id", shopdoccode = "shopdoccode", regdate = "regdate" })',
Here's the appropriate overload that you want:
Action(String, String, Object) with actionName, controllerName, and routeValues, in that order.
You can not *.js or *.html file wrtie razor code.
#Url.Action(string actionName,string controllerName,object routeValues)
The above code can only be used *.cshtml file.
test with Url.RouteUrl instead of Url.Action

Json GET is not showing the details in popup

I am trying to show the details of each Student with Json and I think it is not going to the ajax part.
It shows the id and the url when I console.log() them, but I get this error message for the ajax part
I don't know what's missing or where is the issue?
This is my html link
#Html.ActionLink("Details", "StudentDetails", new { id = item.ID }, new { #class = "modalDetails", #id = item.ID })
script
<script type="text/javascript">
$(function () {
$(".modalDetails").click(function (e) {
e.preventDefault(); //stop the default action upon click
var id = $(this).attr('id');
console.log(id);
var url = $(this).attr("href");
console.log(url);
$.ajax({
type: 'GET',
data: { id: id },
dataType: "json",
url: url,
success: function (data) {
$(".modalDetails").append('<span> First Name: ' + data.firstName + '</span></br>');
console.log("success");
}
});
$('#myModal').modal('show'); // show the modal pop up
});
});
</script>
StudentController
public JsonResult StudentDetails(int id)
{
Student student = studentRepository.GetStudentByID(id);
var json = new{
firstName = student.FirstMidName
};
return Json(json, JsonRequestBehavior.AllowGet);
}
Everything was fine, except that I needed to build the solution and append the details to the modal-body. Sometimes it is just a simple fix.

AJAX whenever I try to submit my text my div area duplicates the current data displayed plus my new data

Hi I have a working script of retrieving a JSON data result for my small chat application but my problem is that it displays a duplicate result of the text that was already posted plus my newly text that was inserted from my DB
here is my whole Javascript code:
function sendChatText() {
if (sendReq.readyState == 4 || sendReq.readyState == 0) {
sendReq.open("POST", 'includes/getChat.php?last=' + lastMessage, true);
sendReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
sendReq.onreadystatechange = AjaxRetrieve();
var param = 'message=' + document.getElementById('txtA').value;
param += '&name='+user;
param += '&uid='+uid;
param += '&rid='+document.getElementById('trg').value;
sendReq.send(param);
document.getElementById('txtA').value = '';
}
}
function AjaxRetrieve()
{
var rid = document.getElementById('trg').value,
data = {chat: uid, rid: rid, name: user};
$.ajax({
url: "includes/getChat.php",
type: "GET",
data: data,
dataType: 'json',
success: function(result){
$.each(result, function(rowKey, row) {
$("#clog").append($('<p />').html('<h4>'+ row.username +':</h4>' + row.message_content) );
});
}
});
}
I think your getChat.php returns all the chat text for that user, also you are appending them to #clog.
I have two suggestions
Return only the latest text from server by sending the time stamp from the JS itself like
data = {"chat": uid, "rid": rid, "name": user, "last_read_time": window.last_read_time};
window.last_read_time = new Date().format("d/M/yyyy hh:mm:ss tt"); //store new time
clear #clog before looping your data
$("#clog").empty(); //clear the previous msgs
$.each(result, function(rowKey, row) {
$("#clog").append($('<p />').html('<h4>'+ row.username +':</h4>' + row.message_content);
});

MVC - On Select thumbnail, show data from database

i have a script if the user select a thumbnail shows
the larger image and the id from my database.
Until this point its works very well
what i try to do now is when the user clicks on the
thumbnail, i want to show the data which are in my table.
how can i do that?
My database relationship:
in my database i have 2 tables which one has the primary key
and the other the foreign key.
when i select the thumbnail which are in the table with the
primary key, i want to show the data from my other table
which contains the foreign key.
My code:
Javascript:
function swap(image) {
document.getElementById("imagem-selec").src = image.href;
$("input[name='Id_Img']").val($(image).data("id"));
}
HTML to show the list of thummbnails:
#foreach (var p in ViewBag.Img)
{
<li>
<a href="~/Files/#p.Name" onclick="swap(this); return false;" data-id="#p.Id">
<img src="~/Files/#p.Name"/>
</a>
</li>
Html which receive the path
<div id="wrap">
<img id="i-selec" src=""/>
</div>
Any sugestions?
Thanks in advance
UDPATE MY CODE:
Script
function swap(image) {
var imageID = $(image).data("id");
$.ajax("/{Admin}/GetImageData",
{
data: JSON.stringify({ ID: imageID }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
// Add your content to DOM here:
// values in data.data1 etc...
values in data.De, data.Sc
}
error: function () {
alert("error!");
}
});
};
Controller:
public JsonResult GetImageData(int ID)
{
using (SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
SqlDataAdapter sqlAdapt = new SqlDataAdapter
(#"SELECT C.* From Content C inner join Image B on C.ID_Img = B.Id WHERE C.Id=" + ID, cn);
SqlCommandBuilder sqlCmdBuilder = new SqlCommandBuilder(sqlAdapt);
DataSet data = new DataSet();
sqlAdapt.Fill(data, "Content ");
cn.Close();
return Json(data);
}
}
It seems like there are two choices:
Load the data in the view and have it hidden, on page load, and have the click event simply show the data.
Have an AJAX call to get the data that you want on the click event, and add the data when the call returns.
I would personally go with the AJAX call, as it uses a little extra network overhead on the requests, but potentially saves a lot of useless data from being downloaded:
// Data model.
class ImageData
{
public int data1 { get; set; }
public string data2 { get; set; }
...
}
// Controller action. Data access abstracted out.
public JsonResult GetImageData(int ID)
{
ImageData data = DataAccess.GetImageData(ID);
return Json(data);
}
Your JavaScript might look something like:
function swap(image) {
var imageID = $(image).data("id");
$.ajax("/{YourControllerHere}/GetImageData",
{
data: JSON.stringify({ ID: imageID }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
// creating the element to add
var div = document.createElement("div");
div.setAttribute("id", imageID);
$(image).parent().append(div);
//adding the data here. do this for each data item?
$("#"+imageID).append(data.details.YOUR_PROPERTY_HERE);
}
error: function () {
alert("error!");
}
});
}
The success callback has a parameter named "data". This is a JavaScript object representation of the data you returned in the controller action JsonResult.

Categories