Rails + Ajax - update view based on combo-box choice? - ruby-on-rails

Just a heads-up, I'm a total beginner as far as ajax is concerned and am just trying to find my way around it, so please bear with me :)
I have a View with a combo box in it (generated through a collection_select) and I display some data on the side of that form that essentially gives more details about the user's choice.
What I'd like to achieve is to be able to change that description on the side as soon as the customer makes a different selection in the combo. Basically, figure out what the current choice is, request data from the model, display returned data on the screen.
What's the simplest / most elegant way of achieving that? I think understanding the process would be a good launching ramp into the rest of the async View world for me.
Thanks!

I don't think ajax is necessary in this situation. Simply preload all the description values and store them in hidden divs:
<div class="description" id="choice1">
description for choice1 ...
</div>
...
Then hide them all:
// somewhere in your stylesheet
div.description {
display: none;
}
And finally on client side, bind to wanted events of the combo box:
// checkout documentation for other events, like select
$('some_id').change(function(data){
$('div.description').css('display', 'none');
var id = // get information about selected choice and figure out the id of description
$('div.description#' + id).css('display', 'block');
});
Chekout documentation for exact details but the main idea should be clear. In this way, you'll save yourself some unnecessary requests to your server.

Related

Refresh the browser once on load or clear DOM

