Auto fields liferay in custom portlet - liferay

I have a doubt.
I have a main.jsp that includes another 2 jsp and a submit button. Both of them are part of a form.
The second one includes an auto field with a validator:
<div id="groupwork-fields" >
<div class="lfr-form-row lfr-form-row-inline">
<div class="row-fields">
<aui:input fieldParam='name' id="repetibleName" cssClass="full-size"
name="<%=AwardConstants.FIELD_OTHERS_NAME%>"
label='<%=AwardConstants.LABEL_NAME %>'
value="">
<aui:validator name="custom" errorMessage="fill-name">
function (val, fieldNode, ruleValue) {
var result = true;
var selector = document.getElementById("<portlet:namespace/>select-group").value;
if (selector == 1 && val === "") {
result = false;
}
return result;
}
</aui:validator>
</aui:input>
<aui:input cssClass="full-size"
id="email0" fieldParam='email0'
name="email0"
label='<%=AwardConstants.LABEL_EMAIL %>'
value="">
<aui:validator name="maxLength">100</aui:validator>
<aui:validator name="email"></aui:validator>
<aui:validator name="custom" errorMessage="fill-email">
function (val, fieldNode, ruleValue) {
var result = true;
var name = document.getElementById("<portlet:namespace/>name0").value;
if (name !== "" && val === "") {
result = false;
}
return result;
}
</aui:validator>
</aui:input>
</div>
</div>
</div>
After validating those fields and pressing the submit button goes to the next method:
public void saveAutofieldData(ActionRequest actionRequest, ActionResponse actionResponse) throws PortalException, SystemException {
String groupworkIndexes = actionRequest.getParameter("groupworkIndexes");
_log.info("::::::::::::::::groupworkIndexes:::::::::::::::::::::::" + groupworkIndexes);
/**
* Split the row index by comma
*/
String[] indexOfRows = groupworkIndexes.split(",");
_log.info("::::::::::::::::indexOfRows.length:::::::::::::::::::::::"+ indexOfRows.length);
for (int i = 0; i < indexOfRows.length; i++) {
String name = (actionRequest.getParameter("name"+ indexOfRows[i])).trim();
String email = (actionRequest.getParameter("email"+ indexOfRows[i])).trim();
_log.info("::::::::::::Name::::::::::::::" + name);
_log.info("::::::::::::Email::::::::::::::" + email);
}
}
The problem is when It tries to read: actionRequest.getParameter("groupworkIndexes"); I get null.
Thank you in advance

I finally got the solution.
All examples I've seen it have been with "actionRequest" to retrieve the data:
String groupworkIndexes = actionRequest.getParameter("groupworkIndexes");
String name = actionRequest.getParameter("name" + indexOfRows[i]));
But in my case i've used the following lines:
String name = (uploadPortletRequest.getParameter("name" + indexOfRows[i]));
String groupworkIndexes = (uploadPortletRequest.getParameter("groupworkIndexes"));
Not always we would get the prefered values with actionRequest

Related

Update cell update without scroll to top

