ASPxUploadControl: how to synchronize data from two controls? - devexpress

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.

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#)

real time view update

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())

Asp.Net CreateChildControls() - Re create controls with Postback data - Event

I have a WebPart custom control (Composite) in .Net, which gets created on page load to show a Chart using 'Dundas Charting Controls' (this is created by a user control inside the page). I get the properties for this control from the database.
I have another control, which is a Filter (outside webpart) and based on data of this filter control which the user selects and which I would get on postback after click of button, I have to show the filtered chart results. The problem is CreateChildControls() gets called before the postback data is available (which would be available only after the Page_Load event fires).
I'm unable to get this data in time to pass on the parameters for filtering the Chart Results.
The implementation os like this ...
Webparts
Page > User Control > Webparts > Composite Control/Chart
Filter
Page > User Control > Composite Control [I get this data on Postback]
It sounds like you are running into an event ordering issue. I always try to make my controles relatively dump - so they don't really know how they are being used.
Consider creating a method in your chart control to force an update of its data:
public void UpdateChart(-- arguments as needed --)
then create an event in your composit control (that has your filters) like
public event Eventhandler FiltersChanged;
Assign this to an event hander on parent page:
filterControl.FiltersChanged += new EventHandler(Filter_OnChange)
Then create an event handler that tells your chart control about the change
Filter_OnChange(Object sender, EventArgs e)
{
// get whatever data you need from your filter control
// tell the chart about the new data and have it reload/redraw
myChart.UpdateData( - filter options here -}
}
In doing so, you let the page direct the order of operations and do not rely on the order in which the child controls Load methods are called.
James - Thanks for your answer, but this does not seem to work in my scenario or rather I couldn't make it work, when I tried it. The controls seems to be doing too much and is getting data from every where, it has its own constructor implementation, Load() override etc so a single UpdateChart() function may not have done the trick in this case.
This is what I did, finally.
I fire an Ajax request with Filter Data and set the value in a Session Variable before page does a Postback, this way I get the data at all places/events, and pass on the same as parameter where required. I know it may seem weird way to implement this, but it saved additional Database calls (which in this case are many to create the controls again) even though it comes at the cost of an additional Server HTTP ajax request.
Let me know this implementation can have any negative impact.

asp.net server control - avoid adding multiple javascript

I created an asp.net Server control that derives from a LinkButton, and renders a small javascript function to the page.
I want to use this control many times on the page, but just want the javascript to be rendered once on the page. On the other hand, I rather not manually add it in a js file, because i don't want to have a chance of forgetting to add the js file in the future.
What will be the best way to go about doing this ?
Preventing duplication in client scripts
Use a registration method such as Page.ClientScript.RegisterClientScriptBlock(..). There are a couple of overloads but they all work in a similar fashion. It's smart enough to render the script only once no matter from how many control instances it's issued.
Microsoft remarks in the MSDN documentation:
A client script is uniquely identified
by its key and its type. Scripts with
the same key and type are considered
duplicates. Only one script with a
given type and key pair can be
registered with the page. Attempting
to register a script that is already
registered does not create a duplicate
of the script.
The MSDN docs also contain sample code such as this:
// Check to see if the client script is already registered.
if (!cs.IsClientScriptBlockRegistered(cstype, csname2))
{
StringBuilder cstext2 = new StringBuilder();
cstext2.Append("<script type=text/javascript> function DoClick() {");
cstext2.Append("Form1.Message.value='Text from client script.'} </");
cstext2.Append("script>");
cs.RegisterClientScriptBlock(cstype, csname2, cstext2.ToString(), false);
}
Other similar registration methods
Different methods can be used to register your client script in different ways - see each of the ClientScriptManager.RegisterClientScript*(..) methods in MSDN for more detail about each. They're all built to prevent duplication in the rendered page.
This gives you the freedom to output scripts at the control level without worrying or having to track or count scripts.
Edit:
The ClientScriptManager instance is accessed through the Page.ClientScript property.
You can use the Page.RegisterClientScriptBlock method.
Here is an example from the MSDN:
if (!this.IsClientScriptBlockRegistered("clientScript"))
{
// Form the script that is to be registered at client side.
String scriptString = "<script language=\"JavaScript\"> function DoClick() {";
scriptString += "myForm.show.value='Welcome to Microsoft .NET'}<";
scriptString += "/";
scriptString += "script>";
this.RegisterClientScriptBlock("clientScript", scriptString);
}
HTH
Any way to reference a script on a CDN and not have it duplicated multiple times? Or can I just not worry about it since it's just a pointer anyway and the browser is (?) smart enough not to load the same library twice?
In other words, suppose I want the following code inserted from a server control:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
If I use a RegisterClientScriptBlock I can use the IsClientScriptBlockRegistered method to not have the server control load it multiple times. But, the preceding code is likely to have been put on the page anyway by either another (different) server control or by the developer who wants to use jQuery for something outside of the server control.
How do I get the server control to not load the script if the developer already loaded it?

Resources