views:

39

answers:

4

Trying to ajaxify "favorite this song".

The way I understand it, it is desirable to separate javascript from the markup completely to an external .js file. However, we require to pass id of the song along with the ajax post.

We have the following markup

<div id="favorite-song"></div>

The way I would have done it using ASP.NET ajax inside the view

<div id="favorite-song"><%= Ajax.ActionLink("Make this your favorite", "FavoriteSong", new { id = Model.ID }, new AjaxOptions {...}) %></div>

When using jQuery, I attach the onclick event to #favorite-song to fire an ajax.post request. But how do I pass the song id, or post/route values in general, to the jQuery request?

Edit: To be more specific - How do we pass that Model.ID (which is the song id) to the javascript?


Edit2: So one way to accomplish this is to add that song id as part of the markup and fetch it from DOM in jQuery roughly this way:

<div id="favorite-song"><span id="SongID-<%= Model.ID %>"></span></div>

And then when doing the AJAX post in jQuery we get that span's id, remove the 'SongID-' from the front and voila, we have the song id.

Is there alternative/better way to do this?

A: 

Just give JQuery your route to post it to, the exact values will depend on your controller.

if you have something like

public class FoodController:Controller
{
    [HttpPost]
    public ActionResult FavoriteFood(int id)
    {
       ....
    }
}

then give JQuery the address of http://yoursite/Food/FavoriteFood/# (where # is the id of the food) to post to.

confusedGeek
Right, but don't we still need to somehow pass the id to JQuery? I know how to make a post with values in JQuery, but currently, I don't know how to access that Model.ID (the song id) from JQuery. EDIT: In order to construct the Food/FavoriteFood/foodID in JQuery, I need to get the foodID somewhere.
thenextwebguy
A: 

IF you do not specifically want the SongID portion for some other reason you CAN select via a relative reference to get the ID such as:

var songid = $('#favorite-song').find('span').attr('id');

OR to access that on a click:

<div id="favorite-song"><span id='mysongid'>Make this your favorite</span></div>

$('#favorite-song').click().find('span').attr('id');

OR more simply:

$('#favorite-song span').click().attr('id');

OR to get this like a "save" button:

$('#favorite-song span').click(function()
    {
      var mysongid = $(this).attr('id');
      $.ajax({
          url: "mypage.aspx/savesong",
          global: false,
          type: "POST",
          data: ({songid : mysongid }),
          dataType: "html",
          success: function(msg){
             alert(msg);
          }
       });
});

and in your ASPX page:

[WEBMETHOD]
savesong(string songid)
{
...

IF you DO need the SongID- for some reason, you can strip that either client or server side...up to you where.

Mark Schultheiss
A: 

if you have

<div id="favorite-song"></div>

As the selector to fire the event. Then

var id = $(this).attr("id");
//this will give you "favorite-song"
console.log(id);

or

var id = this.id;
//this will give you "favorite-song"
console.log(id);

Will provide you with the id of the item the user clicked, that matched the selector.

But I would change the selector to a class, and then use the id as a unique id, such as

 <div id="song_1" class="favorite-song"></div>

Then in the js-file use this

$(document).ready(function(){
    $(".favorite-song").live("click", get_song);
});

function get_song(){
   var id = $(this).attr("id").replace("song_", "");

   //this will give you 1       
   console.log(id);
}

So now you can pass the id to a serverside-script with AJAX using

var data = {};

data.id = id;

$.ajax({
    url: "/path",
    type: "POST",
    data: data,
    success: function(response){
        console.log(response);
    }
});
Stefan Konno
A: 

You can use the html5 data-* attributes to store extra data in a html tag. This works in all recent browsers.

<span data-songid="12345">

Using the method you described in your edit, you can easily get it using javascript, without the parsing. And you can provide more as one data- tag to one element.

// Get the songid
var songid = $(this).attr("data-songid");
GvS
Oooh! I very much like it, but Trident (IE) doesn't support datasets (source: http://en.wikipedia.org/wiki/Comparison_of_layout_engines_(HTML5)). So this is probably out of the question unless it's possible to emulate support for browsers lacking this feature by using some js library?
thenextwebguy
I use this all the time in IE (8). It's not supported, but you can add any attribute to any tag in IE, and query the value from it.
GvS