Shopping Cart logic (?) trouble with KnockoutJS - c#

The Goal
Make a dynamic list of products.
The Scenario
I have a shopping application with products. When I click on the add button of a product, I want to display in the sidebar, the product what I have added.
Summarized Problem (You just need to read this)
I have the following code in my ProductsSummary/Index.cshtml (using Razor Engine):
<ul class="summary">
#if (Session["ProductsSummary"] == null)
{
<li class="is-empty">
<p>Your summary is empty.</p>
</li>
<li data-bind="attr: { 'data-product-id': id }">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini remove-item">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6 data-bind="text: infoComposition"></h6>
</div>
<div class="product-summary-description">
<p data-bind="text: name"></p>
</div>
</li>
}
else
{
foreach
(var product in
(List<MyApp.Models.Data.getSpecificProductToShoppingList_Result>)
Session["ProductsSummary"])
{
<!-- ko foreach: products -->
<li data-product-id="#product.id">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini remove-item">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6>
#product.quantity
#product.measure#(#product.quantity == 1 ? "" : "s")
</h6>
</div>
<div class="product-summary-description">
<p>#product.name</p>
</div>
</li>
<!-- /ko -->
}
}
</ul>
As you can see, there is three <li> on the code. The first is to display a message with "The summary is empty." case the session is null (and of course, the Session is null case any product has been added); the second li serves as model for Knockout when I add something when the session is null; and the last one is to display the products what are in the session.
I'm feeling a little "DRY" right here. How can I reuse the same template regardless of whether session exists or not?
Detailed Problem
I have the following code in my ProductsSummary/Index.cshtml (using Razor Engine):
<ul class="summary">
#if (Session["ProductsSummary"] == null)
{
<li class="is-empty">
<p>Your summary is empty.</p>
</li>
<li data-bind="attr: { 'data-product-id': id }">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6 data-bind="text: infoComposition"></h6>
</div>
<div class="product-summary-description">
<p data-bind="text: name"></p>
</div>
</li>
}
else
{
foreach
(var product in
(List<MyApp.Models.Data.getSpecificProductToShoppingList_Result>)
Session["ProductsSummary"])
{
<!-- ko foreach: products -->
<li data-product-id="#product.id">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini remove-item">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6>
#product.quantity
#product.measure#(#product.quantity == 1 ? "" : "s")
</h6>
</div>
<div class="product-summary-description">
<p>#product.name</p>
</div>
</li>
<!-- ko -->
}
}
</ul>
As you can see, there is an if that checks if ProductsSummary session exists. If yes, then the application displays on the screen a list of products that I added on my summary.
Case the session is null, as you can see, the application displays the message within the li with is-empty class.
The point is: I really need of the "template" after <li class="is-empty">[...]</li> to display an item that was added to the summary?
I mean, I know that Knockout needs something to display when I click the "Add Product" button regardless of whether or not there is a session, but I'm repeating the same template for similar purposes.
Look to this fragment:
<li data-product-id="#product.id">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini remove-item">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6>
#product.quantity
#product.measure#(#product.quantity == 1 ? "" : "s")
</h6>
</div>
<div class="product-summary-description">
<p>#product.name</p>
</div>
</li>
In this case, I'm using it within foreach because I must to display the items fetched from the database.
On the other hand, the following fragment exists if there isn't a session:
<li data-bind="attr: { 'data-product-id': id }">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6 data-bind="text: infoComposition"></h6>
</div>
<div class="product-summary-description">
<p data-bind="text: name"></p>
</div>
</li>
As you can see, the both fragments are similar — one represents the data from database, and the other represents a model to work with Knockout when there is no session, respectively — and I need a way to "templatize" this.
What I Really Need
Someone enters in my site/application;
At the right side of my layout there is a sidebar with a message: "The summary is empty.";
"Oh, what a nice product! I will add it to my summary!", then the user clicks on Add button, the "The summary is empty." message disappears and the product added by user appears in the format of an item from a list (the same template that I have passed before [first/second fragment]).
"Ok, I will to another category of products now." — *The user clicks on "TVs" category* — "OH MY GOD! Look at this TV! I will add to my summary right now!" — *The user clicks on "Add Button" of a random TV.* — Already had a product in the list, but another (the TV) appears.
"Oh, nevermind. I do not have money. I will remove these items from my summary." — *The user clicks on "remove button" of each product on the summary* — And without products, the summary displays: "The summary is empty." just like a magic, without any refresh or something like this.
(Funny, huh?)
The KnockoutJS Script
$(document).ready(function () {
function Product(id, name, measure, quantity) {
this.id = ko.observable(id);
this.name = ko.observable(name);
this.measure = ko.computed(function () {
return quantity > 1 ? measure + "s" : measure;
}, this);
this.quantity = ko.observable(quantity);
this.infoComposition = ko.computed(function () {
return this.quantity() + " " + this.measure()
}, this);
}
function SummaryViewModel() {
this.products = ko.observableArray([]);
this.addToSummary = function (formElement) {
var $productId = $(formElement).children("[name=productId]").val();
var match = $(".summary")
.find("li[data-product-id=" + $productId + "]").length;
if (!match) {
var $productName =
$(formElement).children("[name=productName]").val(),
$productMeasure =
$(formElement).children("[name=productMeasure]").val(),
$productQuantity =
$(formElement).children("[name=productQuantity]").val();
this.products.push
(new Product
($productId,
$productName,
$productMeasure,
$productQuantity));
$.ajax({
type: "POST",
url: "/ProductsSummary/Add",
data:
{
productId: $productId,
productQuantity: $productQuantity
}
});
}
}
};
var summaryViewModel = new SummaryViewModel();
ko.applyBindings(summaryViewModel);
$("body").on("click", ".remove-item", function () {
summaryViewModel.products.remove(ko.dataFor(this));
$.ajax({
type: "POST",
url: "/ProductsSummary/Remove",
data: { productId: $(this).closest("li").data("product-id") }
});
});
});
What is happening, eventually?
What I'm doing works and does not work. Technically, my code works, but I wouldn't to repeat it. Is it possible?
Technical Details
The server-side team is with C#.NET with MVC 4 and Razor Engine and the client-side team is KnockoutJS and jQuery.

