real time view update - spring-mvc

I plan to develop an admin tool using Spring MVC. One view would show an order update, wherein a user would enter a product code and an update status. For every record in the database that is updated, I want to show in real time the record of the order updated.
What I am unsure is how to display this in the view from controller - would i be using a jquery grid to perform this or is there some feature built in spring mvc
Read this article , but seems that may be an overkill for my simple app

If a user is filling out a form in your view (entering the product code and update status) and you want to display the data in that view after they submit (without page reload), you will need to use AJAX. Hook a JavaScript function to an event in your form:
$("#submit_button").click(function(){
$.ajax("/path/to/controller/route", {
// Insert various request options...
data: {
// data to be sent along with the reqest.
}
success: function(data){
// Define function that is fired when the AJAX request returns successfully.
}
});
});
This path should hit an endpoint on the server side that will perform the update on your desired record, and can return the info about the record that you desire back to the client side. When the request returns successfully, you can do whatever you want with the data via the success function's data argument. You can find more information about the jQuery AJAX functions here and more about jQuery Events here.
If by "in real time" you mean on a timer, instead of on some user triggered event, the solution is similar, but the AJAX request would be defined in the callback function of setTimeout() call or a similarly acting jQuery provided function (such as delay())

Related

Can I ko.observable a session variable?

