How to Add New Setting Value in Customer settings - nopcommerce

I want to add new setting value in Customer settings Page(/Admin/Setting/CustomerUser) after installed nopcommerce 2.5.How can I do?I got nopcommerce 2.5 source code.I'm finding the ways to customize Customer settings Page to add new seeting value.

you can add it in AllSetting section under configuration (configuration ->setting->AllSetting)

you need to add new property in CustomerSettingsModel e.g
//Nop.Admin/Models/Setting/
public bool ZipCodeEnbale{get;set}
then add control for it in CustomerUser.cshtml
//Nop.Admin/Views/Setting/
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.CustomerSettings.ZipCodeEnbale):
</td>
<td class="adminData">
#Html.EditorFor(model => model.CustomerSettings.ZipCodeEnbale)
#Html.ValidationMessageFor(model => model.CustomerSettings.ZipCodeEnbale)
</td>
</tr>
after run the application you will see new property will add under Admin/Customer setting page in CustomerSeeting tab.
Note: if you ant to set default value to property while installing nopcommerec then you need to some additional chnages in InstallationService.cs in (Nop.Service)
add new property value in CustomerSettings under InstallSettings method. e.g
EngineContext.Current.Resolve<IConfigurationProvider<CustomerSettings>>()
.SaveSettings(new CustomerSettings()
{
ZipCodeEnbale= true,
}

Related

Delete Field Spring MVC

I am using SimpleFormController with a result page looking like this:
<tr>
<td>Name: </td>
<td>${product.name}</td>
</tr>
<tr>
<td>Text: </td>
<td>${product.text}</td>
</tr>
A user can enter a name and some text. I'm trying to implement a delete functionality for each entry (there should be a link next to each entry). I'm having trouble with understanding, if it can be done in the same Controller as for the input or not (am new to Spring) and how. The onSubmit method helps to display data that was added, do I need to implement an extra delete method? If yes, how can I "map" it to my delete link in my jsp?
I suppose you are not wanting to put a delete link even when the user is just entering the name!
Delete links should normally appear when you are displaying data, not creating them.
Here is how you can create a delete link according to associated ids.
<tr>
<td>Name: </td>
<td>${product.name}</td>
<td>delete</td>
</tr>
and this should be in your controller:
#Controller
public class ProductController{
#RequestMapping("/delete/{id}")
public String deleteProduct(#PathVariable("id")Integer id) {
// get product by id
// delete that product
// save database
// or do as you wish
return "redirect:/index";
}
}
Hope that helps :)

Adding invoice lines with ASP.NET MVC

