I've been working on my shopping cart program, but I keep having problems with adding an item to the shopping cart
here is my code;
HomeController class
[HttpPost]
public ActionResult AddToBasket(int id)
{
var basketJson = HttpContext.Session.GetString(SESSION_KEY);
List<SepetProduct> sepet;
if (basketJson == null)
{
sepet = new List<SepetProduct>();
}
else
{
sepet = JsonSerializer.Deserialize<List<SepetProduct>>(basketJson);
}
if (sepet.Any(x=> x.id == id))
{
sepet.Single(x => x.id == id).Toplam++;
}
else
{
sepet.Add(new SepetProduct { id = id, Toplam = 1 });
}
basketJson = JsonSerializer.Serialize(sepet);
HttpContext.Session.SetString(SESSION_KEY, basketJson);
return Json(new { status = true, Msg = "Ürün Sepete Eklendi", Data = sepet });
}
'''
and here is my Button action code
<form action="#Url.Action("addToBasket","Home")" method="post" enctype="multipart/form-data">
<input type="hidden" name="Id" value="#urun.UrunId" />
<button type="submit" class="btn btn-dark">
<span class="fa fa-shopping-cart"></span>Sepete ekle
</button>
</form>
The problem is that, when ı press to "sepete ekle" button, item was added to cart, but it directs us to a new page called "https://localhost:44302/Home/addToBasket"
and show us those data
'''
status true
msg "Ürün Sepete Eklendi"
data
0
id 2
toplam 1
'''
I would like to when ı press to 'sepete ekle ' button, the page remains the same, but the product is added to the basket. it just shows us a message saying added.
How can ı do that. thank you for interesting and helping
You can try to use ajax to replace form post.Here is a working demo:
TestBasket.cshtml(I use value="1" to test.And add id="Id" to hidden input.Also,I need to change the type of button,so that when click it,it will not submit form,it will go to submitData() function.):
<form action="#Url.Action("addToBasket","Home")" method="post" enctype="multipart/form-data">
<input type="hidden" id="Id" name="Id" value="1" />
<button type="button" onclick="submitData()" class="btn btn-dark">
<span class="fa fa-shopping-cart"></span>Sepete ekle
</button>
</form>
<script>
function submitData() {
$.ajax({
type: "POST",
url: '#Url.Action("addToBasket","Home")',
data: { "id": $("#Id").val() }
}).done(function (data) {
console.log(data.msg);
});
}
</script>
HomeController:
public IActionResult TestBasket()
{
return View();
}
[HttpPost]
public ActionResult AddToBasket(int id)
{
return Json(new { status = true, Msg = "Ürün Sepete Eklendi", Data = new List<SepetProduct>() });
}
result:
Related
I am making a bulletin board system using CKEditor. Most of the features work just fine, but when editing an existing post, the all line breaks in the text are removed from the code block.
Image of create a post
Image of edit a post
Image of part of the response source
I googled as much as possible to solve this problem, but the methods I found were to no avail, so I removed it from the code again.
It seems that line breaks are removed while processing the source internally in CKEditor5, is there any way?
Replace all line breaks with <br /> tags.
Add /\r|\n/g to protectedSource
The following is the view file for that feature.
#model BBSArticleWriteView
#{
// Action name of the current view
var thisActionString = #ViewContext.RouteData.Values["action"].ToString();
if (Model.ArticleId == null)
ViewData["Title"] = "Writing";
else
ViewData["Title"] = "Editing";
}
<p class="page-header">#ViewData["Title"]</p>
<form asp-action="#thisActionString" id="editor-form">
<input asp-for="ArticleId" value="#Model.ArticleId" hidden />
<div>
<input asp-for="Title" required placeholder="Please enter a title." class="form-control w-100 mb-2" />
</div>
<div>
<textarea name="Contents" id="editor">
#Html.Raw(Model.Contents)
</textarea>
</div>
<div>
<input class="btn btn-sm btn-primary" type="submit" value="Save" onsubmit="Editor.submit()" />
<button class="btn btn-sm btn-primary" type="button" href="##" onclick="history.back()">Back</button>
</div>
</form>
<style>
.ck-editor__editable_inline {
min-height: 400px;
}
</style>
#section Scripts {
<script src="~/lib/ckeditor5/ckeditor.js" asp-append-version="true"></script>
<script>
class Editor{
static submit() {
return true;
}
}
ClassicEditor
.create(document.querySelector('#editor'),
{
simpleUpload:{
uploadUrl: "#Url.Action(nameof(CreatorFront.Controllers.FileController.Upload), "File")",
withCredentials: true
},
protectedSource:[
/\r|\n/g
]
})
.catch(error => {
console.error(error);
});
</script>
}
And here is the controller action that puts data into the view model.
[HttpGet]
public async Task<IActionResult> BBSEdit(int id)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
if(user == null)
{
return RedirectToAction("Index", "Home");
}
var article = _cContext.BBSArticle.First(a => a.ArticleId == id);
if(article == null)
{
return RedirectToAction(nameof(BBSList));
}
if(user.Id != article.UserId)
{
return RedirectToAction(nameof(BBSList));
}
var model = new BBSArticleWriteView();
CopyProperties(model, article);
return View(nameof(BBSWrite), model);
}
The following is a function that puts content data in DB.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> BBSWrite(BBSArticleWriteView article)
{
if(ModelState.IsValid)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
if(user == null)
{
RedirectToAction("Index", "Home");
}
// XSS attacks prevent
article.Contents = _htmlSanitizer.Sanitize(article.Contents);
var currentDateTime = DateTime.Now;
CreatorLib.Models.BBS.BBSArticle data = new CreatorLib.Models.BBS.BBSArticle()
{
ArticleId = _cContext.BBSArticle.Max(a => a.ArticleId) + 1,
MainCategory = article.MainCategory,
SubCategory = article.SubCategory,
UserId = user.Id,
Title = article.Title,
Contents = article.Contents,
Status = CreatorLib.Models.BBS.ArticleStatus.A,
IpAddress = HttpContext.Connection.RemoteIpAddress.ToString(),
RegisteredTime = currentDateTime,
LastUpdatedTime = currentDateTime,
HasMedia = article.HasMedia
};
_cContext.BBSArticle.Add(data);
await _cContext.SaveChangesAsync();
return RedirectToAction(nameof(BBSList));
}
return View(article);
}
Here, it is confirmed that HtmlSanitizer has absolutely no impact on this issue.
In DB, line breaks are fully preserved.
I am trying to display the errors associated with a form.
The form has a validation performed on the client (works fine) and on the server (that's my issue). The actual submission code is done through an ajax call:
$.ajax({
type: "POST",
url: url,
dataType: "text",
data: fiscalYearData,
success: function () {
showSuccess('Saved successfully');
closeForm();
},
error: function (error) {
showError('An error occured');
}
});
Unfortunately, that is not satifying. In my controller, I'm returning a ModelSatte with all relevant errors provided:
if (ModelState.ErrorCount > 0)
return BadRequest(ModelState);
// save the modified entity
await fiscalYearService.SaveFiscalYearAsync(fy, SecurityContext);
return Ok();
How can I modify the ajax error handling function to use the ModelState to display the error in the form itself?
Edit I apparently need to clarify what I would like to do:
I receive a ModelState containing errors error back from the ajax call. I would like to display these errors in the form in the same way they would have been displayed if I had submitted the form via a form submit button and page refresh: fields corresponding tot the error's keys should be marked in red with the corresponding error text displayed in the appropriate error labels.
You can pass ModelState error message to ajax,and put error.responseText into form.
Action:
if (ModelState.ErrorCount > 0) {
//Customize your error message
string messages = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => !string.IsNullOrWhiteSpace(x.ErrorMessage) ? x.ErrorMessage : x.Exception.Message.ToString()));
return BadRequest(messages);
}
ajax:
$.ajax({
type: "POST",
url: url,
dataType: "text",
data: fiscalYearData,
success: function () {
showSuccess('Saved successfully');
closeForm();
},
error: function (error) {
showError(error.responseText);
}
});
Update:
If you want to validate like form post,I think you don't need to use ModelState,you can use $("#xxform").valid() in js.So that only when the model is valid,we will use ajax to post data to action.Here is a demo:
Model:
public class TestModelState {
[Required]
public string FirstName { get; set; }
[Required]
public string MiddleName { get; set; }
[Required]
public string LastName { get; set; }
}
View:
<form id="myform" method="post">
<div class="form-group">
<label asp-for="FirstName" class="control-label"></label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MiddleName" class="control-label"></label>
<input asp-for="MiddleName" class="form-control" />
<span asp-validation-for="MiddleName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName" class="control-label"></label>
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<input type="submit" value="submit" />
</form>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script>
$('#myform').submit(function (e) {
e.preventDefault();
// check if the input is valid using a 'valid' property
if ($("#myform").valid()) {
$.ajax({
type: "POST",
url: "/Test1/TestModelState",
data: $("#myform").serialize(),
success: function (data) {
//showSuccess('Saved successfully');
//closeForm();
},
error: function (error) {
//console.log(error.responseText);
}
});
}
})
</script>
result:
I have a list of items with attributes itemname, quantity and price in item table. I would like to populate name and quantity after selecting a dropdownlist in the create order page. I an able to populate item name but the available quantity is not populating in the razor view totalqty input field
The item name is populated but the available quantity is not.
Controller Section
public IActionResult Create(string masterid, string id)
{
var check = _context.Deliverydetails.SingleOrDefault(m =>
m.customerInvoiceLineId == id);
var selected = _context.Delivery.SingleOrDefault(m =>
m.customerInvoiceId == masterid);
ViewData["customerInvoiceId"] = new SelectList(_context.Delivery,
"customerInvoiceId", "invoiceNumber");
ViewData["itemId"] = new SelectList(_context.Item, "itemId",
"itemName");
ViewData["ShipmentStatusId"] = new
SelectList(_context.ShipmentStatus, "ShipmentStatusId",
"ShipmentStatusName");
if (check == null)
{
Deliverydetails objline = new Deliverydetails();
objline.delivery = selected;
objline.customerInvoiceId = masterid;
return View(objline);
}
else
{
return View(check);
}
}
public JsonResult GetItemDetails(string ItemNo)
{
var ItemQuery = _context.Item.Where(x => x.itemId == ItemNo);
return Json(ItemQuery);
}
**Create Order View**
<div class="col-md-6">
<div class="form-group">
<label asp-for="itemId" class="control-label"></label>
<select asp-for="itemId" class="form-control select2"
asp-items="ViewBag.itemId"></select>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="TotalQty" class="control-label"></label>
<input asp-for="TotalQty" class="form-control" />
<span asp-validation-for="TotalQty" class="text-danger">
</span>
</div>
</div>
Javascript section
<script type="text/javascript">
$(function () {
$("#itemId").change(function (val) {
var Itemdata = $(this).val();
$.post('/DeliveryDetails/GetItemDetails', { ItemNo: Itemdata }).then(function (res) {
console.log("response is", res); //res is always empty
$("#AvailableQty").val(res[0].Quantity);
})
});
</script>
Try the following changes in the GetItemDetails method and the javascript
If you want to get the quantity of the item as per the itemId , you could query like below:
var ItemQuery = _context.Item.Where(x => x.itemId == ItemNo).Select(x=>x.TotalQty);
And in the callback of the $.post() , if you want to populate the totalqty input field , you should add the id of the input and set the totalqty value like below
<input id="totalQty" asp-for="TotalQty" class="form-control" />
$.post('/DeliveryDetails/GetItemDetails', { ItemNo: Itemdata }).then(function (res) {
console.log("response is", res);
$("#result").val(res);
})
I believe you need to add the [FromBody] attribute to your controller action. This is because in ASP.NET Core, you need to elect where you read your model-binding data from
[HttpPost]
public JsonResult GetItemDetails([FromBody] string ItemNo)
{
var ItemQuery = _context.Item.Where(x => x.itemId == ItemNo);
return Json(ItemQuery);
}
I would also be explicit about [HttpPost] here as well just to ensure a consistent API surface, unless you want to expose that action through GET as well as POST by default?
I'm trying to do a basic login with a form in my .cshtml file that goes like this:
<form method="post">
<input type="text" name="nombre"/>
<input type="password" name="contra"/>
<input type="submit" value="login" />
</form>
And checking it in the .cshtml.cs with his method where I compare each input with a value:
public void OnPost()
{
var Username = Request.Form["nombre"];
var Password = Request.Form["contra"];
if (Username.Equals("jsplata") && Password.Equals("1234"))
{
RedirectToPage("https://www.google.com/");
}
else
{
RedirectToPage("https://www.stackoverflow.com/");
}
}
When I press the submit button it returns a blank page, I don't know what might be wrong about this.
You can try to use below codes :
public IActionResult OnPost()
{
var Username = Request.Form["nombre"];
var Password = Request.Form["contra"];
if (Username.Equals("jsplata") && Password.Equals("1234"))
{
return Redirect("https://www.google.com/");
}
else
{
return Redirect("https://www.stackoverflow.com/");
}
}
At the moment I am working on a MVC4 view with multiple submit buttons. To handle the submit of the different buttons, I use this class:
http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx
I have three buttons and one label:
Start
Standby
Resume
How can I display a certain text in that label based on which button is pressed?
I wan to use Ajax.BeginForm to update the label text (so I do not have to reload the webpage).
Thank you in advance!
Update:
For example when I click at the Start Button a method will be executed. This method returns true or false. How to catch this bool and display text in the label, based on the result of the method?
Update 2:
<div>
<fieldset>
<legend>Admin Form</legend>
#Html.Label("Options")
<div id="StartBtn">
<input id="Start" type="submit" value="Start" name="action:Start" />
</div>
<div id="StandbyBtn">
<input id="Standby" type="submit" value="Standby" name="action:Standby" />
</div>
<div id="ResumeBtn">
<input id="Resume" type="submit" value="Resume" name="action:Resume" />
</div>
</fieldset>
</div>
[MultipleButton(Name = "action", Argument = "Start")]
public ActionResult Start()
{
if (start())
{
}
else
{
}
}
From your update I would use an ajax call instead of the ajax form
$('.btnSubmit').on('click', function(){
$.ajax({
url: '#Url.Action('Start', 'Controller')',
type: 'post',
data: {
button: this.id
}
dataType: 'json',
success: function(result){
if(result.Success){
$('.lblText').text(result.SetText);
}
}
});
});
I don't know what you want passed to your controller but if you put the same class on all of your buttons (you need to change them to type button instead of submit also) then this.id will will be the id of the clicked button and that will be sent to the controller
then on your controller have an input field matching what is in the data field
public ActionResult Start(string button){
//do something
//from here http://stackoverflow.com/questions/7732481/returning-json-from-controller-never-a-success
return Json(new { Success = "true", SetText = 'SetText' });
//Where SetText is whatever you want your label set to.
}
You can check on this post. http://www.developersnote.com/2013/02/multiple-button-in-mvc-4.html
#using (Html.BeginForm("ActionTaken", "TestController"))
{
<button name="button" value="ActionOne" class="button" style="width: 200px;">
test1</button>
<button name="button" class="button" style="width: 160px;" value="ActionTwo">
test2</button>
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ActionTaken(string butt)
{
string ButtCommand= butt;
switch (ButtCommand)
{
case "ActionOne":
//do stuff here
case "ActionTwo":
//do stuff here
default:
return View();
}
}