I need help to get a solution to a question. The case is as follows:
We are working on a group project with asp.net, c #, javascript, html and razor technologies.
The structure of projects within the solution is as follows:
1.POJO-entities: where the models are located.
2.DataAccess: it is divided into three folders: 1. Crud (where are the classes that contain the "crudfactory" of each Pojo, 2. Dao (find the connection to the database, in this case SQL Server) and finally, the Mapper
3.CoreApi, where are the managers of each well.
4.WebApi, where are the controllers of each well.
5.WepApp, where is the UI (cshtmls) and javascripts.
Now, I have to implement a virtual wallet that can be topped up via PayPal and I have a method that receives the price and the description of the payment, for now it is "burned", but it must be parameterizable. I want to know if I can take the value of CtrlInput and put it in the HTMLAtributes of my ActionLink.
The idea may remove the # Html.ActionLink and leave the functionality in the "Update", but I don't know how to send the parameters from the view JS to the PayPal controller.
This is the javascript code for the wallet view:
function vMonedero() {
//this.tblMonederoId = 'tblMonedero';
this.service = 'monedero';
this.ctrlActions = new ControlActions();
this.columns = "IdUsuario, IdMonedero, Monto";
this.paypal = new PaymentWithPayPal();
this.RetrieveAll = function () {
this.ctrlActions.FillTable(this.service, this.tblMonedero, false);
}
this.Create = function () {
var monederoData = {};
monederoData = this.ctrlActions.GetDataForm('frmEdition');
if (monederoData["Monto"] == "") {
this.ctrlActions.ShowMessage('E', "Favor ingresar el nuevo valor");
}
else if (isNaN(monederoData["Monto"])) {
this.ctrlActions.ShowMessage('E', "Favor ingresar un valor numérico");
}
else {
this.ctrlActions.PostToAPI(this.service, monederoData);
}
}
this.Update = function () {
var monederoData = {};
monederoData = this.ctrlActions.GetDataForm('frmEdition');
price = monederoData["Monto"];
paypal.PaymentWithPayPal(price, "Recarga de monedero");
//Hace el post al create
this.ctrlActions.PutToAPI(this.service, monederoData);
//Refresca la tabla
}
this.Delete = function () {
var monederoData = {};
monederoData = this.ctrlActions.GetDataForm('frmEdition');
//Hace el post al create
this.ctrlActions.DeleteToAPI(this.service, monederoData);
//Refresca la tabla
}
this.BindFields = function (data) {
this.ctrlActions.BindFields('frmEdition', data);
}
}
//ON DOCUMENT READY
$(document).ready(function () {
var vmonedero = new vMonedero();
//vmonedero.RetrieveAll();
});
This is the view code:
#using WebApp.Helpers;
<script src="~/Scripts/Views/vMonedero.js"></script>
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="card border-secondary" style="margin-top: 50px;">
<div class="card-header">
<div class="row pull-right">
<div class="col-md-8">Monedero</div>
<div class="col-md-4">
#Html.CtrlButton(viewName: "vMonedero", id: "btnCreate", label: "Crear", onClickFunction: "Create", buttonType: "success")
#Html.CtrlButton(viewName: "vMonedero", id: "btnUpdate", label: "Recargar", onClickFunction: "Update", buttonType: "info")
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-6">
<div class="bs-component">
<form id="frmEdition">
#Html.CtrlInput(id: "txtIdUsuario", type: "text", label: "N° de identificación", columnDataName: "IdUsuario")
#Html.CtrlInput(id: "txtIdMonedero", type: "text", label: "N° de monedero", columnDataName: "IdMonedero")
#Html.CtrlInput(id: "txtIdMonto", type: "text", label: "Monto", columnDataName: "Monto")
#* #Html.CtrlDropDown(id: "drpGender", label: "Gender", listId: "LST_GENERO")*#
</form>
</div>
</div>
</div>
</div>
</div>
#*<script>
$('#price').click(function () {
var monederoData = {};
ctrlActions = new ControlActions();
ctrlActions.GetDataForm('frmEdition');
monederoData["Monto"] = price;
return price;
});
</script>*#
Paypal Controller Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PaymentPayPal.Models;
using PayPal.Api;
namespace WebApp.Controllers
{
public class PayPalController : Controller
{
// GET: PayPal
public ActionResult Index()
{
return View();
}
public ActionResult PaymentWithPaypal(string price, string product)
{
//getting the apiContext as earlier
APIContext apiContext = ConfigurationPayPal.GetAPIContext();
try
{
string payerId = Request.Params["PayerID"];
if (string.IsNullOrEmpty(payerId))
{
string baseURI = Request.Url.Scheme + "://" + Request.Url.Authority +
"/Paypal/PaymentWithPayPal?";
var guid = Convert.ToString((new Random()).Next(100000));
var createdPayment = this.CreatePayment(apiContext, baseURI + "guid=" + guid, price, product);
var links = createdPayment.links.GetEnumerator();
string paypalRedirectUrl = null;
while (links.MoveNext())
{
Links lnk = links.Current;
if (lnk.rel.ToLower().Trim().Equals("approval_url"))
{
paypalRedirectUrl = lnk.href;
}
}
Session.Add(guid, createdPayment.id);
Console.WriteLine(createdPayment.id);
return Redirect(paypalRedirectUrl);
}
else
{
var guid = Request.Params["guid"];
Console.WriteLine("Session:" + Session[guid] as string);
var executedPayment = ExecutePayment(apiContext, payerId, Session[guid] as string);
if (executedPayment.state.ToLower() != "approved")
{
return View("FailureView");
}
}
}
catch (Exception ex)
{
return View("FailureView");
}
return View("SuccessView");
}
private PayPal.Api.Payment payment;
private Payment ExecutePayment(APIContext apiContext, string payerId, string paymentId)
{
var paymentExecution = new PaymentExecution() { payer_id = payerId };
this.payment = new Payment() { id = paymentId };
return this.payment.Execute(apiContext, paymentExecution);
}
private Payment CreatePayment(APIContext apiContext, string redirectUrl, string price, string product)
{
var itemList = new ItemList() { items = new List<Item>() };
itemList.items.Add(new Item()
{
name = product,
currency = "USD",
price = price,
quantity = "1",
sku = "sku"
});
var payer = new Payer() { payment_method = "paypal" };
var redirUrls = new RedirectUrls()
{
cancel_url = redirectUrl,
return_url = redirectUrl
};
// similar as we did for credit card, do here and create details object
var details = new Details()
{
tax = "1",
shipping = "1",
subtotal = price
};
// similar as we did for credit card, do here and create amount object
var amount = new Amount()
{
currency = "USD",
total = "" + (int.Parse(price) + 1 + 1), // Total must be equal to sum of shipping, tax and subtotal.
details = details
};
var transactionList = new List<Transaction>();
transactionList.Add(new Transaction()
{
description = "Transaction description.",
invoice_number = Convert.ToString((new Random()).Next(100000)),
amount = amount,
item_list = itemList
});
this.payment = new Payment()
{
intent = "sale",
payer = payer,
transactions = transactionList,
redirect_urls = redirUrls
};
// Create a payment using a APIContext
return this.payment.Create(apiContext);
}
}
}
Related
I am making a tweak to an app and doing an UPDATE. It throws me the following error:
There is no ViewData item of type 'IEnumerable' that has the key 'Conve'.
My DropDownList loads the data perfectly but when I select any of that list to use its value and change it to the value that is in my BD it throws that error
Model: TableAsign.cs
public class TableAsign
{
public long IdCliente { get; set; }
public string nombre { get; set; }
}
Controller: MastController.cs
[Authorize]
public ActionResult Asign_Conv(int idUsuario)
{
List<Models.TableAsign> lst = null;
using (TPConveniosEntities db = new TPConveniosEntities())
{
lst = (from d in db.Cliente
orderby d.nombre
select new TableAsign
{
IdCliente = d.idCliente,
nombre = d.nombre
}).ToList();
}
List<SelectListItem> items = lst.ConvertAll(d =>
{ return new SelectListItem()
{ Text = d.nombre.ToString(),
Value = d.IdCliente.ToString(),
Selected = false
};
});
ViewBag.items = items;
using (TPConveniosEntities db = new TPConveniosEntities())
{
Usuario user = db.Usuario.FirstOrDefault(u => u.idUsuario == idUsuario);
return View(user);
}
}
In this part it performs the UPDATE and it seems to me that it has to do when I bring the value of my DropDownList with my long variable, it throws me the error and then when I consult my DB I see that if it performs the UPDATE but giving me that error
[Authorize]
[HttpPost]
public ActionResult Asign_Conv(FormCollection collection)
{
using (TPConveniosEntities contexto = new TPConveniosEntities())
{
var idUsuario = Convert.ToInt32(collection["IdUsuario"].Trim());
Usuario user = contexto.Usuario.FirstOrDefault(u => u.idUsuario == idUsuario);
var userName = collection["usuario"].Trim();
long IdCliente = Convert.ToInt32(collection["Convenio"].Trim());
user.userName = userName;
user.idCliente = IdCliente;
contexto.SaveChanges();
return View(user);
}
}
VIEW: Asign_Conv.cshtml
#using TPConvenios.App_Data;
#model Usuario
#{
Layout = null;
AjaxOptions ajaxOpciones = new AjaxOptions
{
UpdateTargetId = "cuerpoPopUpGenerico2",
InsertionMode = InsertionMode.Replace,
OnSuccess = "OnSuccess_Asign",
OnFailure = "OnFailure"
};
List<SelectListItem> items = (List<SelectListItem>)ViewBag.items;
}
<div id="contenedor" style="margin: 15px 30px">
#using (Ajax.BeginForm("Asign_Conv", "Mast", null, ajaxOpciones, new { id = "Asign_Conv" }))
{ #Html.ValidationSummary(true);
<input type="hidden" name="idUsuario" id="idUsuario" value="#(null != Model ? Model.idUsuario : 0)" />
<p>
<input name="usuario" type="text" id="usuario" class="usuario" placeholder="Usuario" value="#(null != Model ? Model.userName : String.Empty)"/>
</p>
<p>
#Html.DropDownList("Convenio", items, "Seleccione el Convenio", new { #class = "form-control" })
</p>
<p id="bot">
<input name="submit" type="submit" id="submit" value="Asignar" class="botonNuevo" style="float: right" />
</p>
}
</div>
I managed to solve my problem by bringing me the code with which I load my DropdownList, and pasting it to the POST where it performs UPDATE.
staying this way
[Authorize]
[HttpPost]
public ActionResult Asign_Conv(FormCollection collection)
{
using (TPConveniosEntities contexto = new TPConveniosEntities())
{
var idUsuario = Convert.ToInt32(collection["IdUsuario"].Trim());
Usuario user = contexto.Usuario.FirstOrDefault(u => u.idUsuario == idUsuario);
var userName = collection["usuario"].Trim();
long IDCliente = Convert.ToInt32(collection["Conve"].Trim());
/*********** ESTO FUE LO QUE COPIE PARA QUE FUNCIONARA **********/
List<Models.TableAsign> lst = null;
using (TPConveniosEntities db = new TPConveniosEntities())
{
lst = (from d in db.Cliente
orderby d.nombre
select new TableAsign
{
IdCliente = d.idCliente,
nombre = d.nombre
}).ToList();
}
List<SelectListItem> items = lst.ConvertAll(d =>
{
return new SelectListItem()
{
Text = d.nombre.ToString(),
Value = d.IdCliente.ToString(),
Selected = false
};
});
ViewBag.items = items;
/*************************** HASTA AQUI **********************/
user.userName = userName;
user.idCliente = IDCliente;
contexto.SaveChanges();
return View(user);
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
How do I use custom stripe form and then integration with 3D Security options using ASP.NET MVC?
Custom Form Design using Razor/ Html
<div class="campagin_start content" style="max-width:100%">
<div class="cell example example2" id="">
<form>
<div class="row">
<div class="field">
<div id="example2-card-number" class="input empty"></div>
<label for="example2-card-number" data-tid="elements_examples.form.card_number_label">Card number</label>
<div class="baseline"></div>
</div>
</div>
<div class="row">
<div class="field half-width">
<div id="example2-card-expiry" class="input empty"></div>
<label for="example2-card-expiry" data-tid="elements_examples.form.card_expiry_label">Expiration</label>
<div class="baseline"></div>
</div>
<div class="field half-width">
<div id="example2-card-cvc" class="input empty"></div>
<label for="example2-card-cvc" data-tid="elements_examples.form.card_cvc_label">CVC</label>
<div class="baseline"></div>
</div>
</div>
<button id="card-button">#WebResources.Donate $#Model.budget</button>
Cancel
</form>
<p id="payment-result"><!-- we'll pass the response from the server here --></p>
</div>
</div>
Script
var stripe = Stripe('#ViewBag.StripePublishKey');
var elementStyles = {
base: {
color: '#32325D',
fontWeight: 500,
fontFamily: 'Source Code Pro, Consolas, Menlo, monospace',
fontSize: '16px',
fontSmoothing: 'antialiased',
'::placeholder': {
color: '#CFD7DF',
},
':-webkit-autofill': {
color: '#e39f48',
},
},
invalid: {
color: '#E25950',
'::placeholder': {
color: '#FFCCA5',
},
},
};
var elementClasses = {
focus: 'focused',
empty: 'empty',
invalid: 'invalid',
};
var elements = stripe.elements({
fonts: [
{
cssSrc: 'https://fonts.googleapis.com/css?family=Source+Code+Pro',
},
],
// Stripe's examples are localized to specific languages, but if
// you wish to have Elements automatically detect your user's locale,
// use `locale: 'auto'` instead.
locale: window.__exampleLocale
});
var Id = #Html.Raw(Json.Encode(Model.Id)); // Get Id From Model
var cardNumber = elements.create('cardNumber', {
showIcon: true,
style: elementStyles,
classes: elementClasses,
});
cardNumber.mount('#example2-card-number');
var cardExpiry = elements.create('cardExpiry', {
style: elementStyles,
classes: elementClasses,
});
cardExpiry.mount('#example2-card-expiry');
var cardCvc = elements.create('cardCvc', {
style: elementStyles,
classes: elementClasses,
});
cardCvc.mount('#example2-card-cvc');
var formClass = '.example2';
var example = document.querySelector(formClass);
var form = example.querySelector('form');
var resultContainer = document.getElementById('payment-result');
// Payment Button Handle
form.addEventListener('submit', function (event) {
$('#AjaxLoader').show();
event.preventDefault();
resultContainer.textContent = "";
stripe.createPaymentMethod({
type: 'card',
card: cardNumber,
}).then(handlePaymentMethodResult);
});
function handlePaymentMethodResult(result) {
if (result.error) {
$('#AjaxLoader').hide();
$("#canceltran").show();
// An error happened when collecting card details, show it in the payment form
resultContainer.textContent = result.error.message;
} else {
// Otherwise send paymentMethod.id to your server
fetch('/cart/pay', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ PaymentMethodId: result.paymentMethod.id, Id: Id})
}).then(function (result) {
return result.json();
}).then(handleServerResponse);
}
}
function handleServerResponse(responseJson) {
if (responseJson.error) {
// An error happened when charging the card, show it in the payment form
resultContainer.textContent = responseJson.error;
$('#AjaxLoader').hide();
$("#canceltran").show();
} else if (responseJson.requiresAction) {
// Use Stripe.js to handle required card action
stripe.handleCardAction(
responseJson.clientSecret
).then(function (result) {
if (result.error) {
$('#AjaxLoader').hide();
resultContainer.textContent = result.error.message;
$("#canceltran").show();
// Show `result.error.message` in payment form
} else {
// The card action has been handled
// The PaymentIntent can be confirmed again on the server
fetch('/cart/pay', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ PaymentIntentId: result.paymentIntent.id, Id:Id })
}).then(function (confirmResult) {
return confirmResult.json();
}).then(handleServerResponse);
$('#AjaxLoader').hide();
}
});
}
else {
// Show a success message or Required action
}
}
Controller -In Constructor, you have to use your Stripe Credentials
public class CartController : ControllerBase
{
public CartController()
{
StripeConfiguration.ApiKey = YOUR API KEY; // Replace your API KEY here
}
string stripePublishKey = YOUR PUBLISHER KEY; // Replace your PUBLISHER KEY here
private class StripeDataReq
{
public string PaymentMethodId { get; set; }
public string PaymentIntentId { get; set; }
public string Id { get; set; }
}
public async Task<ActionResult> Pay(StripeDataReq stripeDataReq)
{
// From Id you can get the value
var cart = await Cart.Table.LookupAsync(stripeDataReq.Id);
// We set amount (amout*100) because here amount consider in cent (100 cent charge $1) so
var amount = cart.Budget * 100;
var email = ""; // Set Email Id for payment Receiver
var service = new PaymentIntentService();
PaymentIntent paymentIntent = null;
try
{
if (stripeDataReq.PaymentMethodId != null)
{
// Create the PaymentIntent
var options = new PaymentIntentCreateOptions
{
Description = cart.Desc,
PaymentMethod = stripeDataReq.PaymentMethodId,
//Shipping is not nessasery for every region this is useful for an Indian Standard
//Shipping = new ChargeShippingOptions
//{
// Name = giver.Name,
// Address = new AddressOptions
// {
// Line1 = "510 Townsend St",
// PostalCode = "98140",
// City = "San Francisco",
// State = "CA",
// Country = "US",
// },
//},
ReceiptEmail = email,
Amount = amount,
Currency = "usd",
Confirm = true,
//ErrorOnRequiresAction = true,
ConfirmationMethod = "manual",
};
paymentIntent = service.Create(options);
}
if (stripeDataReq.PaymentIntentId != null)
{
var confirmOptions = new PaymentIntentConfirmOptions { };
paymentIntent = service.Confirm(
stripeDataReq.PaymentIntentId,
confirmOptions
);
}
}
// StripeException handle all types of failure error and then return the message into FE
catch (StripeException e)
{
return Json(new { error = e.StripeError.Message });
}
TempData["Id"] = stripeDataReq.Id;
return await generatePaymentResponse(paymentIntent);
}
//For 3D secure card
private async Task<ActionResult> generatePaymentResponse(PaymentIntent intent)
{
var CartId = TempData["Id"];
if (intent.Status.ToString().ToLower() == "succeeded")
{
// Handle post-payment fulfillment
return Json(new { success = true });
}
// requires_action means 3d secure card required more authentications for payment
else if (intent.Status == "requires_action")
{
// Tell the client to handle the action
return Json(new
{
requiresAction = true,
clientSecret = intent.ClientSecret
});
}
else
{
// Any other status would be unexpected, so error
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Invalid PaymentIntent status");
}
}
}
Here is my working code with custom form integration using stripe payment, hope this post will help many developers
Firstly, I'd like to thank you for reading this post.
I have a small problem, I am trying to sort my posts in descending order of date created. It sorts the date in descending order by the posts created today and yesterday get mixed up.
For example: Posts created show as;
Created: Today, Created: Yesterday, Created: 29/09/2015, Created: 28/09/2015
After sorting they're displayed in this order:
Created: Yesterday,
Created: Today,
Created: 29/09/2015,
Created: 28/09/2015,
The code I am using is shown below
foreach.Posts.sort(function (l, r) { return l.Created() > r.Created() ? -1 : 1 })
Is there a way around this ?
Thank you.
Updated: Added C# Class
[HttpGet]
public LivePostModel GetPosts(string id, string page = null, string startDate = "", string endDate = "")
{
Thread thread = _threadManager.GetThreadByDomain(id);
if (thread == null)
return new LivePostModel();
DateTime? dtDateFrom = null;
DateTime? dtDateTo = null;
if (string.IsNullOrEmpty(startDate) == false)
dtDateFrom = DateTime.Parse(startDate);
if (string.IsNullOrEmpty(endDate) == false)
dtDateTo = DateTime.Parse(endDate);
PostWithCount posts = _postManager.GetPosts(new PostsFilter
{
SubDomain = id,
Page = string.IsNullOrEmpty(page) ? 0 : int.Parse(page),
StartDate = dtDateFrom,
EndDate = dtDateTo
});
IOrderedEnumerable<Post> sortedPosts = posts.Items.OrderByDescending(x => x.Created);
var postsModel = new List<PostModel>();
List<string> userKeys = sortedPosts
.Select(obj => obj.CreatedByUserId)
.Distinct()
.ToList();
IList<User> users = _userManager.GetUsersByKeys(userKeys);
foreach (Post post in sortedPosts)
{
User user = users.FirstOrDefault(u => u.Key == post.CreatedByUserId);
if (user != null)
{
PostModel postModel = Mapper.Map<Post, PostModel>(post);
postModel.User = GetUserDetails(postModel.User, user);
postsModel.Add(postModel);
}
}
var model = new LivePostModel
{
Posts = postsModel.ToList(),
CountPages = posts.Count.ToString(CultureInfo.InvariantCulture),
CountItems = posts.CountItems.ToString(CultureInfo.InvariantCulture),
CurrentId = thread.Key,
Subdomain = thread.Subdomain,
CurrentUserName = UserContextService.IsAuthenticated ? UserContextService.Key : String.Empty,
OwnerThreadName = thread.OwnerUserId,
OwnerThreadFullName = string.Format("{0} {1}", thread.FirstName, thread.LastName),
CanAddPost = _threadManager.IsCurrentUserCanUploadContent(thread)
};
model.CurrentUserCanDelete = CheckIfUserCanDeletePost(thread);
return model;
}
JSON Data:
"Posts":[
{"Key":"Post_ab780bb71",
"Header":null,
"Message":"Post details go here ",
"PostId":"Post_11338",
"Created":"today",
"Modified":"today",
"User":{ User Details below }
Yes, however you'll need to make some changes...
You need to use a sortable time format... For example, 2015-10-02T10:09:56.
I assume the posts have a property called CreatedOn which indicate whether it was posted today yesterday etc... Add another property called CreatedOnSortable that includes the actual DateTime in the format show, you can do this by calling ToString('s') on the DateTime...
DateTime.UtcNow.ToString("s");
Edit
HomeController
public ActionResult Index()
{
var livePostModel = new PostsViewModel
{
Posts = new Post[]
{
new Post
{
Created = "Today",
CreatedDateTime = DateTime.UtcNow,
Header = "Todays Post",
Key = Guid.NewGuid().ToString(),
Message = "Todays message",
Modified = string.Empty,
PostId = Guid.NewGuid().ToString()
},
new Post
{
Created = "Yesterday",
CreatedDateTime = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)),
Header = "Yesterdays Post",
Key = Guid.NewGuid().ToString(),
Message = "Yesterdays message",
Modified = string.Empty,
PostId = Guid.NewGuid().ToString()
},
new Post
{
Created = DateTime.UtcNow.Subtract(TimeSpan.FromDays(2)).ToString("D"),
CreatedDateTime = DateTime.UtcNow.Subtract(TimeSpan.FromDays(2)),
Header = DateTime.UtcNow.Subtract(TimeSpan.FromDays(2)).ToString("D") + " Post",
Key = Guid.NewGuid().ToString(),
Message = DateTime.UtcNow.Subtract(TimeSpan.FromDays(2)).ToString("D") + " message",
Modified = string.Empty,
PostId = Guid.NewGuid().ToString()
},
new Post
{
Created = DateTime.UtcNow.Subtract(TimeSpan.FromDays(3)).ToString("D"),
CreatedDateTime = DateTime.UtcNow.Subtract(TimeSpan.FromDays(3)),
Header = DateTime.UtcNow.Subtract(TimeSpan.FromDays(3)).ToString("D") + " Post",
Key = Guid.NewGuid().ToString(),
Message = DateTime.UtcNow.Subtract(TimeSpan.FromDays(3)).ToString("D") + " message",
Modified = string.Empty,
PostId = Guid.NewGuid().ToString()
},
}
};
this.ViewBag.Json = JsonConvert.SerializeObject(livePostModel);
return View();
}
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<div class="row" data-bind="foreach: posts">
<div class="col-md-6" data-bind="text: Created"></div>
<div class="col-md-6" data-bind="text: CreatedSortable"></div>
</div>
<div class="row">
<div class="col-md-6"><button data-bind="click: orderByAsc">Order Ascending</button></div>
<div class="col-md-6"><button data-bind="click: orderByDesc">Order Descending</button></div>
</div>
#section scripts{
<script src="~/Scripts/knockout-3.3.0.js" type="text/javascript"></script>
<script type="text/javascript">
var json = #this.Html.Raw(this.ViewBag.Json);
function Post(post) {
var self = this;
self.key = ko.observable(post.Key || '');
self.header = ko.observable(post.Header || '');
self.message = ko.observable(post.Message || '');
self.postId = ko.observable(post.PostId || '');
self.created = ko.observable(post.Created || '');
self.createdSortable = ko.observable(post.CreatedSortable || '');
self.modified = ko.observable(post.Modified || '');
}
function PostsViewModel(model)
{
var self = this;
self.posts = ko.observableArray(model.Posts);
self.orderByAsc = function() {
self.posts.sort(function(left, right) { return left.CreatedSortable == right.CreatedSortable ? 0 : (left.CreatedSortable < right.CreatedSortable ? 1:-1 ) });
}
self.orderByDesc = function() {
self.posts.sort(function(left, right) { return left.CreatedSortable == right.CreatedSortable ? 0 : (left.CreatedSortable < right.CreatedSortable ? -1: 1 ) });
}
}
ko.applyBindings(new PostsViewModel(json));
</script>
}
Result
Ascending
Descending
I have a database which i would like to fill with a filler-method. I wish to call on this method from the Index-view in my MVC-project. I have tested that the method works by running it each time the index.cshtml is run, and it fills the table. The only problem with this is that if I refresh the index-page, the table gets filled with the exact same data once again. Which results in me getting two of every item.
So I have come to the conclusion that I want to bind my filler()-method to a button on the index-page to fill the table. My question is then:
How do I directly bind a method to a button in my project?
Extra info:
The filler-method is in its own class called DBFiller.cs, and when I set it to run on index launch I added DBfiller.filler() in the actionresult of my controller.
Code:
DBFiller.cs
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Oblig1.BLL;
using Oblig1.Model;
using Oblig1.DAL;
namespace Oblig1
{
public class DBFiller
{
public void Filler()
{
var userDb = new UserBLL();
var itemDb = new ItemBLL();
var city1 = new Cities();
var city2 = new Cities();
var city3 = new Cities();
city1.Cityname = "Oslo";
city1.Postcode = "9382";
city2.Cityname = "Trondheim";
city2.Postcode = "2301";
city3.Cityname = "Bergen";
city3.Postcode = "1723";
var user1 = new Users()
{
Address = "Moroveien 7",
Firstname = "Martin",
Surname = "Hermansen",
Email = "mh#mh.no",
Password = "mhmhmh",
Phonenr = "93929392",
Postcode = "9382",
cities = city1
};
var user2 = new Users()
{
Address = "Bakvendtgata 8",
Firstname = "Hanne",
Surname = "Lande",
Email = "hl#hl.no",
Password = "hlhlhl",
Phonenr = "82711212",
Postcode = "2301",
cities = city2
};
var user3 = new Users()
{
Address = "Fisefin Aveny 14",
Firstname = "Voldemort",
Surname = "Olsen",
Email = "vo#vo.no",
Password = "vovovo",
Phonenr = "12672891",
Postcode = "1723",
cities = city3
};
var item1 = new Items()
{
Currentstock = 40,
Itemname = "Blanding",
Itemprice = 99,
Itemtype = "Pasta",
PictureURL = "/img/pasta_blanding.png",
Itemid = 78
};
var item2 = new Items()
{
Currentstock = 17,
Itemname = "Fusilli",
Itemprice = 119,
Itemtype = "Pasta",
PictureURL = "/img/pasta_fusilli.png",
Itemid = 63
};
var item3 = new Items()
{
Currentstock = 80,
Itemname = "Farfalle",
Itemprice = 69,
Itemtype = "Pasta",
PictureURL = "/img/pasta_farfalle.png",
Itemid = 30
};
var item4 = new Items()
{
Currentstock = 63,
Itemname = "Colored Fusilli #1",
Itemprice = 45,
Itemtype = "Pasta",
PictureURL = "/img/pasta_fusilli_farget.png",
Itemid = 22
};
var item5 = new Items()
{
Currentstock = 3,
Itemname = "Colored Fusilli #2",
Itemprice = 33,
Itemtype = "Pasta",
PictureURL = "/img/pasta_fusilli_farget2.png",
Itemid = 98
};
var item6 = new Items()
{
Currentstock = 77,
Itemname = "Macaroni",
Itemprice = 25,
Itemtype = "Pasta",
PictureURL = "/img/pasta_macaroni.png",
Itemid = 76
};
var item7 = new Items()
{
Currentstock = 80,
Itemname = "Measure",
Itemprice = 299,
Itemtype = "Tools",
PictureURL = "/img/pasta_messure.png",
Itemid = 59
};
var item8 = new Items()
{
Currentstock = 14,
Itemname = "Multitool",
Itemprice = 499,
Itemtype = "Tool",
PictureURL = "/img/pasta_multitool.png",
Itemid = 69
};
var item9 = new Items()
{
Currentstock = 88,
Itemname = "Penne",
Itemprice = 19,
Itemtype = "Pasta",
PictureURL = "/img/pasta_penne.png",
Itemid = 79
};
var item10 = new Items()
{
Currentstock = 45,
Itemname = "Roller",
Itemprice = 59,
Itemtype = "Tool",
PictureURL = "/img/pasta_ruller.png",
Itemid = 79
};
var item11 = new Items()
{
Currentstock = 179,
Itemname = "Spoon",
Itemprice = 39,
Itemtype = "Tool",
PictureURL = "/img/pasta_sleiv.png",
Itemid = 110
};
var item12 = new Items()
{
Currentstock = 17,
Itemname = "Spagetti",
Itemprice = 9,
Itemtype = "Pasta",
PictureURL = "/img/pasta_penne.png",
Itemid = 79
};
itemDb.registerItem(item1);
itemDb.registerItem(item2);
itemDb.registerItem(item3);
itemDb.registerItem(item4);
itemDb.registerItem(item5);
itemDb.registerItem(item6);
itemDb.registerItem(item7);
itemDb.registerItem(item8);
itemDb.registerItem(item9);
itemDb.registerItem(item10);
itemDb.registerItem(item11);
itemDb.registerItem(item12);
userDb.setIn(user1);
userDb.setIn(user2);
userDb.setIn(user3);
}
}
}
My attempt at adding it in the index-launcher in my User-Controller:
namespace Oblig1.Controllers
{
public class UserController : Controller
{
public ActionResult Index()
{
var model = new UserBLL();
var filler = new DBFiller();
filler.Filler();
List<Item> allItems = model.getItems();
return PartialView(allItems);
}
}
}
Index.cshtml if it helps any:
#using Oblig1
#model IEnumerable<Oblig1.Model.Item>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
<br />
<br />
<head>
<title>Index</title>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
</head>
#if (Model != null)
{
<div class="row">
#foreach(var item in Model)
{
<div class="col-sm-6 col-md-3">
<div class="thumbnail">
<img src="#item.pictureURL" alt="...">
<div class="caption">
<h3>#item.itemname</h3>
<p>Antall på lager: #item.currentstock<br />kr #item.itemprice,00</p>
<button class="btn btn-success">#Html.ActionLink("Add to Cart", "AddToCart", new { id = item.itemid }, null)</button>
</div>
</div>
</div>
}
</div>
}
Attempt at filler-call by JS:
#model IEnumerable<Oblig1.Model.Item>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
<br />
<br />
<head>
<title>Index</title>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script type="text/jscript">
$('#fill').click(function () {
var url = "/UserController/Filler";
$.post( url);
});
</script>
</head>
<button class="btn btn-success" id="fill" value="Fill Database"> </button>
Controller:
public ActionResult Filler()
{
var filler = new DBFiller();
filler.Filler();
return View("Index");
}
You can move the logic of filling to another action method and call it using jquery Ajax call on the click of the button
EDIT:
Please refer the below link for sample
http://www.itorian.com/2013/02/jquery-ajax-get-and-post-calls-to.html
Basically below is the code to link the click of your button with Action method
<script type="text/javascript">
$(document).ready(function()
{
$('#ButtonID').click(function () {
var url = "/ControllerName/YourActionMethod";
$.post( url);
});
});
Add the above code in your page with appropriate url and button id
In a view I'm using 3 dropdownlist strongly-typed to a model like this:
#using (Html.BeginForm())
{
<p>Filter by rarity: #Html.DropDownListFor(_item => _item.mRarity, Model.mRarityList, new {#id = "cardRarity"})
Filter by type: #Html.DropDownListFor(_item => _item.mType, Model.mTypeList, new {#id = "cardType"})
Filter by color: #Html.DropDownListFor(_item => _item.mColor, Model.mColorList, new {#id = "cardColor"})
</p>
}
Here's the view in which the thing is displayed:
#model PagedList.IPagedList<MvcMagicAdmin.Utilities.CardDisplay>
#{
ViewBag.Title = "Cards Display Results";
}
<h2>
Cards Display Results
</h2>
<script type="text/javascript">
$(document).ready(function () {
$('#cardRarity').change(function () {
var showCardRarity = $(this).val();
alert(showCardRarity);
var showCardType = $('#cardType').val();
var showCardColor = $('#cardColor').val();
refreshResults(showCardRarity, showCardType, showCardColor);
});
$('#cardType').change(function () {
var showCardType = $(this).val();
alert(showCardType);
var showCardRarity = $('#cardRarity').val();
var showCardColor = $('#cardColor').val();
refreshResults(showCardRarity, showCardType, showCardColor);
});
$('#cardColor').change(function () {
var showCardColor = $(this).val();
alert(showCardColor);
var showCardRarity = $('#cardRarity').val();
var showCardType = $('#cardType').val();
refreshResults(showCardRarity, showCardType, showCardColor);
});
function refreshResults(rarity, type, color) {
$.get("#Url.Action("DisplayCardsResults", "Card")", {
_page: 1,
_sortOrder: "#ViewBag._sortOrder",
_rarity: rarity,
_type: type,
_color: color,
}, function(data) {
$("#resultsDiv").html(data);
});
}
});
</script>
<div>
<div class="float-left">
<p>#Html.ActionLink("Make a new search", "SearchCardsAdvanced")</p>
</div>
<div class="float-right">
<p><span class="bold baseFontSize">Legend: </span>Details #Html.Image("~\\Images\\Functional\\Icons\\detailsIcon.jpg", "details", new { #class = "centerVert" } )
Edit #Html.Image("~\\Images\\Functional\\Icons\\editIcon.png", "edit", new {#class = "centerVert"} )
Delete #Html.Image("~\\Images\\Functional\\Icons\\trashIcon.png", "delete", new {#class = "centerVert"} )</p>
</div>
<div class="clear"></div>
</div>
#{
Html.RenderAction("FilterCardsResults", "PartialViews");
}
<div id="resultsDiv">
#{
Html.RenderPartial("ResultsTable", Model);
}
</div>
So, yes, I am calling a partial view from another controller because I pass a model which is not included in the Original List of models.
The view is generated like this:
private static readonly CardsFilters mCardsFilters = new CardsFilters();
public ActionResult FilterCardsResults()
{
return PartialView("Filters/FilterCardsResults", mCardsFilters);
}
Here's the model on which the data is built:
public class CardsFilters
{
public string mRarity { get; set; }
public IEnumerable<SelectListItem> mRarityList { get; set; }
public string mType { get; set; }
public IEnumerable<SelectListItem> mTypeList { get; set; }
public string mColor { get; set; }
public IEnumerable<SelectListItem> mColorList { get; set; }
public CardsFilters()
{
List<SelectListItem> items = new List<SelectListItem>
{
new SelectListItem() {Value = "All", Text = "All"},
new SelectListItem() {Value = "Land", Text = "Land"},
new SelectListItem() {Value = "Common", Text = "Common"},
new SelectListItem() {Value = "Uncommon", Text = "Uncommon"},
new SelectListItem() {Value = "Rare", Text = "Rare"},
new SelectListItem() {Value = "Mythic Rare", Text = "Mythic Rare"},
new SelectListItem() {Value = "Special", Text = "Special"}
};
mRarityList = new SelectList(items, "Value", "Text");
items = new List<SelectListItem>
{
new SelectListItem(){ Value = "All", Text = "All"},
new SelectListItem(){ Value = "Artifact", Text = "Artifact"},
new SelectListItem(){ Value = "Instant", Text = "Instant"},
new SelectListItem(){ Value = "Creature", Text = "Creature"},
new SelectListItem(){ Value = "Land", Text = "Land"},
new SelectListItem(){ Value = "Planeswalker", Text = "Planeswalker"},
new SelectListItem(){ Value = "Enchantment", Text = "Enchantment"},
new SelectListItem(){ Value = "Sorcery", Text = "Sorcery"},
new SelectListItem(){ Value = "Tribal", Text = "Tribal"},
};
mTypeList = new SelectList(items, "Value", "Text");
items = new List<SelectListItem>
{
new SelectListItem(){ Value = "All", Text = "All"},
new SelectListItem(){ Value = "White", Text = "White"},
new SelectListItem(){ Value = "Red", Text = "Red"},
new SelectListItem(){ Value = "Green", Text = "Green"},
new SelectListItem(){ Value = "Blue", Text = "Blue"},
new SelectListItem(){ Value = "Black", Text = "Black"},
new SelectListItem(){ Value = "Gold", Text = "Gold"},
new SelectListItem(){ Value = "Colorless", Text = "Colorless"},
};
mColorList = new SelectList(items, "Value", "Text");
}
}
And, finally, the post method called in the controller:
public ActionResult DisplayCardsResults(int? _page, string _sortOrder, string _rarity = "", string _type = "", string _color = "")
{
ViewBag._rarity = _rarity;
ViewBag._color = _color;
ViewBag._type = _type;
if (Request.HttpMethod != "GET")
{
_page = 1;
}
if (mListCards.Count == 0)
{
TempData[MessageDomain.Tags.TEMPDATA_MESSAGE_ERROR] = NODATAFILTERERRORMESSAGE;
}
int pageNumber = (_page ?? 1);
if (Request.IsAjaxRequest())
{
mListCardsToShow = GetListCardsToShow(_rarity, _color, _type);
return PartialView("ResultsTable", mListCardsToShow.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
if (mListCardsToShow.Count > 0)
{
mListCardsToShow = SortListOrder(_sortOrder, mListCardsToShow);
return View(mListCardsToShow.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
if (mListCards.Count > 0)
{
mListCards = SortListOrder(_sortOrder, mListCards);
}
return View(mListCards.ToPagedList(pageNumber, ValueDomain.PAGE_SIZE));
}
The dropdownlist works very fine, except for one reason. When I post back the form, all the values selected in the dropdownlist resets to "All", and I'd like to keep them selected. How might I do this?
You must make shure that you are correctly binding your return model into the view.
I took your example and included it into a simple project, that is working ok:
The controller with a simple POST:
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
var model = new CardsFiltersViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(CardsFiltersViewModel model)
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View(model);
}
public ActionResult About()
{
return View();
}
}
It returns the object the you presented above.
The View is the exact same as your code.
#using (Html.BeginForm())
{
<p>
Filter by rarity: #Html.DropDownListFor(_item => _item.mRarity, Model.mRarityList, new { #id = "cardRarity" })
Filter by type: #Html.DropDownListFor(_item => _item.mType, Model.mTypeList, new { #id = "cardType" })
Filter by color: #Html.DropDownListFor(_item => _item.mColor, Model.mColorList, new { #id = "cardColor" })
</p>
<input type="submit" name="name" value=" " />
}
With the reference to the model class object (
#model MvcApplication7.Controllers.CardsFiltersViewModel
)