I have an issue where on updating a cell with cellEdited, The page jumps back to the top of the page when the mutator or formatter is called.
I've tried setting table.redraw(false) and then the formatter/mutator doesn't seem to do anything.
When a user updates the proficiency level the formatter or mutator should add a button if it's above 3. It works perfectly. However it jumps to the top of the screen.
Any help appreciated.
var evidenceMutator = function(value, data, type, params, component){
skillsTable.redraw(false);
var claimedProficiency = data.Proficiency;
var skillClaimed = data.SkillID;
var Evidence = data.Evidence;
var memberID = $("#user").data("memberid");
if (claimedProficiency >= 3 ) {
// has provided evidence
if (Evidence == 1) {
return '<a class="btn btn-outline-success btn-xs btn-slim evidence" href="#" id="'+ skillClaimed + '" onclick="openEvidenceModal(this, this.id, '+ memberID +')"> <i class="fas fa-check-circle cssover"></i> Edit Evidence </a>';
} else { // needs to provide
return '<a class="btn btn-outline-danger btn-xs btn-slim evidence" href="#" id="'+ skillClaimed + '" onclick="openEvidenceModal(this, this.id, '+ memberID +')"> <i class="fas fa-times-circle cssover"></i> Add Evidence </a>';
}
} else {
// cell.getElement().style.color = "#CCD1D1";
//cell.getElement().style.fontStyle ="italic";
// cell.getElement().style.fontSize = "0.75em";
return ' No Evidence Needed';
}
}
function complianceTick(cell) {
var isCompliant = cell.getData().Compliance;
var Evidence = cell.getData().Evidence;
var claimedProficiency = cell.getData().Proficiency;
// style all with sucesss and only change if we need to
cell.getElement().style.color = "#33CC66";
cell.getElement().style.fontSize = "0.85em";
cell.getElement().style.fontStyle = "italic";
if (claimedProficiency >= 3 ) {
if (Evidence == '1') {
return '<i class="fas fa-check-circle"></i>';
} else {
cell.getElement().style.color = "#FF0000";
cell.getElement().style.fontSize = "0.85em";
cell.getElement().style.fontWeight = "bold";
return '<i class="fas fa-times-circle"></i>';
}
} else {
return '';
}
}
var skillsTable = new Tabulator("#SkillsTable", {
index: "SkillID",
height:"100%",
headerVisible:false,
autoResize:true,
layout:"fitColumns", //fit columns to width of table
groupBy:"SkillCatID",
groupHeader: groupMaker,
initialSort:[ //set the initial sort order of the data
{column:"RowOrder", dir:"asc"}
],
columns:[ //define the table columns
{title:"", field:"SkillID", visible:false},
{title:"Skill", field:"SkillName", visible:true, headerSort:false, formatter: skillName},
{title:"", field:"SkillCatID", visible:false},
{title:"", field:"SkillCatName", visible:false},
{title:"My Level", field:"Proficiency", visible:true, editor:inputEditor, formatter:prof, width:"7%", headerSort:false, align:"center",
cellEdited:function(cell, row, success){ // EDITING FUNCTION
var $value = cell.getValue();
var $field = cell.getField();
var $row = cell.getRow();
var $id = $row.getData().SkillID;
var integer = parseInt($value, 10);
if ($value != "" && integer < 5 && integer >= 0) {
// update record
updateRecord($id, $field, $value, $row);
//$row.update({"Proficiency" : $value});
//$row.update({"Evidencer" : $value});
skillsTable.updateRow($id, {id:$id,"Proficiency":$value});
skillsTable.updateRow($id, {id:$id,"Evidencer":$value});
} else {
cell.restoreOldValue();
if ($value != "") {
alert ("Values should be between 0 and 4, the cell has been restored to its previous value.")
}
}
},
},
{title:"Target", field:"MinLevel", visible:false, headerSort:false},
{title:"", field:"Proficiency", visible:true, formatter: skillDec, headerSort:false},
{title:"Evidence", field:"Evidencer", visible:true, hozAlign:"center", formatter: evidenceCell, mutator: evidenceMutator, width:"10.5%", headerSort:false},
{title:"", field:"RowOrder", visible:false, sorter:"number"},
{title:"disc", field:"DisciplineID", visible:false, headerFilter:true}
],
});
UPDATE
I think I've narrowed down the issue to the formatter:
```
function evidenceCell(cell, formatterParms, onRendered) {
var claimedProficiency = cell.getData().Proficiency;
var skillClaimed = cell.getData().SkillID;
var Evidence = cell.getData().Evidence;
var memberID = $("#user").data("memberid");
if (claimedProficiency >= 3 ) {
// has provided evidence
if (Evidence == 1) {
return '<a class="btn btn-outline-success btn-xs btn-slim evidence" href="#" id="'+ skillClaimed + '" onclick="openEvidenceModal(this, this.id, '+ memberID +')"> <i class="fas fa-check-circle cssover"></i> Edit Evidence </a>';
} else { // needs to provide
return '<a class="btn btn-outline-danger btn-xs btn-slim evidence" href="#" id="'+ skillClaimed + '" onclick="openEvidenceModal(this, this.id, '+ memberID +')"> <i class="fas fa-times-circle cssover"></i> Add Evidence </a>';
}
} else {
cell.getElement().style.color = "#CCD1D1";
cell.getElement().style.fontStyle ="italic";
cell.getElement().style.fontSize = "0.75em";
return 'No Evidence Needed';
}
}
```
It looks like the issue is with the cell.getData(). It seems to trigger the scroll to the top of page. I think it may be a bug with the newer version. Testing 4.2 and it seems to not be an issue. However, I have issues with modals going to the top of the page with the older version.
The issue seems to be with the virtual DOM. In my case I can luckily turn it off by using the following:
virtualDom:false,
I'm not sure this would be a good fix for people with hundreds of rows.

