So I have a page where I would like to be able to add multiple, dynamic users to a record in a database. Here's the rough start page:
<div id="records">
<div id="userRecord">
Name: <asp:TextBox runat="server" ID="objNameTextBox"></asp:TextBox> <br />
Phone Number: <asp:TextBox runat="server" ID="objPhoneNumberTextBox"></asp:TextBox> <br />
</div>
</div>
And the jquery:
$(function () {
$(".button").button().click(function (event) { addnew(); event.preventDefault(); });
})
function addnew() {
$('#userRecord').clone().appendTo('#records');
}
So my question is what do I use within ASP.NET to be able to poll all of the data in the form and add a unique record for each #userRecord div within the #records div? Yes - I should change the userRecord to a class - I will deal with that. This is just simple testing here.
Should I look in JSON for this type of function? I'm not familiar with it but could figure it out if that is indeed my best option. Thanks for the guidance!
You cannot duplicate ASP.NET web forms controls with Javascript, because the runtime keeps tracks of the controls in your HTML, if you try to duplicate them with Javascript, you duplicate the HTML and they may look the same, but ASP.NET won't know anything about them.
You could do it using an UpdatePanel, and triggering a post back in it with your button and create the controls in your backend programmatically and appending them to said panel, that would mimic what you are trying to do.
Another way would be creating HTML inputs and submitting the things to a web service, or a web method and do the actual insertions to the database there, but normal ASP.NET methods won't work on said inputs, as they are not controls as far as ASP.NET is concerned.
If you're trying to add new records during postback of the ASP.NET page, then ... good luck. I'm not sure you CAN add new 'items' to a list client-side. ASP.NET WebForms uses the view state (which is really just a big blob of information embedded directly in the HTML of the page that's returned to the user) to maintain the state of the page and I don't think you can easily (I'm sure it's theoretically possible) update the view state client-side (regardless of whether you're using jQuery or even JavaScript).
Maybe my own situation is similar enough. If I have a page with a list of items and I wish to allow the user to add new items, I'd add the appropriate input fields, as you've done, and add a special button for which I'd bind a JavaScript function (via jQuery) that makes an AJAX request to a web-service (another item in your Visual Studio project) and passes data back-and-forth using JSON (much simpler than using the default XML). That way the entire page doesn't need to be posted to the web server for the user to make changes to the backend data and you don't need to (somehow) parse the page data itself to determine what items need to be added to the database.
Related
I have a standalone webform (no masterpage) that opens in a div from another page. The standalone page uses jquery to move a user through a non-linear questionnaire. At the end of the questionnaire there is a result displayed with a "complete" button. When the user hits the complete button the result is sent back to the parent/host page of the div.
I have a new requirement where i need to actually pass the question and answer id's to code-behind or web service where i can insert the question and answer id's to my DB.
None of what i need to do requires object serialization. I want to do this as simply as possible.. none of the controls in the questionnaire are server controls.. just regular select boxes or radio button groups. I suppose i could do an ajax postback using an update panel or something but not sure if making the controls runat=server will screw up all the jquery/js i have working in the questionnaire.
Any help is appreciated thanks!
I would tackle this by using jQuery to post the data to a web service, which is fairly trivial. There's are a couple of code examples for doing this with asp.net here:
jQuery: Ajax call to asp.net webservice fails, server return 500 error
and
Calling a webservice through jquery cross domain
To answer your other question, putting runat="server" will not have an affect of jQuery's ability to parse the elements in the DOM.
I'm struggling with an issue I just can find a solution for.
First of all, I can't use asp.net AJAX or anything else thant standard asp.net 2.0 as the server admin won't install anything else.
So here is, what I try to do. (For the curious, skip to the bold question below)
My page consists of several parts, each of which gets loaded by jquery.load(url). One of these page parts gets filled with an aspx that contains a form view. As I don't want to have postbacks, I switch to the EditTemplate of the form view by a simple click on a regular html button that submits a parameter indicating the aspx page to switch to edit mode, e.g.
Page_Load(...)
{
if(Request.Params["SwitchEditMode"]) SwitchEditMode();
}
This works perfectly! Now here the part where I'm stuck. The elements in the EditTemplate are based on a select from a database view and bound to the fields by <%# Bind("xx"). Then I have a html button (no asp control) that submits a parameter to the aspx page that tells it to invoke the DataSource update method. In the dataSource_updating method I look for the controls that contain the values I want to save. But these values are always the same, as when I switch to the edit view. No changes I make in the textboxes or dropdowns are preserved.
A long story short, the question how to save the values from EditTemplate back to the database with jquery?
Up to now I tried several approches, that didn't work out.
In the updating() method look for the controls by FindControl and set e.Command.Parameter["xyz"] = foundcontrol.SelectedValue;. The values are always the same as in the beginning.
Set <asp:parameter name="SampleValue" /> and in the EditTemplate <asp:TextBox Value='<%# Bind("SampleValue")#> The values are always null.
Set a hidden input field with the selected value via javascript. This doesn't work as the control within EditTemplate are only visible after the switch into edit mode
So maybe I'm totally wrong with my ideas, heading into a totally wrong direction and this can be accomplished much easier, but up to now I don't know how to achieve this. I could do it without ajax, but for the user experience I'd prefer the version with jquery.
For all that have read this far and not got confused :-), thanks for your effort!
Best regards,
Andreas
I would forget using a form view and just use a regular html form with regular input controls. Return an object from your web service that has all of your values and populate the controls with ajax and then subjmit with ajax. Either do fully asp.net or fully html/jquery with asmx back end. Otherwise it's just too confusing.
If you load both "modes" of the FormView into the same page using AJAX, you're probably getting duplicate field names. One of them contains the unchanged values which are being saved. How will ASP.NET know the difference? You only want to submit the ones from the EditTemplate, which will require a separate form (or some other hack).
Or perhaps your HTML submit button isn't giving ASP.NET what it needs to repopulate the controls. Are you using ViewState in the page with the FormView?
All in all, this sounds like a hairy combination of technologies... as you well know.
I have in my webform many TBs bound to a property in the code behind:
<asp:TextBox ID="tbFirstName" Text="<%# Contact.FirstName %>" runat="server" />
<script language="c#">
public Contact Contact
{
get
{
return (Contact)ViewState["Contact"];
}
}
</script>
<script language="VB">
Public ReadOnly Property Contact() As Contact
Get
return ViewState("Contact");
End Get
End Property
</script>
While Contact is that property.
I want that when the user inserts text, it should immediately be bound to the Contact object e.g. when the user presses a key down or even when losing focus (TextChanged) would be good too.
Is there a way to do it dynamically (rather than manually retrieve the data from all the TBs and update the Contact object)?
I am actually willing to achieve two-way databinding with simple textboxes spread in the form body.
Note: I am not going to store the items to the DB of course, I just want the object (Contact) which resides in the state manager.
Do you realize you're talking about a web application? It's running in the users' browser. In order to update a database, you have to make a round trip to the server, either through AJAX or through a postback. Do you really want to do this for every keystroke?
From your comments, it's apparent that you aren't trying to write back to the database on every keystroke.
Still, data binding doesn't work this way. Data binding is a purely server-side action in ASP.NET. Even the two-way data binding afforded by the Bind method only works on a full postback (though I admit I haven't tried it with an UpdatePanel).
As an experiment, create a new page, and set up two-way databinding (see "Using the FormView for a More Flexible Data Modification User Interface" in An Overview of Inserting, Updating, and Deleting Data for an example). Once you get it working "normally", try putting the FormView into an UpdatePanel and see if the Bind still works. If so, see if you can get the UpdatePanel to fire on every keystroke.
Stop thinking like you are developing a desktop application! Because yo are not. The "Contact" object lives on the server while your textbox "lives" at the client, refreshing the server object would be very costly, you'll have to do async transfers between the server and the client with the new data, and doing it at so shorts intervals wouldn't even be possible. Thought you can add a delay on the textbox after which you would transfer the data to the server. Why would you ever need this?
I have a Repeater control that I bind server-side. It repeats a series of divs, and does so with no problem. I have some buttons that I use to sort the repeater (newest, highest ranked, random) and this works the way it should.
I would like to improve my user experience by making the buttons sort the divs using Ajax/jQuery somehow so that there is no page postback and the user does not lose his/her spot on the page.
Is there a way to use jQuery to access server-side code like this, or use Ajax to re-bind a server-side control?
Thanks... if I need to list more details, please let me know!
EDIT I'm aware of UpdatePanels, but I would prefer not to use them if I don't have to.
Have you considered moving the Repeater's functionality to the client-side?
Doing it that way, functionality like paging and sorting is not very difficult to add. In fact, you can lean on the framework pretty heavily by using ADO.NET data services as the service layer.
It's relatively easy.
Move your repeater to a separate custom control, let's say MyControl. Now repeater in your page becomes uc1:MyControl.
Wrap MyControl into a div:
<div id="mydiv">
<uc1:MyControl ID="MyControl1" runat="server" />
</div>
Create a new page, pgMyControl.aspx, that contains MyControl only.
On your main page, add jQuery handlers to your sort links. Use load method to dynamically replace div contents:
$('#link_sort_random').click(function()
{
$("#mydiv").load("pgMyControl.aspx&sort=random");
}
Use QueryStringParameter in datasource inside MyControl to change order. Or use Request.QueryString in code-behind file.
Using an updatePanel or a jquery Ajax postback are the same thing essentially. Both will ask your code to fetch the new query, then make your control render itself, and then feed the HTML back to the client as a partial page render, and then insert the content in place of the old content in the same DOM location.
It is considerably harder to make JQuery and ASP.NET talk to each other this way due to the nature of web controls and their lifecycle that determines when they render. An updatePanel knows how to call all this, maintain proper viewstate and return the result to the correct location.
In this case, don't make things any harder on yourself, use the updatePanel unless you have some very specific reason not to.
EDIT: If you're having JQuery issues with update panels it is probably due to the fact that new DOM nodes being created. JQuery has the live event to handle this. It will notice when new DOM elements are created and match them against your selector even after the document ready.
Maybe it's an OT, but you can consider to change the way you bind even the client and the server control, using XSLT transformation instead od the classics server controls.
You can find an example here (sorry, it's in italian...).
This question is similar to Forcing client ids in ASP.NET but not quite.
ASP.NET generates clientids according to its own internal mechanism. I would like to run a xmlhttprequest query in the background to do an update and selectively reload some of the controls. My plan is to run the query and regenerate the page in the background, but only selectively rendering the controls I want to update - then just replace the html of those controls with the new ones.
My question is, can I expect the clientids to be the same (since I'm generating the same page) and is there any thing else I need to be aware of if I want to update asp.net-generated html through javascript?
ASP.NET generates control names and ID's according to the position of the control in the page hierarchy.
If this hierarchy is not going to change between successive page regenerations,then you can be sure that the control ID generated will not differ. Another notable point is that control IDs have random names on each request when you use Fragment caching.
Another idea would be store the ClientIDs (available server-side) into hidden field(s) and then retrieve this information via script.
Whilst the system is predictable, it's ill-advised to build a dependency on these names as they are generated and it has the ability to create both a difficult maintenance burden and the possibility for some subtle bugs when your pages do change, which they will.
This is all part of the problem with working with asp.net generally, I suggest you find a more reliable way to target nodes, like targeting non-asp wrapper nodes and then looking at the children, or targeting classnames.
I use the following trick to get the ClientID of an ASP.NET control:
<script type="text/javascript">
//textBox will contain the DOM element rendered for the <asp:TextBox /> control
var textBox = document.getElementById("<%= nameTextBox.ClientID %>");
</script>
<asp:TextBox runat="server" ID="TextBox1" />