How to Update asp:Label after AJAX Callback - callback

I'm using the ajaxtoolkit:Rating. It all works fine except I'm trying to write a value to an asp label on the changed event and can't get it to work. Here are the relevant lines of code:
page.aspx
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
<td>
<ajaxtoolkit:Rating ID="YourRating" runat="server" BehaviorID="RatingBehavior1" CurrentRating="0"
MaxRating="10" StarCssClass="ratingStar" WaitingStarCssClass="savedRatingStar"
ReadOnly="false" FilledStarCssClass="filledRatingStar" EmptyStarCssClass="emptyRatingStar"
OnChanged="YourRating_Changed" />
</td>
<td>
(<asp:Label ID="YourRatingNumber" Text="" runat="server"></asp:Label>)
</td>
</LoggedInTemplate>
<AnonymousTemplate>
<td>
Login or Register to Rate
</td>
</AnonymousTemplate>
page.aspx.cs
protected void YourRating_Changed(object sender, AjaxControlToolkit.RatingEventArgs e)
{
((HtmlGenericControl)FindControl("MainContent_LoginView1_YourRatingNumber")).InnerHtml = e.Value;
}
What I'm trying to do is update my asp:label control named "YourRatingNumber" text to e.value. I've tried many ways. I realize the asp:label is rendered as a span tag but I can't seem to access that value either. How can do this?
Thanks ... Bob

AJAX is asynchronous, meaning that a page load does not occur. Changing the value of a label server-side during an AJAX operation causes nothing client side. You would need to signal the client to update the page. You should use javascript to do this. I do not think you can do this using Web Forms. If you use MVC, you can use their AJAX helpers to do this, but it would require rewriting the site.
I would suggest that you write some javascript to cause an AJAX event and have it update the label when it gets a response. I would also suggest reading http://w3schools.com/ajax/default.asp, it explains how to use javascript to create AJAX requests, but you would need to tweak it a little to work with asp.net.
Also note, you should include whether you are using Web Forms or MVC, although they are similar, they have different handling of AJAX.

Related

Dynamically loading content through Groovy server page upon form submit

I have a Groovy project (vanilla; no Grails) with an index.gsp that takes form input from the user and sends it in a POST request to a Groovy script. The form is set up like this:
<form action="somewhere" method="POST" enctype="multipart/form-data">
// some other inputs
<input type="submit"/>
</form>
Is there any way (ideally not using Javascript) to dynamically load content on the same page after the user submits? Redirecting to another GSP might also work. Just something simple, like a string containing whatever the user typed. It seems like Grails has plenty of options, but unfortunately I can't use it.
As you mentioned, Grails is capable of doing what you need without any complex code. Since you can't use it, you will have to use JQuery(Javascript) to make an AJAX call. AJAX is the he only way that I know to achive that.
Just make an AJAX call to your groovy script. JQuery.ajax has a success function to be called if the request succeeds. You can use it to update a hidden dive after the form. This success function has the data returned from the server as an argument, that data could be the string containing whatever the user typed. In that case just add the data to the hidden div and then make that div visible.
function onSucceed(data) {
$('#hiddenDivToUpdate').text(data);
$('#hiddenDivToUpdate').show();
}
You can learn about JQuery.ajax() in this link AJAX

How to add a contact form to a static web site?