the view "Delete" or its master was not found asp.net mvc5

I want to be able to upload a file then to download it or delete it. But when I try to delete it, I get this error:
The view 'Delete' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/FileUpload/Delete.aspx ,~/Views/FileUpload/Delete.ascx, ~/Views/Shared/Delete.aspx,~/Views/Shared/Delete.ascx, ~/Views/FileUpload/Delete.cshtml, ~/Views/FileUpload/Delete.vbhtml, ~/Views/Shared/Delete.cshtml ,~/Views/Shared/Delete.vbhtml .
[HttpGet]
public ActionResult Delete( string deletedfile)
{
string current_usr = User.Identity.GetUserId();
string fullPath = Request.MapPath("~/Files/" + current_usr + "/" + deletedfile);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
ViewBag.Message="Deleted";
}
var items = GetFiles();
return View(items);
}
// GET: FileUpload
public ActionResult Index()
{
var items = GetFiles();
return View(items);
}
// POST: FileUpload
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
try
{
string current_usr = User.Identity.GetUserId();
//string path = Path.Combine(Server.MapPath("~/Files/"),
// Path.GetFileName(file.FileName));
var folder = Server.MapPath("~/Files/" + current_usr + "/");
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
string path = Path.Combine(String.Format(folder),
Path.GetFileName(file.FileName));
file.SaveAs(path);
ViewBag.Message = "File uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
else
{
ViewBag.Message = "You have not specified a file.";
}
var items = GetFiles();
return View(items);
}
public FileResult Download(string downloadedfile)
{
string current_usr = User.Identity.GetUserId();
var FileVirtualPath = "~/Files/" + current_usr + "/" + downloadedfile;
return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
}
private List<string> GetFiles()
{
string current_usr = User.Identity.GetUserId();
var dir = new System.IO.DirectoryInfo(Server.MapPath("~/Files/" + current_usr + "/"));
System.IO.FileInfo[] fileNames = dir.GetFiles("*.*");
List<string> items = new List<string>();
foreach (var file in fileNames)
{
items.Add(file.Name);
}
return items;
}
The View :
<h2> File Upload </h2>
#model List<string>
#using (Html.BeginForm("Index", "FileUpload", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file"> Upload </label>
<input type="file" name="file" id="file" />
<br /><br />
<input type="submit" value="Upload" />
<br /><br />
#ViewBag.Message
<br />
<h2>Documents list</h2>
<table style="width:100%">
<tr>
<th> File Name </th>
<th> Link </th>
</tr>
#for (var i = 0; i <= (Model.Count) - 1; i++)
{
<tr>
<td>#Model[i].ToString() </td>
<td>#Html.ActionLink("Download", "Download", new { downloadedfile = Model[i].ToString() }) </td>
<td>
#Html.ActionLink("Delete", "Delete", new { deletedfile = Model[i].ToString() })
</td>
</tr>
}
</table>
}
The issue is that your Delete Controller method is calling View() at the end. That method will attempt to find a view file with the name of the controller method. If you want to show the list of files after the delete you can redirect to your index action like this:
[HttpGet]
public ActionResult Delete(string deletedfile)
{
string current_usr = User.Identity.GetUserId();
string fullPath = Request.MapPath("~/Files/" + current_usr + "/" + deletedfile);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
ViewBag.Message = "Deleted";
}
return RedirectToAction("Index");
}
See this link from the microsoft Docs for more detail on redirecting
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs

Custom validation are not executing on focus change of applied control but works well in case of form submit

