First of all, I have to mention that I am a newbie in the JavaScript and JQuery world. I am not sure if I put down an appropriate title for my question but I'll try my best to explain my problem.
Scenario: I have a list of items whose names are being displayed. When one of the items is being clicked, a popup should show up and display the description of the item. The description is retrieved from the server via an AJAX call upon the click. The AJAX call requires the unique id of the item (in the database) to be provided. Here comes my problem which has two parts:
I don't know how and where to include the item id in the HTML. Note that the list only displays item name not id.
Assume 1) is resolved, how can I pass the id of the item that's being clicked to the AJAX call.
This is the HTML of the list of items. As you can see, it illustrates part 1) of my problem (ie. don't know how to include the ids in the HTML).
<ul>
<li class="item">Item1</li> <!-- this item has id=1 in the database -->
<li class="item">Item2</li> <!-- this item has id=2 in the database -->
<li class="item">Item3</li> <!-- this item has id=3 in the database -->
</ul>
Below is the JQuery click event handler that sends the AJAX call (ie. getJSON) to the server. Note that the part 2) of the problem is illustrated by the line var item_id = ??. Note that popup is a self-defined javascript.
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$(".item").click(function() {
var item_id = ??
var data = {"item_id":item_id};
$.getJSON("/item/json", data, function(data) {
var name = data[0]["fields"]["name"]
var description = data[0]["fields"]["description"]
popup.call(this, name, description);
});
});
});
</script>
Additional Info: For the server side I use Django 1.3, and JQuery 1.5.2 for the client side.
I hope I have made my question clear and I appreciate any help from you experts. Thanks.
Here is an example that is similar to what I am looking for.
http://esdi.excelsystems.com/iseries400apps/exmain.pgm?wsname=DIALOG.pgm&wsnumb=214&wsprogtype=P
http://www.w3schools.com/tags/tag_li.asp
The < li > tag supports the following standard attributes:
id Specifies a unique id for an element
In this case use:
<ul>
<li class="item" id="item_1">Item1</li> <!-- this item has id=1 in the database -->
<li class="item" id="item_2">Item2</li> <!-- this item has id=2 in the database -->
<li class="item" id="item_3">Item3</li> <!-- this item has id=3 in the database -->
</ul>
And
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$(".item").click(function() {
var item_id = $(this).attr('id').replace('item_','');
var data = {"item_id":item_id};
$.getJSON("/item/json", data, function(data) {
var name = data[0]["fields"]["name"]
var description = data[0]["fields"]["description"]
popup.call(this, name, description);
});
});
});
</script>
Javascript (and jQuery in particular) are used for client-side scripting. As such, you will need to supply the data within the HTML document. You can use jQuery' Metadata plug-in to supply the item ID:
<li class="item" data="{ItemID: 'Your_Item_ID'}">Item1</li>
and retrieve it via:
var item_id_structure = $(this).metadata().ItemID;
If your item names are unique, then send the item names via Ajax.That way you can avoid Item ID's.
HTML5 natively supports data attributes that can be easily accessed with jquery
http://api.jquery.com/data/#data-html5
For example, given the following HTML:
<div data-role="page" data-last-value="43" data-hidden="true" data-options='{"name":"John"}'></div>
1
All of the following jQuery code will work.
$( "div" ).data( "role" ) === "page";
$( "div" ).data( "lastValue" ) === 43;
$( "div" ).data( "hidden" ) === true;
$( "div" ).data( "options" ).name === "John";
Related
I am generating a list from a template engine (Template7) and adding a userID to the data tag in each list item. For example
<li>
<a id='user' data-user-id='5'>
<div>content here</div>
</a>
</li>
<li>
<a id='user' data-user-id='6'>
<div>content here</div>
</a>
</li>
I am trying to get the "user-id" data of the list item clicked on using jQuery, but what I seem to be doing instead is getting the user-id of the first list item - in this case always 5.
$(document).on("touchend", "#user", function(e) {
e.preventDefault();
var userItem = $("#user");
var userID = userItem.data("user-id");
console.log(matchID);
});
Where am I going wrong? A unique ID for each item would work, but then it would need to be parsed etc so there must be a better way! Is there a best practice for this kind of thing?
try replacing #user with this should work in your case
Id selector always selects first element with matching Id. it is advisable not to have multiple element with same id. try to use class name instead.
any ways for your query you can use below code.
$(document).on("touchend", "#user", function(e) {
e.preventDefault();
var userID = $(this).data("user-id");
console.log(userID);
});
Use a css class on each anchor item, like this:
<li>
<a class='user' data-user-id='5'>
<div>content here</div>
</a>
</li>
Id attributes are meant to be unique to that element.
To get the content of the attribute **data-user-id** like in <a id='user' data-user-id='5'> you have to use
$(this).attr("data-user-id") // will return the string "5"
or .data() (if you use newer jQuery >= 1.4.3)
$(this).data("user-id") // will return the number 5
I am mapping the subjects object to the li element using knockout attribute mapping as given below.
<ul class="nav nav-pills nav-stacked" id="subjects">
<!-- ko foreach:Subjects -->
<li data-bind='attr:{"data-event":$data}'>
<a href="#" data-bind='text:subject_name + " by " + teacher_name;'>
</a>
</li>
<!-- /ko -->
</ul>
After that I have to access the subject object using the JQuery methods.
var originalEventObject = $(element).data('event');
Note: "element" is correctly here. The code is inside a loop and don't want to complicate the question by having full code here.
But always getting string as [Object Object] but not real JSON. Please help me on this.
Usually it's not good practice to access data such way. In case of drag & drop it depends is you clone element or not. But you can to this on drag start in case in you use clone. Just override "helper" function in draggable. And then put this data using jQuery if you need:
ko.dataFor
ko.contextFor
jsfiddler
$(function() {
var model = {
Subjects: [{text:'first'}, {text: 'second'}]
};
ko.applyBindings(model);
$('#result').text(JSON.stringify(ko.dataFor($('li')[0])));
});
I have a problem not sure how to reload a tab based on a selector in the previous tab.
My code for tab is here:
<ul class="nav nav-tabs">
<li class="active">
<a href="#addpropertypanel1" data-toggle="tab">
<s1>
<?php echo Jtext::_( 'ADDRESS');?>
</s1>
</a>
</li>
<li>
<a href="#addpropertypanel2" data-toggle="tab">
<s1>
<?php echo Jtext::_( 'GENERAL_INFORMATION');?>
</s1>
</a>
</li>
<li>
<a href="#addpropertypanel3" data-toggle="tab">
<s1>
<?php echo Jtext::_( 'OTHER_INFORMATION');?>
</s1>
</a>
</li>
<li>
<a href="#addpropertypanel4" data-toggle="tab">
<s1>
<?php echo Jtext::_( 'PHOTOS');?>
</s1>
</a>
</li>
</ul>
In my GENERAL INFORMATION Tab, there is a category selector to choose a value. This value chosen will affect the content in Tab OTHER INFORMATION.
I would like to know how can i reload OTHER INFORMATION tab only with information based on the selection chosen in GENERAL INFORMATION.
I am a very inexperience programmer, any assistance is very much appreciated.
Regards
JavaScript
You can use JavaScript (jQuery) to manipulate the links based on their contents.
See this example: JsFiddle
var myValue = '';
switch( $('a[href=#addpropertypanel2]').text() ) {
// put here your all cases that Jtext::_( 'GENERAL_INFORMATION') can offer
case "abc":
myValue = "new value 1";
break;
case "def":
myValue = "new value 2";
break;
case "GENERAL_INFORMATION": // just for example manipulation
myValue = "new value 3";
break;
}
$('a[href=#addpropertypanel3]').text( myValue );
PHP
You could also manipulate it with PHP by switching the output of Jtext::_( 'GENERAL_INFORMATION') before inserting it to the links. So insert the value that you want after the switch instead of Jtext::_( 'OTHER_INFORMATION')
You need to bind AJAX events for loading the desired information from PHP and injecting it into the tab.
A little step by step tutorial:
The data source:
In PHP you have to write some code, that echos the desired data when calling a new URL (something like http://www.your_domain.com/get_info) depending on POST or GET parameter. For this example I'd like to use GET parameter, which would result to http://www.your_domain.com/get_info?address_id=1 (1 is just an example id value)
The container:
Then in the HTML add a container into the tab for your data. It needs an id, so you can use it with JavaScript. Something like <li><s1><div id="general_information"></div></s1></li>
The event: Now you've got a data source (the new URL) and a destination (the container in the tab of your HTML), all you need to do is use some JavaScript to add the data from the source into the destination. But before you can bind an event to your <select>, you should give it an id, to ease the binding (something like <select id="addresses_select">). I would highly recommend using jQuery for the binding, because it's easy for new developers and it just works in all browsers. (To add jQuery to your page, simply add the following snippet into the <head> of your HTML: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>). When using jQuery you can use the following snippet for retrieving the desired data and injecting it into your HTML container.
jQuery event snippet:
$('#addresses_select').change(function(){
var selected_address_id = this.value;
$.ajax({
url: "/get_info?address_id=" + selected_address_id,
success: function(desired_data_from_php) {
$("#general_information").html("<p>" + desired_data_from_php + "</p>");
}
});
});
That should be all.
Good luck :-)
PS: in the following fiddle you can see how the event for the <select> works: http://jsfiddle.net/LyLHL/
I'm having a problem with JavaScript/jQuery at the moment where I'm trying to access the element inside the h4 element in my code. I'm doing this because I would like to dynamically display to the user how many guides are available in each "h4" section. For the PC section, it should display "4 reviews available" and for the Xbox One section, it should display "3 reviews available". However, both say " reviews available", and I'm assuming it's because I'm not using the jQuery functions properly. Here's the HTML code:
<h4><li class="console">PC (<span class="number"></span> reviews available)</li></h4>
<div class="gameList">
<ul>
<li class="game">Guide #1</li>
<li class="game">Guide #2</li>
<li class="game">Guide #3</li>
<li class="game">Guide #4</li>
</ul>
</div>
<h4><li class="console">Xbox One (<span class="number"></span> reviews available)</li></h4>
<div class="gameList">
<ul>
<li class="game">Guide #1</li>
<li class="game">Guide #2</li>
<li class="game">Guide #3</li>
</ul>
</div>
And here's the jQuery/JavaScript code:
$("h4").each(function() {
var node = $(this).children().children(); // gets node that has "number" class
var count = $(this).next().children().children().length; // gets number of li tags
node.innerHTML = count;
});
I tested whether or not it's properly getting the correct node and count by using the alert function for JavaScript, but for some reason, node.innerHTML = count won't display the contents of "content" properly in the element. Rather, it just displays a blank. Does anyone know why?
Its a jquery object not a DOM one..use this...
node.html(count);
node is a jQuery object here. It does not have "innerHTML". Instead you can use one of these:
node.html(count);
node.get(0).innerHTML = count;
node.get(0) will give you first DOM object from jQuery one.
A good practice is to prefix or suffix all jQuery objects with $ (e.g. $node), so that you will always know if a variable is meant to be a jQuery object.
use find() lot more cleaner and readable
$("h4").each(function() {
var $this=$(this);
var node = $this.find('.number');
var count = $this.next().find('li').length; // gets number of li tags
node.text(count); //or html()
});
and you have come invalid HTML li in h4 make sure you change that
working fiddle here
Do not use .children().children().
Only one .children() would do.
$(this).children('.game');
Also innerHTML is plain javascript. use .html(value) as node is JQuery Object.
$("h4").each(function() {
var node = $(this).children('.number');
var count = $(this).next().children('li').length;
node.html(count);
});
Reference to JQuery APIs:
.html()
.children()
$("h4").each(function() {
var $spanNumber = $('.console .number', this),
gameListCount = $(this).next().find('ul li').size();
$spanNumber.text(gameListCount)
});
You may use this also,
$("h4").each(function() {
var node = $(this).find('.number');
var count = $(this).next().find('.game').length;
node.html(count);
});
<div id="detailed">
#foreach (var item in Model.Result.Items)
{
<div id="movie_#(movie.UserMovieID)" class="movie border-gray">
<!-- Some html code -->
</div>
<script type="text/javascript">
new InitMovieWicket(#(MvcHtmlString.Create(movie.ToJSon())),"movie_#(movie.UserMovieID)");
</script>
}
</div>
I am getting list of movie objects from ASP.NET MVC server-side and generating html like above. As you can see , I am also initializing javascript wickets for each of these movies by using movies's JSON data and script tags.
I want to remove these script tags from html and javascript code to be unobtrusive but I dont know how to do that because for each movie to create wicket I need JSON data and without rendering time script tags I cannot see a way to do this. Do you have any idea ? Thanks..
Update
I want want my html code to look like this.
<div id="detailed">
#foreach (var item in Model.Result.Items)
{
<div id="movie_#(movie.UserMovieID)" class="movie border-gray">
<!-- Some html code -->
</div>
}
</div>
And I want my Javascript code to look like this.
$(document).ready(function() {
//init all movie wickets
});
A potentially better way, for users which don't have JavaScript enabled but still want to see movie details for each item, would be to actually render those details as HTML elements, and then hide them if JavaScript is available.
For example, you would render your HTML to look something like:
<div id="detailed">
<div id="movie_#1234" class="movie border-gray">
<div class="wicketData title">Some title</div>
<div class="wicketData year">Year</div>
<div class="wicketData synopsis">Some other stuff</div>
</div>
</div>
And then iterate through the elements and replace divs with anything you like:
$(doument).ready(function() {
// get the parent div
var $detailedParent = $("#detailed");
// get a list of all movie class divs
var $items = $detailedParent.find(".movie");
$.each($items, function(i) {
// get the movie div
var movie = $items[i];
// get all wicket data
var data = movie.find(".wicketData");
// prepare the JSON data using DOM
var movieData = {
title = data.children("title").text(),
year = data.children("year").text(),
synopsis = data.children("synopsis").text()
};
// remove or hide dummy elements
data.remove();
// init your wicket
new InitMovieWicket(movieData, movie.attr('id'));
};
});
This will allow users without JavaScript to get a bit degraded presentation, but all the data will still be there.
here's how I'd do it:
Put only one script tag in the <head></head> part where you initialize an JSON array with all the movies in it (on the server side) like:
var movies = '[{"userMovieID": "123", ...}, {"userMovieID": "432", ...}]';
when the document is ready, you should start building the widgets by first parsing the json array and then iterating through the array of movies, then create a Widget for every movie and insert
<div id="movie_#(movie.UserMovieID)" class="movie border-gray">
<!-- Some html code -->
</div>
to your <div id="detailed">..</div>, maybe you want to use Javascript Templates like jquery-tmpl
The best solution would be if your widget class "InitMovieWicket" creates the <div id="movie_"..>...</div> entry.