A similar question was asked here in storing information in a given html element.
I'm still green to jQuery, but I'm looking for the best way to store information on the page. I have a Repeater that holds one image per item. These images are clickable and can fire a given jQuery event. The issue I'm having is, the objects that the Repeater is bound to holds some specific information(such as "Subtext", "LargerImage", etc) which I would like to be accessible from the page.
Core/Data in jQuery accomplishes this just fine, however we would still need to build the jQuery statement from C#, as all the data is stored on the server. To clarify a bit, this is storing information on the page from a database, which is a bit different than arbitrary information being made available through jQuery.
I'm not restricting this question to "how to bind a custom attribute to an element", because I did come across an idea of generating a JS Struct from the C# codebehind to store information, but I'm avoiding any code generating code scenarios(or trying to).
Custom Attributes from HTML5(ie, "data-subtext") are also a possibility as I can easily add those from the itemdatabound event:
sampleImageElement.Attributes.Add("data-subtext", "And this what the image is about");
I'm a bit confused on browser support for this specific attribute though, or if it is even best practice so early in the game. If custom attributes are the way to go, that's an easy change to make happen. If jQuery can accomplish the same, I'd love to be pointed that way at least for my own understanding.
Any thoughts are greatly appreciated.
I'm answering this question only for the record keeping purposes of stackoverflow, as this is the solution I've moved forward with for this scenario. An AJAX call is completely warranted for any larger datasets and is a direction I would definitely go otherwise.
I went ahead with the "data-" field in the HTML5 spec, provided by the jQuery meta-data plugin.
I'm wrote a short extension method on the Web.UI.AttributeCollection class called "AddMetaData", which accepts an IList as well as a string "Key" to ease the attachment to a given page element.
I'm not marking this as the answer just yet, as there might be some community feedback on my own direction.
To clarify what happens in ASP.NET, once the page is served to the client, the objects that the Repeater is bound to on the server are destroyed and are then recreated upon each page postback.
It sounds like you want to achieve some kind of tooltip effect where the contents are retrieved from the server through AJAX? There are numerous different tooltip options available
jQuery Tooltip plugin
Random.Next()'s jQuery AJAX tooltip
dhtml goodies AJAX tooltip
clueTip
that can be used to do this. You could then set up a webservice or page method to retrieve the relevant data from your datasource.
Of course, you could have the content rendered in the HTML sent to the client when the request is processed and simply hide this markup. Then write your own plugin to display the markup in the form you require.
Related
I am on a C# .NET MVC project, and have a form that can dynamically add/remove n number of complex objects in a list. This complex object, for example represents a Person. This person has FirstName and Address properties.
When the user loads the page, all the People in the system are displayed in a list. When the user presses the 'add' button, two new text boxes show up for the Person's FirstName and Address properties. When the user presses the submit button, it will make a POST request to the server.
I know that you can write regular html in the View, and can use Javascript to add the new DOM elements for the FirstName and Address properties.
And with regards to when the user submits, I can use javascript to scrape all the data in the screen, and send a POST request to the server. Theoretically, another method is instead of using javascript, just make the button submit the form to the POST action of the controller; if I give my DOM elements the proper name attribute, the Action should recognize the data.
However, is there a MVC way of doing this? Maybe, with the help of Razor Helpers?
I am not sure what you are asking here; is it how to remove and add lists to your table or is it how to make a post?
I'll try to answer both:
1: Post without javascript:
Your assumption that you can post by naming the properties is correct! However, the page will have to reload if you want the new person in your table. Reading your description, I don't think this is really what you are looking for.
2: Add a row without javascript:
This cannot be done. You need javascript for this or a javascript framework which uses data-binding (there are a lot)
I would strongly advise you to make a decision on if a page reload is a deal-breaker or not for your solution. If it is, try to solve your issue with jQuery or better yet: investigate in javascript frameworks which use data-binding (knockoutjs, angular, react, etc...). There is a learning curve to these frameworks but they make your developer life so much easier and increase the maintainability of your code.
I am facing a pesky problem at the moment on a large website with multiple languages. On arrival at the website, it detects what country you are from and prompts you to confirm this. On confirmation, it swaps out the pages languages from the DB and displays the relevant language. This is done using jQuery. Now the problem is that Arabic reads rtl, so I need to either:
-- swap out the stylesheets for "rtl" version
or
-- change the HTML tag and include a "dir='rtl'" arrtribute
Now, I have tried both of these, with failures on both. When I view the page source, it still shows the old Css file or HTML tag without the "dir" attribute. Correct me if I'm wrong but I believe this to be due to the DOM not registering the new changes, as they have happened asynchronously via jQuery after the DOM has been instantiated.
After all that blah blah and tldr;
Is there not an easier way to swap out the text direction dynamically? If this is a DOM issue, how can I reload the DOM after the asynchronous callback?
I have been at this issue for hours now and have had very little luck on the interwebz.
Any and all help is welcome and greatly appreciated.
Kind Regards,
William Francis
EDIT:
After much investigation I found that the only way to truly work the Arabic way is with a post-back. Once the language has been selected you do a postback, then its just a simple process of changing the Stylesheet HREF attribute from code behind. There doesn't seem to be any form of JavaScript or jQuery that can change it without a post-back and still reflect the new Stylesheet. NOTE: you need to set the Stylesheet HREF on each post-back, i.e. through a master page. The Stylsheet changes do not persist across pages.
Here's a website that helped greatly and explains a whole lot on Stylesheet changes using JavaScript. sadly, it didn't work for me.
http://www.alistapart.com/articles/alternate/
There could be several things going on. I found this page to be very helpful when I was dealing with a similar thing, so I highly recommend it:
http://www.w3.org/International/tutorials/bidi-xhtml/
Also, if you aren't already doing so, use a tool like Firebug to examine the generated DOM after your AJAX has run to be sure you are seeing the altered state of the DOM and not the initial source of the page. It is possible to change the dir dynamically--you can use Firebug to add a new attribute to the HTML tag of this very page (set dir="rtl") to see it change dynamically. It could be some other element is overriding the direction, it could be that the AJAX changes aren't loading correctly, or other things. If you can post more of your code it would be helpful to give a better answer, but I hope this will help.
I wrote a page which user can input a name and get some infos from the database. In the .cs file I got the texts from the database and assigned them to the labels and in the debugging mode, the labels did change their texts. BUT I don't know how to update them in the same page. I used some ways to update the page, but it updated the whole page and display nothing in the labels.
How can I achieve this function?
I google it and found the AJAX is a good way, but it's an emergency i have no time to learn AJAX?
does someone have good idea to help me solve it?
Thanks a lot!
What you're talking about is a postback. When the page posts back to the server, the page is refreshed.
If you want to set the labels and avoid losing the data with a postback, you can do so through an ajax call in your JavaScript code, you can set hidden fields or you can set the values in the Session object (not the best idea). There are numerous ways around this; you just have to pick one.
Do some reading on ajax (it's not as hard as you think). You can call the server through ajax, which will get the data from the Db and return it to your JavaScript as JSON. You can then use that to fill your labels.
You may want to look into an UpdatePanel as well. They aren't the fastest solution available, but they are very easy to implement.
I have a page with a lot of dynamically generated check boxes on it. As the users click these check boxes a lot of content on the page changes dynamically via ajax. The end users are complaining that after hitting submit and then hitting the back button to change something, their selections are blown away and they have to do it all over again.
I have seen a few sites (gmail, facebook, etc...) use the hash symbol in the URL to hack the back button so that it performs AJAX calls instead of going back to the previous full page request. I would like to do this to modify the URL before the page submits so that hitting the back button will load their previously selected fields.
For instance:
In Gmail if I am viewing my inbox then my URL looks like this: https://mail.google.com/mail/?shva=1#inbox
Then if I click "Sent Mail" an AJAX call is performed and my URL is modified to look like this: https://mail.google.com/mail/?shva=1#sent
I really like this behavior and want to duplicate it. How is this accomplished?
Do your links actually trigger any javascript or do they just link to the URL with the appropriate hash symbol information?
How do you read in the hash symbol info in javascript?
How does this type of navigation affect search engines? Would a search engine know that two URLS that are the same except for the information after the hash are actually different URLs and index them as such?
What are some other pros and cons of this technique that I should take into consideration?
NOTE: I am using C# with ASP.NET Web Forms and ASP.NET MVC 3.0 in case that matters at all.
To manipulate hashtags, look at location.hash (javascript).
You'll also be interested in the new push/pop state stuff in HTML 5. https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history.
github has done some pretty cool things with this. Check out their blog entry on their tree slider feature at https://github.com/blog/760-the-tree-slider.
There's also the jQuery history plugin at http://tkyk.github.com/jquery-history-plugin/. (EDIT: I see Joe beat me to this one).
take a look at the jquery history plugin http://tkyk.github.com/jquery-history-plugin/ I have used it in the past, and it just might do what you want.
JQuery plugin:
http://tkyk.github.com/jquery-history-plugin/
Another jQuery library that I have used in the past:
jQuery BBQ: Back Button & Query Library
Also, a more scaled down version of the previous if you don't need all it's features and just gives you the hashchange event for all browsers:
jQuery hashchange event
NOTE: Just as a brief intro to the above libraries. The hashchange event is supported natively by newer(HTML5 supported) browsers in which case the scripts will just bind to that event. For older browsers that don't support that event, the script creates a polling loop to simulate the event. In either case you can bind to the event and handle appropriately.
EDIT: To answer your questions:
The links do not trigger javascript, links simply change the url with the hash. The hashchange event monitors this action, and when the hash changes(which is logged in browser history stack) the event fires.
location.hash is used to read the hash value, and any appropriate parsing you would need from that point.
Probably not SEO savvy enough to give you a complete answer on that, but fairly sure search engines DO NOT index hashes.
Pros for this technique is usability as your users will be able to properly use their back buttons. Also any history.back(0) javascript calls will also work properly(i don't like them but people use them). Cons are that as you're initially developing, you can get some quirky bugs depending on how your code is written. All in all though, I think with the use of the plugins much of the legwork has been taken out of the process and it is a great method for usability purposes.
I ran into this problem multiple times in my career, and never was able to find a elegant solution for it. Imagine you have a simple page, that has a repeater. You populate that repeater on the server-side through the databinding. That's great, works fast and does what it's supposed to. But now you want to add paginator to that repeater, or otherwise change the output. Doing it through Ajax is a preferred way to enable rich client interaction.
So you create a web-service that serves you the data as JSON, but now you are stuck... Either you have to write complicated client-side code to find each field that you need to modify in each repeater-item, or you have to blow away the whole server-side output of the repeater and construct new HTML from the scratch, or, the method that I've been using lately, take the first repeated item, blow away everything else and clone the first item as many time as you need to and modify it's fields.
All of the described methods are not optimal, because no matter what, they require quite a bit of repeated logic on the server-side (i.e. template in repeater) and on the client-side (javascript to display JSON data). There's got to be a better, easier way to do this. First thing that comes to mind, is instead of returning JSON from the web-server, return HTML of the pre-populated repeater. But for something like that, I might as well use ASP.NET AJAX Update panel. The output isn't going to be any smaller with a stand-alone web-service.
Next thing that I thought of, is JavaScript templates. What if there would be some way to take unprocessed repeater template on the server-side, and convert it to JavaScript template that could be either embedded on the page at load, or served as part of the web-service response. However, I couldn't find any existing solutions for something like this. And I can't think of a simple way to do that myself. Any ideas?
P.S. Rendering JavaScript template to the client-side on page load, and using JavaScript to populate it without the initial view being rendered on the server (no repeater and databinding) is out of the question. I care too much about performance.
Firstly, I don't believe that using client template with JSON data even on first load will adversely affect the performance unless we are talking about devices with different form factors such as phones etc.
However, if you must use server side templating/rendering then why not make server return the html for the repeater. This can be done by putting repeater logic into a different user control/page and processing only that page on ajax request. And this is not at all equivalent to using UpdatePanel (as stated by you) - UpdatePanel posts entire page data (including view-state) having more request size. The response size is also larges because it must contain the view-state. On server side also, use of UpdatePanel results in loading complete control tree with state data and post-back event processing. Sending only the requisite html is much better approach and will fit your needs perfectly - only issue is the html would be larger in size as compared to JSON.
Lastly, there are some interesting projects such as Script# - Script# converts C# code into java-script. You may build something similar (using script# itself) to convert the server side templating code into eqivalent JS code. More viable approach on similar lines could be use T4 templating to convert a technology-agnostic template into both server side code (markup + code or pure code) and equivalent JS-code.
After thinking about all pros and cons of different approaches, I stopped on the following method. I created a custom ASP.NET databound control, that can render HTML, however, when the page is requested with query string parameters, instead of just doing standard rendering, it will use Response.Clear() and Response.End() and in between of those two commands output JSON version of data based on the query string parameters. Also on the first rendering of the page, it will also output JavaScript template using reflections to read names of the variables from the control's template area.
This method works great, all I have to do, is drop my control on the page, data bind it, and it works as a true AJAX grid that supports pagination, sorting and filtering. However it does have limitation. In the control's template you can only specify variables, not expressions. Otherwise reflections can't convert it to a JavaScript variable. But I can live with that.
Other possibilities that I considered is a separate web-service that takes a type of the page as parameter and uses reflection to get data bound object as well as create template for the grid. I also though about writting my own version of update panel, that would not use view state and only send in part of the page.