For the empty cart message, you can do this:
<li class="is-empty" data-bind="visible: products().length < 1">
<p>Your summary is empty.</p>
</li>
For the rest, you should be able to do this (no MVC loops):
<!-- ko foreach: products -->
<li data-bind="attr: { 'data-product-id': id }">
<div class="product-summary-actions float-right">
<button class="btn btn-danger btn-mini remove-item">
<i class="icon-remove"></i>
</button>
</div>
<div class="product-summary-quantity">
<h6 data-bind="text: infoComposition"></h6>
</div>
<div class="product-summary-description">
<p data-bind="text: name"></p>
</div>
</li>
<!-- /ko -->
And populate the list on the client side, even if you have items saved to the session. In your view, serialize the existing data to a JSON object and save it to a javascript variable on the page which can be read on document ready and pushed into the products observable.
var existingItems = #Html.Raw(Json.Encode((List<MyApp.Models.Data.getSpecificProductToShoppingList_Result>)Session["ProductsSummary"]));
$(document).ready(function() {
// push existingItems into products observable.
});
Note my syntax may not be quite right on the JSON encoding.

Related

Get value of textbox into view component without using begin form or post

I have a list within a dropdown of users a person can say share a case with above that is a form field
This is called update info and is just a text area field.
<div class="col-md-12">
<textarea id="updateInfo" name="updateInfo" class="form-control" rows="10"></textarea>
</div>
Question is without using post back or ajax begin form how does one get only the value from UpdateInfo textbox to a data attritube of the anchor tag.
#foreach (var allUsers in Model) {
<a class="dropdown-item" asp-controller="MisObjects" asp-action="ShareCase" asp-route-
id="#allUsers.Id.ToString()" >#allUsers.FirstName.ToUpperInvariant()
#allUsers.LastName.ToUpperInvariant()</a>
}
To overcomplicate things I have the list of users in a view component
<li class="nav-item dropdowntest">
<a class="nav-linkb dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Share Case
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
#await Component.InvokeAsync("ShareButtonList", new { caseId = Model.Id ,Text=UpdateInfo.Text ///how do i do this })
</div>
</li>