I'm creating ASP.NET applications with MVC 4 Technology, and I want to allow the end-user to enter line items onto an invoice. I want the user to have the ability to add as many line items as they wish to the invoice, and then when they are finished to be able to click the Save button on the form which would then write the invoice and all line item data to the database. Can somebody help guide me how to handle this?
This is the way I decided to do it after several other ideas failed me. It may sounds strange, but please bear with me. I used the MVC Index View as a basis.
Before the user even sees the Invoice, I add a new Invoice to the database so that I have an Invoice ID. I then display the Invoice Index View. But instead of the table showing #foreach (var item in Model) I changed it to #foreach (var item in Model.LineItems). Its blank now, but after I add some LineItsms I will be displaying a list of LineItems - which is exactly what an invoice is.
But we want to be able to add on our Invoice Index View as well. So at the top of the Index View, in the part where you can code, create a new LineItem and save its LineItem.invoiceID as the Model.ID. Then before you display the table of LineItems add a partial View - Create LineItem.
Now you have a list of Invoice Lines on a page where you can add new ones.
Here's some code from the Index View of LineItem:
#model MyAppName.Models.Invoice
#{
ViewBag.Title = "Index";
MyAppName.Models.LineItem line = new LineItem();
line.invoiceID = Model.ID;
}
<h2>Invoice</h2>
#Html.Partial("Create", line)
<table>
<tr>
<th>
#Html.DisplayName("Amount")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th></th>
</tr>
#foreach (var item in Model.LineItems)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
#Html.DisplayFor(modelItem => item.Description
</td>
<td>
#Html.ActionLink("Delete", "DeleteConfirmed", new { id = item.invoiceID })
</td>
</tr>
}
<tr>
<th>Total</th>
<th>R #Model.LineItems.Sum(amt => amt.Amount)</th>
<th></th>
<th></th>
</tr>
</table>
And here is what it looks like (except that mine was not an Invoice):
You want something like this. But it will be much more complex for your case. Use jquery to simplify your work.
$('#add_item').click(function() {
$('#invoice_listing tbody')
.append(
"<tr><td>" + $('#item').val() + "</td>" +
"<td>" + $('#amount').val() + "</td></tr>"
)
});
On every line item being added, the [Add Item] button will fire an event to do a ajax post of the line item data to the MVC controller. The controller will then do business logic and store the line item data into the database. Once the transaction is successful, the controller should return a "success" flag to the client browser. Use JSON for that will help. Your javascript should recognize the "success" flag, and add the item to the item listing.
Then finally, user will pressed on [Save] button, which complete the whole invoice data entry. You should then marked the invoice as successfully entered.
Try not to let user keep on adding the line item without being saved. They will be angry when saving failed after adding lines of item.
Have a popup where your users can search for the line items and add them. When selected capture the ItemId and use it to build a row, probably a tr or a div. So then you will have a tr or div for each line item that contains the Id of the line item and then one or two textboxes. Say a textbox for the quantity and another for the price. Then either do an ajax post where you iterate all the divs and put that info as a json data and post it to your controller method. Or format each div where your binding can collect them and be submitted when you do a postback - via your submit button. That should get you starting.

How to Add New Setting Value in Catalog settings

I would like to add a decimal setting to the Catalog Settings named CustomerEnterPricePercentageSurcharge in nopcommerce 2.65. I followed the instructions on How to Add New Setting Value in Customer settings thread.
However, after following the 3 steps (listed below and modified for Catalog Settings) mentioned in the aforementioned thread, when login into the admin section and save the catalog settings the value is always 0.0000. It seems that it isn't saving (or loading) the "catalogsettings.customerenterpricepercentagesurcharge" settings value. Could someone help me clarify what the value isn't being saved?
Updating Nop.Admin/Models/Setting/CatalogSettingsModel.cs with
[NopResourceDisplayName("Admin.Configuration.Settings.Catalog.CustomerEnterPricePercentageSurcharge")]
public decimal CustomerEnterPricePercentageSurcharge { get; set; }
Updating Nop.Admin/Views/Setting/Catalog.cshtml with
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.CustomerEnterPricePercentageSurcharge):
</td>
<td class="adminData">
#Html.EditorFor(model => model.CustomerEnterPricePercentageSurcharge)
#Html.ValidationMessageFor(model => model.CustomerEnterPricePercentageSurcharge)
</td>
</tr>
Adding:
"catalogsettings.customerenterpricepercentagesurcharge" under (configuration ->setting->AllSetting) and updating the
Your help is very much appreciated.
To be honest, you don't really have to create a new field in Nop.Admin/Views/Setting/Catalog.cshtml
You can avoid all this, and simply:
Add a new value in All Settings.
Then to use it, just add a new field to:
Nop.Core.Domain.Catalog.CatalogSettings
such as
/// <summary>
/// Gets or sets a surcharge
/// </summary>
public decimal CustomerEnterPricePercentageSurcharge { get; set; }

Validating a drop down list in MVC3?

