I'm building a webshop in C# (MVC). Now I want to change the number of items that is shown in the cart-icon (at the layout-page). I've found this code and want to customize it to my page.
$(function () {
// Document.ready -> link up remove event handler
$("##product.ArtNumber").click(function () {
// Get the id from the link
var itemToAdd = $(this).attr("data-id");
if (itemToAdd != '') {
// Perform the ajax post
$.post("/ShoppingCart/RemoveFromCart", { "id": recordToDelete },
function (data) {
// Successful requests get here
// Update the page elements
if (data.ItemCount == 0) {
$('#row-' + data.DeleteId).fadeOut('slow');
} else {
$('#item-count-' + data.DeleteId).text(data.ItemCount);
}
$('#cart-total').text(data.CartTotal);
$('#update-message').text(data.Message);
$('#cart-status').text('Cart (' + data.CartCount + ')');
});
}
});
});
Now I have a question about " $.post("/ShoppingCart/RemoveFromCart" "
In my case I don't want to switch to another page when you click the button - but add an item to the cart (at the layout-page). What can I write instead of "post"? As I've understand this is used when you want to open a new HTML-page?
The $.post is shorthand of jQuery.post. http://api.jquery.com/jquery.post/
It is an ajax call, and occurs in the background asynchronously. You are expected to have an endpoint that will handle the HTTP post on the server. Ideally this will update the server with the cart information such that it is available later if the client disconnects or closes their browser.
In my case I don't want to switch to another page when you click the button
I failed to actually answer your question directly. It will not take you to a different page or navigate away from the current page. You can actually open a new tab and paste that URL into the browser and see that it returns JSON.
Related
its me again.
this time i am trying to keep the current JQuery accordion pane open after postback. I have followed the example here: Keep the current jQuery accordion pane open after ASP.NET postback? in addition to couple others i have seen around. i still cannot get it to work, the only difference with mine is that i am formulating the script through my code behind and pushing to the client.
this is what i have:
public static string getAccordionContainerScript(string container)
{
return #"$(document).ready(function() { var activeIndex = parseInt($('#<%=accordionActiveIndex.ClientID %>').val()); $(" + '"' + '#' + container + '"' + ").accordion({collapsible: true, heightStyle: \"content\", navigation: true,change: function (event, ui) { var index = $(this).accordion(\"option\", \"active\");$('#<%=accordionActiveIndex.ClientID %>').val(index);} }).show(); })";
}
my reason for doin this is due to the fact that i am re-using code blocks as i have several of the same controls throughout the application.
also, when i use the markup display expression (<%= =>), it throws a client error and my other client controls do not work such as my modal, etc.
client error is: Uncaught Error: Syntax error, unrecognized expression: #<%=accordionActiveIndex.ClientID %>
what could i be doing wrong?
You are doing wrong exactly what the error message says:
You are sending to the Response the string <%=accordionActiveIndex.ClientID %>. That string must be processed by the WebForms engine, so it must be in the aspx page. The browser doesn't know how to deal with that code, and that's why the browser is throwing that error.
I'm afraid that you need the accordionActiveIndex.ClientID value passed to that function, so you can do something like this (note the new parameter, and also, ignore the line breaks in the string. I've added for legibility):
public static string getAccordionContainerScript(string container, string clientId)
{
return string.Format(#"$(document).ready(function() { var activeIndex = parseInt($('#<%=accordionActiveIndex.ClientID %>').val());
$(" + '"' + '#' + container + '"' + ").accordion({collapsible: true, heightStyle: \"content\", navigation: true,change: function (event, ui) { var index = $(this).accordion(\"option\", \"active\");
// pay attention here
$('#{0}').val(index);} }).show(); }), clientId);
}
I followed the MVC4 Music Store tutorial for making a shopping card. Unfortunately, when I use the RemoveFromCard function I get the following message:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is temporarily
unavailable. Please review the following URL and make sure that it is spelled
correctly.
Requested URL: /ShoppingCart/RemoveFromCart/1
The code I use on the View Page is the following:
<script src="/Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
// Document.ready -> link up remove event handler
$(".RemoveLink").click(function () {
// Get the id from the link
var recordToDelete = $(this).attr("data-id");
if (recordToDelete != '') {
// Perform the ajax post
$.post("/ShoppingCart/RemoveFromCart", { "id": recordToDelete },
function (data) {
// Successful requests get here
// Update the page elements
if (data.ItemCount == 0) {
$('#row-' + data.DeleteId).fadeOut('slow');
}
else {
$('#item-count-' + data.DeleteId).text(data.ItemCount);
}
$('#cart-total').text(data.CartTotal);
$('#update-message').text(data.Message);
$('#cart-status').text('Cart (' + data.CartCount + ')');
});
}
});
});
</script>
With the following actionlink:
<td>
<%: Ajax.ActionLink("Remove from cart", "RemoveFromCart",
new { id = item.RecordId },
new AjaxOptions { OnSuccess = "handleUpdate" })%>
</td>
Furthermore,
I have this method in ShoppingCard.cs
public int RemoveFromCart(int id) //code
Why does it not find this method? I would be very grateful for some help!
Okay I solved the problem... I changed the actionlink to:
Remove from cart
and now it is working.
I've just implemented paging using PagedList in my MVC 4 application. The homepage of my app contains a partial view that displays a list of summarised data about certain objects. Beside each list item is a button that when clicked launches a modal window, displaying more information about that particular list item.
All works well on the first 'paged' page of list items, however if I navigate to the second 'paged' page and click the button to launch modal nothing happens. From developer tools in Chrome I get Uncaught TypeError: Object [object Object] has no method 'modal'.
The partial in question outputs the list, contains the DIV for the modal and a JS function to handle the button click event that launches modal windows. Here's the JS from that partial view:
<script type="text/javascript">
$(document).ready(function () {
$('.show-modal').click(function () {
var url = $('#modal-view-property-from-get-all').attr('data-url');
var id = $(this).attr('data-id');
$.get(url + '/' + id, function (data) {
$('#view-property-from-get-all-container').html(data);
$('#modal-view-property-from-get-all').modal('show');
});
});
});
</script>
When I navigate back to the first 'paged' page, the button doesn't fire either and same uncaught typeError is thrown. Another jQuery plugin I use that truncates multi-line text also stops working and text overflows its containing DIV.
What's actually happening here - why does using paging interfere with JS like this?
How can I resolve this?
EDIT:
All records of particular type are returned from controller action:
return PartialView("_GetAllPropertiesPartial", model.ToPagedList(pageNumber, pageSize));
Since it's a partial, paging navigation is handled by Ajax.ActionLinks():
#Ajax.ActionLink("<<", "GetAllProperties", new { page = 1 }, new AjaxOptions { UpdateTargetId = "quick-property-search-results" })
You need to bind the event handler to something that doesn't get replaced in your markup, and use the .on() method rather than .click(), like so:
<script>
$(function () {
$('body').on('click', '.show-modal', function (e) {
var url = $('#modal-view-property-from-get-all').attr('data-url');
var id = $(this).attr('data-id');
$.get(url + '/' + id, function (data) {
$('#view-property-from-get-all-container').html(data);
$('#modal-view-property-from-get-all').modal('show');
});
});
});
</script>
You can use something other than body if you have a parent element that you know won't get replaced. It's also worth noting that you could be using .load(): http://api.jquery.com/load/
$('#view-property-from-get-all-container').load(url + '/' + id, function (response, status, jqxhr) {
// this is an optional callback
$('#modal-view-property-from-get-all').modal('show');
});
I am trying to use the jQuery Autocomplete UI widget on a text box and I am having no luck getting the source to work. I have a database full of names that I want the autocomplete to work against, so I created a page called searchpreload.aspx and it looks for a variable in the url and queries the db based on the querystring vraiable.
When I type in the search box, I am using the keyup function so I can capture what the value is that needs to be sent over. Then I do my string gathering from the db:
if (Request.QueryString["val"] != null)
{
curVal = Request.QueryString["val"].ToString();
curVal = curVal.ToLower();
if (Request.QueryString["Type"] != null)
type = Request.QueryString["Type"].ToString();
SwitchType(type,curVal);
}
It queries the database correctly and then it takes the strings and puts them in a list and prints them out to the page:
private void PreLoadStrings(List<string> PreLoadValues, string curVal)
{
StringBuilder sb = new StringBuilder();
if (PreLoadValues.Any())
{
foreach (string str in PreLoadValues)
{
if (!string.IsNullOrEmpty(str))
{
if (str.ToLower().Contains(curVal))
sb.Append(str).Append("\n");
}
}
Response.Write(sb.ToString());
}
}
This works fine, if I navigate to this page I get a listing of all of the data that I need, however I can not get it to show up in the autocomplete box. When I debug the code, the source of the autocomplete is calling this page correctly each time and getting the correct data, it just is not displaying anything. Am I doing something wrong?
JQuery Code:
<script type="text/javascript">
$(document).ready(function () {
$(".searchBox").focus();
var checked = 'rbCNumber';
$("input:radio").change(function (eventObject) {
checked = $(this).val();
});
$(".searchBox").keyup(function () {
var searchValue = $(".searchBox").val();
//alert("Searchpreload.aspx?val=" + searchValue + "&Type=" + checked);
$(".searchBox").autocomplete({
source:"Searchpreload.aspx?val=" + searchValue + "&Type=" + checked,
minLength: 2
});
});
});
</script>
Also, should I be doing this a different way to make it faster?
You arent displaying the results into anything - source will return a data item that you can then use to populate something else on the page. Look at autocomplete's select and focus methods.
here is an example of how i have done it:
field.autocomplete({
minLength: 1,
source: "whatever",
focus: function (event, ui) {
field.val(ui.item.Id);
return false;
},
search: function (event, ui) {
addBtn.hide();
},
select: function (event, ui) {
setup(ui);
return false;
}
})
.data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.Id+ ", " + item.Name + "</a>")
.appendTo(ul);
};
The .data part is the part you are missing. Once the data comes back from the autocomplete you arent doing anything with it.
The source does not need to include the term the user entered into the search box. Jquery will automatically append the term onto the query string for you. If you watch the request get generated in firebug, you will see the term query hanging off the end of the url.
This is with ASP.NET Web Forms .NET 2.0 -
I have a situation that I am not sure how to fulfill all the requirements. I need to update an img source on the page if selections are made from a drop down on the same page.
Basically, the drop downs are 'options' for the item. If a selection is made (i.e. color: red) then I would update the img for the product to something like (productID_red.jpeg) IF one exists.
The problem is I don't want to do post backs and refresh the page every time a selection is made - especially if I do a check to see if the image exists before I swap out the img src for that product and the file doesn't exist so I just refreshed the entire page for nothing.
QUESTION:
So I have easily thrown some javascript together that formulates a string of the image file name based on the options selected. My question is, what options do I have to do the following:
submit the constructed image name (i.e. productID_red_large.jpg) to some where that will verify the file exists either in C# or if it is even possible in the javascript. I also have to check for different possible file types (i.e. .png, .jpg...etc.).
not do a post back and refresh the entire page
Any suggestions?
submit the constructed image name
(i.e. productID_red_large.jpg) to some
where that will verify the file exists
either in C# or if it is even possible
in the javascript. I also have to
check for different possible file
types (i.e. .png, .jpg...etc.).
not do a post back and refresh the
entire page
If you wish to not post back to the page you will want to look at $.ajax() or $.post() (which is just short hand for $.ajax() with some default options)
To handle that request you could use a Generic Http Handler.
A simple outline could work like the following:
jQuery example for the post:
$("someButton").click(function () {
//Get the image name
var imageToCheck = $("#imgFileName").val();
//construct the data to send to the handler
var dataToSend = {
fileName: imageToCheck
};
$.post("/somePath/ValidateImage.ashx", dataToSend, function (data) {
if (data === "valid") {
//Do something
} else {
//Handle error
}
}, "html");
})
Then on your asp.net side you would create an http handler that will validate that request.
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var fileName = context.Request["fileName"];
var fullPath = Path.Combine("SomeLocalPath", fileName);
//Do something to validate the file
if (File.Exists(fullPath))
{
context.Response.Write("valid");
}
else
{
context.Response.Write("invalid");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Hope this helps, if I missed the mark at all on this let me know and I can revise.
We have an app of the same type, webforms .net 2, we do something similar with the following setup:
Using jQuery you can call a method in the page behind of the current page, for example, the following will trigger the AJAX call when the select box called selectBoxName changes, so your code work out the image name here and send it to the server.
$(document).ready(function () {
$('#selectBoxName').change(function (event) {
var image_name = 'calculated image name';
$.ajax({
type: "POST",
url: 'SomePage.aspx/CheckImageName',
data: "{'imageName': '" + image_name + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg);
},
error: function (a, b, c) {
alert("The image could not be loaded.");
}
});
});
});
Where SomePage.aspx is the current page name, and image_name is filled with the name you have already worked out. You could replace the img src in the success and error messages, again using jQuery.
The code behind for that page would then have a method like the following, were you could just reutrn true/fase or the correct image path as a string if needed. You can even return more complex types/objects and it will automatically send back the proper JSON resposne.
[System.Web.Services.WebMethod(true)]
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public static bool CheckImageName(string imageName)
{
/*
* Do some logic to check the file
if (file exists)
return true;
return false;
*/
}
As it is .net 2 app, you may need to install the AJAX Extensions:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ca9d90fa-e8c9-42e3-aa19-08e2c027f5d6&displaylang=en
Could you not use a normal ajax call to the physical path of the image and check if it returns a 404?
Like this:
http://stackoverflow.com/questions/333634/http-head-request-in-javascript-ajax
<script type="text/javascript">
function UrlExists(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status != 404;
}
function ConstructImage() {
var e = document.getElementById("opt");
var url = '[yourpath]/' + e.value + '.jpg';
if (!UrlExists(url)) {
alert('doesnt exists');
//do stuff if doesnt exist
} else {
alert('exists');
//change img if it does
}
}
</script>
<select id="opt" onchange="ConstructImage()">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>