I want to use the Same View to show different result in different nav bar using MVC razor Engine.I have designed a page using html tags

I have designed a page using html tags. i have used the same code in a View in my MVC application. The page has three tabs tab1, tab2 and tab3.
#using (Html.BeginForm("ViewName", "Home", FormMethod.Post))
{
<div class="col">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="tab">Search</a>
</li>
<li class="nav-item">
<a class="nav-link tab" id="tab2" href="#tab2"</a>
</li>
<li class="nav-item">
<a class="nav-link tab" id="tab3">Details</a>
</li>
</ul>
</div>
<div class="col-auto text-right">
#Html.TextBoxFor(Model => Model.Name) <!--This is my text box to enter the text.-->
<input type="submit" class="btn btn-primary" value="Search" name="Search" action="ViewName"><!--On submitting it, it will hit the "test" action method in the Controller.-->
</div>
<div class="tab-pane fade" id="tab2" role="tabpanel" aria-labelledby="results-tab">
<table id="Table" class="table" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Name1</th>
</tr>
</thead>
<tbody>
<tr>
<td>name2</td>
<td>name2</td>
</tr>
</tbody>
</table>
</div>
<div class="tab-pane fade" id="details" role="tabpanel" aria-labelledby="details-tab">Details</div>-- the above is the table to which i want to bind the data and show the result and it is in the same view.
}
The above is the HTML code i am using in my view of the MVC code. i have three tabs in my Html code.
In my Tab1:
I have a text box with my search button.
I am binding the text box to the required model property.
After i have entered the text and hit the search button. It would call an API and give the list which contains or equals the required text.In my controller i have used the [HttpPost] attribute.I am posting the form on clicking the submit button.
public IActionResult ViewName()
{
NameModel obj = new NameModel();
return View("ViewName", obj);
}
[HttpPost]
public IActionResult ViewName(NameModel obj1)
{
NameModel model = new NameModel();
-- Call the api and take out the Json response.
--Bind the json response to the Model.
--Send the model back to the same view but different tab.
return View("ViewName", model);
}
Now i want to display the result in the Tab2 in the grid format which is in the Same View.
The tab2 contains the table. How do i bind the resulted model value to it since it is in the same view.
I dont want to use the JQuery. i want to use any .net core concepts to implement it.
Can someone please tell me how to do it.
Solution 1: Partial view included in different views
I would go for another type of implementation. It looks like the views are indeed different from each other and the fact that you require different models for each tab tells me the same.
If that's the case, Check the partial view guide here
The main idea is to create the navbar as a reusable partial view, and include it in every other View (that is every other tab) you want to use.
Solution 2: Use the jquery option
MVC uses html/css and javascript to render clientside items. It is not non-MVC practice to use JQuery with it, it is in fact a common practice.
Solution 3: Use razor logic check w3schools entry
You can add checks like this below in your razor and have one model
#if (Model.Tab == 1)
{
<div class="col-auto text-right">
#Html.TextBoxFor(Model => Model.Name) <!--This is my text box to enter the text.-->
<input type="submit" class="btn btn-primary" value="Search" name="Search"
action="ViewName"><!--On submitting it, it will hit the "test" action method in the
Controller.-->
}
</div>
Now in your backend, change the Model.Tab and have an overall model like this:
public MyModel {
public int Tab;
public TabOneModel;
public TabTwoModel;
public TabThreeModel;
}
While I have seen this quite a lot it has major disadvantages.
You can't apply an overall validation.
Your code will become very complicated in a single function. It violates multiple principles and can't be easiy unit tested.
IMO, you could post the name using ajax and return the partial view where locates the Tab2 content, and display the result to the main view.
Refer to my following steps:
1.ViewName.cshtml
#model NameModel
<div class="col">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="#tab" role="tab" data-toggle="tab">Search</a>
</li>
<li class="nav-item">
<a class="nav-link tab" href="#tab2" role="tab" data-toggle="tab">Grid</a>
</li>
<li class="nav-item">
<a class="nav-link tab" href="#tab3" role="tab" data-toggle="tab">Details</a>
</li>
</ul>
</div>
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="tab">
<div class="col-auto text-right">
<input asp-for="#Model.Name" id="myText" />
<input type="button" class="btn btn-primary" onclick="myFunction()" value="Search" id="Search" name="Search" /><!--On submitting it, it will hit the "test" action method in the Controller.-->
</div>
</div>
<div role="tabpanel" class="tab-pane fade" id="tab2">
<div id="Tab2Content">
</div>
</div>
<div role="tabpanel" class="tab-pane fade" id="tab3">ccc</div>
</div>
#section Scripts{
<script>
function myFunction() {
var name = document.getElementById("myText").value;
$.ajax({
type: 'POST',
url: '/Home/ViewName',
data: { name: name },
error: function (result) {
console.log("error");
},
success: function (result) {
$("#Tab2Content").html(result);
}
});
}
</script>
}
2.Post method:
[HttpPost]
public IActionResult ViewName(NameModel obj1)
{
NameModel model = new NameModel();
-- Call the api and take out the Json response.
--Bind the json response to the Model.
--Send the model back to the same view but different tab.
return PartialView("_Tab2PartialView", tab2model);
}
3.Partial View (located at /Views/Shared/_Tab2PartialView.cshtml) to display the grid
#model tab2model
#*or #model List<tab2model>*#
#*grid view*#
<table id="Table" class="table" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Name1</th>
</tr>
</thead>
<tbody>
<tr>
<td>name2</td>
<td>name2</td>
</tr>
</tbody>
</table>