I have a mostly "static" web site with no server-side code and just a little JavaScript. Now I would like to add a contact form. I do not care how I get the contact form data (so just writing this data to a text file in the server will be ok).
What is the simplest solution for this problem? How do people usually handle this?
I believe I can add some server-side code (PHP or something) to handle the form (and write the form data to a file, for instance) but I would prefer a client-side solution.
Use an external tool, they are commonly referred to as "formmailer". You basically submit the form to their server, and they send the form contents via mail to you.
If you don't want that, you have to do something server-sided: Storing data on the server, without having a server side program that accepts the data from the client, is just not possible.
You could install CouchDB and interface that from Javascript :) Everyone could use that then, too :)
The most easy PHP script that stores POST data on your harddisk:
<?php file_put_contents('/path/to/file', serialize($_POST) . "\n", FILE_APPEND); ?>
You can use Google Drive and create form with required fields. and embed code (which will be iframe) in your static web page.
You will be able to get submitted data in spreadsheet.
You can use qontacto . it is a free contact form you can add to any website. it forwards you the messages.
I set up the fwdform service for this exact need.
Just two simple steps to get your form forwarded to your email.
1.Register
Make an HTTP POST request to register your email.
$ curl --data "email=<your_email>" https://fwdform.herokuapp.com/register
Token: 780a8c9b-dc2d-4258-83af-4deefe446dee
2. Set up your form
<form action="https://fwdform.herokuapp.com/user/<token>" method="post">
Email: <input type="text" name="name"><br>
Name: <input type="text" name="email"><br>
Message: <textarea name="message" cols="40" rows="5"></textarea>
<input type="submit" value="Send Message">
</form>
With a couple of extra seconds you can spin up your own instance on Heroku.

How to architecture a webapp using jquery-mobile and knockoutjs

