I recently learned that when using onclick, for a button, the field name and button id have to each be unique. While thats not a problem, depending on how many rows my script outputs, this could be a lot of waste.
For example, i have a while loop, it does this for each person on my server (minecraft), so it could be 10, it could be 50.
this is the code to create the js objects
$kickbtn .= " $('#kick_btn$k').click(function(event) {
var player_name$k = jQuery('input[name=\"player$k\"]').val()
jQuery.get('testing.php?action=kick', { player_input: player_name$k} );
alert('Successfully kicked');
});\n\n";
this is the form data
<form name=\"$pdata[name]\" action=\"\">
<input type=\"hidden\" name=\"player$k\" value=\"$pdata[name]\">
<input type=\"submit\" id=\"kick_btn$k\" value=\"Kick Player\">
</form>
$k++;
Is there an easier way to accomplish this without creating all this excess code?
The output is nice in the html, and it does work, just hoping theres something a little more dynamic i can do, and not so messy in the code. Below is from the parsed code and works and looks good.
$('#kick_btn14').click(function(event) {
var player_name14 = jQuery('input[name="player14"]').val()
jQuery.get('testing.php?action=kick', { player_input: player_name14} );
alert('Successfully kicked');
});
Only one delegated event handler is needed, which means attaching it to a parent/container element, unless you want 50+ click handlers in your document which will unnecessarily slow things down:
// bind to all elements starting with 'kick_btn' within #container
// (could even be 'body')
$("#container").delegate('[id^="kick_btn"]', "click", function(event) {
// get the current player number from the id of the clicked button
var num = this.id.replace("kick_btn", "");
var player_name = jQuery('input[name="player' + num + '"]').val();
jQuery.get('testing.php?action=kick', {
player_input: player_name + num
});
alert('Successfully kicked');
});
Reference:
http://api.jquery.com/attribute-starts-with-selector/
http://api.jquery.com/delegate/
Related
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
I have a a script that on click do a ajax call connect to the database get imagename and set the image name inside an < -img - > with the right path also it adds a hidden checkbox after it and then echo it.
i then take the ajax message returned and put it as div's HTML. my question is will i be able to preform more action on the inserted content..
The main goal is to be able to click on the image as if it were a checkbox(this part is already sorted for me) however no matter what i try i cant have a .click function works..
Here is the code.
This is the PHP part that echos the images.
if($_POST['updateIgallery'] == 'ajax'){
global $wpdb;
$table_name= $wpdb->prefix . "table_T";
$imagecounter = 1;
$toecho = '';
$currentselected = $wpdb->get_row("query");
preg_match_all('/\/(.+?\..+?)\//',$currentselected ['image_gal'],$preresualts); // images are stored with /image/.
foreach ($preresualts[1] as $imagename){
$toecho .= '
<img rel="no" id="JustantestID" class="JustaTestClass" src="'.site_url().'/wp-content/plugins/wp-ecommerce-extender/images/uploads/'.$imagename.'">
<input name="DoorIMGtoDeleteIDcheck'.$imagecounter.'" style="display:none;" name="DoorIMGtoDelete['.$imagecounter.']" value="/'.$imagename.'/" type="checkbox">
';
$imagecounter++;
}
echo $toecho;
}
This is the ajax part that send and receive and insert the HTML to the div:
$.ajax({
type: "POST",
url: "/wp-content/plugins/wp-ecommerce-extender/DB_Functions.php",
data: { updateIgallery: "ajax", CurrentDoorIDnum: $('#dooridforgallery').val()}
}).success(function(insertID) {
$("#ImgGalleryID").html(insertID);
});
This so far works what i am having trouble with is the following:
$("#JustantestID").click(function() {
//DoorImageGallery($(this).attr('id')); // the function i will use if the alert actually works
alert("kahdaskjdj");
return true;
});
I hope the question and the code is understandable.
Thanks in advanced.
When you replace element's html, all the elements inside it are removed and gone. That means the event handlers attached to them are removed as well.
You could try attaching an event handler to a higher level element that is static and permanent on your page. Without more info I am going to use document:
$(document).on( "click", "#yaniv", function() {
alert("kahdaskjdj");
});
$('img.JustaTestClass').bind('click', function() {
var checkbox = $(this).siblings('input[type=checkbox]');
if (!checkbox.is(':checked')) checkbox.attr('checked', true);
else checkbox.attr('checked', false);
});
Since the elements are dynamically inserted into the DOM with ajax, you have to delegate events to a parent element that actually exists when binding the click handler, which in this case looks to be #ImgGalleryID
$('#ImgGalleryID').on('click', '#yaniv', function() {
DoorImageGallery(this.id);
alert("kahdaskjdj");
});
See this form - http://schnell.dreamhosters.com/form.php
This form has a portion of it where you enter data and can choose to add more of the same data by clicking a button called 'Add A Site' and it will make another of that section to enter another site. This is the jQuery that performs the duplication...
$(function () {
var sites = 1;
var siteform = $("#site1").html();
$(".addsites").live("click", function(e) {
e.preventDefault();
sites++;
$("#events").append("<div id='site" + sites + "'>"
+ "<br /><hr><br />"
+ siteform
+ "<center><button class='removesites' title='site"
+ sites + "'>Remove This Site</button><br />"
+ "<button class='addsites'>Add Another Site</button>"
+ "</center></div>");
});
$(".removesites").live("click", function(e) {
e.preventDefault();
var id = $(this).attr("title");
$("#" + id).remove();
});
});
The duplication works perfectly, but one thing that's bugging me is that when I have to enter data for someone claiming a LOT of sites, it gets very annoying having to repeat same or similar parts of this section of the form (like every site is in the same city, on the same day, by the same person, etc.) So I had the idea that with each duplication, the values of the form elements would also carry over and I just edit what's not the same. The current implementation only duplicates the elements, not the data. I'm not sure how to easily copy the data into new sections, and I can't find any jQuery tools to do that.
PS - This part isn't as important, but I've also considered using this same form to load the data back in for viewing/editing, etc. The only problem with this is that the reprinting of the form means that there will be a form section with the id "Site7" or something, but jQuery starts its numbering at 1, always. I've thought about using selectors to find the highest number site and start off the variable 'sites' at that number, but I'm not sure how. Any advice how to do this, or a better system overall, would be much appreciated.
You want to itterate over the input fields in siteform and store them in an object using their name attribute as a key.
Then after the duplication of the object you made and look for the equivelant fields in the new duplicated form ans set their values.
Somthing like this (not tested, just the idea)
var obj = new Object();
$("#site1 input").each(function(){
obj[this.id] = this.value;
);
// Dupicate form
$.each(obj, function(key, value){
$('#newform input[name="'+key+'"]').value = value;
});
Mind you these two each() functions differ from each other.
http://api.jquery.com/jQuery.each/
http://api.jquery.com/each/
You could consider using cloneNode to truely clone the previous site-div and (by passing true to cloneNode) all of its descendants and their attributes. Just know that the clone will have the same id as the original, so you'll have to manually set its id afterwards
Try this in your click-function
var clone = $("#site" + sites).clone(true, true); // clone the last div
sites++; // increment the number of divs
clone.attr('id', "site" + sites); // give the clone a unique id
$("#events").append(clone); // append it to the container
As Scuzzy points out in a comment jQuery does have its own clone() method (I don't use jQuery much, so I didn't know, and I didn't bother to check before answering). Probably better to use jQuery's method than the built-in cloneNode DOM method, since you're already using jQuery for event listeners. I've updated the code
The query to transfer values is quite simple (please, check the selector for all the right types on the form):
$("#site1").find("input[checked], input:text, input:hidden, input:password, input:submit, option:selected, textarea")
//.filter(":disabled")
.each(function()
{
$('#site2 [name="'+this.name+'"]').val(this.value);
}
Ok I finally figured this out. It's, more or less, an expansion on Alex Pakka's answer.
sites++;
$("#events").append("<div id='site" + sites + "'>"
+ "<hr><br />"
+ siteform
+ "<center><button class='removesites' title='site"
+ sites + "'>Remove This Site</button><br />");
$("#site1").find("input:checked, input:text, textarea, select").each(function() {
var name = $(this).attr("name");
var val = $(this).val();
var checked = $(this).attr("checked");
var selected = $(this).attr("selectedIndex");
$('#site' + sites + ' [name="'+name+'"]').val(val);
$('#site' + sites + ' [name="'+name+'"]').attr("checked", checked);
$('#site' + sites + ' [name="'+name+'"]').attr("selectedIndex", selected);
});
I used extra vars for readability sake, but it should do just as fine if you didn't and used the methods directly.
Dont forget to create a function for registering the event! Its very important because when the DOM is loaded, all new attributes need to be registrated to the DOM.
Small example:
<script>
$(document).ready(function(){
$('#click-me').click(function(){
registerClickEvent();
})
function registerClickEvent(){
$('<input type="text" name="input_field_example[]">').appendTo('#the-div-you-want')
}
registerClickEvent();
})
</script>
I'm building a site which allows users to log on to it, and uses jquery to dynamically update the page to show all users who are currently on.
I want to have a button beside each users name that would let another user select that person (a game match-making service, if you will.)
Currently I'm generating the names with a combination of jquery and php.
Jquery does long polling:
function waitForMsg(){
$.ajax({
url: "tictac_code1.php",
type: 'POST',
data: 'longpoll=1',
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:10000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
$('#loggedinnames').empty();
$('#loggedinnames').append(data);
setInterval(waitForMsg, 10000);
//setTimeout(
// 'waitForMsg()', /* Request next message */
// 1000 /* ..after 1 seconds */
//);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
//alert("error in waitformsg.");
addmsg("error", textStatus + " (" + errorThrown + ")");
setInterval(waitForMsg, 10000);
//setTimeout(
// 'waitForMsg()', /* Try again after.. */
// "15000"); /* milliseconds (15seconds) */
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
PHP does the sql queries and returns data to the jquery to be displayed.
if (isset ($_POST['longpoll'])) {
if (filter_input(INPUT_POST,'longpoll') == '1') {
$name = $_SESSION['name'];
$result = mysql_query("select name from tictac_names where logged_on='1' AND name!='$name'", $db);
$rowCheck = mysql_num_rows($result);
if ($rowCheck > '0') {
while ($row = mysql_fetch_assoc($result)){
foreach ($row as $val){
$spanid = 'sp_' . $val;
$buttonid = 'b_' . $val;
//echo "<br><span id=\"$spanid\">$val</span></br>";
//<input type ="button" id="nameButton" value ="OK"/><br>
echo "<br><span id=\"$spanid\">$val <input type =\"button\" id=\"$buttonid\" value =\"Button!\"/> </span></br>";
//echo "<br><p><span id=\"$spanid\">$val</span>Click here to play a game with this player.</p></br>";
}
}
} // end rowcheck
}
} //////////// end of the LONGPOLL if
So it successfully puts out the name and a button, but the button's ID is not unique. If I want it to be clickable, I'm sure that the ID will have to be unique, but then there will need to be additional jquery to catch the button click.
How can I make this work?
Should I take a different approach, perhaps names with radio buttons, and a single "Match us!" button?
An alternative to #Craig M 's answer would be to use the built in delegate features in jQuery.
$('#loggedinnames').delegate('span','click',function(){
alert($(this).text());
});
It does the same thing but you can use any selector, not just tag name, and you don't need to code all of the boiler plate delegation code.
You could remove the buttons, and use event delegation to figure out which username the person clicked on. Then do what you need to do with it in the click handler.
To do this, set a click handler on #loggedinnames like so:
$('#loggedinnames').click(function(e) {
if ($(e.target).is('span')) { //e.target is the element that was actually clicked.
alert($(e.target).text());
}
});
The advantage of this approach is that you only have one click handler and don't need to bind an event every time the list of logged in users changes.
What I usually do in this situation is to build the button in JavaScript rather than on the server. Then you can just keep a global variable that serves as a counter, increment it each time you add a button, and use that to put together your unique button ID.
I've used this approach in a lot of situations, and 90% of the time, it works every time.
Give all of your buttons the same class and unique ids. Write an event handler in JQuery using live() for your class where you get the id of this and use it in your code. This way the code works for ALL buttons (including new ones) and you do not have to duplicate any code.
$('#loggedinnames .button').live('click', function() {
someMethod($(this).attr('id')); //run your code here
});
I asked a similar question earlier here, and it got me down the right track, but I am little stumped still. However, now I know how to ask a more educated question.
I have a database I connect to, with a table name of PRODUCTS. Within PRODUCTS are the columns ID, STOCK, SHORTNAME, DESCRIPTION, PRICE and SHIPPING.
If the user clicks a button, I need to send a request to find all the rows in PRODUCTS. I believe the following file.php accomplishes that (DB connect code not show).
$query = "SELECT `ID` FROM `PRODUCTS`";
$result = mysql_query($query) or die('Query failed:'.mysql_error());
$num=mysql_numrows($result);
When the user clicks the button, and it gets $num, it then needs to create as many div elements as there are rows. I can do this with for() , but I am not 100% sure how to do it. Also, I am not sure how to do this in Jquery, instead of just JS.
function ajaxFunction(phpFunction){
var ajaxRequest;
try{
ajaxRequest = new XMLHttpRequest();
} catch (e){
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
for (var i = 0; i < ajaxRequest.responseText ; i++)
//Create Div code here
}
}
var url = "file.php;
ajaxRequest.open("GET", url, true);
ajaxRequest.send(null);
}
So here are the final questions:
If a user clicks a specific div (#revealProductButton), how do I create as many divs as $num returns?
How do I make those divs that were created display STOCK, PRICE, and SHIPPING from the DB? Each div must display it's own information, not just one div that displays everything.
If the user then clicks one of the divs that were created, how do I then reveal the rest of the information in the DB (DESCRIPTION, etc), but only for the div that was clicked?
How to I write my file.php to work with all this?
The easiest way would be something like this:
function fetchData(){
var url = 'file.php';
// The jQuery way to do an ajax request
$.ajax({
type: "POST",
url: url,
data: "", // Your parameters here. (like "dummy=1&sort=description")
success: function(html){
// html contains the literal response from the server
$("#result").html(html);
}
});
}
The response of the php script will be written directly to #result.
Now on the php side you can just output html:
$result = mysql_query($myQuery);
while ($row = mysql_fetch_assoc($result)) {
echo '<div>'.$row['description'].'</div>';
}
This is just a quick 'n dirty approach. An alternative is to return a json object from the php script and process that further in javascript.
You can go something like this:
for (var i = 0; i < ajaxRequest.responseText ; i++)
{
var div = document.createElement("div");
var doc = document.getElementsByTagName("body")[0];
doc.appendChild(div);
div.setAttribute("id", "div_" + i);
// now some php code to get STOCK, PRICE, and SHIPPING through sql queries
// ...........................
// ...........................
// ...........................
// javascript again
document.getElementById("div_" + i).innerHTML = <?php echo $price, $shipping, etc in any way you want?>;
div.onclick = function()
{
// again php code to get more info like DESCRIPTION
//..................
document.getElementById("div_" + i).innerHTML += '<br /><br />' + <?php echo $description?>;
};
}
Hope that helps.
If the user clicks a button, I need to send a request to find all the rows in PRODUCTS
SELECT `ID` FROM `PRODUCTS`
Note, this query only retrieves the ID values from all records, not all record data. Is this what you want?
To answer your questions:
1) The PHP script should be returning a specfic format, e.g. XML or JSON (the latter is preferred, IMHO). The number of collections returned will dictate how many DIV elements you create, if your intent is to stick each resulting record into a new DIV. Example, a JSON response has a collection (array) with 10 elements. You loop through each element in the array and create N DIV elements based on the array size.
2) Are you sure you want to create a new DIV for these values? Not TR element in a TABLE?
3) You'd format the returning data in such a way that it was initially "hidden", and use an onclick handler for the main DIV element relating that record data to "reveal" the other data. It's all on the page, it's just hidden, you don't need to create a new XHR call.
4) There are many Ajax related tutorials online. Find one and start tinkering. In other words, it's a bit too complex to scratch out in a couple of lines here.
Although I don't normally jump on the JS library bandwagon, you may want to look at jQuery, it will make these tasks a snap. You should understand the underlying JS code and how the request is made, however.
Since you mentioned the jQuery framework, why not consider using javascript templating? It allows you to simply build the divs (and all of their children) in HTML and populate them with arbitrary data whenever you need them.
Go and take a look at http://aefxx.com/jquery-plugins/jqote, it's a jQuery plugin that allows you to do the above mentioned.
You would use it like this in jQuery:
<script type="text/html" id="template">
<![CDATA[
<div class="product">
Product ID: <%= this.id %>
</div>
]]>
</script>
<script type="text/javascript">
// Let's pretend your ajax call returns an array in json notation like so:
// [{"id": "1", "shortname": "Shoe"}, {"id": "2", "shortname": "Shirt"}]
$.ajax({
url: '/file.php',
....
success: function(data) {
$('#template').jqote(data).appendTo('#container');
}
});
</script>
This would give you to divs that are appended to an element with the ID "container" which are populated
with data returned from your database.
Hope I could help.
cheers