I have a dynamic MVC4, jQuery Mobile application that works for the most part quite well. I have an auto posting dropdown list that selects a list from the database via the following code.
<script type="text/javascript">
$(function () {
$("#TownID").live('change', function () {
//$("#TownID").change(function () {
var actionUrl = $('#TheForm1').attr('action') + '/' + $('#TownID').val();
$('#TheForm1').attr('action', actionUrl);
$('#TheForm1').submit();
});
});
</script>
<p>
#using (Html.BeginForm("SearchTown", "Home", FormMethod.Post, new { id = "TheForm1" }))
{
#Html.DropDownList("TownID", (SelectList)ViewBag.TownId, "Select a Town")
}
</p>
The problem is it only works properly the first time a search is performed unless I click refresh. I don’t think this has anything to do with MVC, I think the problem is with AJAX and jQuery Mobile.
Edit:
The first time I search www.mysite.com/Home/Search/2 yields a result and woks fine, but the second time something seems to be left behind in the DOM??? and it looks for:
www.mysite.com/Home/Search/2/2 also
I get 404 errors in my log and “Error Loading Page” but it still finds the results and displays the page correctly!
Then with a third search I get the error 404’s in my log and “Error Loading Page” but it has grown and now looks for:
www.mysite.com/Home/Search/2/2
www.mysite.com/Home/Search/2/2/2 also
This then continues to grow after every search until at some seemingly random point on each test, it seems to give up and I get error 505
Additional Edit:
The code works perfectly if I take jQuery Mobile out of the question
Can anyone tell me what might be going on here?
Get rid of: $(function () {
And replace it with: $(document).delegate('[data-role="page"]', 'pageinit', function () {
Please read the big yellow sections at the top of this page: http://jquerymobile.com/demos/1.1.0/docs/api/events.html
You can't rely on document.ready or any other event that only fires once per page. Instead you have to get used to using jQuery Mobile's custom page events like pageinit so your code will work no-matter when the page is added to the DOM (which you don't know when this will happen in a jQuery Mobile website). There are a ton of events, so again, please read the documentation I linked-to above.
Firstly, dynamically generated html using a server side templating engine blows. I really don't understand what value people see in it.
My guess is that it used to make sense 10 years ago before AJAX became popular, and has just hung in there ever since because people have this feeling that it is "the right way to do it". It isn't. ESPECIALLY for mobile web apps.
Secondly, it looks like you are trying to do pretty simple search. All this MVC4 garbage makes it difficult for you to see what is really happening though. You don't need to append parameters to your URL for a simple form submission like this. In fact your TownId should already be part of the POST data when you submit, so you can just remove the URL modification bit.
Alternatively, don't use a form submission, but just a GET and AJAX. I don't know what your app is doing here, but I imagine you want to display the results on the page dynamically somehow, so a GET is more than enough.
Use your developer browser tools (F12) to see what exactly is getting submitted when you do the submit - it really helps. And for your next project, abandon MVC4! "Well established design patterns" my foot.
I have been bothered by this problem for a long time
There are same select element in the DOM I think so...
and I used $('.SelectCSS:last').val()
It seen work well.
I come from China , English is poor...
I guess this is one for the future, MVC and jQuery Mobile don't seem to blend completely right now. Maybe MS's response to the issue is Single Page Applications!
SPA may satisfy Danial also?

In a Rails app, how can I make a link load in a div as opposed to refreshing the whole page?

I'm still a beginner at web development. It's not my profession. So go easy.
I started building a rails app today, and realized it would make my application so much better if I could get certain links to display in a separate div instead of a new page, or refreshing the entire page. I'm not quite sure how to search for this, and I keep chasing red herrings with google.
Basically, I have a list in a div on the left side of the page, and when one item from that list is clicked, it should appear in the right div. (Nothing else on the page need be changed)
That's really as simple as it is. Do I need to use Javascript for this? Can I get away with the rails js defaults, or should I be using JQuery?
Is there a way to do this without javascript? I really just need a push in the right direction here, I'm tired of not even knowing how to search for this, or what documentation I should be reading.
Like I said, go easy, and you should just go ahead and err to the side of caution, and assume I know nothing. Seriously. :)
Thanks in advance,
-Kevin
(By the way, I'm developing with Rails 3)
Create your views (along with controllers) to be shown inside the div for each item on the left menu. Lets say we have the following structure now:
Item1 (Clicking on it will fetch:
http://myapp.com/item1)
Item2 (Clicking on it will fetch:
http://myapp.com/item2)
and so on...
make sure you only render the html to be put inside your content div. Should not include <head> <body> etc. tags
In your main page you may have your markup like this >
<div id="leftMenu">
Item 1
Item 2
</div>
<div id="content">
Please click on an item on the left menu to load content here
</div>
Finally, add the following Javascript (you'll need jQuery; trust me it's a good decision).
$("#leftMenu a").click(function () {
$("#content").load($(this).attr("href")); //load html from the url and put it in the #content element
return false; //prevent the default href action
});
You will need JavaScript if you want to avoid reloading the page. You can use link_to for links in your lists, and you'll need to use :remote => true to make it send AJAX requests to the server. The server will need to respond appropriately and supply HTML for your div.
link_to documentation is here: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to (and admittedly it isn't very useful for AJAX functionality).
The last post in this thread shows one possible solution you could use.

What is a good way to implement a data report grid on my MVC3 page

Before I start work I would like to get some ideas. What I have is an MVC3 page that I currently use to display rows of data. There are many rows so I would like to filter them. Ideally at the top of my page I would like to have a select drop down box and a refresh button with rows of data appearing below when the refresh button is clicked.
I can imagine doing this with Ajax and then having the data from my controller populate new HTML text between a DIV.
Does this sound like the best approach? I am not looking for a person to write code for me. Just want to be sure my solution sounds like a good way to go.
thank you
i recommend this approach:
http://geekswithblogs.net/michelotti/archive/2008/06/28/mvc-json---jsonresult-and-jquery.aspx
You can 'enchance' it with AJAX of course, but do not forget about users with disabled javascript. Make it work without client scripting, then enchance it, when its working.
I also think that you can simply create controller action, that is accepting parameters like pageNumber and amountOfItems. Then in your controls at page, you can just change values (number of page etc..) and use them in call for your controller action at form submit.

Generate URL client-side for jQuery Grid from json field?

We are using Struts 2 and want a jQuery Grid showing a list of accounts. When a user clicks an account we want to take them to a page specific to that account.
At this point I'm looking for suggestions as to the best way to do this. Currently I'm building a URL server side which I then return but this isn't optimal since I don't have access to <s:url>.
One idea I've had is to combine <s:url> and each row Id on the client side but I haven't found a way to do this. Is there a grid would that allow this? or a better way?
Updated Explanation Attempt:
I am returning a json list to jQuery grid. One column in the grid is a url but I can't build that in the service level. Instead I'd love to have a way to use <s:url> when my json results are returned. Is there anyway to do this?
You cannot use <s:url> client side.
The Struts2-Tags get used serverside
to generate the HTML, so there's
basically no difference if you
construct them yourself or let JSP
construct the HTML.
There's the struts2-jQuery Plugin and with it the jQuery grid plugin. Find out more about it here:
https://code.google.com/p/struts2-jquery/
If you know the actionName and have the ID in the list you're iterating over, you can just code the necessary link yourself (if the object in the list has a getter named getId()):
<a href="http://host:port/webapp/actionName?id=<s:property value='id' />">
Hope that helps, if not please show the code of the page and / or dredefine your question.
There isn't a really straight forward way. Here is the answer to "Struts2 URL buiilding in action for JSON" answered on the struts mailing list:
http://old.nabble.com/Struts2-URL-building-in-action-for-JSON.-td30487914.html
If you get a chance let me know how you implement this.

Is there a way to change the browser's address bar without refreshing the page?

I'm developing a web app. In it I have a section called categories that every time a user clicks one of the categories an update panel loads the appropriate content.
After the user clicked the category I want to change the browser's address bar url from
www.mysite.com/products
to something like
www.mysite.com/products/{selectedCat}
without refreshing the page.
Is there some kind of JavaScript API I can use to achieve this?
With HTML5 you can modify the url without reloading:
If you want to make a new post in the browser's history (i.e. back button will work)
window.history.pushState('Object', 'Title', '/new-url');
If you just want to change the url without being able to go back
window.history.replaceState('Object', 'Title', '/another-new-url');
The object can be used for ajax navigation:
window.history.pushState({ id: 35 }, 'Viewing item #35', '/item/35');
window.onpopstate = function (e) {
var id = e.state.id;
load_item(id);
};
Read more here: http://www.w3.org/TR/html5-author/history.html
A fallback sollution: https://github.com/browserstate/history.js
To add to what the guys have already said edit the window.location.hash property to match the URL you want in your onclick function.
window.location.hash = 'category-name'; // address bar would become http://example.com/#category-name
I believe directly manipulating the address bar to a completely different url without moving to that url isn't allowed for security reasons, if you are happy with it being
www.mysite.com/products/#{selectedCat}
i.e. an anchor style link within the same page then look into the various history/"back button" scripts that are now present in most javascript libraries.
The mention of update panel leads me to guess you are using asp.net, in that case the asp.net ajax history control is a good place to start
I don't think this is possible (at least changing to a totally different address), as it would be an unintuitive misuse of the address bar, and could promote phishing attacks.
This cannot be done the way you're saying it. The method suggested by somej.net is the closest you can get. It's actually very common practice in the AJAX age. Even Gmail uses this.
"window.location.hash"
as suggested by sanchothefat should be the one and only way of doing it. Because all the places that I have seen this feature, it's all the time after the # in URL.

Resources