I want to be able to call a function from a link (this function will delete the corresponding row). If I place the function inside document ready it wont load upon call. But it works while outside. The function is delRow(id) located at the end of .
I tried making a ‘copy’ of “$(“#participants”).click(function() {” and calling it just like the “Lägg till deltagare” link (add user link).
How do I solve this in the best way? And Why cant you call functions inside document.ready and why wont my copy of the participants click.function work? (I dont have it in the code example, i named it like “$(“#deleterow”).click(function() and set the id of the button to deleterow)
URL: http://min.xn--spyp-toa.se/addrows.php (Some DNS servers have problem with this, run googles DNS instead! 8.8.8.8 )
<?php
//Inkluderar fil för inläsning av databasinfo.
require("core.inc");
?>
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
//Denna kod ska hämta users i databasen till js-arrayen users
var users = new Array();
$.ajax({
url: 'getuser.php',
dataType: 'json',
error: function(){alert("Kunde inte hämta data från databas");},
success: function(data){
users = data;
}
});
//Denna kod lägger till en ny rad
var rowCount = 1; // Räknare som räknar hur många rader man lagt till
var selectedUsers = new Array(); //Denna array innehåller användare man lagt till
$("#participants").click(function() {
var participantSelect = document.getElementById('participantSelect'); //Denna variabel håller värdet från selecten
//En funktion som loopar fram användarna i databasen till <option> taggar
function addOption(){
var option; //Denna variabel lagrar alla options som genereras i loopen
for (var i=0; i < users.length-1; i++) {
var user = users[i].id;
if(jQuery.inArray(user, selectedUsers) > -1) {
}
else{
option += ('<option value="'+users[i].id+'">'+users[i].name+'</option>');
}
}
return option; //Skickar alla genererade <option>-taggar till append-scriptet
}
//Funktionen som uppdaterar <select>-satsen
function updateSelect(){
$('#participantSelect').replaceWith('<select name="participantSelect" id="participantSelect">'+addOption()+'</select>');
}
//Function som matas in i apenden, den plockar ut namnet som hör till ID som kommer från selecten
function name(){
//kör igenom arraeyn men avslutar när den hittar en träff
for(var i=0; users.length; i++){
if(users[i].id == participantSelect.value){ //Om användar ID är samma som ID från select
selectedUsers.push(users[i].id); //Denna lägger till valda användare i en array för filtrering av redan använda användare
//Denna funktion anropar koden som genererar om <select> och utelämnar redan valda användare
updateSelect();
return users[i].name; //Return i if-satsen för att avbryta vid träff.
}
}
}
//Skriver in en input som är read-only med den valda användaren
$('#container').append('<input type="text" name="participant_'+rowCount+'" id="'+participantSelect.value+'" value="'+name()+'" class="participant_1" readonly="readonly" /> <a href="#" name="participant_'+rowCount+'" id="'+rowCount+'" class="participant_1" onclick="bajs(this.name)">Ta bort deltagare</a><br>');
rowCount++;
});
//Denna kod tar bort redan inmatad användare och lägger tillbaka denne i <select>
function delRow(id){
alert(id);
alert("test");
}
});
</script>
<!-- Här väljer man vilka användare som deltagit, sedan trycker man på lägg till-knappen -->
<select name="participantSelect" id="participantSelect">
<?php
$result = mysql_query("SELECT id, name FROM user");
while ($db_field = mysql_fetch_assoc($result)) {
echo '<option value="'.$db_field['id'].'">'.$db_field['name'].'</option>';
}
mysql_free_result($result);
?>
</select>
<!-- Knapp för att lägga till ny rad inom container-diven -->
<a href="#" id="participants" class="myButton">Lägg till deltagare</a>
<!-- Container diven hit vad alla användare kommer läggas till-->
<h2>Deltagare:</h2>
<div id="container" class="container">
<!-- Här kommer allt läggas in -->
</div>
<button name="participant_1" id="delete_participants" onclick="delRow()">Ta bort deltagare</button><br>
When you use old-style DOM0 handler hookup (
onclick="..."), any functions you reference in that string must be globals. YourdelRowfunction isn’t a global, it’s contained by the function you’re passing intoready— which is a good thing, the global namespace is already too full.Two choices for dealing with this:
1. Hook things up with jQuery
The best way (in my view) to deal with it is to hook up your
buttonusing jQuery from within yourreadyfunction. E.g.:2. Export just that function
Alternatively, you could make a global that points to
delRowby doing this within thereadyfunction:That works because all global variables are properties of the
windowobject in browsers, so by assigning a reference todelRowto thedelRowproperty onwindow, you’re explicitly making it available in the global namespace (without cluttering up the global namespace with any of your other functions). Then theonclick="..."handler will be able to see it. But I wouldn’t advocate using globals if you can avoid it. It’s a useful bridging technique, though, as you transition from the old style to the newer style.Side note: You don’t have to use the
readyfunction, you can just put your script at the bottom of the page (just before or after the ending</body>tag) and do this:It will run slightly sooner, and still have access to all of the DOM elements on the page (ref | ref). But
readyis mostly fine too.Re your comment below:
That’s because you can’t have more than one element on a page with the same
id. Theidvalues must be unique.If you’re going to be adding and removing rows, and if you’re using jQuery to hook things up, you have two additional choices:
A. Hook Them Up Individually
This is just a matter of calling
click(function() { ... })on the new button once you’ve created it, e.g.:So for instance, here’s a complete example:
HTML:
JavaScript:
Live copy
B. Use Event Delegation
But in cases like this, another technique is frequently better: Event delegation. In event delegation, you hook the event (“click”) on some container of all of the things that might receive that click, and then when the click happens check to see if the event has passed through any of the relevant elements (because most events, including “click”, “bubble” from the element on which the click actually occurred up to its parent, grandparent, and other ancestors). jQuery makes delegation dead easy, using
delegate:or, as of 1.7 or later, using one of the several variants of
on:(Note that the order of arguments is slightly different.)
Complete example (using
delegate, since a lot of people aren’t on 1.7 yet):HTML:
(Same as above)
JavaScript:
Live copy