I have 2 simple aspx pages. On my default page, I have a simple label that's using ko.data-binding to a Session variable.
I thought if I change that variable KnockoutJS would update the user interface. When I click the button on sessionchanger page I changed the session variable that is being observed by ko. Where did I go wrong?
You have to change value of status property of viewModel instance to reflect changes on ui.
var vm = new viwModel;
ko.applyBindings(vm);
vm.status('new value');
You bind vm object to body not session object. You just use session object to initialize vm.status property.
So, you can't set new value in vm.status from the other page.
To be able to track it you should use client-server communication. It can be AJAX with polling functionality or WebSocket. So, you should check or listen server side and if any changes occur you can update vm.status property and after that it will reflect ui as you expect.
You cannot do it because asp.net rendering engine simply pass value of Session["target"] and not any link to that variable, also your knockout code isn't well written, see #Viktor Kukurba answer to get clearer idea of how to use and apply data-binding.
To achieve desired result you could use one of techniques listed below:
Preferable
Use WebSockets to notify your "Default" page about changing session variable by "Session Changer" page.
Take a look on tutorialBuilding real-time web apps with WebSockets using IIS, ASP.NET and WCF to get practical knowledge of how apply that techniques.
Workaround
As workaround you could get quite similar to required behaviour after applying next steps:
Create asp.net http request handler which would return value of Session["target"] in json format.
Create javascript function (let's call it refreshSessionTarger), which would send AJAX request to newly created asp.net http handler and update value of observable variable ( so knockout would reflect to that change, but note that you have to add ko data-binding properly).
Put refreshSessionTarger function created in step 2 into setInterval function as callback and set interval of how often in milliseconds refreshSessionTarger shall be executed.
function refreshSessionTarger(){
// perform ajax request and update variable which holds session target
};
var delay = 5000;
setInterval(refreshSessionTarger, delay)

ASP.NET User Control & AJAX

I have this ASP.NET User Control that (as a part of its rendering phase) needs to execute some javascript at client-side. I use ScriptManager.RegisterStartupScript to register the script I want to execute when response reaches the client. Now, in my scenario my control is contained inside an Update panel (to be more precise, it is ajaxified using a Telerik RadAjaxManager). On the same page, I have a second Update panel (again to be more precise, a second panel ajaxified with a second RadAjaxManager setting). When this second panel raises a partial postback, I expect the changes (including any emitted script) from my control to be ignored. This is not the case and frustratingly, I cannot determine what to do? Any ideas ?
IDEA #1: Stop using UpdatePanel.
ASP Webforms are great for a lot of things...partial page rendering is not one of them. While the UpdatePanel does technically perform "partial page-rendering", it also performs a full postback.
Instead, use this alternative . . .
Create an ASP Web API and regain control over your page loading process. By creating a web API controller (which is pretty much just a function on the server that you can call using javascript) you can pass to the server specific information, run only the function (or functions) necessary for the action you are performing, and then return the exact data you need to display on your client.
The same javascript function that makes the call to the server (i.e., your ASP Web API controller) will also handle the response returned, which is easily formatted in the always-simple-to-use JSON format. In the end, your javascript would look something like this:
$('.show-kitten-button').click(function () { // this binds the click event whatever button begins the action.
// then we'll store some values in our variables
var kittenType = $('input.kitten-type').val(); // "calico" ...from asp textbox with a CssClass="kitten-type" attribute.
});
// function to make the call to the ASP Web API controller.
function getKittenPicture(kittenType) {
$.ajax({ // jQuery's AJAX function works well
type: "GET" // there are four types of requests: get, post, update, and delete. You can do most actions with get and post.
, url: 'http://yourWebSite.com/api/kittens/' + kittenType // the URL that routes to your ASP Web API controller. This is specified in the global.asax file.
, success: function (data) { // handle the data if the HTTP response indicates success
if (data || false) { // if data exists
var jsonData = JSON.parse(data); // parse it as JSON. This is assuming you are returning a serialized class object from C# or VB.NET. See below for more info on this.
var kittenImageSrcUrl = jsonData.src; // grab the data from the JSON object.
showKittenImage(kittenImageSrcUrl); // run the function to show the kitten image.
}
}
, error: function (data) { // handle the data if the HTTP response indicates an error.
console.log('An error occurred while retrieving the cute kitten picture.');
console.log('Error response: ', JSON.parse(data.responseJSON));
}
, complete: function (data) {
// any code to perform once the success (or error) function is complete.
}
});
};
function showKittenImage(imgSrc) { // function to show cute kitten image
$("#kittenImage").attr("src", "kittenImageSrcUrl"); // change the src attribute of the image to match the src URL we got back from the server.
};
More info
If you haven't yet dabbled in the world of APIs, then you're in for a real treat, because it is much, much easier and more effective than using UpdatePanels. UpdatePanels seem simple at first glance--there's not much to making one and they do give the appearance of dynamic page content--but once you start adding multiple panels, inserting start-up scripts, etc...it gets hairy very quickly. Below here are links to everything you'll need to build your first API. I encourage you to check them out...
Chad Carter's tutorial on how to implement ASP Web API in Webforms. (VB)
Microsoft's tutorial on how to use ASP Web API with Webforms. (C#)
Making POST requests to ASP Web API with multiple parameters.
Using jQuery to POST parameters from body. (VB & C#)

How to display error on the client when using ASP.NET MVC AJAX

I am using ASP.NET MVC AJAX with the #AJAX.ActionLink helper to implement item deletion from a grid. When the request is executed it returns the grid without the deleted item and the AJAX helpers replace the grid. This works just fine but the problem is what to do if the item cannot be deleted (in my case due to foreign key constraints). How can I report the error to the client and display appropriate message. I don't want to use the OnFailure function blindly because I don't want to show the same error message for all errors. Ideally there will be a way to send specific error from the action and inspect the error in the JavaScript OnFailure function but I can't seem to find it.
Of course I can downgrade to returning JSON, manually executing AJAX calls and replacing UI elements but I don't really feel like it. I'd rather do something dirty like render a hidden input with the error information and check for it on the client but I don't want to do that either if there is better way.
You can return status code and error message from the controller and pass it to the ajax OnFailure function
return new HttpStatusCodeResult(HttpStatusCode.Conflict, "The entity is currently used");
as shown here: ASP.NET MVC AJAX onError handling
and in the client side JS:
function deleteFailure(responce) {
var statusCode = responce.status;
var responceText = responce.statusText;
if(statusCode == 409){
//do something specific for specific errors
}
alert(responceText);
}

hold data in session until the user leaves the page

I have a question about using session, or maybe TempData to store data while working on one page. I store and retrieve data using multiple Ajax requests and I save to session on my controller Action. What I'd like to do is, when user leaves my page, I'd like to clear session variables. How would I do that with session? Or maybe there is some kind of other way to store data only for one http request (I am not sure about this because as I said I have multiple POST as well as GET requests within the page.)
Any help would be appreciated. Thanks
You dont you make use of Hiddenfields in your html to hold that data...
Same as Asp.Net using hiddenfield to store the viewstate data.....
Use Html.HiddenFor(myModel => myModel.SomeField) to do this. You can assign the values to it, and then it will automatically post back the values in to your model which is super handy dandy.
I hope this is helpful!
If you really want to use TempData (which I do on occasion), I have a KeepTempDataAlive(string tempKey) method that looks something like this...
if(TempData[tempKey] != null)
{
TempData.Keep(tempKey);
}
That should keep it around for 1 more post back. Just do this as long as you need it.
Depends on your intentions.
If you want to do async stuff with Ajax requests, you can store the data in a hidden field or the jQuery .data() on your .success event. Then when everything is done, use jQuery to populate what you need done.
If you want a true session variable (across multiple pages), then the best way to do that is an AJAX process on window.close to clear out session. Although that's limited to users who have javascript enabled. I don't think there's a foolproof way to do this.
I solved this problem utilizing jQuery and an ajax request that runs when the page unloads.
In your javascript:
$(window).unload(function () {
$.ajax({
url: applicationPath + "/api/ExampleApiController/ExampleWebMethod",
async: false,
type: 'GET',
data: {
"someVariable": anythingYouWantToPassIfAny,
"otherVariable": anythingElseYouWantToPass,
}
});
});
Note: You need to set async: false or else the page will unload before it has a chance to run the ajax request. For the type you can use either a GET or POST, whatever your preference is and what you all want to do with the request.
Then in your api controller:
public class ExampleApiController
{
[HttpGet]
public void ExampleWebMethod(string someVariable, string otherVariable)
{
HttpContext.Current.Session.Remove("sessionVariableA");
HttpContext.Current.Session.Remove("sessionVariableB");
...
}
}
You can also add code to check the return if you want to see if it was successful or not, but in my case I just wanted a quick thing to run and didn't really want it to return anything and it wasn't a big deal if it failed so I just send the request off and unload. I know this question is old, but hopefully it will help someone else.
Note: The problem with this solution is that if the user refreshes the page it will still call the unload event and drop all your session variables.

ASPxUploadControl: how to synchronize data from two controls?

I need to have TWO ASPxUploadControl controls on the same Web page. A single UPLOAD button should start the uploading from the both controls. This is simple: in Jscript code I call Upload() method for the both controls; on the server side I handle FilesUploadComplete event on the both controls.
But I have the following problem – my application needs to have UploadedFiles lists from the both controls SIMULTANEOUSLY. When FilesUploadComplete event handler is called for the 1st ASPxUploadControl, property UploadedFiles of the 2nd control is null. And, correspondingly, when FilesUploadComplete event handler is called for the 2nd ASPxUploadControl, property UploadedFiles of the 1st control is null.
Can I resolve the trouble somehow? I could upload the files using Postback – do perform postback of the whole form when the UPLOAD button is clicked. This gives me the both UploadedFiles lists simultaneously, but leads to another problem: Progress Indicator does not work in Postback mode. This is not acceptable for me – I want uploadcing progress to be displayed.
This is a strange situation but you could try this:
1. Send both upload controls file list to server before you call Upload methods trigger. You can do this by calling custom http handler using ajax. If you use jQuery:
$.ajax(
{
url: 'MyHandler.ashx',
dataType: 'json',
cache: false,
data: { fileList1: uploadControlFileList1, fileList2: uploadControlFileList2},
success: function ()
{
// call Upload methods here;
}
});
2.In your handler save those file lists in your db together with session id. Or you could store this list in session if it is easier for you. Also store time when file list is received.
3.When you receive file(s) check if you have it in your list and try to pair it with other control files. If necessary Use time from step 2 to choose between filelists. Mark file as uploaded when you receive it. Wait for other control files. When all controls files are uploaded remove fileLists from session/db and continue with your logic.
There is some work with this but it should work.
You can use a single ASPxUploadControl instance with multiple file inputs. See the “Upload Control - Multi-File Upload” http://demos.devexpress.com/ASPxperienceDemos/UploadControl/MultiFileUpload.aspx online demo regarding this.

Resources