I'm working in MVC3 with Entity Framework. I've got an entity called Product that has two properties I'd like to validate when a user adds a new record. To do this, I've created a buddy class, as so:
using System;
using System.ComponentModel.DataAnnotations;
namespace Rpm.Data.Partials
{
[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
}
}
The metadata class is as so:
using System;
using System.ComponentModel.DataAnnotations;
namespace Rpm.Data.Partials
{
public class ProductMetadata
{
[Required]
public string ProductName { get; set; }
[Range(200, 1000, ErrorMessage = "You must select a valid Account Type")]
public int AccountTypeId { get; set; }
}
}
The view that allows users to add a new record is like this:
#model Rpm.Data.Product
#{
ViewBag.Title = "Product"
}
<script type="text/javascript">
$(document).ready(function() {
//There should be no selection in the drop-down box when the form is first displayed.
document.getElementsByTagName("select")[0].selectedIndex = -1;
}
function formSubmit() {
var form = $("form");
if (form.valid()) {
(event.preventDefault) ? event.preventDefault() : event.returnValue = false;
document.getElementById("frmNewProduct").submit();
return true;
}
else {
return false;
}
}
</script>
<h2>Add New Product</h2>
#using (Html.BeginForm("Create", "Product", new { id = new Product() }, FormMethod.Post, new { id = "frmNewProduct" }))
{
#Html.ValidationSummary(true)
<table>
<tr>
<td>
Product Name
</td>
<td>
#Html.TextBoxFor(m => new Product().ProductName)
#Html.ValidationMessageFor(m => new Product().AccountTypeId)
</td>
</tr>
<tr>
<td>
Account Type
</td>
<td>
#Html.DropDownListFor(m => new Product().AccountTypeId, new SelectList(Lookup.Instance.AccountTypes, "AccountTypeId", "AccountTypeName"))
#Html.ValidationMessageFor(m => new Product().AccountTypeId)
</td>
</tr>
<tr>
<td />
<td>
<input type="image" src="#Url.Content("~/Content/images/savebutton.png")" onclick="return formSubmit()" />
</td>
</tr>
</table>
}
(Of course, the above is quite simplified just to avoid overloading the post with code that's not really relevant.)
The problem is that, when the user clicks the Save button, the validation for the ProductName fires just fine and displays the validation message if the field is blank; however, the message for AccountTypeId is never displayed, even if the drop-down is left without a selection (selectedIndex == -1). I know the RangeAttribute on AccountTypeId is being picked up, because when EF tries to save changes to the entities, it throws a DbEntityValidationException, and the text of the ErrorMessage is the custom error message I specified in the metadata. I just can't seem to get it to display on the page and cause the form to fail validation, preventing the user from saving.
Any suggestions as to what I'm doing wrong would be most appreciated!
TIA,
Jeff
When you do this:
#Html.TextBoxFor(m => new Product().ProductName)
#Html.ValidationMessageFor(m => new Product().AccountTypeId)
You're create two entirely different Product() instances, and you create additional Product instances for each property. this might work, since MVC is just using the lambda to create a layout format, but it's in general not very efficient and wastes memory.
Your model type is already product. You should just be using m => m.ProductName
This might be confusing the validation system. I'd just do as I suggest and see if the problem continues.
You also don't need the javascript to set the dropdownlist type. Just do this:
#Html.DropDownListFor(m => new Product().AccountTypeId,
new SelectList(Lookup.Instance.AccountTypes,
"AccountTypeId", "AccountTypeName"), "Select")
And make sure AccountTypeId is nullable int, and you put a [Required] attribute on it. The validator will make sure there's a value.
I'm also not sure why you're using the formSubmit code. image inputs are already submit types, so they submit the form when you click on them. You don't appear to actually be doing anything other than submitting the form again.

Collection of complex child objects in Asp.Net MVC 3 application?

I want to be able to update a model and all its collections of child objects in the same view. I have been referred to these examples: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx and http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ .
For example, I have an object Consultant, that has a collection of "WorkExperiences". All this is in an Entity Framework model. In the view, the simple properties of the Consultant object is no problem, but the collection I cannot get a textbox to show up for. I tried following the examples in the links above, but it doesn't work. The problem is, in those examples the model is just a list (not an object with a child list property). And also, the model again is an EF model. And for some reason that doesn't seem to work as in those examples.
Just to make it simple, I tried to do something along the lines of Phil Haacks example, and just get the View to show the textbox:
#for (int i = 0; i < Model.WorkExperiences.Count; i++)
{
Html.TextBoxFor(m => m.WorkExperiences[i].Name);
}
I tried to create a new WorkExperience object in the controller for the ViewModel:
public ActionResult Create(int id)
{
Consultant consultant = _repository.GetConsultant(id);
DetailsViewModel vm = new DetailsViewModel();
vm.WorkExperiences = consultant.WorkExperiences.ToList();
vm.WorkExperiences.Add(new WorkExperience());
return View(vm);
}
But the View doesn't show any empty textbox for the WorkExperience Name property. If on the other hand I create a separate View just for adding a new WorkExperience object, passing a new empty WorkExperience object as the model, this works fine:
#Html.EditorFor(model => model.Name)
That gives me an empty textbox, and I can save the new object. But why can't I do this in the same view as the Consultant object, with collections according to the examples in the links above?
BTW, this is sort of a follow-up question to an earlier one, that pointed me to the above links, but I never got to a final solution for it. See that question if more info is needed: Create Views for object properties in model in MVC 3 application?
UPDATE:
According to answers and comments below, here's an update with the View and an EditorTemplate:
The View:
#model Consultants.ViewModels.DetailsViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Add work experience", "CreateWorkExperience", new { id = ViewBag.Consultant.Id })
</p>
<table>
<tr>
<th></th>
<th>
Name
</th>
</tr>
#foreach (var item in Model.WorkExperiences) {
<tr>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
<td>
#item.Name
</td>
</tr>
}
</table>
#for (int i = 0; i < Model. WorkExperiences.Count; i++)
{
Html.EditorFor(m => m. WorkExperiences[i]);
}
(Please note that all this is not really how I'll design it in the end, all I am after right now is to get the WorkExperience object to show up as an empty textbox to fill out, and to be able to add and delete such textboxes as in Phil Haack's and Steven Sanderson's examples.)
The EditorTemplate:
#model Consultants.Models.WorkExperience
#Html.TextBoxFor(m => m.Name);
This stuff with the EditorTemplate works fine in Phil Haack's sample project, which I downloaded to try, but here, with the EF model or whatever the problem is, I don't get any textbox at all. The table in the view is just there as a test, because in the table I do get the rows for WorkExperiences, whether I add an empty WorkExperience object or fill out its properties doesn't matter, the rows show up for each object. But again, no textbox...
For example, I have an object Consultant, that has a collection of "WorkExperiences". All this is in an Entity Framework model.
That's the first thing you should improve: introduce view models and don't use your domain models into the view.
This being said let's move on to the templates. So you can completely eliminate the need to write loops in your views.
So here's how your view might look like:
#model Consultants.ViewModels.DetailsViewModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Add work experience", "CreateWorkExperience", new { id = ViewBag.Consultant.Id })
</p>
<table>
<tr>
<th></th>
<th>
Name
</th>
</tr>
#Html.DisplayFor(x => x.WorkExperiences)
</table>
#Html.EditorFor(x.WorkExperiences)
So as you can we are using a display template and an editor template. Let's define them now.
Display template (~/Views/Shared/DisplayTemplates/WorkExperience.cshtml):
#model AppName.Models.WorkExperience
<tr>
<td>
#Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
#Html.ActionLink("Details", "Details", new { id = Model.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = Model.Id })
</td>
<td>
#Model.Name
</td>
</tr>
Editor template (~/Views/Shared/EditorTemplates/WorkExperience.cshtml):
#model AppName.Models.WorkExperience
#Html.TextBoxFor(x => x.SomePropertyOfTheWorkExperienceModelYouWantToEdit)
...
What is important here is the naming convention. The name of the template should be the name of the type of the item in the collection. So for example if in your view model you have a property
public IEnumerable<Foo> { get; set; }
the corresponding template should be called Foo.cshtml and should be located in ~/Views/Shared/DisplayTemplates or ~/Views/Shared/EditorTemplates depending on its role.
So as you can see we have gotten rid of the nasty loops. Now not only that the views look clean, but you get correct names for the input fields so that you can bind the values back in the post action.
The easiest way to do this is probably to create a WorkExperienceList class that inherits List<WorkExperience> (or List<string>, if that's what they are) and then create a custom template for your WorkExperienceList. That way, you'd simplify your view code to #Html.EditorFor(Model), and ASP.NET MVC would take care of the rest for you.

Resources