Bootstrap slider in ASP.NET MVC from SQL Server database

I tried to make Bootstrap carousel slider for news from SQL Server database
I want the slider to look like this: https://www.w3schools.com/bootstrap/bootstrap_carousel.asp
But the role said
The .active class needs to be added to one of the slides. Otherwise, the carousel will not be visible.
but I did not know how to use .active class to one of my news because it is foreach loop.
All of my news has been under each other also, the left and right controls not working
Here is a screenshot of news slider result now
The code now:
HomeController.cs
public ActionResult Index()
{
return View(db.News.ToList());
}
Index.cshtml
#model IEnumerable<Project.Models.News>
#{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Scripts.Render("~/bundles/bootstrap")
<!--Start slide code-->
<div class="container imgs">
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<!-- Wrapper for slides -->
#foreach (var item in Model)
{
<div class="carousel-inner">
<div class="item active"> //My mistake is here, how to make first news of class active?
<div class="item ">
#{ string imageBase64 = Convert.ToBase64String(item.newImg);
string imageSrc = string.Format("data:image/gif;base64,{0}", imageBase64);
<img src="#imageSrc" />
}
<div class="carousel-caption">
<h3>#item.newName</h3>
Read More
#*<button type="button" class="btn btn-default">Read More</button>*#
</div>
</div>
</div>
</div>
}
<!-- Left and right controls -->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
Any help?
To add class="active" to the first element in the list you can either:
#{int v = 0;}
#foreach (var item in Model)
{
<div class="carousel-inner">
<div class="item#(v == 0 ? " active" : "")">
#item.newName
</div>
</div>
v++;
}
Or:
#foreach (var item in Model.Select((value, i) => new { i, value }))
{
<div class="carousel-inner">
<div class="item#(item.i == 0 ? " active" : "")">
#item.value.newName
</div>
</div>
}

Partial View Render