I would like to build a mobile app, brewed from nothing more but html/css and JavaScript. While I have a decent knowledge of how to build a web app with JavaScript, I thought I might have a look into a framework like jquery-mobile.
At first, I thought jquery-mobile was nothing more then a widget framework which targets mobile browsers. Very similar to jquery-ui but for the mobile world. But I noticed that jquery-mobile is more than that. It comes with a bunch of architecture and let's you create apps with a declarative html syntax. So for the most easy thinkable app, you wouldn't need to write a single line of JavaScript by yourself (which is cool, because we all like to work less, don't we?)
To support the approach of creating apps using a declarative html syntax, I think it's a good take to combine jquery-mobile with knockoutjs. Knockoutjs is a client-side MVVM framework that aims to bring MVVM super powers known from WPF/Silverlight to the JavaScript world.
For me MVVM is a new world. While I have already read a lot about it, I have never actually used it myself before.
So this posting is about how to architecture an app using jquery-mobile and knockoutjs together. My idea was to write down the approach that I came up with after looking at it for several hours, and have some jquery-mobile/knockout yoda to comment it, showing me why it sucks and why I shouldn't do programming in the first place ;-)
The html
jquery-mobile does a good job providing a basic structure model of pages. While I am well aware that I could have my pages to be loaded via ajax afterwards, I just decided to keep all of them in one index.html file. In this basic scenario we are talking about two pages so that it shouldn't be too hard to stay on top of things.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<link rel="stylesheet" href="libs/jquery-mobile/jquery.mobile-1.0a4.1.css" />
<link rel="stylesheet" href="app/base/css/base.css" />
<script src="libs/jquery/jquery-1.5.0.min.js"></script>
<script src="libs/knockout/knockout-1.2.0.js"></script>
<script src="libs/knockout/knockout-bindings-jqm.js" type="text/javascript"></script>
<script src="libs/rx/rx.js" type="text/javascript"></script>
<script src="app/App.js"></script>
<script src="app/App.ViewModels.HomeScreenViewModel.js"></script>
<script src="app/App.MockedStatisticsService.js"></script>
<script src="libs/jquery-mobile/jquery.mobile-1.0a4.1.js"></script>
</head>
<body>
<!-- Start of first page -->
<div data-role="page" id="home">
<div data-role="header">
<h1>Demo App</h1>
</div><!-- /header -->
<div data-role="content">
<div class="ui-grid-a">
<div class="ui-block-a">
<div class="ui-bar" style="height:120px">
<h1>Tours today (please wait 10 seconds to see the effect)</h1>
<p><span data-bind="text: toursTotal"></span> total</p>
<p><span data-bind="text: toursRunning"></span> running</p>
<p><span data-bind="text: toursCompleted"></span> completed</p>
</div>
</div>
</div>
<fieldset class="ui-grid-a">
<div class="ui-block-a"><button data-bind="click: showTourList, jqmButtonEnabled: toursAvailable" data-theme="a">Tour List</button></div>
</fieldset>
</div><!-- /content -->
<div data-role="footer" data-position="fixed">
<h4>by Christoph Burgdorf</h4>
</div><!-- /header -->
</div><!-- /page -->
<!-- tourlist page -->
<div data-role="page" id="tourlist">
<div data-role="header">
<h1>Bar</h1>
</div><!-- /header -->
<div data-role="content">
<p>Back to home</p>
</div><!-- /content -->
<div data-role="footer" data-position="fixed">
<h4>by Christoph Burgdorf</h4>
</div><!-- /header -->
</div><!-- /page -->
</body>
</html>
The JavaScript
So let's come to the fun part - the JavaScript!
When I started to think about layering the app, I have had several things in mind (e.g. testability, loose coupling). I'm going to show you how I decided to split of my files and comment things like why did I choose one thing over another while I go...
App.js
var App = window.App = {};
App.ViewModels = {};
$(document).bind('mobileinit', function(){
// while app is running use App.Service.mockStatistic({ToursCompleted: 45}); to fake backend data from the console
var service = App.Service = new App.MockedStatisticService();
$('#home').live('pagecreate', function(event, ui){
var viewModel = new App.ViewModels.HomeScreenViewModel(service);
ko.applyBindings(viewModel, this);
viewModel.startServicePolling();
});
});
App.js is the entry point of my app. It creates the App object and provides a namespace for the view models (soon to come). It listenes for the mobileinit event which jquery-mobile provides.
As you can see, I'm creating a instance of some kind of ajax service (which we will look at later) and save it to the variable "service".
I also hook up the pagecreate event for the home page in which I create an instance of the viewModel that gets the service instance passed in. This point is essential to me. If anybody thinks, this should be done differently, please share your thoughts!
The point is, the view model needs to operate on a service (GetTour/, SaveTour etc.). But I don't want the ViewModel to know any more about it. So for example, in our case, I'm just passing in a mocked ajax service because the backend hasn't been developed yet.
Another thing I should mention is that the ViewModel has zero knowledge about the actual view. That's why I'm calling ko.applyBindings(viewModel, this) from within the pagecreate handler. I wanted to keep the view model seperated from the actual view to make it easier to test it.
App.ViewModels.HomeScreenViewModel.js
(function(App){
App.ViewModels.HomeScreenViewModel = function(service){
var self = {}, disposableServicePoller = Rx.Disposable.Empty;
self.toursTotal = ko.observable(0);
self.toursRunning = ko.observable(0);
self.toursCompleted = ko.observable(0);
self.toursAvailable = ko.dependentObservable(function(){ return this.toursTotal() > 0; }, self);
self.showTourList = function(){ $.mobile.changePage('#tourlist', 'pop', false, true); };
self.startServicePolling = function(){
disposableServicePoller = Rx.Observable
.Interval(10000)
.Select(service.getStatistics)
.Switch()
.Subscribe(function(statistics){
self.toursTotal(statistics.ToursTotal);
self.toursRunning(statistics.ToursRunning);
self.toursCompleted(statistics.ToursCompleted);
});
};
self.stopServicePolling = disposableServicePoller.Dispose;
return self;
};
})(App)
While you will find most knockoutjs view model examples using an object literal syntax, I'm using the traditional function syntax with a 'self' helper objects. Basically, it's a matter of taste. But when you want to have one observable property to reference another, you can't write down the object literal in one go which makes it less symmetric. That's one of the reason why I'm choosing a different syntax.
The next reason is the service that I can pass on as a parameter as I mentioned before.
There is one more thing with this view model which I'm not sure if I did choose the right way. I want to poll the ajax service periodically to fetch the results from the server. So, I have choosen to implement startServicePolling/stopServicePolling methods to do so. The idea is to start the polling on pageshow, and stop it when the user navigates to different page.
You can ignore the syntax which is used to poll the service. It's RxJS magic. Just be sure I'm polling it and update the observable properties with the returned result as you can see in the Subscribe(function(statistics){..}) part.
App.MockedStatisticsService.js
Ok, there is just one thing left to show you. It's the actual service implementation. I'm not going much into detail here. It's just a mock that returns some numbers when getStatistics is called. There is another method mockStatistics which I use to set new values through the browsers js console while the app is running.
(function(App){
App.MockedStatisticService = function(){
var self = {},
defaultStatistic = {
ToursTotal: 505,
ToursRunning: 110,
ToursCompleted: 115
},
currentStatistic = $.extend({}, defaultStatistic);;
self.mockStatistic = function(statistics){
currentStatistic = $.extend({}, defaultStatistic, statistics);
};
self.getStatistics = function(){
var asyncSubject = new Rx.AsyncSubject();
asyncSubject.OnNext(currentStatistic);
asyncSubject.OnCompleted();
return asyncSubject.AsObservable();
};
return self;
};
})(App)
Ok, I wrote much more as I initially planned to write. My finger hurt, my dogs are asking me to take them for a walk and I feel exhausted. I'm sure there are plenty things missing here and that I put in a bunch of typos and grammer mistakes. Yell at me if something isn't clear and I will update the posting later.
The posting might not seem as an question but actually it is! I would like you to share your thoughts about my approach and if you think it's good or bad or if I'm missing out things.
UPDATE
Due to the major popularity this posting gained and because several people asked me to do so, I have put the code of this example on github:
https://github.com/cburgdorf/stackoverflow-knockout-example
Get it while it's hot!
Note: As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
I'm working on the same thing (knockout + jquery mobile). I'm trying to write a blog post about what I've learned but here are some pointers in the meantime. Remember that I'm also trying to learn knockout/jquery mobile.
View-Model and Page
Only use one (1) view-model object per jQuery Mobile-page. Otherwise you can get problems with click-events that are triggered multiple times.
View-Model and click
Only use ko.observable-fields for view-models click-events.
ko.applyBinding once
If possible: only call ko.applyBinding once for every page and use ko.observable’s instead of calling ko.applyBinding multiple times.
pagehide and ko.cleanNode
Remember to clean up some view-models on pagehide.
ko.cleanNode seems to disturb jQuery Mobiles rendering - causing it to re-render the html. If you use ko.cleanNode on a page you need to remove data-role’s and insert the rendered jQuery Mobile html in the source code.
$('#field').live('pagehide', function() {
ko.cleanNode($('#field')[0]);
});
pagehide and click
If you are binding to click-events - remember to clean up .ui-btn-active. The easiest way to accomplish this is using this code snippet:
$('[data-role="page"]').live('pagehide', function() {
$('.ui-btn-active').removeClass('ui-btn-active');
});

SiteFinity 4.0: Trouble Accessing Postback Data in Custom User Control

I'm trying to get a highly customized hand built form into sitefinity 4.0 and my problem is that no matter what I do I can't access the form's postback data in the code behind. My form is a user control and I've added it in the way described here:
http://www.sitefinity.com/40/help/developer-manual/controls-adding-a-new-control.html
After struggling for several hours, I created a basic test form and I'm still not able to access the postback data. I've also tried adding EnableViewState="true" all over the place but the form data is still empty on postback. The exact same user control runs and posts data perfectly outside of sitefinity. I also tried other methods of accessing the postback data and I discovered that Request.Form does contain the data I need. I'd still love to access my form elements in the usual way though, so I don't have to do Request.Form for every control on the page and loop that way, which seems really hokey.
Here's the code for the basic form:
"BasicUserControl.ascx"
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="BasicUserControl.ascx.cs" Inherits="SitefinityWebApp.UserControls.Assessments.BasicUserControl" EnableViewState="true" %>
<div id="assessmentDiv" runat="server">
<asp:TextBox ID="TextBox1" runat="server" clientidmode="Static" enableviewstate="true"></asp:TextBox>
<asp:Literal ID="Literal1" runat="server" clientidmode="Static" enableviewstate="true"></asp:Literal>
<asp:Button ID="Button1" runat="server" Text="Button" />
</div>
"BasicUserControl.ascx.cs" Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SitefinityWebApp.UserControls.Assessments
{
public partial class BasicUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
Literal1.Text = TextBox1.Text;
}
}
}
}
Again, if I add the control via the method described at the link above, I am able to successfully create a Sitefinity 4.0 CMS page, drag the control onto it, run the page, step into the code behind using the debugger, yet when VS2010 reaches the line below there is no form data being posted:
Literal1.Text = TextBox1.Text;
FYI: The reason why there is no form tag in my usercontrol.ascx code above is because I get an error when running the form thru sitefinity that only one server-side form tag can exist on a .net page (sitefinity injects it's own form tag).
Thanks in advance for your help!
Ben
Never mind - I figured it out. For some reason, data isn't available at the Page_Load stage of the .net page lifecycle in a sitefinity form submission (at least not via a custom user control). If I wait until the Page_PreRender stage to retrieve the data from the form on the page, it's all there.
My current prevailing theory is that Sitefinity 4.0 grabs the postback data when a form submits and hasn't finished monkeying around with it at the Page_Load stage, so you have to wait until the Page_PreRender stage before sitefinity has injected the data back into the page cycle.
I had the same issue you did and came to the same solution. Spent a bunch of time on it - wish this answer had been around then.
Try adding enableviewstate into masterpages. I had the same situation and solved with this.
Also checked "enable view state" when creating pages.
Hope this help.
`<%# Master Language="C#" AutoEventWireup="true" CodeFile="HomePageClubManavgat.master.cs" Inherits="App_Master_HomePageClubManavgat" EnableViewState="true" %>
<script type="text/C#" runat="server">
protected override void OnInit(EventArgs e)
{
this.Page.EnableViewState = true;
base.OnInit(e);
}
`

Reload MVC2 user control with jQuery

I know I've had a ton of questions today, but still trying to get everything under control learning MVC 2 tie right way. Before I get into the question I already tried the solution offered here but I get an 500 internal server error.
So here's what I'm trying to do, I give the user the ability to select from a list of skills (loaded in a ListView user control) or add a new one to the list and select that. The adding new one is completed (using a WCF service & jQuery) but now I'm trying to reload the skills user control.
According to the solution I linked to I added an action to my AccountController
public ActionResult GetSkillControl()
{
return View("~/Views/Shared/SkillsListView.ascx");
}
I have the control inside a span (so it has a container)
<tr>
<td style="vertical-align:top;"><label for="SkillsListView" title="Skills">Skills:</label></td>
<td class="regElements"><span id="SkillListViewContainer"> <% Html.RenderPartial("SkillsListView"); %></span><%= Html.ValidationMessageFor(m => m.Skills, "*")%><br />
<span id="AddSkillError"></span>
Add: <input type="text" id="NewSkill" class="inputbox" style="width:75px;" /> <input type="button" value="Add" id="AddSkill" name="AddSkill" /></td>
<td></td>
</tr>
And in my jQuery ajax call I have
success: function () {
$('#SkillListViewContainer').load('../AccountController/GetSkillControl');
}
It's when it reaches that point that the JavaScript console in Chrome shows it returns a 500 internal server error. What am I missing here?
Based on the standard routes in ASP.NET MVC, try "/Account/GetSkillControl". Anything you use from jQuery's load method must be a valid URL. The route engine is looking or Account and not AccountController. Also by using the leading "/" it will resolving from the root of the site.