I'm reading data from a database and adding it to a table to be displayed on a webpage. The table that this data is added to lies inside a panel. To view this table I would have to use this Javascript to expand the panel:
<script type="text/javascript">
$(document).ready(function(){
$(".flip").click(function(){
$(".panel").slideToggle("slow");
});
});
</script>
To see where the class names flip and panel come from see below:
<div class="panel">
<table>
...
</table>
</div>
<p class="flip" onmouseover="this.style.color='red';this.style.cursor='hand'" onmouseout="this.style.color='black';this.style.cursor='pointer'"> VIEW TABLE </p>
Now, since I'm reading data from the database iteratively, the number of item in there could be anything.
How do I do this such that each has it's own identity, so that when I click on "VIEW TABLE" then each responds on its own. At the moment when I click on one, all expand and vice-versa, obviously because the share a common class name. I've tried to make sure that the class name be the entry id, but certain things break.
add to the element you want to fire the click event and send a refrence to it for example
the div will have on click event will look like this
<div onclick="MyFunction(this);"> </div>
in the function body recieve the object then reach to the element you want
function MyFunction(sender)
{
$(sender).//now you have the element and could reach to the parent or the child as you want
}
Use .prev() for your layout:
<script type="text/javascript">
$(function() {
$(".flip").live("click", function(){
$(this).prev(".panel").slideToggle("slow");
});
});
</script>
This will select the previous class="panel" to the class="flip" you clicked and slideToggle it. Also, since you may have any number of these handlers that will be the same, I suggest you use .live() like my example above, using 1 event handler instead of n event handlers.
Can you assign a new id for each 'panel' based on something in the db, or just with a sequential number? If so, then you could try this:
<div class="panel" id="panel_1">
<table>
...
</table>
</div>
<p class="flip" onClick="$(".panel_1").slideToggle("slow"); " ... >
<div class="panel" id="panel_2">
</div>
<p class="flip" onClick="$(".panel_2").slideToggle("slow"); " ... >
etc.
Making this assumption: You saying you have a new <div... for each new <p... and that the mouse over (or click) of the <p> should show the cooresponding <div>.
Try using this: for cooresponding instances.
$('.flip').click(function()
{
$('.panel').eq($(this).index()).slideToggle("slow");
});
Related
I am using jquery to implement some functionality that is repeated multiple place in the same jsp. I want to re-use the same jquery code again. Can anyone let me know how can I achieve that? Hope the below code snippet explain what I really want to achieve.
<div id="1" class="a">
//implement the some functionality to all the
elements that below to this class and id="1"
</div>
<div id="2" class="a">
//implement the similar functionality that is happening
int above div to all the elements that below to this class and id="2"
</div>
<div id="3" class="a">
//implement the similar functionality that is happening
int above div to all the elements that below to this class and id="2"
</div>
<script type="text/javascript">
//Re-usable code goes here that applies for class type 2 and tracks id 1,2,3 differently.
</script>
Edit
I want to use datatable at multiple places in the same html page and at each instance of the datatable used, I want to do similar customization using Jquery.
https://datatables.net/examples/
I think this is what you're after. When any element with id 1,2 or 3 is clicked, then it will execute the same function.
$(document).on('click', '#1, #2, #3', function (e) {
console.log(e.target); // This is the element that was clicked
alert('Clicked')
});
https://jsfiddle.net/cnLvk3o1/1/
If you want to select by class like A.Wolff has mentioned below. You can use this instead.
$(document).on('click', '.a', function (e) {
console.log(e.target); // This is the element that was clicked
alert('Clicked')
});
I am using jQuery to reveal an extra area of a page when a button is clicked.
The script is
$(document).ready(function() {
$("#prices").on('click', 'a.click', function() {
$(".hiddenstuff").slideToggle(1000),
$("a.click").toggleClass("faded");
});
});
Then the button is
Enquire or Book
and the newly revealed area is
<div class="hiddenstuff" style="display:none">
<!-- HTML form in here -->
</div>
The problem I have is that the button and "hiddenstuff" div are wrapped in a PHP while loop so they repeat anything between one and six times. When the user clicks on one of the buttons, all the hidden divs are revealed. I would like just the hidden div related to the clicked button to reveal.
I presume that I have to create a javascript variable that increments in the while loop and somehow build that into the script. But I just can't see how to get it working.
EDIT, in response to the comments
The while loop is actually a do-while loop. The code inside the loop is about 200 lines of PHP and HTML. That's why I didn't show it all in my question. In a shortened version, but not as shortened as before, it is
do {
<!-- HTML table in here -->
Enquire or Book
<!-- HTML table in here -->
<div class="hiddenstuff" style="display:none">
<!-- HTML form and table in here -->
</div>
<!-- More HTML in here -->
} while ($row_season = mysql_fetch_assoc($season));
EDIT 2
The final solution was exactly as in UPDATE2 in the reply below.
The easiest thing for you to do is to keep your onclick binding but change your hiddenstuff select. Rather than grabbing all the hiddenstuffs which you are doing now, you can search for the next one [the element directly after the specific button that was clicked].
$(this).next('div.hiddenstuff').slideToggle(1000);
UPDATE
i created a fiddle for you with what I would assume would be similar to the output from your php loop. one change from my early answer was rather than using next(), i put a div around each group as I would assume you would have and used .parent().find()
http://jsfiddle.net/wnewby/B25TE/
UPDATE 2: using IDs
Seeing your PHP loop and your nested tables and potentially complex html structure, I no longer thing jquery select by proximity is a good idea [be it by big parent() chains or sibling finds].
So I think this is a case for injecting your ids. I assume your table structure has an id that you can get from $row_season ( $row_season["id"] )
you can then place it in the anchor:
Enquire or Book
and the same for your hiddenstuff
<div class="hiddenstuff" data-rowid=" . $row_season['id'] . " style="display:none">
and then your js can find it easily
$(document).ready(function() {
$("#prices").on('click', 'a.click', function() {
var rowid = $(this).attr("data-rowid");
$(".hiddenstuff[data-rowid='" + rowid + "']").slideToggle(1000),
$(this).toggleClass("faded");
});
});
updated fiddle
If your structure is something like this:
<div class="container">
Enquire or Book
<div class="hiddenstuff" style="display:none">
<!-- HTML form in here -->
</div>
</div>
You can do your js like this:
$(document).ready(function() {
$("#prices").on('click', 'a.click', function() {
$(this).siblings(".hiddenstuff").slideToggle(1000),
$(this).toggleClass("faded");
});
});
which is similar to William Newby answer, but a close look at your while loop, I'd think you could do this:
$(document).ready(function() {
$("#prices").on('click', 'a.click', function() {
var index = $(this).index();
$(".hiddenstuff")[index].slideToggle(1000),
$(this).toggleClass("faded");
});
});
There are several ways of do it, I hope I was useful.
I am trying to create a to-do list using HTML/CSS, Javascript and JQuery. The problem I have occurs when I try to delete an item off the list. Here is the Javascript.
$(document).ready(function(){
$('#add').click(function(){
if($('#input').val() != '')
$('.container').append('<p class="todo">'+$('#input').val()+'</p><span class="del">×</span><br/>');
});
$(document).on('click','.del',function(){
$(this).click(function(){
$('.todo').hide();
});
});
});
The HTML
<body>
<h1 class="header">To-Do List</h1>
<hr/>
<br/>
<input type="text" id="input"/>
<button id="add">Add</button>
<br/>
<br/>
<div class="container">
</div>
</body>
What the above does is it removes all of the dynamically generated todo [paragraph] elements when a single del element [an x] is clicked. I am asking how to change the code so clicking the del element removes the todo element that it was generated with. I understand I can use ids but I feel that is too cumbersome. Thanks for the help.
You can use .prev() to hide only the immediate previous sibling .todo paragraph of clicked .del:
$('.container').on('click','.del',function(){
$(this).prev().hide();
});
Also take note that you don't need to use .click() event for .del any more since you've already using event delegation to attach the click event to them as well as using closest static parent for delegated event instead of $(document).
Try this jQuery, this also hides the 'x':
$(document).on('click','.del',function(){
$(this).hide();
$(this).prev().hide();
});
I've got a table row where it retrieves data from MySQL and I have included a .onclick function where it opens up a text editor with data inside, but the text editor is only opening for the first row and not the rest in the table.
This is the jQuery code: The first opens the text editor and the second switches the textarea for the text editor which is ckeditor.
<script type="text/javascript">
$(document).ready(function()
{
$(".trClass").click(function()
{
var id = $(this).attr('id');
$('#d_'+id).css("display", "block");
$('#table_id').css("display", "none");
});
});
window.onload = function()
{
CKEDITOR.replace("editor1");
};
</script>
and this here is echo for the table, I am using a foreach.
echo '
<tr class="trClass" id="'.$counter.'">
<td class="marker">
<i class="fa fa-align-left"></i>
</td>
<td class="title">
'.$article_title.'
</td>
<td class="content">
'.$article_content.'
</td>
</tr>
<section id="d_'.$counter.'" style="display:none;">
<textarea id="editor1">
<div style="width:468px;">
'.$article_content_full.'
</div>
</textarea>
</section>
';
$counter++;
}
I cannot figure out how to make the CKEDITOR.replace("editor1"); load for every table, I tried using .click function within it but it does not work as it doesn't load. Here is the problem, if you click on the first row it opens the text editor if you click on the second it does not; http://www.goo.gl/dQrLPN
Typically the id attribute should be unique for each element. Applying properties across multiple elements is usually accomplished with a class. Knowing this, CKEditor is probably just grabbing the first instance of an object with the given id (probably using document.GetElementById behind the scenes).
(According to the documentation, CKEDITOR.replace(var) will either take a DOM element, ID, or name.)
Given that, you have a couple of options. One is to defer loading the CKEditor until you actually click on the table row. This would look something like this... (note how each textarea has a unique id)
<section id="d_' . $counter . '" style="display:none;">
<textarea id="editor_'.$counter.'">
<div style="width:468px;">
'.$article_content_full.'
</div>
</textarea>
$(document).ready(function()
{
$(".trClass").click(function()
{
var id = $(this).attr('id');
$('#d_'+id).css("display", "block");
$('#table_id').css("display", "none");
CKEDITOR.replace('editor_'+id);
});
});
The second option would be to loop through all of the textarea elements and call replace on each one of them on-load. I wouldn't really recommend this, unless there's some specific reason you want to load everything up-front.
EDIT: Although this should fix your issue, you should look in to the HTML issues the other answerers have put forward. <section> doesn't belong as a child of <table> :-)
Try targeting the table and filtering by the rows using the .on() method.
$(document).ready(function()
{
$('#table_id').on('click','.trClass',function() {
var id = $(this).attr('id');
$('#d_'+id).css('display', 'block');
$('#table_id').css('display', 'none');
});
});
Details on .on() are here: https://api.jquery.com/on/
And as noted in the comments above, there are some overall issues with your HTML that you should probably fix before proceeding further.
I am handling a hyperlink's click event with a JavaScript function. I want to retrieve data from the hyperlink.
The page looks like this:
<div class="div1">
<div title="Title 1" class="div2">
<p class="p1"><a class="linkJs">The link in question</a></p>
</div>
</div>
<div class="div1">
<div title="Title 2" class="div2">
<p class="p1"><a class="linkJs">The link in question</a></p>
</div>
</div>
And the JavaScript something like this:
$(function() {
$('a.linkJs').click(function(){
value=$(this).parent().prev().text();
alert(value);
});
});
What I want to have is the value of the TITLE in the div2. By clicking the first link I get : Title 1. And by clicking on the 2nd: Title 2.
This must be very very basic but I just can't find my answer anywhere.
Thanks.
You want to use closest
var value = $(this).closest('div').attr('title');
Your problem is that the <p> tag is not a sibling to the <div> but a child, so you would have to do parent() twice - there's no need, though, as the closest function is a handy shortcut. Also, the text() function returns the pure text contents inside the tag, if you want the title attribute of the tag you need to use the attr function.
You can find it with the closest method:
$('a.linkJs').click(function(){
value=$(this).closest('div').attr('title');
alert(value);
});
try using the closest() method: http://api.jquery.com/closest/
Get the first ancestor element that
matches the selector, beginning at the
current element and progressing up
through the DOM tree.
$(function() {
$('a.linkJs').click(function(){
value=$(this).closest(".div2").attr("title");
alert(value);
});
});
var value = $(this).closest('.div2').attr('title');
Instead of using div, .div2 may be a more appropriate selector because there may be other div elements inside div.div2.
Not very pretty, but this should work too.
$(function() {
$('a.linkJs').click(function(){
value=$(this).parents()[1];
alert($(value).attr('title'));
});
});