I am new to the world of MVC programming with C #, I already read the topic, made some examples and of course with the guide of StackOverflow I think I'm doing well.
However I find myself with an exercise that I want to perform and from which I have seen several answers but none has worked for me, and I come to you asking for the support.
Index
#{
ViewBag.Title = "Bienvenido";
}
<div class="container-fluid">
<div class="row">
<div class="col-md-3" id="menu">
<ul class="nav nav-pills nav-stacked">
<li role="presentation" class="active">Inicio</li>
<li role="presentation">Datos Generales</li>
<li role="presentation">Datos Curriculares</li>
<li role="presentation">Experiencia Laboral</li>
<li role="presentation">Datos Laborales</li>
<li role="presentation">Cónyuge y Dependientes</li>
<li role="presentation">Inmuebles</li>
<li role="presentation">Vehículos</li>
<li role="presentation">Muebles</li>
<li role="presentation">Inversiones</li>
<li role="presentation">Adeudos</li>
<li role="presentation">Posible Conflicto de Intereses</li>
<li role="presentation">Observaciones</li>
</ul>
</div>
<div class="col-md-9">
<div class="row" id="opciones">
</div>
<div class="row" id="crear">
</div>
<div class="row" id="registros">
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#dependientes').click(function () {
$.get('#Url.Action("Create","Dependientes")', function (data) {
$('#crear').replaceWith(data);
});
});
});
$(function () {
$('#dependientes').click(function () {
$.get('#Url.Action("Mostrar","Dependientes")', function (data) {
$('#registros').replaceWith(data);
});
});
});
</script>
Partial View _Mostrar
#model List<projectD.Models.dependiente>
#{
ViewBag.Title = "_Mostrar";
}
<br />
<div class="container">
<div class="row">
#foreach (var item in Model)
{
<div class="card" style="width: 20rem; display:inline-block; margin-top:10px">
<img class="card-img-top" src="~/Content/images/familia.png" alt="Card image cap" width="50" height="50">
<div class="card-block">
<h4 class="card-title">Dependiente</h4>
<p class="card-text">
#item.nombre
<br />
#item.apellidoPaterno
<br />
#item.apellidoMaterno
<br />
#item.CURP
</p>
#Html.ActionLink("Detalle", "Details", new { id = item.idDependiente }, new {#class= "btn btn-primary"})
</div>
</div>
}
</div>
</div>
I have a project with a main view, which has a menu to the left when selecting each option to the right render two partial views each with its controller the first to add records and the second to display them.
main screen
What I want to do is that when I click on add record, only the partial views are updated and the URL is not reloaded since I would lose the menu option in which I am.
I hope you can support me

Put elements into an array that I can then pass to my MVC partial view

