I'm developing an asp.net mvc 5 online store project . I want to create cart to add Goods with Cookie . I'm confused about it and don't know why it didn't work . it didn't gave me any error . also I add break points to debug it but any data didn't send to my actions !
could anyone help me ? what's the problem ?
I'm not good in javascript and I think problem would be in javascript codes :/
Thanks in advance
Goods controller
[HttpPost]
public ActionResult AddToCart(int Id, int Count)
{
try
{
if (Request.Cookies.AllKeys.Contains("NishtmanCart_" + Id.ToString()))
{
//edit cookie
var cookie = new HttpCookie("NishtmanCart_" + Id.ToString(), (Convert.ToInt32(Request.Cookies["NishtmanCart_" + Id.ToString()].Value) + 1).ToString());
cookie.Expires = DateTime.Now.AddMonths(1);
cookie.HttpOnly = true;
Response.Cookies.Set(cookie);
}
else
{
//add new cookie
var cookie = new HttpCookie("NishtmanCart_" + Id.ToString(), Count.ToString());
cookie.Expires = DateTime.Now.AddMonths(1);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
}
int CartCount = Request.Cookies.AllKeys.Where(p => p.StartsWith("NishtmanCart_")).Count();
return Json(new MyJsonData()
{
Success = true,
Script = MessageBox.Show("product added to your basket", MessageType.Success).Script,
Html = "Shopping Cart (" + CartCount.ToString() + ")"
});
}
catch (Exception)
{
return Json(new MyJsonData()
{
Success = false,
Script = MessageBox.Show("product didn't add to your basket", MessageType.Error).Script,
Html = ""
});
}
}
public ActionResult RemoveCart(int Id)
{
try
{
int CartCount = Request.Cookies.AllKeys.Where(p => p.StartsWith("NishtmanCart_")).Count();
if (Request.Cookies.AllKeys.Contains("NishtmanCart_" + Id.ToString()))
{
Request.Cookies["NishtmanCart_" + Id.ToString()].Expires = DateTime.Now.AddDays(-1);
return Json(new MyJsonData()
{
Success = true,
Script = MessageBox.Show("product removed from your basket", MessageType.Success).Script,
Html = "Shopping Cart (" + CartCount.ToString() + ")"
});
}
else
{
return Json(new MyJsonData()
{
Success = false,
Script = MessageBox.Show("this product doesn't have in your basket", MessageType.Warning).Script,
Html = "Shopping Cart (" + CartCount.ToString() + ")"
});
}
}
catch (Exception)
{
return Json(new MyJsonData()
{
Success = true,
Script = MessageBox.Show("product didn't remove from your basket", MessageType.Error).Script,
Html = ""
});
}
}
MyJsonData.cs
public class MyJsonData
{
public string Script { get; set; }
public string Html { get; set; }
public bool Success { get; set; }
}
_GoodDetailsAjax.cshtml
#foreach (var item in Model.GoodDetails)
{
<div>
<p class="nowprice">NowPrice : #item.DetailsNowPrice</p>
<p class="preprice">PrePrice : #item.DetailsPrePrice</p>
<a class="button icon-cart" href="#" GoodID="#item.DetailsGoodID">Add to cart</a><br>
<a class="link" >Shopping Cart (0)</a>
</div>
}
#section scripts{
<script src="~/Scripts/jquery-2.1.4.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script>
$(function () {
$("a.button.icon-cart").click(function (e) {
e.preventDefault();
var goodId = $(this).attr("GoodID");
alert(goodId); //////// I just added this code
$.ajax({
url: "/Goods/AddToCart",
data: { Id: goodId, Count: 1 },
type: "Post",
dataType: "Json",
success: function (result) {
if (result.Success) {
$("#CartItems").html(result.Html);
}
eval(result.Script);
},
error: function () {
alert("Error!");
}
});
});
});
</script>
}
I don't know what's the implementation of MessageBox.Show("....", MessageType.Error).Script but I'm assuming that it just generates a simple JavaScript statement like this:
Script = "alert('product added to your basket');"
So you can add this tag for the result:
<div id="CartItems">
</div>
Now it works without any problem.
All of my codes was true , I just made some simple mistakes .
I loaded a JQuery file in my layout and also I loaded another version of JQuery in my view! I deleted one of them .
And also I used those codes in a partial view and loaded they using Ajax but my partial view couldn't pass data to Controller , I moved codes to main view (GoodDetails.cshtml) and it works fine now .
Related
I have a table that's populated by JSON data. In the last column you can open up a modal that corresponds to each row and you can add a comment in an input box---doing so will update that modal. In other words, table rows that have no comments have an empty modal and rows with at least one comment should appear in the modal that they correspond with.
In my backend manager (SQL Server Management Studio) I can see that the comments are showing up there, but they're not appearing in the modals.
I can't tell if the problem is coming from the JavaScript side (the view) or from the model, or from elsewhere.
The addition of the DocBudgetId is relatively new. Before that, the review/comment data was tied to the DocNumber and the info was appearing in the modals. I suspect that I have to make an adjustment/change to the DocBudgetId but I'm not sure how.
Modal screenshot: https://i.stack.imgur.com/Vqd4o.png The DocNumber appears on the top left. Comments have been made to the row that this modal belongs to but they're not appearing in the modal table.
Model:
public class ReviewRow
{
public Guid DocBudgetId { get; set; }
public string DocNumber { get; set; }
public string ReviewBy { get; set; }
public string ReviewOn { get; set; }
public string ReviewComment { get; set; }
}
View:
<div class="modal-body">
<div id="review"></div>
<table>
<tr>
<td>
#Html.LabelFor(x => Model.ReviewComment)<br />
#Html.TextAreaFor(x => x.ReviewComment, new { style = "width: 200px; " })<br />
#Html.HiddenFor(x => x.DocUnderReview, new { id = "txtDocUnderReview" })
<input type="submit" value="#BB360.Models.BudgetReportingViewModel.Buttons.Review" name="#Html.NameFor(x => x.SubmitButton)" id="SubmitButton" class="btn btn-secondary" />
</td>
</tr>
</table>
// --- other code --- //
function ShowReviewModal(DocBudgetId, DocNumber) {
$("#txtDocUnderReview").val(DocNumber);
console.log(DocNumber)
$.ajax({
type: "POST",
url: "/Doc/GetDocUnderReviewDetails",
data: "docNumber=" + DocNumber + "&docBudgetId=" + DocBudgetId,
timeout: 5000,
success: function(data) {
console.log(data); // ------------- empty array
// write out the modal table
var tBody = $("#tblExpenseDeductionDetails tbody");
tBody.empty();
s = "";
for (x = 0; x < data.length; x++) {
let ReviewBy = data[x].ReviewBy,
ReviewOn = data[x].ReviewOn,
ReviewComment = data[x].ReviewComment;
s = s + "<tr>";
s = s + "<td>" + ReviewBy + "</td>";
s = s + "<td>" + ReviewOn + "</td>";
s = s + "<td title='" + ReviewComment.replace(/'/g, '') + "' style='max-width:550px;word-wrap: break-word;'>" + stringTruncate(ReviewComment, 65) + "</td>";
s = s + "</tr>";
}
$("#modalDocName").text(DocNumber);
tBody[0].innerHTML = s;
$("#ReviewModal").modal();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
$("#ReviewModal").modal();
}
Controller
public ActionResult BudgetReporting(BudgetReportingViewModel model)
{
Common.GetDbExecutor().QueryNonQuery(Sql.InsertDocUnderReview, new {
model.DocBudgetId,
DocNumber = model.DocUnderReview, // D is uppercase
ReviewBy = Common.GetUserName(),
ReviewComment = model.ReviewComment,
}, 30).ToString();
PopulateBudgetReportingDetail(model);
return View(model);
}
public ActionResult GetDocUnderReviewDetails(Guid docBudgetId) // camelCase //
{
var data = Common.GetKKDbExecutor().Query<BudgetReportingViewModel.ReviewRow>(Sql.GetDocUnderReviewDetails, new {
docBudgetId
}).ToList();
return Json(data);
}
Sql file
namespace BB360
{
public partial class Sql
{
public const string GetDocUnderReviewDetails = #"
select
DocBudgetId,
DocNumber,
ReviewBy,
convert(varchar, ReviewOn, 101) as ReviewOn,
isnull(ReviewComment, '') as ReviewComment
from DocBudgetReview
where DocBudgetId = #DocBudgetId
order by ReviewOn desc
";
}
}
The issue here is your "GetDocUnderReviewDetails" action accepts GET request and you're sending a post request to it. You just need to change the ajax request type to GET.
type: "GET",
url: "/Doc/GetDocUnderReviewDetails",
Another thing i noticed is that, you're sending the docNumber also in the request which your action doesn't require. Even though that won't cause any issue but you don't need to send that in ajax
Update: I did some tinkering and got the table data to show.
In the stored procedure (GetDocUnderReviewDetails.cs) I commented out the line where DocBudgetId = #DocBudgetId and added where DocNumber = #DocNumber. I noticed that if I just commented out where DBI = then it showed all of the comments made for every modal, which was an issue I was dealing with earlier.
So now, my stored procedure looks like this:
namespace BB360
{
public partial class Sql
{
public const string GetDocUnderReviewDetails = #"
select
DocBudgetId,
DocNumber,
ReviewBy,
convert(varchar, ReviewOn, 101) as ReviewOn,
isnull(ReviewComment, '') as ReviewComment
from DocBudgetReview
--where DocBudgetId = #DocBudgetId
where DocNumber = #DocNumber
order by ReviewOn desc
";
}
}
I also added string docNumber to the Controller:
public ActionResult GetDocUnderReviewDetails(Guid docBudgetId, string docNumber)
{
var data = Common.GetBBDbExecutor().Query<BudgetReportingViewModel.ReviewRow>(Sql.GetDocUnderReviewDetails, new {
docBudgetId,
docNumber
}).ToList();
return Json(data);
}
I am able to get my url response in the console tag in google chrome. I need your help in displaying those values in my interface. The provided below code only enables me to display the first value in the url response.
main.js:
try{
var getNameOfEmployee = document.getElementById('getNameOfEmployeeID');
function displayEmployee(){
if (getNameOfEmployee.value != "") {
$("#someform").submit(function (event) {
event.preventDefault();
});
AjaxGet();
}
else{
alert("Please enter any name of employee that you wish to know the extension code of!");
}
}
AjaxGet = function (url, storageLocation, mySuccessCallback) {
var result = $.ajax({
type: "GET",
url: 'http://localhost:8080/employee/' +$("#getNameOfEmployeeID").val(),
param: '{}',
contentType: "application/json",
dataType: "json",
success: function (data) {
storageLocation = data;
globalVariable = data;
console.log(storageLocation);
console.log(storageLocation.empName0.extCode);
var length = Object.keys(storageLocation).length;
var empArray = new Array(length);
}
}).responseText ;
return result;
return storageLocation;
//console.log(result);
} ; }
catch(e){ document.getElementById("demo").innerHTML = e.message; }
My console is as:
empName0
:
{empName: "Aran", extCode: 5500}
empName1
:
{empName: "Bran", extCode: 5900}
empName2
:
{empName: "Cran", extCode: 5750}
Please somebody help me how to get all these results get printed in my index page once the submit button is clicked.
Just now I tried JSON.stringify(storageLocation) and print the results on an alert message. Please provide me an answer to display the results which are now duplicated. If you need my java file which retrieves the data, it follows:
employeeDAO.java :
#Repository public class EmployeeDAO {
private static final Map empMap = new HashMap();
static {
initEmps();
}
private static void initEmps() {
}
public JSONObject getEmployee(String empName){
Map<String ,Employee> empMap2 = new HashMap<String ,Employee>();
String filePath="D:\dummy.xls";
ReadExcelFileAndStore details = new ReadExcelFileAndStore();
List<Employee> myList= details.getTheFileAsObject(filePath);
JSONObject emp1 = new JSONObject();
boolean check=false;
int j=0;
for (int i=0; i<myList.size(); i++) {
if (myList.get(i).getEmpName().toLowerCase().contains(empName.toLowerCase()))
{
emp1.put("empName"+j,myList.get(i));
j++;
check = true;
}
}
if(check == true)
{
//System.out.println("yes");
return emp1;
}
else
{
return null;
}
}
public Employee addEmployee(Employee emp) {
empMap.put(emp.getEmpName(), emp);
return emp;
}
public Employee updateEmployee(Employee emp) {
empMap.put(emp.getEmpName(), emp);
return emp;
}
public void deleteEmployee(String empName) {
empMap.remove(empName);
}
public List<Employee> getAllEmployees() {
String filePath="D:/dummy.xls";
ReadExcelFileAndStore details = new ReadExcelFileAndStore();
return details.getTheFileAsObject(filePath);
}
public List<Employee> getAllImportantEmployees() {
String filePath="D:/dummy.xls";
ReadImportantExtensionSheet impDetails = new ReadImportantExtensionSheet();
return impDetails.getTheFileAsObject(filePath);
} }
You could add some DOM manipulation inside you AJAX success method:
success: function (data) {
storageLocation = data;
console.log(storageLocation.empName0.extCode);
$("#someform #someLabel").val(storageLocation.empName0.extCode);
$("#someform #someOtherLabel").val(storageLocation.empName0.empName);
}
This will wait for the AJAX to complete and then update your page with the results.
You can use a jQuery each function to loop over each element in the results and update their corresponding elements on the page.
success: function (data) {
storageLocation = data;
$.each(storageLocation, function (index, value) {
console.log(value.extCode);
$("#someform #someLabel" + index).val(value.extCode);
$("#someform #someOtherLabel" + index).val(value.empName);
});
}
Have a table in your html
Upon receiving the response populate in UI
This is a sample code, change as per the json structure
function load() {
var resp = '[{"empName":"Aran","extCode":5500},{"empName":"Bran","extCode":5900},{"empName":"Cran","extCode":5750}]';
var emps = JSON.parse( resp );
var i;
for(i=0; i<emps.length; i++) {
$('#empdata').append('<tr><td>'+emps[i]['empName']+'</td><td>'+emps[i]['extCode']+'</td>...</tr>');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table id="empdata" style="border: 1px solid;background-color: #eedaff;">
<th>Name</th><th>Ext</th>
</table>
<button onclick="load();">Load</button>
</body>
I am implementing "show more posts" in my blogs list following
this example but I want to make a change and switch from using ViewData to ViewModel.
This the relevant code:
private void AddMoreUrlToViewData(int entryCount)
{
ViewData["ShowMore "] = Url.Action("Index", "Messaggi", new { entryCount = entryCount + defaultEntryCount });
}
that I switch to
ViewModel.ShowMore = Url.Action("Index", "Messaggi", new { entryCount = entryCount + defaultEntryCount });
the Index action of the example:
public ActionResult Index(int? entryCount)
{
if (!entryCount.HasValue)
entryCount = defaultEntryCount;
int totalItems;
if(Request.IsAjaxRequest())
{
int page = entryCount.Value / defaultEntryCount;
//Retrieve the page specified by the page variable with a page size o defaultEntryCount
IEnumerable<Entry> pagedEntries = GetLatestEntries(page, defaultEntryCount, out totalItems);
if(entryCount < totalItems)
AddMoreUrlToViewData(entryCount.Value);
return View("EntryTeaserList", pagedEntries);
}
//Retrieve the first page with a page size of entryCount
IEnumerable<Entry> entries = GetLatestEntries(1, entryCount.Value, out totalItems);
if (entryCount < totalItems)
AddMoreUrlToViewData(entryCount.Value);
return View(entries);
}
Here I add a lot of code to load the post from the db, the only code I think is relevant is that I swtich return View("EntryTeaserList", pagedEntries); to return View(myViewModel); after setting BlogsList and ShowMore property.
But my problem is in the javascript command:
$(function() {
addMoreLinkBehaviour();
});
function addMoreLinkBehaviour() {
$('#entryTeaserList #moreLink').live("click", function() {
$(this).html("<img src='/images/ajax-loader.gif' />");
$.get($(this).attr("href"), function(response) {
$('#entryTeaserList ol').append($("ol", response).html());
$('#entryTeaserList #ShowMore').replaceWith($("#ShowMore", response));
});
return false;
});
}
where
$('#entryTeaserList #ShowMore').replaceWith($("#ShowMore", response));
to take ViewData property and use it to replace the link.
How can I read the ViewModel Property instead?
I am trying to call the controller action from my script but the method is not being invoked.
This is my controller action:
[HttpPost]
public ActionResult EditQuantity(int? id, int quantity)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Cart cart = db.Carts.Find(id);
if (cart == null)
{
return HttpNotFound();
}
cart.Quantity = quantity;
db.SaveChanges();
string url = this.Request.UrlReferrer.AbsolutePath;
return Redirect(url);
}
This is my script:
<script>
function refreshTotal(ProductId) {
var qty = document.getElementById("product-quantity-" + ProductId).value;
var UnitPrice = document.getElementById("unit-price-" + ProductId).innerText;
var total = qty * UnitPrice;
document.getElementById("product-total-" + ProductId).innerHTML = "$" + total.toFixed(2);
$.post('#Url.Action("EditQuantity", "Home")', { "id": ProductId, "quantity": qty }, function (data) {
});
}
</script>
And the script is being called as follows from HTML:
<td class=""><img src="" class="img-responsive" onclick="refreshTotal(#product.Id)"></td>
The solution is going in the script, from the script the call is not being made to the action.
everything seems good in your provided code. Have you looked for any javascript error in browser console and your action is in right controller ?
I had a typo in 'productId' - should be 'ProductId'. It's working now :)
I cant figured out how to show whole page after Ajax call to Controler. After 'Order' buton click I call javascript function where I make Ajax call to controler action to get XML in string and with that string I call another controller action where I return model. In last step I want to call third controller action with return View(model) but I get null object parameter.
function order(model) {
$('#details-container').html("<h2>Loading Complete Frame Module. Please wait...</h2>");
$.p({
url: '#Url.Action("CompleteFrameBrandDetails", "PacCompleteFrame")',
data: { item: model },
success: function (xml) {
if (xml.Success) {
$.p({
url: '#Url.Action("GlassCompleteFrame", "PacModule")',
data: JSON.stringify({ b2bXml: xml.Data }),
success: function (model) {
var pacModuleModel = {
CustomerNumber: model.Data.CustomerNumber,
Language: model.Data.Language,
Comission: model.Data.Comission,
GlassXml: model.Data.GlassXml,
Price: model.Data.Price,
ReadOnly: model.Data.ReadOnly,
Mode: model.Data.Mode,
IframeUrl: model.Data.Mode
};
var url = '#Url.Action("GlassCompleteFrameView", "PacModule", "__view__")';
window.location.href = url.replace("__view__", JSON.stringify(pacModuleModel));
}
});
} else {
$.alert({
message: 'error while trying to load xml details'
});
}
}
});
}
public ActionResult GlassCompleteFrame(string b2bXml)
{
string mode = "5";
//If the Store isn't selected, redirect to HomePage
if (string.IsNullOrEmpty(_workContext.SelectedCustomerNumber))
{
return RedirectToRoute("HomePage");
}
else
{
PacModuleModel model = new PacModuleModel();
model.CustomerNumber = _workContext.SelectedCustomerNumber;
model.Language = _workContext.WorkingLanguage.UniqueSeoCode;
model.Comission = "";
if (b2bXml == null || b2bXml == String.Empty)
{
return RedirectToRoute("HomePage");
}
else
{
model.GlassXml = b2bXml.Replace("\"", "\\\"");
}
int index = b2bXml.IndexOf("<price>") + "<price>".Length;
string p = b2bXml.Substring(index, b2bXml.IndexOf("</price>") - index);
model.Price = Convert.ToDouble(p, System.Globalization.CultureInfo.InvariantCulture);
model.ReadOnly = false;
model.Mode = ModuleMode.ByProduct;
model.IframeUrl = "http://ItkCompleteConfiEmbedded.aspx?lang=" + _workContext.WorkingLanguage.LanguageCulture; //_pacGeneralSettings.GlassModuleUrl + ;
return new JsonResult()
{
Data = new
{
Success = true,
Data = model
}
};
}
}
public ActionResult GlassCompleteFrameView(PacModuleModel model)
{
// here I get null model parameter
return View("Glass", model);
}
Curently I don't know how to pass model to the last action controller. Thank you nice people for help.
If I understand correctly, something like this should do the trick:
Let's say you have, in your controller MyModelController:
public ActionResult SomePage(MyModel myModel){
return View(myModel);
}
To naviguate to that page, you could do:
<script>
window.location.href = "#Url.Action("SomePage", "MyModel", myModelObject)";
</script>
I hope this helps!
I use Session variable to get model in GlassCompleteFrameView(PacModuleModel model) and works perfect. I set Session variable in public ActionResult GlassCompleteFrame(string b2bXml).
public ActionResult GlassCompleteFrameView(PacModuleModel model)
{
model = Session["xml"] as PacModuleModel;
return View("Glass", model);
}