Passing selected rows in a controller in nop Commerce Terilik grid - asp.net

I am beginner in using nopCommerce 2.30 (MVC 3 Razor) and Telerik().Grid. I am currently working
on Nop.Admin project.I try to create a Html.Telerik().Grid in my form, with many features.
Please see my grid image below.
These are the features.
grid data should be filter the selected value of the dropdownlist.
all grid columns are enable sorting.
in first column header contains a checkbox,for multiselect.
grid view must enable a column context menu.
Please see my code below.
My .cshtml file
<td>
#(Html.Telerik().Grid<NotificationMailReminderModel>()
.Name("productvariants-grid")
.DataKeys(keys =>
{
keys.Add(pv => pv.Username);
})
.DataBinding(dataBinding =>
dataBinding.Ajax()
.Select("EmailReminderByEvent", "Customer")
)
.Columns(columns =>
{
columns.Bound(pv => pv.IsSelected)
.ClientTemplate("<input type='checkbox' name='Id' value='<#= Id #>' />")
.HeaderTemplate(#<text><input type="checkbox" title="check all records" id="checkAllRecords" /></text>)
.Width(50)
.HeaderHtmlAttributes(new { style = "text-align:center" })
.HtmlAttributes(new { style = "text-align:center" });
columns.Bound(pv => pv.Username).ReadOnly().Width(250);
columns.Bound(pv => pv.Firstname).ReadOnly();
columns.Bound(pv => pv.Lastname).ReadOnly();
})
.ClientEvents(events => events.OnDataBinding("Grid_onDataBinding").OnError("Grid_onError").OnSubmitChanges("Grid_onSubmitChanges")
.OnRowDataBound("onRowDataBound"))
.Editable(editing => editing.Mode(GridEditMode.InCell))
.Pageable(settings => settings.PageSize(2).Position(GridPagerPosition.Both))
.Sortable(sorting => sorting.Enabled(true))
)
<script type="text/javascript">
$(document).ready(function () {
$('#search-products').click(function () {
var grid = $('#productvariants-grid').data('tGrid');
grid.currentPage = 1; //new search. Set page size to 1
grid.ajaxRequest();
return false;
});
$('#send-mail-reminder').click(function () {
var grid = $('#productvariants-grid').data('tGrid');
grid.ajaxRequest();
return false;
});
$('#grdCustomerEventRoleData #productvariants-grid table thead #checkAllRecords').click(function () {
$("#grdCustomerEventRoleData #productvariants-grid table tbody input:checkbox").attr("checked", this.checked);
});
});
function Grid_onError(args) {
if (args.textStatus == "modelstateerror" && args.modelState) {
var message = "Errors:\n";
$.each(args.modelState, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
args.preventDefault();
alert(message);
}
}
function Grid_onDataBinding(e) {
var loadData = true;
var grid = $(this).data('tGrid');
if (loadData) {
var searchModel = {
Event: $('#select-event').val()
};
e.data = searchModel;
}
}
function Grid_onSubmitChanges(e) {
//TODO pass current search parameters
//we can't pass search parameters in submit changes
//that's why let's just clear search params
//$('##Html.FieldIdFor(model => model.Event)').val('');
//$('#SearchCategoryId').val('0');
//$('#SearchManufacturerId').val('0');
}
</script>
</td>
My Controller actions
public ActionResult EmailReminder()
{
if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
var model = new NotificationMailReminderModels();
model.Event = 0;
List<Nop.Core.Domain.Catalog.Product> products = _productRepository.Table.Where(p => p.EventDate != null && p.EventDate >= DateTime.MinValue).OrderBy(o => o.Name).ToList();
model.Events = products.Select(p => new System.Web.Mvc.SelectListItem
{
Text = p.Name.Trim(),
Value = p.Id.ToString()
}).ToList();
return View(model);
}
[HttpPost, GridAction(EnableCustomBinding = true)]
public ActionResult EmailReminderByEvent(int[] Id, GridCommand command, NotificationMailReminderModels model)
{
if (!_permissionService.Authorize(StandardPermissionProvider.ManageCustomers))
return AccessDeniedView();
var gridModel = new GridModel();
string vwSlEv = ViewBag.SelectedEvent;
int selevent = 0;
if (!string.IsNullOrEmpty(vwSlEv))
{
Int32.TryParse(vwSlEv, out selevent);
}
else
{
selevent = model.Event;
}
var csts = _customerEventRoleRepository.Table.Where(e => e.EventId == selevent).Select(cs => cs.CustomerId).Distinct().ToArray();
var customers = _customerRepository.Table.Where(c => !string.IsNullOrEmpty(c.Username) && !string.IsNullOrEmpty(c.Email) && csts.Contains(c.Id)).ToList();
var gridmodel = customers.Select(x =>
{
NotificationMailReminderModel not = new NotificationMailReminderModel();
not.Id = x.Id;
not.Username = x.Username;
not.Firstname = x.CustomerAttributes.FirstName;
not.Lastname = x.CustomerAttributes.LastName;
return not;
});
var grddata = new PagedList<NotificationMailReminderModel>(gridmodel.ToList(), command.Page - 1, command.PageSize);
gridModel.Data = grddata;
gridModel.Total = grddata.TotalCount;
return new JsonResult
{
Data = gridModel
};
}
data grid sorting and filtering works fine in my grid. But i can't get the ContextMenu
function in the Razor intellisence.
I want to passing the selected rows to the Controller POST function.
But, How to pass the selected rows in to the controller function.
please help.

But, How to pass the selected rows in to the controller function.
JQuery (Sample Code)
var MyConnectionList = {
ColorList: []
};
function SendStream() {
debugger;
MyConnectionList.ColorList.push({
"Name": 'Test1',
"Color": 'red'
});
MyConnectionList.ColorList.push({
"Name": 'Test2',
"Color": 'Green'
});
$.ajax({
url: "Ur url",
data: JSON.stringify(MyConnectionList),
type: 'POST',
contentType: 'application/json',
dataType: 'json',
success: function (data) { }
});
}
Action Method
public ActionResult SendStream(List<Sample> ColorList)
{
}

Related

Passing data from view to net-mvc controller using AngularJS

public class Home
{
string CustEmail { get;set;}
string CustName { get; set;}
int id { get; set;}
}
Model
[HttpPost]
public void CreateCustomer(Home cust)
{
if (ModelState.IsValid)
{
}
}
Controller
angular.module('myFormApp', []).controller('CustomerController', function ($scope, $http, $location, $window) {
debugger;
$scope.cust = {};
$scope.message = '';
$scope.result = "color-default";
$scope.isViewLoading = false;
//get called when user submits the form
$scope.submitForm = function () {
$scope.isViewLoading = true;
console.log('Form is submitted with:', $scope.cust);
//$http service that send or receive data from the remote server
var cust = {
CustEmail: $scope.cust.CustEmail,
CustName: $scope.cust.CustName,
id: 1,
};
$http(
{
method: 'POST',
url: '/Home/CreateCustomer',
data: cust,
}).then(function (data, status, headers, config) {
$scope.errors = [];
if (data.success === true) {
$scope.cust = {};
$scope.message = 'Form data Submitted!';
$scope.result = "color-green";
$location.path(data.redirectUrl);
$window.location.reload();
}
else {
$scope.errors = data.errors;
}
})
$scope.isViewLoading = false;
}
}).config(function ($locationProvider) {
//default = 'false'
$locationProvider.html5Mode(true);
});
I get the data in the proper format in front-end and the post-back call is also working but I cannot get value in MVC controller. I don't know what am I doing wrong. I have tried using the individual item in controller then it's working fine but i want it through model only.
The .then method of a promise only exposes one value, not four values.
$http(
{
method: 'POST',
url: '/Home/CreateCustomer',
data: cust,
̶}̶)̶.̶t̶h̶e̶n̶(̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶(̶d̶a̶t̶a̶,̶ ̶s̶t̶a̶t̶u̶s̶,̶ ̶h̶e̶a̶d̶e̶r̶s̶,̶ ̶c̶o̶n̶f̶i̶g̶)̶ ̶{̶
}).then(function (response) {
var data = response.data;
var status = response.status;
var headers = response.headers;
var config = response.config;
$scope.errors = [];
if (data.success === true) {
$scope.cust = {};
$scope.message = 'Form data Submitted!';
$scope.result = "color-green";
$location.path(data.redirectUrl);
$window.location.reload();
}
else {
$scope.errors = data.errors;
}
})
For more information, see
AngularJS $http Service API Reference - returns
UPDATE
You can add a .catch block to console log any errors:
$http(
{
method: 'POST',
url: '/Home/CreateCustomer',
data: cust,
̶}̶)̶.̶t̶h̶e̶n̶(̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶(̶d̶a̶t̶a̶,̶ ̶s̶t̶a̶t̶u̶s̶,̶ ̶h̶e̶a̶d̶e̶r̶s̶,̶ ̶c̶o̶n̶f̶i̶g̶)̶ ̶{̶
}).then(function (response) {
var data = response.data;
var status = response.status;
var headers = response.headers;
var config = response.config;
$scope.errors = [];
if (data.success === true) {
$scope.cust = {};
$scope.message = 'Form data Submitted!';
$scope.result = "color-green";
$location.path(data.redirectUrl);
$window.location.reload();
}
else {
$scope.errors = data.errors;
}
console.log("OK:", response.data);
}).catch(function(response) {
console.log("ERROR:", response);
});

jQuery function not getting called in mvc text-changed event

I am getting this strange behavior in jQuery when working with mvc application.
Below is MVC view in which I have implemented Text change event,
#Html.TextBoxFor(m => m.UserId, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.UserId, "", new { #class = "text-danger" })
$("#UserId").change(function () {
var UserId = $(this).val();
//$("#txtName").val(emailId);
$.ajax({
url: 'GetValidUserName',
type: 'POST',
data: JSON.stringify({ UserId: UserId }),
dataType: 'json',
contentType: 'application/json',
success: function (data) {
if (!$.trim(data)) {
alert("User does not exist in system. Please enter valid User Id.");
$(':input[type="submit"]').prop('disabled', true);
}
else {
$("#UserId").val(data);
$("#UserId").focus();
$(':input[type="submit"]').prop('disabled', false);
}
}
});
});
While debugging application when I load Index view directly first time , jQuery function gets called and invoke the controller action properly.http://localhost:51012/UserApplication/Index
But when I load the view again, jQuery function doesn't get called.
Controller code,
public JsonResult GetValidUserName(string userId)
{
LMTUsage objLMT = new LMTUsage();
LMTDAL objLMTDAL = new LMTDAL();
string UserID = "";
objLMT.UserList = objLMTDAL.GetAll_User("", 0, "6");
var AllUsersInDatabase = from p in objLMT.UserList
where p.UserId == userId
select new
{
Name = p.UserName,
Id = p.UserId,
};
foreach (var user in AllUsersInDatabase)
{
if (user.Name != null)
{
UserID = user.Id;
}
}
return Json(UserID, JsonRequestBehavior.AllowGet);
}
You have several issues with AJAX callback:
1) type: 'POST' option requires [HttpPost] attribute. If the attribute isn't present on the action method, use type: 'GET' instead.
2) You don't need JSON.stringify() to pass single parameter containing simple types (numeric and string values). A simple { userId: UserId } should be fine.
3) The controller action's parameter name must be exactly match with parameter name sent from AJAX callback.
Therefore, your AJAX callback should be follow example below:
$(function () {
$("#UserId").change(function () {
var UserId = $(this).val();
$.ajax({
url: '#Url.Action("GetValidUserName", "ControllerName")',
type: 'GET',
data: { userId: UserId },
dataType: 'json',
success: function (data) {
if (!$.trim(data)) {
alert("User does not exist in system. Please enter valid User Id.");
$(':input[type="submit"]').prop('disabled', true);
}
else {
$("#UserId").val(data);
$("#UserId").focus();
$(':input[type="submit"]').prop('disabled', false);
}
}
});
});
});