I need to throw anywhere from 2 elements and up into an array that I can then jQuery.Ajax post to my MVC controller.
My issue is how to put them into an acceptable array or object that I can then pass to the MVC partial view?
I have classes setup I think will work for the buttons and jQuery btnMoveUp, btnMoveDown
I need to pass the data-procedureid and data-sortid to my MVC controller.
And for bonus points another part I think I will be stuck on. If they click the "Move Up" button. I need to grab the element above it and switch their sort orders. Or the "Move Down" button need to grab the element below it and switch their sort orders.
I'm hoping this will be as easy as jQuery(".btnMoveDown").next(".btnMoveDown").attr("data-sortorder") but i haven't tested this possibility.
Here is my future aJax:
$(".btnMoveUp").click(function () {
var currSortOrder = jQuery(this).data('sortorder');
// find the element above this one and grab the sort order
// switch the sort orders
$.ajax({
url: "YourController/GetData",
type: "get",
data: // What can I pass here that my MVC partial view can then use?
success: function (result) {
$("#procedures").html(result);
}
});
}
Here is the code:
<ul class="commentlist">
#{
int i = 1;
//foreach (var item in #Model.IPACS_Processes.IPACS_Procedures)
foreach (var item in #Model.IPACS_Procedures)
{
<li class="span6">
<img src="../../Images/thumbs/doc.png" alt="" class="pull-left" />
<div class="comment-info">
<h4>
<a href="#Url.Action("ViewProcedure", new { id = item.procedureID })">
#item.name</a></h4>
<h5>
<small>Owner: </small>#item.owner</h5>
<br />
<p>
#item.description
</p>
<br />
<p>
#if (i > 1)
{
<a href="javascript:void(0);" class="btn btn-small btnMoveUp" data-procedureid="#item.procedureID" data-sortorder="#i"><span class="iconfa-double-angle-up icon-white">
</span>Move Up</a>
}
#if (i < #Model.IPACS_Procedures.Count)
{
<a href="javascript:void(0);" class="btn btn-small btnMoveDown" data-procedureid="#item.procedureID" data-sortorder="#i"><span class="iconfa-double-angle-down">
</span>Move Down</a>
}
#{i++;}
</p>
</div>
</li>
<br style="clear: both;" />
}
}
</ul>
Here it is generated:
<ul class="commentlist">
<li class="span6">
<img src="../../Images/thumbs/doc.png" alt="" class="pull-left">
<div class="comment-info">
<h4>
<a href="/MasterList/ViewProcedure/123">
XYZ Process Server</a></h4>
<h5>
<small>Owner: </small>Some Dude</h5>
<br>
<p>
Enter Description for XYZProcess Server Procedure
</p>
<br>
<p>
<a href="javascript:void(0);" class="btn btn-small btnMoveDown" data-procedureid="122" data-sortorder="1"><span class="iconfa-double-angle-down">
</span>Move Down</a>
</p>
</div>
</li>
<br style="clear: both;">
<li class="span6">
<img src="../../Images/thumbs/doc.png" alt="" class="pull-left">
<div class="comment-info">
<h4>
<a href="/MasterList/ViewProcedure/122">
XYZ2 Process Server</a></h4>
<h5>
<small>Owner: </small>Some Dude</h5>
<br>
<p>
Enter Description for XYZ2 Process Server Procedure
</p>
<br>
<p>
<a href="javascript:void(0);" class="btn btn-small btnMoveUp" data-procedureid="123" data-sortorder="2"><span class="iconfa-double-angle-up icon-white">
</span>Move Up</a>
<a href="javascript:void(0);" class="btn btn-small btnMoveDown" data-procedureid="123" data-sortorder="2"><span class="iconfa-double-angle-down">
</span>Move Down</a>
</p>
</div>
</li>
<br style="clear: both;">
<li class="span6">
<img src="../../Images/thumbs/doc.png" alt="" class="pull-left">
<div class="comment-info">
<h4>
<a href="/MasterList/ViewProcedure/121">
XYZ3 Process Server</a></h4>
<h5>
<small>Owner: </small>Some Dude</h5>
<br>
<p>
Enter Description for XYZ3 Process Server Procedure
</p>
<br>
<p>
<a href="javascript:void(0);" class="btn btn-small btnMoveUp" data-procedureid="124" data-sortorder="3"><span class="iconfa-double-angle-up icon-white">
</span>Move Up</a>
<a href="javascript:void(0);" class="btn btn-small btnMoveDown" data-procedureid="124" data-sortorder="3"><span class="iconfa-double-angle-down">
</span>Move Down</a>
</p>
</div>
</li>
<br style="clear: both;">
<li class="span6">
<img src="../../Images/thumbs/doc.png" alt="" class="pull-left">
<div class="comment-info">
<h4>
<a href="/MasterList/ViewProcedure/120">
XYZ4 Process Server</a></h4>
<h5>
<small>Owner: </small>Some Dude</h5>
<br>
<p>
Enter Description for XYZ4 Process Server Procedure
</p>
<br>
<p>
<a href="javascript:void(0);" class="btn btn-small btnMoveUp" data-procedureid="125" data-sortorder="4"><span class="iconfa-double-angle-up icon-white">
</span>Move Up</a>
</p>
</div>
</li>
<br style="clear: both;">
</ul>
I'm actually (literally) writing code like this right now. I am using jQuery UI to do the drag/drop re-ordering. (This code may be a little different then most other code examples).
jQuery/javascript
$(document).ready(function ()
{
$(".ui-sortable-container").sortable({
handle: ".handle",
stop: function (event, ui)
{
AJAX.postRouteUpdate();
}
});
var AJAX =
{
postRouteUpdate: function ()
{
// create object that matches MVC object
// not case sensitive
var request = {};
request.routeIDs = [];
var selector = ".ui-routes .ui-route";
// for each of my objects grab the routeid
// this is the new order of the routeids
// send them all in, it's just easier on the backend
// and allows for future multiple re-sorts before
// sending the request to the server
$(selector).each(function (index)
{
request.routeIDs.push($(this).data('routeid'));
// update the title value, as I have mine numbered
$(this).find('.title').text((index + 1).toString());
});
$.ajax({
url: '/Routes/UpdateSequence',
data: JSON.stringify(request),
type: 'GET',
success: function (result) {
$("#procedures").html(result);
}
});
}};
Model:
public class RouteUpdateModel()
{
public IEnumerable<int> RouteIDs { get; set; }
}
Controllers
public ActionResult UpdateSequence(RouteUpdateModel model)
{
this.db().UpdateSequence(model.RouteIDs);
return this.Partial(model);
}
View
#Model RouteUpdateModel
#foreach (var routeID in model.RouteIDs)
{
//do whatever
}

Categories

Resources