I'm trying to implement a comment section and after button-press I want to update the comment section with ajax so the page doesn't have to refresh...
In this comment section I have 1 textarea + 1 button + a couple of hidden fields for every comment so users can answer specific comments...
so if there are 50 comments there are also 50 answer-fields, 1 for each...
And every thing works except for 1 thing...
- either I name all id's of the buttons and fields the same name (ie. id="sendAnswer" and id="answer", id="userID", ...) and then only the first one works...
-or I dynamically name them all (ie. id="sendAnswer(echo $i) ) thereby naming them all id="sendAnswer0", "sendAnswer1", "sendAnswer2", ... and then I do that for the textarea and hidden fields too (ie. id="answer(echo $i), id="userID(echo $i), ...)
And that works great too... except for now I have to make a jQuery-script for each... and since they are dynamically created that's difficult - as how many there are changes as more comments comes in...
Code for approach 1: naming them all the same...
$(document).ready(function(){
"use strict";
$("#sendAnswer").click(function(){
var comment = $("#comment").val();
var userID = $("#userID").val();
var randomStringVideo = $("#randomStringVideo").val();
var commentID = $("#commentID").val();
$.ajax({
type: "POST",
url:'../scripts/comment.php',
data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
success:function(){
$("#commentDiv").load(location.href + " #commentDiv>*", "");
$("#commentsDiv").load(location.href + " #commentsDiv>*", "");
$("#comment").val('');
}
});
});
});
And as I said... this works fine for the first one and the rest are duds...
Code for approach 2: I dynamically name all values...
$(document).ready(function(){
"use strict";
$("#sendAnswer"+$(this).val()).click(function(){ // this +$(this).val() doesn't work, only if I put #sendAnswer3 - then the 4th works and the rest are duds etc.
var comment = $("#comment"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
var userID = $("#userID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
var randomStringVideo = $("#randomStringVideo"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
var commentID = $("#commentID"+$(this).val()).val(); // works perfectly no matter what #sendAnswer I use
$.ajax({
type: "POST",
url:'../scripts/comment.php',
data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
success:function(){
$("#commentDiv").load(location.href + " #commentDiv>*", "");
$("#commentsDiv").load(location.href + " #commentsDiv>*", "");
$("#comment"+$(this).val()).val(''); // this +$(this).val() doesn't work, only if I put #comment3 (matching the #sendAnswer)- then the 4th works and the rest are duds etc.
}
});
});
});
With this I would have to name every single possible #sendAnswer-number + #comment-number for it to work... and with an infinite set of numbers to choose from 0-(infinite) - that's not viable...
If of any interest...
Php that dynamically creates the buttons and fields in question
.
.
.
<?php if ($_SESSION[numberOfComments] != 0) {
for ($i=0; $i<$_SESSION[numberOfComments]; $i++) ?> // run through all comments that aren't answers to other comments
// show comment info
<div class="media">// answer comment box starts here
<img class="mr-3 rounded" src="<?php $file = USER . $_SESSION['randomString'] . THUMBNAIL; if ( file_exists ( $file ) ) {echo $file; } else { echo USER . "default" . THUMBNAIL; } ?>" width="50" height="50" data-toggle="tooltip" data-placement="left" title="<?php echo $_SESSION['username']; ?>">
<div class="media-body">
<textarea class="form-control" rows="2" type="text" name="comment<?php echo $i; ?>" id="comment<?php echo $i; ?>" value="" placeholder="Great video!"></textarea>
<input type="hidden" name="userID<?php echo $i; ?>" id="userID<?php echo $i; ?>" value="<?php if ( isset ( $_SESSION['id'] ) ) { echo $_SESSION['id']; } ?>">
<input type="hidden" name="randomStringVideo<?php echo $i; ?>" id="randomStringVideo<?php echo $i; ?>" value="<?php echo $_GET['v']; ?>">
<input type="hidden" name="commentID<?php echo $i; ?>" id="commentID<?php echo $i; ?>" value="<?php echo $_SESSION['commentID_getComment']; ?>">
<button type="button" class="btn btn-primary float-right margin-top-5" id="sendComment<?php echo $i; ?>" value="<?php echo $i; ?>">
Answer
</button>
</div>
</div> // answer comment box ends here
<?php if ($_SESSION[numberOfAnswers][$i] != 0) {
for ($j=0; $j<$_SESSION[numberOfAnswers][$i]; $j++) { ?> // run through all answer to this comment
// show answer info
<?php }
}
}
} ?>
.
.
.
two ways .. 1st use classes instead of ids .OR. 2nd use selector id starts with [id^="something"] .. and on both ways you need to use $(this) to refer to the same section .. And for me its bad practice to use .load() to refresh the whole comment section you can directly get the specific comment and append it to the #commentDiv
by using $("#sendAnswer"+$(this).val()) $(this) in this case refer to nothing/window or something else but not to your element
$(document).ready(function(){
"use strict";
$('button[id^="sendAnswer"]').on('click',function(){
var ThisIs = $(this);
var ClosestDiv = ThisIs.closest('.media-body');
var comment = ClosestDiv.find('textarea').val();
var userID = ClosestDiv.find('[id^="userID"]').val();
var randomStringVideo = ClosestDiv.find('[id^="randomStringVideo"]').val();
var commentID = ClosestDiv.find('[id^="commentID"]').val();
$.ajax({
type: "POST",
url:'../scripts/comment.php',
data:"comment="+comment+"&userID="+userID+"&randomStringVideo="+randomStringVideo+"&commentID="+commentID,
success:function(){
var commentDiv = ThisIs.closest('.BigDiv').find('[id^="commentDiv"]'); // change `.BigDiv` with the div id/class which hold both commentDiv and comment section
commentDiv.load(location.href + " #commentDiv>*", "");
ClosestDiv.find('textarea').val('');
}
});
});
});
Note: Change .BigDiv with the div id/class which hold both
commentDiv and comment section
Using your current approach, where everything is identified with ids, the best option would be to use event delegation. Create just one event handler, on some parent element which exists at the time the page is loaded, which via delegation will handle any of your buttons - existing and future. Once the handler fires, you can determine which set of elements you are working with, and continue as normal.
Here's an example, using body as the parent, but you can use any element which contains all your present and future buttons/inputs, eg maybe you have a parent <div id="something">. This also assumes your button inputs are actual button elements, you'll have to adjust if that's not the case:
$(document).ready(function(){
"use strict";
// A single event handler on body, which handles any child button
$("body").on('click', 'button', function(event) {
// $(this) will be the button that was clicked. We can find its id,
// and if your buttons all have ids like sendAnswer1, sendAnswer2,
// sendAnswerX, we can find the X
var id = $(this).attr('id').replace('sendAnswer', '');
// Now we can use the X to access each of this button's matching
// inputs etc. Again this assumes your other elements have ids like
// commentX.
var comment = $("#comment" + id).val(),
userID = $("#userID" + id).val(),
// ... etc, rest of your code
As well as the article linked above, the jQuery .on() docs have a good description of event delegation (see "Direct and delegated events").
Update
Another option, which I find neater, is to wrap each comment section in a div (or any identifying element, such that each comment/input/button set is nested inside it), and use only classes for each element. Again using event delegation, you can find the section which contains the button that was clicked, and therefore identify which input elements you're working with.
For example, your HTML might look like:
<div id="all-comments">
<div class="comment-section">
<textarea class="comment" name="whatever"> ... </textarea>
<button name="button" type="submit">Post!</button>
<!-- your hidden fields, etc -->
</div>
<div class="comment-section">
...
</div>
<!-- ... etc, many comment sections -->
</div>
Now your JS would look something like this:
$(document).ready(function(){
"use strict";
// A single event handler on the parent div, which handles any child button
$("#all-comments").on('click', 'button', function(event) {
// $(this) will be the button that was clicked. We need to find the
// .comment-section containing that button
var div = $(this).closest('div.comment-section');
// Now we can find all elements inside that particular section
var comment = $(".comment", div).val(),
userID = $(".userID", div).val(),
// ... etc, rest of your code
Related
I am running queries in Wordpress that should return a customer's three most recent orders. When a user clicks on the "Change" button, it should open an order form with a "Save" and "Cancel" button.
My jQuery is only working on the first result of the query. When I click the "Change" button on the second and third entries, nothing happens.
I've tried doing a loop on the jQuery, but it still only applies to the first result, so I am thinking I need to attach a variable unique ID to "order_form" or request the jQuery to run three times.
Suggestions on what I should try?
function hgf_myhome_dash() {
foreach( array_combine( $menuid, $custom_field_data ) as $menuid => $custom_field_data ) {
$user_menu = json_decode( stripcslashes( $custom_field_data ) );
// The button
echo '<div id="change_button" style="float: left;">' . do_shortcode('[button]Change this menu[/button]') . '</div>';
// The loop
foreach( $user_menu as $single ){
if( $single->id ) {
echo get_post( $single->id )->post_title;
}}
// The form
echo '
<div id="form_show" class="modal">
<form id="order_form" action="" method="POST">
<div class="modal-content">
<div class="col_title"><h3>'.__('Current Menu' ,'rm_domain').'</h3>
<input type="button" id="cancel_button" class="cancel_menu" value="Cancel" />
<input type="submit" class="save_menu" style="" name="msubmit" id="msubmit" value="Save" />
</div>
I am text, hear me roar.
</div>
</form>
</div>
';
}
}
And here is my jQuery:
jQuery(document).ready(function($){
$("#order_form").hide();
$( function() {
$( "#change_button" ).on( "click", function() {
$("#form_show").css('display', 'block');
$("#order_form").show();
});
$( "#cancel_button" ).on( "click", function() {
$("#form_show").css('display', 'none');
$("#order_form").hide();
});
} );
});
The id attributes must be unique. You can’t have more than one tag with the same ID. When you have several elements with the same ID, the browser will ignore all the IDs except the first one.
So, only the first appearances of id="change_button", id="form_show", id="order_form", id="cancel_button" will be counted. Other tags will behave as if they don’t have IDs.
Instead of ID, you can use the class element, which doesn’t need to be unique, like this:
echo '<div class="change_button" style="float: left;">' . do_shortcode('[button]Change this menu[/button]') . '</div>';
Then, you need to change your selectors: the #change_button searches for the element with id="change_button", and .change_button searches for elements with class="change_button" (you can have several classes separated by spaces, like class="some_class change_button some_other_class", and .change_button will still work).
However, there is a rub: the selector will find all the elements with this class. So, $(".form_show").css('display', 'block'); will show all the forms with class="form_show", and clicking on any button will show all the forms. Which is not what you need.
So, your code needs to know which form is clicked, and select the correct one.
You can access the button you’ve clicked with this inside the click handler. Note that this would be a DOM element and not a jQuery object. To convert it into a jQuery object, you need to use $(this).
You can use jQuery functions on $(this) to get elements around the button. For example, the .next() function will return a jQuery object containing the next element. So, you could use $(this).next().show() to show the element after .change_button (which is the form).
However, I would advise agains using .next. It makes the JavaScript too dependent on the layout. The designer might need to add some other tags between the button and the form, and then you’d need to change your code.
Instead, you can add some data into the .change_button that will allow to identify the form that needs to be opened. For example, you can assign numbers to all your forms, and add that number to the .change_button.
To add custom data to any element, you can use data-something="any data". This is HTML5 tag for adding arbitrary data. It is very handy because it can be accessed by using $(this).data('something') in jQuery.
So, you can add unique index to your buttons, and add that index to your form. You can add unique index like this:
function hgf_myhome_dash() {
$index = 1;
foreach( array_combine( $menuid, $custom_field_data ) as $menuid => $custom_field_data ) {
$user_menu = json_decode( stripcslashes( $custom_field_data ) );
// The button
echo '<div class="change_button" data-index="' . $index . '" style="float: left;">' . do_shortcode('[button]Change this menu[/button]') . '</div>';
// The loop
foreach( $user_menu as $single ){
if( $single->id ) {
echo get_post( $single->id )->post_title;
}
}
// The form
echo '
<div id="form_show_' . $index . '" class="modal">
<form id="order_form_' . $index . '" action="" method="POST">
<div class="modal-content">
<div class="col_title"><h3>'.__('Current Menu' ,'rm_domain').'</h3>
<input type="button" class="cancel_menu cancel_button" value="Cancel" />
<input type="submit" class="save_menu" style="" name="msubmit" id="msubmit_' . $index . '" value="Save" />
</div>
I am text, hear me roar.
</div>
</form>
</div>
';
}
++$index;
}
Note that I’ve used class for change_button and cancel_button (because there might be several buttons with these classes), but I’ve kept id for form_show_{INDEX}, order_form_{INDEX}. This is because, when we add index, the IDs become unique (there will be only one form_show_1, only one form_show_2 and so on in the document), so we use id and not class.
N.B. IDs must be unique, so you can only call your function hgf_myhome_dash only once per page. If you call it more than once, your JavaScript will only work correctly for the first instance. If you want to call the function many times, you can use some global variable instead of $index — but then you probably need to rename it to something longer, to avoid name clashes.
Then, you can change your JS code like this:
jQuery(document).ready(function($){
$("#order_form").hide();
$( function() {
$( ".change_button" ).on( "click", function() {
var index = $(this).data('index');
$("#form_show_" + index).css('display', 'block');
$("#order_form_" + index).show();
});
$( "#cancel_button" ).on( "click", function() {
var index = $(this).data('index');
$("#form_show_" + index).css('display', 'none');
$("#order_form_" + index).hide();
});
} );
});
P.S. By the way, $menuid and $custom_field_data are not defined inside your function. Since it’s not a matter of your question, I assume you’ve removed some part of the code code. If not, you probably need to make them global, or to pass them via function arguments.
I am trying to pass the link's text as a value to the next page so I can use it to search the database for the item and retrieve the information related to the value .I have tried using the POST method but regardless the information is not passed. This is the code I tried .
<form action="DetailedMenu.php" method = "POST" action = "<?php $_PHP_SELF ?>">
<?php
for($i=0;$i<sizeof($array);$i++) {
if($array[$i]["Food_Category"]=="starters") {
echo str_repeat(' ', 4); ?>
<a href="DetailedMenu.php" ><?php echo $array[$i]["Food_Name"];?></a>
<?php echo " " .str_repeat('. ', 25). "€".$array[$i]["Food_Price"]."<br>"; ?>
<input type="hidden" name="name" value="<?php echo $array[$i]["Food_Name"];?>">
<?php
}
}
?>
</form>
You don't need the form.
The easiest way to do what you're trying to do....
In addition to including the text in the content of the link, include it as a query string parameter.
for($i=0;$i<sizeof($array);$i++) {
if($array[$i]["Food_Category"]=="starters") {
...
<?php echo $array[$i]["Food_Name"];?>
...
}
}
I would actually recommend something more like this. I obviously don't know the names of your fields, so I've just taken a guess...
for($i=0;$i<sizeof($array);$i++) {
if($array[$i]["Food_Category"]=="starters") {
...
<?php echo $array[$i]["Food_Name"];?>
...
}
}
You'll be able to access "FoodID" as a parameter within your PHP, just as you would if it had been submitted from a form.
You may be looking for AJAX. AJAX lets you send the form data to a back end PHP file (that can then insert data into a DB, and/or get data from the DB) without refreshing the page.
In fact, when you are using AJAX you don't even need to use a <form> structure -- simple DIVs work just fine. Then you don't need to use event.preventDefault() to suppress the built-in form refresh.
Just build a structure inside a DIV (input fields, labels, etc) and when the user is ready to submit, they can click an ordinary button:
<button id="btnSubmit">Submit</button>
jQuery:
$('#btnSubmit').click(function(){
var fn = $('#firstname').val();
var ln = $('#lastname').val();
$.ajax({
type: 'post',
url: 'ajax_receiver.php',
data: 'fn=' +fn+ '&ln=' +ln,
success: function(d){
if (d.length) alert(d);
}
});
});
ajax_receiver.php:
<?php
$fn = $_POST['fn'];
$ln = $_POST['ln'];
//Do your stuff
Check out this post and especially its examples. Copy them onto your own system and see how they work. It's pretty simple.
I have the following script :
<script type="text/javascript" >
$('form').each(function() {
$(this).on('submit', function() {
var first_firstname = $(".first_firstname", this).val();
var first_lastname = $(".first_lastname", this).val();
var second_firstname = $(".second_firstname", this).val();
var second_lastname = $(".second_lastname", this).val();
var TeamName = $(".TeamName", this).val();
var dataString = 'first_firstname='+ first_firstname + '&first_lastname=' + first_lastname +
'&second_firstname=' + second_firstname + '&second_lastname=' + second_lastname + '&TeamName=' + TeamName;
$.ajax({
type: "POST",
url: "data.php",
data: dataString,
success: function(){
window.setTimeout(function(data)
{
$('#propspectDiv').html('Team Name Added!');
$('#data').css("display","block");
$('#data').html(data);
}, 2000);
}
});
return false;
});
</script>
And the following php that generates a number of forms on a page using mysql database
<?php
echo '<table class="greensmalltbl" cellspacing="10px" cellpadding="5px"><div id="propspectDiv"></div>';
for ($i=1, $o=$totalEntrants; $i<=$half; $i++, $o=$o-1) {
$formid = $i;
echo "<div style='border:3px;'><form action='' method='post'>
<tr><td><input type='text' name='first_firstname' id='first_firstname' value='$firstName[$i]' />
<input type='text' name='first_lastname' id='first_lastname' value='$lastName[$i]' />
Skill Level : ".$skill[$i]."</td></tr>";
echo "<tr><td>WITH</td></tr>";
echo "<tr><td><input type='text' name='second_firstname' id='second_firstname' value='$firstName[$o]' />
<input type='text' name='second_lastname' id='second_lastname' value='$lastName[$o]' /> Skill Level ".$skill[$o]."</td></tr>";
echo "<tr><td>Enter Team Name : <input type='text' name='TeamName' id='TeamName' value='' />
<input type='submit' name='submit' value='Submit'></form></td></tr>";
}
echo '</table>';
?>
I want to update the db table with the TEAM NAME in each form
The problem is only the first forms input is passed all other forms do nothing
I have tried a number of variations to the ajax code but none have worked.
Can anyone find the problem here
This line will not return the form.
var parent = $(this).parent('form');
because your submit button is wrapped inside tr and td tags. Either get rid of those tags (they are invallid anyway, because your are not using them in a table), or update your code to:
var parent = $(this).closest('form');
closest() searches its way up to all the ancestors of an element, and will return the first match of the selector.
Check out the documentation here: http://api.jquery.com/closest/
Or, if you only have a single form in your page, you could just go:
var parent = $('form');
:: EDIT ::
OK. Forget all of the above. Seems like you are not even using the parent variable later in the code.
A more important problem is that even though you are catching the Click event on the form submit button, what you probably really want to do is catch the submit-event of the form.
So change your first line of code to this:
$('form').on('submit', function() {
Also, in your HTML, your code is invalid.
<form action'' method='post' id='$formid'>
action'' should be action = ''
Chances are this doesn't really fix your problem, because there might be more errors. Next time, try to validate your code before posting a question.
:: EDIT ::
Last edit, I promise. I quickly went trough your code again, and it seems you will have multiple forms. this means, that you will get elements in different forms with the same id's. An id should be unique for troughout the page. So when you try to get a value like this $("#second_firstname").val(); that won't work. because jQuery doesn't know what element you mean, so all elements that can appear multiple times in a page need to have a class and CAN NOT have an id.
You could then loop trough your forms by changing things to:
$('form').each(function() {
$(this).on('submit', function() {
var first_firstname = $(".first_firstname", this).val(); // . instead of # and use 'this' as context
// and so on..
// the rest of your code here.
}
});
table with forms can be seen here
My question might be quite easy for you guys, but it's hard for me...
I have a text field and I want to change its value between once <label id="some_id"> is clicked. Until what I've described now, I can do it myself with jQuery, but here comes the complex part (for me, obviously):
I have two values I want for that text field, and once that <label> is clicked, it switches to the value that isn't shown, but once we click it again, it goes back to the original text the text field contained.
I have to keep my jQuery/JS internal because I get the desired values from the database and I don't want to make my .js files .php.
This is what I got:
<label for="html" onclick="$('#html').val('<?php echo $image->convert('html_b', $image_data['image_link']); ?>')">HTML:</label>
<input type="text" id="html" value="<?php echo $image->convert('html_a', $image_data['image_link']); ?>" readonly />
It does the first part I need, changing the value of the field to the new value, but once that button gets clicked again, I want the original text.
Thank you.
You can compare its current value to the available possibilities.
<label id="toggle" for="stuff">I'm a label</label>
<input type="text" val="" name="stuff" id="stuff">
var possibilities = ["foo", "bar"];
$('#toggle').click(function(){
var old_val = $("#stuff").val(), new_val;
if (old_val == possibilities[0])
new_val = possibilities[1];
else
new_val = possibilities[0];
$("#stuff").val(new_val);
});
demo
First, don't use inline JavaScript.
You can use a combination of .toggle() and data-* attributes for this. For example, using a data-toggle attribute for the value you want to toggle with.
<label for="html" data-toggle="This is a placeholder">HTML:</label>
<input type="text" id="html" value="This is my real value" readonly>
$("label[for][data-toggle]").each(function() {
var $this = $(this);
var $for = $("#" + $this.attr("for"));
var originalValue;
$this.toggle(function() {
originalValue = $for.val();
$for.val($this.data("toggle"));
}, function() {
$for.val(originalValue);
});
});
See it here.
UPDATE #1
I added usage of for attribute of <label>.
UPDATE #2
If you don't want to use .toggle() due to the deprecation notice.
$("label[for][data-toggle]").each(function() {
/* cache */
var $this = $(this);
var $for = $("#" + $this.attr("for"));
var originalValue = $for.val();
/* state variable */
var which = 0;
$this.click(function() {
$for.val(which ? originalValue : $this.data("toggle"));
which = 1 - which;
});
});
See the non-.toggle() alternative here.
For doing this, on the first button click you need to store the current value of input in some variable and then on 2nd click you can assign that variable to input value. If you donot want to have js file, you can simply use <script></script> tags to write the jquery.
`<label id="label" onclick="replaceText('newvalue')">Click Mee</label>
<input id="html" type="text" value="some value">
<script>
var currentValue="";
function replaceText(newval){
currentValue= $("#html").val();
if(currentValue!=newval)
$("#html").val(newval);
$("#label").attr("onclick","replaceText('"+currentValue+"')");// Here we assigned the other value to label onclick function so that it will keep on toggling the content.
}
</script>`
DEMO HERE
You can store the values into JavaScript variables and use jQuery click method instead of onclick attribute.
var def = "<?php echo $image->convert('html_a', $image_data['image_link']); ?>",
up = "<?php echo $image->convert('html_b', $image_data['image_link']); ?>";
$('label[for=html]').click(function() {
$('#html').val(function(i, currentValue) {
return currentValue === def ? up : def;
});
});
i am using while loop to output data in
<p><?php echo $title;?></p></font></a><button id=show>show()</button> <button id=hide>hide()</button>
my show hide function is
$("#show").click(function () {
$("p").show('fast');
});
$("#hide").click(function () {
$("p").hide('fast');
});
$("#reset").click(function(){
location.reload();
});
now when i am clicking show hide only the first show hide loop is working and it shows/hides all the data not just the one i clicked
Change the code to use this, like so:
$(this).prev('p').show('fast');
You will need to do this in each JQuery .click section.
Edit:
Another good point which has been mentioned, you are using an ID for your element which won't allow this to work on more than one. Your new markup should look like:
<p><?php echo $title;?></p></font></a><button class="show">show()</button>
and the JQuery:
$(".show").click(function () {
$(this).prev('p').show('fast');
});
Welcome to SO. Nice to see that you have formated your first question nicely.
Few things you might want to change.
As you are going through a loop, make sure you use a counter inside the loop and add the counter to the id. This will make the id a unique identifier. Also wrap them inside a div.
$counter = 0;
forloop {
$counter++;
<div>
<p><?php echo $title;?></p></font></a><button id="show<?php echo $counter; ?>">show()</button>
</div>
}
So now your id will be unique.
Now you can write your jquery in the below way.
$("button").click(function () {
$(this).attr('id'); //not required but incase you need the id of the button which was clicked.
$(this).parent().find("p").show('fast');
});
$("button").click(function () {
$(this).parent().find("p").hide('fast');
});
Two things: 1. I think you can only have one element with one id, such as #show. If you want to reference more buttons, you should use a class, such as this: show() (as I understand the buttons are output in a loop, there will be more of them).
Second: inside your javascript code, you do $("p")... - this references all elements on the page. I think you should use $(this) and start from there, check out this article, it explains a lot: http://remysharp.com/2007/04/12/jquerys-this-demystified/
There are many ways to go at this. Here's one:
First, add the loop number to the IDs (let's say it's $i)
<p id="TITLE_<?php echo $i; ?>" style="display:none;"><?php echo $title;?></p>
<input type="button" class="show" data-number="<?php echo $i; ?>"/>
<input type="button" class="hide" data-number="<?php echo $i; ?>" />
Your functions will then be:
$(".show").click(function () {
$("TITLE_" + $(this).data('number')).show('fast');
});
$(".hide").click(function () {
$("TITLE_" + $(this).data('number')).hide('fast');
});
Of course there are ways to do it via JQUERY without the use of the $i.
Edit: To have the tags hidden on page load, either use the style=display:none as I have added in the tag above, or you can use JQuery as follows:
$(document).ready( function() {
$("p[id^=TITLE_]").hide();
// this will retrieve all <p> tags with ID that starts
// with TITLE_ and hide them
});