I am using normal mvc textboxfor on strong view, I have created custom validation attribute (the detailed code explained below).
On form submit everything works fine. In case if validation fails by natural it shows error message as configured.
Now when I enter the correct value inside text box I expect the error message to be vanished automatically but this does not happen until I post the form
JS File
$.validator.addMethod('validaterequiredif', function (value, element, parameters) {
var id = parameters['dependentproperty'];
var clickValue = $("input[name=" + id + "]:checked").val();
// get the target value (as a string,
// as that's what actual value will be)
var targetvalue = parameters['targetvalue'];
if (clickValue == targetvalue) {
if (value == null) {
return false;
}
else {
return $.validator.methods.required.call(
this, value, element, parameters);
}
}
else {
return true;
}
});
$.validator.unobtrusive.adapters.add(
'validaterequiredif',
['dependentproperty', 'targetvalue'],
function (options) {
options.rules['validaterequiredif'] = {
dependentproperty: options.params['dependentproperty'],
targetvalue: options.params['targetvalue']
};
options.messages['validaterequiredif'] = options.message;
});
Server side custom validator class as below
public class ValidateRequiredIf : ValidationAttribute, IClientValidatable
{
protected RequiredAttribute _innerAttribute;
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public bool AllowEmptyStrings
{
get
{
return _innerAttribute.AllowEmptyStrings;
}
set
{
_innerAttribute.AllowEmptyStrings = value;
}
}
public ValidateRequiredIf(string dependentProperty, object targetValue)
{
_innerAttribute = new RequiredAttribute();
DependentProperty = dependentProperty;
TargetValue = targetValue;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(DependentProperty);
if (field != null)
{
// get the value of the dependent property
var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
// trim spaces of dependent value
if (dependentValue != null && dependentValue is string)
{
dependentValue = (dependentValue as string).Trim();
if (!AllowEmptyStrings && (dependentValue as string).Length == 0)
{
dependentValue = null;
}
}
// compare the value against the target value
if ((dependentValue == null && TargetValue == null) ||
(dependentValue != null && (TargetValue.Equals("*") || dependentValue.Equals(TargetValue))))
{
// match => means we should try validating this field
//if (!_innerAttribute.IsValid(value))
if (value == null)
// validation failed - return an error
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
}
}
return ValidationResult.Success;
}
private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
{
// build the ID of the property
string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty);
// unfortunately this will have the name of the current field appended to the beginning,
// because the TemplateInfo's context has had this fieldname appended to it. Instead, we
// want to get the context as though it was one level higher (i.e. outside the current property,
// which is the containing object, and hence the same level as the dependent property.
var thisField = metadata.PropertyName + "_";
if (depProp.StartsWith(thisField))
// strip it off again
depProp = depProp.Substring(thisField.Length);
return depProp;
}
public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "validaterequiredif",
};
string depProp = BuildDependentPropertyId(metadata, context as ViewContext);
// find the value on the control we depend on;
// if it's a bool, format it javascript style
// (the default is True or False!)
string targetValue = (TargetValue ?? "").ToString();
if (TargetValue is bool)
targetValue = targetValue.ToLower();
rule.ValidationParameters.Add("dependentproperty", depProp);
rule.ValidationParameters.Add("targetvalue", targetValue);
yield return rule;
}
}
Model property
[ValidateRequiredIf("IsFeederSelected", "True", ErrorMessage = "Please select atleast one feeder")]
public List<string> selectedMeterName { get; set; }
Strongly typed view
<div class="meterTextboxRadio col-md-4">
<p>
#Html.RadioButtonFor(m => m.IsFeederSelected, true, new { #class = "radio", #Name = "IsFeederSelected", value = "meter", id = "rdbMeterConsumption", #checked = "checked" })
<span> Feeder</span>
#Html.RadioButtonFor(m => m.IsFeederSelected, false, new { #class = "radio", #Name = "IsFeederSelected", value = "group", id = "rdbGroupConsumption",style= "margin-left: 30px;" })
<span> Group</span>
</p>
<div class="group dropdownhidden" id="MeterNameConsumption" style="margin-top:4px;">
#Html.DropDownListFor(m => m.selectedMeterName, Model.MeterName
, new { #class = "chosen-select" ,#id= "ddlConsumptionMeterName", multiple = "multiple", Style = "width:100%", data_placeholder = "Choose Feeders.." })
<span class="highlight"></span> <span class="bar"></span>
</div>
<div class="group dropdownhidden" id="GroupNameConsumption" style="margin-top:4px;">
#Html.DropDownListFor(m => m.selectedGroupName, Model.GroupName
, new { #class = "chosen-select", #id = "ddlConsumptionGroupName", multiple = "multiple", Style = "width:100%", data_placeholder = "Choose Group.." })
<span class="highlight"></span> <span class="bar"></span>
</div>
#Html.ValidationMessageFor(m => m.selectedMeterName, "", new { #class = "error" })
#Html.ValidationMessageFor(m => m.selectedGroupName, "", new { #class = "error" })
</div>
Please provide some inputs for the same
Thanks.

Controlling cart with session

My cart is working fine in localhost but when i have hosted in cloud hosting it is not working well problem is that when i click add to cart button it will add one product with one quantity but when i add another product in the cart again it will override the previous one and show only one product in cart when i have added on last.. i don't know whats wrong with the sessions it will override the session again i guess. And another problem is that my my update cart button's functionalities and delete button functionalities in cart is not working it throw exception
Object reference not set to an instance of an object.
I have a controller name shoppingCartController here is the code
namespace Medi.Areas.User.Controllers
{
public class ShoppingCartController : Controller
{
ArrayList arr = new ArrayList();
int id;
BLL.IRepository<tbl_Product> de = new BLL.IRepository<tbl_Product>();
public ActionResult Index()
{
return View();
}
private int isExisting(int id)
{
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
if (cart[i].Pr.ProductID == id)
return i;
return -1;
}
public ActionResult Delete(int id)
{
int index = isExisting(id);
List<Items> cart = (List<Items>)Session["cart"];
cart.RemoveAt(index);
Session["cart"] = cart;
return PartialView("_pvCart");
}
public ActionResult OrderNow(string q)
{
if (Session["cart"] == null)
{
List<Items> cart = new List<Items>();
cart.Add(new Items(de.GetById(Convert.ToInt32(q)), 1));
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart,"Quantity","Quantity");
// cart[1]
}
else
{
id = Convert.ToInt32(q);
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity++;
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart, "Quantity", "Quantity");
}
return View("Cart");
}
[HttpPost]
public ActionResult UpdateCart(int[] ProductID,int [] quantity )
{
int[] x = new int[4];
int[] y = new int[4];
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
{
x[i] = ProductID[i];
y[i] = quantity[i];
updcart(x[i],y[i]);
}
Session["cart"] = cart;
return PartialView("_pvCart");
}
public void updcart(int id,int quantity) {
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity = quantity;
Session["cart"] = cart;
}
}
}
and here is the view name Cart.cshtml
#{
ViewBag.Title = "Cart";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("UpdateCart", "ShoppingCart", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }))
{
#Html.AntiForgeryToken()
<br />
<br />
<div id="MyData">
#{Html.RenderPartial("_pvCart");}
</div>
<br /><br />
<input id="updatecart" type="submit" value="update Cart" />
}
and here is the partial view code
#using Medi.Models;
<script src="~/Scripts/metro.min.js"></script>
<table class="table hovered" cellpadding=" 2" cellspacing="2" border="1px">
<tr class="info">
<th></th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Sub Total</th>
</tr>
#{
decimal s = 0;
}
#foreach (Items item in (List<Items>)Session["cart"])
{
<input id="ProductID" name="ProductID" type="hidden" value="#item.Pr.ProductID" />
s = s + (Convert.ToInt32(item.Pr.Price) * item.Quantity);
<tr>
<th>#Ajax.ActionLink("Delete", "Delete", new { id = item.Pr.ProductID }, new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }, new { #class = "mif-cross" })</th>
<td>#item.Pr.ProductName</td>
<td>#item.Pr.Price</td>
<td>
<input name="quantity" id="quantity" type="text" style="width:25px;" value="#item.Quantity" />
</td>
<td>#(item.Pr.Price * item.Quantity)</td>
</tr>
}
</table><br />
<hr />
<table cellpadding="1px" cellspacing="1px" style="float:right;">
<tr align="center" colspan="5" style="background-color:gray;">
<td><h3 style="padding:1px;">Total</h3></td>
<td> <h3 style="padding:1px;">Rs #s</h3></td>
</tr>
</table>
here is the model class
using BOL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Medi.Models
{
public class Items
{
tbl_Product pr = new tbl_Product();
public tbl_Product Pr
{
get { return pr; }
set { pr = value; }
}
int quantity;
public int Quantity { get; set; }
public Items()
{
}
public Items(tbl_Product product, int quantity)
{
this.Pr = product;
this.Quantity = quantity;
}
}
}
i have also write this code in web.config
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
<sessionState mode="InProc"/>