MVC4 Detailview from GridMvc.selectedData

I am trying to get the selected row of a MVCGrid and display the details in an modal dialog using a partialview.
I am getting the selected row via ajax:
$(document).ready(function(){
var selectedRow;
$(document).on('click', '.grid-mvc', function () {
pageGrids.PersonGrid.onRowSelect(function (e) {
// $.prompt(e.row.ID);
SendData(e.row);
});
});
});
The 'SendData'-function is:
function SendData(i) {
var data= i.ID;
$.ajax({
url: '/Home/Person',
contentType: "application/html; charset=utf-8",
type: "GET",
data: { "id": daten },
dataType: "html"
, success: function () {
ShowPersonDetails(data);
}
});
}
and the ShowPersonDetails(data) is like that:
function ShowPersonDetails(data) {
$(document).ready(function () {
$('#PersonDiv').load("Person?id=" + data);
$("#PersonDiv").prompt(
$("#PersonDiv").html(),
{
title: "some title",
buttons: { OK: 'true', Abbruch: 'false' },
position: { width: 800, height: 600 }
});
});
}
The controller:
[HttpGet]
public ActionResult Person(int id)
{
var pS = new DbAccess(MvcApplication.Connection).GetUserData(id);
var p = new Person();
if (pS.Rows.Count < 0)
{
return PartialView("Person");
}
p.Alter = pS.Rows[0].ItemArray[0].ToString();
p.Nachname = pS.Rows[0].ItemArray[5].ToString();
return PartialView("Person", p);
}
Any advice would be nice!
Greetings
PP
i did something like you are trying to do, so hope my code helps
in the grid, table, i put a link for details
<tr>
<td>
#Html.ActionLink("Details", "ActionDetails", new { id = Model.LstItems[x].ID }, new { #class = "detailsLink" })
</td>
</tr>
the javascript
$('#detailsDialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
modal: true,
buttons: {
"Cancel": function () {
$(this).dialog("close");
}
}
});
$(".detailsLink").button();
$(".detailsLink").click(function () {
linkObj = $(this);
var dialogDiv = $('#detailsDialog');
var viewUrl = linkObj.attr('href');
$.get(viewUrl, function (data) {
dialogDiv.html(data);
//open dialog
dialogDiv.dialog('open');
});
return false;
});
in somewhere in the view
<div id="detailsDialog" title="Offer Details">
</div>
the controller
public ActionResult ActionDetails(int id)
{
ItemEntity model = ItemEntity .GetBy(id);
return PartialView(model);
}
the partial view
#model YourNameSpace.Entities.ItemEntity
#using (Ajax.BeginForm("ActionDetails", "YourController", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "updateSuccess",
OnFailure = "showErrorMessage"
}, new { #id = "detailForm" }))
{
//your details for your item
}
hope this help you

How to get Ember.js's bindAttr to refresh?

I am trying to create "sort by" buttons which change sorting and css-classes when clicked on using Ember.js.
The sorting part and the initial class assignments work, however, the class assignments are not refreshed when I update the dependant properties.
What am I missing?
This is in my HTML:
<script type="text/x-handlebars" data-template-name="sort-option-item">
<dd {{bindAttr class="IsActive:active IsDesc:reversed"}}
{{action sortBy on="click"}}>{{Name}}</dd>
</script>
<script type="text/x-handlebars">
{{#each option in controller.sortOptions}}
{{view App.SortOptionView controllerBinding="option"}}
{{/each}}
</script>
An this is in my Javascript:
var App = null;
$(function () {
App = Ember.Application.create();
// Define Types:
App.SortOptionCtrl = Ember.Controller.extend({
Name: null,
Predicate: null,
Controller: null,
IsActive: false,
IsDesc: false,
sortBy: function () {
if (this.Controller != null)
this.Controller.sortBy(this.Predicate);
},
Check: function () {
this.IsActive = this.Controller != null
&& this.Controller.isSortedBy(this.Predicate);
this.IsDesc = this.Controller != null
&& this.Controller.isSortedDescBy(this.Predicate);
// adding an alert(this.IsActive); here
// proves that the function is indeed called and works as expected
}
});
App.ProductsController = Ember.ArrayController.extend({
initialized: false,
content: [],
viewContent: [],
sortProperties: ['Order'],
sortAscending: true,
sortOptions: [],
initialize: function () {
if (this.initialized == true)
return;
this.initialized = true;
var ctrl = this;
this.sortOptions.pushObject(App.SortOptionCtrl.create({
Name: 'Unsorted',
Predicate: null,
Controller: ctrl,
}));
this.sortOptions.pushObject(App.SortOptionCtrl.create({
Name: 'By Name',
Predicate: 'Name',
Controller: ctrl,
}));
this.sortOptions.pushObject(App.SortOptionCtrl.create({
Name: 'By Date',
Predicate: 'Date',
Controller: ctrl,
}));
this.sortOptions.forEach(function (opt) { opt.Check(); });
},
load: function () {
this.initialize();
// ....
},
sortBy: function (predicate) {
var prevPredicate = this.sortProperties[0];
if (predicate == prevPredicate && predicate != null) {
this.sortAscending = !(this.sortAscending);
}
else {
this.sortAscending = true;
}
this.sortProperties.length = 0;
if (predicate)
this.sortProperties.pushObject(predicate);
else
this.sortProperties.pushObject('Order');
this.sortOptions.forEach(function (opt) { opt.Check(); });
},
isSortedBy: function (predicate)
{
if (predicate == null)
predicate = 'Order';
var activePredicate = this.sortProperties[0];
if (predicate == activePredicate) {
return true;
}
else {
return false;
}
},
isSortedDescBy: function (predicate) {
if (predicate == null)
predicate = 'Order';
var activePredicate = this.sortProperties[0];
if (predicate == activePredicate) {
if (this.sortAscending)
return false;
else
return true;
}
else {
return false;
}
},
});
App.SortOptionView = Ember.View.extend({
templateName: 'sort-option-item'
});
// Create Instances:
App.productsController = App.ProductsController.create({
});
App.productsController.load();
App.initialize();
});
Versions: Ember: 1.0.0-rc.2, handlebars: 1.0.0-rc.3
If you want your views to react to whatever happens in the controller, you should create computed properties (via fn(){}.property('dependency')). However, in order for computed properties to work properly, you need to use Ember's get() and set() property accessors.
In your code you are doing things like
this.IsActive = this.Controller != null &&
this.Controller.isSortedBy(this.Predicate);
When you should be doing something like this:
this.set('active',
this.get('controller') != null &&
this.get('controller').isSortedBy(this.get('Predicate'))
);
You might have noticed that this code is setting a value into active, but the template is listening to isActive. That property has been changed into a computed property:
isActive: function() {
return this.get('active');
}.property('active')
It will listen for changes in the active property, and whenever that happens, it will cache the new value, and notify all subscriber objects to refresh/update.
Using Ember's get and set accessors is indicated in order to properly use the observables that make this chain of events possible.
I have modified your sample applying get and set where appropriate.
You can see it in this fiddle: http://jsfiddle.net/schawaska/fRMYu/
After Joe's help, more reading of Ember's manual and clean up of my code, I got to this sorter solution:
Sort option controller:
App.SortOptionCtrl = Em.Controller.extend({
Name: null,
Predicate: null,
_isActive: false,
isActive: function () {
return this.get('_isActive');
}.property('_isActive'),
_isDesc: false,
isDesc: function () {
return this.get('_isDesc');
}.property('_isDesc'),
controller: null,
updateState: function () {
if (!this.Predicate) {
this.set('_isActive', (this.get('controller')
.get('activePredicate') == null));
this.set('_isDesc', false);
}
else {
this.set('_isActive', (this.get('controller')
.get('activePredicate') == this.Predicate));
this.set('_isDesc', (this.get('_isActive')
&& !this.get('controller').get('sortAscending')));
}
}.observes('controller.activePredicate', 'controller.sortAscending'),
sortBy: function () {
if (this.get('controller') != null) {
this.get('controller').sortBy(this.Predicate);
}
},
});
Products controller:
App.ProductsController = Ember.ArrayController.extend({
content: [],
viewContent: [],
activePredicate: null,
sortProperties: ['Order'],
sortAscending: true,
sortOptions: [],
filter: function (obj) {
return true;
},
init: function () {
this._super();
var ctrl = this;
this.sortOptions.pushObject(App.SortOptionCtrl.create({
Name: 'Unsorted',
Predicate: null,
controller: ctrl,
}));
this.sortOptions.pushObject(App.SortOptionCtrl.create({
Name: 'By Name',
Predicate: 'Name',
controller: ctrl,
}));
this.sortOptions.pushObject(App.SortOptionCtrl.create({
Name: 'By Date',
Predicate: 'Date',
controller: ctrl,
}));
this.sortOptions.forEach(function (opt) {
opt.updateState();
});
},
sortBy: function (predicate) {
var prevPredicate = this.sortProperties[0];
if (predicate == prevPredicate && predicate != null) {
this.set('sortAscending', !(this.get('sortAscending')));
}
else {
this.set('sortAscending', true);
}
this.set('activePredicate', predicate);
this.set('sortProperties.length', 0);
if (predicate)
this.get('sortProperties').pushObject(predicate);
else
this.get('sortProperties').pushObject('Order');
},
});

MVC3 JSON Return to Edit Page

So I have some javascript code that sends data to my controller:
Javascript:
<script type="text/javascript">
$(document).ready(function () {
$("#newGrade").click(function () {
var newGradeName = $("#newGradeName").val();
var newGradeValue = $("#newGradeValue").val();
var vSchoolID = $("#SchoolID").val();
if (newGradeName != null && newGradeValue != null) {
$.ajax({
url: '#Url.Action("NewGrade", "School")',
data: { gradeName: newGradeName, gradeValue: newGradeValue, schoolID: vSchoolID },
type: 'POST',
traditional: true,
success: function (data) {
if (data.status)
window.location = data.route;
},
error: function () {
return false;
}
});
}
});
});
</script>
Controller:
public ActionResult NewGrade(String gradeName, Int32 gradeValue, Guid schoolID)
{
School school = schoolRepository.GetByID(schoolID);
school.Grades.Add(
new Grade
{
GradeID = Guid.NewGuid(),
Name = gradeName,
NumericalValue = gradeValue
});
schoolRepository.Update(school);
schoolRepository.Save();
if (Request.IsAjaxRequest())
{
var json = new { status = true, route = Url.RouteUrl(new { action = "Edit", id = schoolID }) };
return Json(json, JsonRequestBehavior.AllowGet);
}
return View();
}
My issue now is I want to return to my Edit page (possibly refreshing the page, but not the data, or just refresh the entire page), but my Edit page takes an ID (schoolID). Shown here when pressing the button to get to the Edit page:
<i class="icon-pencil"></i> Edit
Try window.location.href and see what happens.
success: function(data) {
if (data.status)
window.location.href = data.route;
},
This should work fine assuming you are getting a JSON reponse from your action method like
{"status":"true","route":"/School/Edit/1"}
where 1 is the ID of new record.

Resources