My Shopping Cart is not working as expected in ASP.NET MVC 5

My cart is working fine in localhost but when i have hosted in cloud hosting it is not working well problem is that when i click add to cart button it will add one product with one quantity but when i add another product in the cart again it will override the previous one and show only one product in cart when i have added on last.. i don't know whats wrong with the sessions it will override the session again i guess. And another problem is that my my update cart button's functionalities and delete button functionalities in cart is not working it throw exception
Object reference not set to an instance of an object.
I have a controller name shoppingCartController here is the code
namespace Medi.Areas.User.Controllers
{
public class ShoppingCartController : Controller
{
ArrayList arr = new ArrayList();
int id;
BLL.IRepository<tbl_Product> de = new BLL.IRepository<tbl_Product>();
public ActionResult Index()
{
return View();
}
private int isExisting(int id)
{
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
if (cart[i].Pr.ProductID == id)
return i;
return -1;
}
public ActionResult Delete(int id)
{
int index = isExisting(id);
List<Items> cart = (List<Items>)Session["cart"];
cart.RemoveAt(index);
Session["cart"] = cart;
return PartialView("_pvCart");
}
public ActionResult OrderNow(string q)
{
if (Session["cart"] == null)
{
List<Items> cart = new List<Items>();
cart.Add(new Items(de.GetById(Convert.ToInt32(q)), 1));
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart,"Quantity","Quantity");
// cart[1]
}
else
{
id = Convert.ToInt32(q);
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity++;
Session["cart"] = cart;
// ViewBag.quantity = new MultiSelectList(cart, "Quantity", "Quantity");
}
return View("Cart");
}
[HttpPost]
public ActionResult UpdateCart(int[] ProductID,int [] quantity )
{
int[] x = new int[4];
int[] y = new int[4];
List<Items> cart = (List<Items>)Session["cart"];
for (int i = 0; i < cart.Count; i++)
{
x[i] = ProductID[i];
y[i] = quantity[i];
updcart(x[i],y[i]);
}
Session["cart"] = cart;
return PartialView("_pvCart");
}
public void updcart(int id,int quantity) {
List<Items> cart = (List<Items>)Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new Items(de.GetById(id), 1));
else
cart[index].Quantity = quantity;
Session["cart"] = cart;
}
}
}
and here is the view name Cart.cshtml
#{
ViewBag.Title = "Cart";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("UpdateCart", "ShoppingCart", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }))
{
#Html.AntiForgeryToken()
<br />
<br />
<div id="MyData">
#{Html.RenderPartial("_pvCart");}
and here is the partial view code
#using Medi.Models;
<script src="~/Scripts/metro.min.js"></script>
<table class="table hovered" cellpadding=" 2" cellspacing="2" border="1px">
<tr class="info">
<th></th>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Sub Total</th>
</tr>
#{
decimal s = 0;
}
#foreach (Items item in (List<Items>)Session["cart"])
{
<input id="ProductID" name="ProductID" type="hidden" value="#item.Pr.ProductID" />
s = s + (Convert.ToInt32(item.Pr.Price) * item.Quantity);
<tr>
<th>#Ajax.ActionLink("Delete", "Delete", new { id = item.Pr.ProductID }, new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "MyData", InsertionMode = InsertionMode.Replace }, new { #class = "mif-cross" })</th>
<td>#item.Pr.ProductName</td>
<td>#item.Pr.Price</td>
<td>
<input name="quantity" id="quantity" type="text" style="width:25px;" value="#item.Quantity" />
</td>
<td>#(item.Pr.Price * item.Quantity)</td>
</tr>
}
</table><br />
<hr />
<table cellpadding="1px" cellspacing="1px" style="float:right;">
<tr align="center" colspan="5" style="background-color:gray;">
<td><h3 style="padding:1px;">Total</h3></td>
<td> <h3 style="padding:1px;">Rs #s</h3></td>
</tr>
</table>
here is the model class
using BOL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Medi.Models
{
public class Items
{
tbl_Product pr = new tbl_Product();
public tbl_Product Pr
{
get { return pr; }
set { pr = value; }
}
int quantity;
public int Quantity { get; set; }
public Items()
{
}
public Items(tbl_Product product, int quantity)
{
this.Pr = product;
this.Quantity = quantity;
}
}
}
i have also write this code in web.config
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
<sessionState mode="InProc"/>

Resources