Simply what I want is to to change the button class and value in order to change the button functionality.
what happening is that the value and the class are changed successfully BUT the functionality remain the same as for the old class
why?!
does the browser store the jquery code somewhere and load from it?! and how can i refresh it in that case??
here's piece of my code:
(I'm using Jquery Ajax with html and php)
var target_button; // global variable to store the target button
$(".activateButton").click(function(){
var serial_number = $(target_button).attr("id");
var cvc = $("#cvc").val();
$.ajax({
type: "GET",
url: '../ajax/tag.php',
data:
{
s: serial_number,
c: cvc
}
}).done(function(data)
{
var result = jQuery.parseJSON(data);
if (result == "1")
{
$("#message").text('Tag Successfully Activated');
$("#overlay_form").fadeOut(500);
$(target_button).attr("value", "Disable");
$(target_button).removeClass("popActivateButton"); //<---------- REPLACING THE CLASS
$(target_button).addClass("enableDisableButton"); //<----------
}
here's the buttons:
if($tags[$i]['Status'] == 1){
$button = "<input type=\"button\" class=\"enableDisableButton\" id=\"".$tags[$i]['SerialNumber']."\" value=\"Disable\"/>";
}
if($tags[$i]['Status'] == 2){
$button = "<input type=\"button\" class=\"popActivateButton\" id=\"".$tags[$i]['SerialNumber']."\" value=\"Activate\"/>";
}
When you use a selector it selects all elements that match at the time you execute the code. Previously called selectors - even if cached - do not dynamically update when new elements that match them are added to the page.
If you've bound event handlers to elements, then they're going to stay there until you a. remove the event handler(s), or b. remove the element entirely. Just changing the class isn't going to magically change the event handlers that are bound.
I'd suggest using event delegation instead:
$(document).on('click', '.enableDisableButton', function() {
//your code for enableDisableButton
}).on('click', '.popActivateButton', function() {
// your code for popActivateButton
});
With event delegation the selector is checked when the event is triggered, rather than when the code executes, so it will reflect changes to the page.
Note that I've used document in the code example above. However, you should instead use a selector for a static element (one that won't be removed) that will contain the elements you want to execute the event handler function for; the closer it is in the DOM structure to the dynamic elements the better.
Yes once event assigned you need to clear those previous events and bind new events to each.
suppose you have button and you have assigned click event now unfortunately you want to clear click event and something else you can do it as below,
$(SOMESELECTOR).unbind('previous_event').bind('new_event');.
For more search for jQuery bind and unBind.
Related
I have a dropdown selector on a page that allows a user to select a template type (for example, "human" or "dog").
Based on what template is selected, different fields will need to populate below the dropdown (for example, text fields for "parents names" or a dropdown list for "breed") that are unique to each template.
I will have a button that the user will click once the data fields are put in that will output data to an "output div" section of the same page when clicked (no POSTing data as it's not being saved). The output will have different output logic based on the selected template (for example, "I'm a human named X" or "I'm a dog, my breed is Y").
My real program will be more complex and each template will have a php class that stores all of the logic. Since I will be dealing with both php objects and variables gathered by jquery, what's the best way to let them interact?
For 1., I know I can do something easy like -
var selected_template = $('#my-template-dropdown :selected').text();
if (selected_template == 'Human'){
$('#my-fields').html('<?php echo HumanTemplate::render_fields(); ?>');
}
which is easy enough, but for 2. I need to pass variables from jquery to php, then return output back to jquery.
I would like some advice on the easiest way to do this before I start down the wrong path.
HTML
Allow the user to select the template type:
<form>
<select id="my-template-dropdown" name='template'>
<option value="dogs">Dogs</option>
<option value="humans">Humans</option>
</select>
</form>
<div id="my-fields"><div>
<div id="output"><div>
jQuery
Any time the user changes the template selection, request new content to display via AJAX, and insert it on the current page so the page does not have to refresh:
$('#my-template-dropdown').on('change', function() {
var template = $(this).val();
$.ajax({
url: 'http://your-site/path/to/' + template,
success: function(resp) {
$('#my-fields').html(resp);
}
});
});
PHP
http://your-site/path/to/template simply generates the HTML you want to display for that template, eg (just an example, don't know if this is suitable for your app):
if ($template == 'humans') {
echo HumanTemplate::render_fields();
} else if ($template == 'dogs') {
echo DogTemplate::render_fields();
}
For part 2, assuming all the logic you refer to is in the template rendered by PHP, you could then handle it with jQuery. This is pretty crude, you probably need something more sophisticated (eg a full template which you swap variables into?), but you get the idea:
$('#output').on('click', 'button', function(e) {
e.preventDefault();
// fields in your template which the user will fill
var species = $('#species').val(),
title = $('#title').val();
// Probably better to have this text as a template in your source
$('#output').html("I'm a " + species + ' named ' + title);
});
NOTE the gotcha in the event handler. Event handlers will only attach to elements that exist at the time the handler is defined. Since the content is injected after page load, an event handler like $('#button).on('click', function() {... would have no effect when clicking a button inserted via AJAX. The syntax here attaches to the parent #output div, which does exist at page load, and filters for clicks on a button. See the jQuery event delegation docs for more info.
Another option would be to POST the submitted data to some PHP controller, which generates and returns the output. This way all your logic is in the one place. For example, here the user's click will query the same PHP file which generated the initial template, this time including the values the user has entered. It could then generate the required output and return it, to be inserted on the page. You'd need to update the PHP so it can determine which of these cases it is handling (eg hidden field?); alternatively if you wanted to keep those separate you could hit another PHP file all together.
$('#output').on('click', 'button', function(e) {
var template = $('#my-template-dropdown').val(),
$form = $('form'),
data = $form.serialize(); // Values from all fields user has entered
$.ajax({
url: 'http://your-site/path/to/' + template,
data: data,
success: function(resp) {
$('#output').html(resp);
}
});
});
The best way to pass data from jQuery to PHP, is by using AJAX.
Mozilla has an excellent guide on getting started, that i recommend you follow.
An example of how you can achieve what you are requesting, is by trying the following:
var selected_template = $('#my-template-dropdown :selected').text();
var ajaxurl = 'ajax.php',
data = {'select_template': selected_template };
$.post(ajaxurl, data, function (response) {
console.log(response);
});
On the PHP end (Ajax.php in my example) It could look something like this
if(isset($_POST['select_template'])) {
// do something with the input from jQuery
$selected_template = $_POST['select_template'];
// return the result back to the client
echo $seleted_template;
}
?>
$selected_template will be sent back to the client, and response in the AJAX function will be whatever the server returned. So the console.log(response) should display whatever was being sent to the server
You can have a look to the function wp_localize_script.
This function make available PHP datas to JS files on the page load through the wp_enqueue_scripts action.
This will not work like an Ajax request and only populate data for a specific handle on page load. But you can mix this method with ajax in the same script.
Hope it helps even it doesn't seems to fit to your case.
As your class not fires on page load, you can use the action wp_ajax_{custom _action} and wp_ajax_nopriv_{custom_action} . For example, that's usually used to populate multiple dropdown, each time an event is trigger by the user, a php function returns result the js script.
I dynamically load a div on page Leagues.php with a button like this:
$("#leaguesSelectionTable th").click(function(){
var leagueSelect = $(this).attr('id');
if ($('#leaguesTable').length){
$("#loadLeagueTables").empty();
$("#loadLeagueTables").load("php/leagueTable.php?leagueSelect="+encodeURIComponent(leagueSelect));
}
else {
$("#loadLeagueTables").load("php/leagueTable.php?leagueSelect="+encodeURIComponent(leagueSelect));
}
});
This loads a table based on which button I pressed, using leagueTable.php to handle all of that. Once that table is loaded, (a bunch of leagues) I want to then be able to click on a row from this table and following the same logic, display the team table.
$("#assoc_league tr").click(function(){
var teamSelect = $(this).attr('id');
if ($('#teamsTable').length){
$("#loadTeamTables").empty();
$("#loadTeamTables").load("php/teamTable.php?teamSelect="+encodeURIComponent(teamSelect));
}
else {
$("#loadTeamTables").load("php/teamTable.php?teamSelect="+encodeURIComponent(teamSelect));
}
});
I think the problem is that since table #assoc_league is not yet present, this does not work. I tried an alert and don't get any response. This jQuery is in the same file attached to Leagues.php. Any ideas how to approach this?
Thanks.
Since your table has been added dynamically to the DOM, all the events for this table and child elements inside it will not be avaliable. In this case, you need to use event delegation :
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all children matching a selector,
whether those children exist now or are added in the future.
$('#loadLeagueTables').on('click', '#assoc_league tr', function() {
// Your code here
});
I am trying to post the element information that jQuery pulls, when a user clicks on table cell, to a new page that will use that information (an id in this case) in a sql query. i.e., the user clicks a cell and the job he/she clicks has an id of 25, that is to be passed to my php page that queries the database for the job with that id and then populates the page with said information. The user can then alter the information from the query and submit it to update the database table. I have the id from the click function and a success alert tells me that the info was posted. The problem is that when the page is opened it states that the posted name index is undefined.
Here is my script to get the information:
<script>
$(document).ready(function()
{
$("table.jobs tbody td#job").click(function()
{
var $this = $(this);
var col = $this.text();
var LeftCellText = $this.prev().text();
if (col == '')
alert("Please pick another column");
else
$.ajax(
{
type:"POST",
url:"../php/jobUpdate.php",
data:"name=" + LeftCellText,
success: function()
{
window.location = "../php/jobUpdate.php";
}
});
});
});
</script>
and here is the simple php page it is sending to:
$name = $_POST['name'];
echo $name;
I am new to jQuery, and I cannot figure out why this is not working?
When you use ajax, the second page ../php/jobUpdate.php processes the data sent by the first page, and returns a value (or even a huge string of html, if you want).
The first page receives the new data in the ajax routine's success function and can then update the current page. The updating part happens in the success: function, so you're on the right track.
But in your success function, you are redirecting the user to the 2nd page -- after already being there and processing the data. Redirecting them is probably not what you want to do.
Try replacing this:
success: function()
{
window.location = "../php/jobUpdate.php";
}
with this:
success: function(data)
{
alert(data);
}
If you want to see how to update the first page with the data received via ajax, try adding an empty DIV to your html, like this:
<div id="somestuff"></div>
Then, in the success: function of the ajax routine, do this:
$('#somestuff').html(data);
(Note that the term "data" can be any name at all, it only needs to match the name used in the function param. For example:
success: function(whatzup) {
alert(whatzup);
}
From your comment to my previous post, it seems that you don't need ajax at all. You just need a form in your HTML:
<form id="MyForm" action="../php/jobUpdate.php" method="POST">
<input type="hidden" id="jobID" name="yourJobID">
</form>
Note that forms are invisible until you put something visible inside them.
You can have select controls (dropdowns) in there, or all form elements can be invisible by using hidden input fields (like the HTML just above), which you can populate using jQuery. Code to do that would look something like this:
<script>
$(document).ready(function() {
$("table.jobs tbody td#job").click(function() {
var $this = $(this);
var col = $this.text();
var LeftCellText = $this.prev().text();
//Set value of hidden field in form. This is how
//data will be passed to jobUpdate.php, via its `name` param
$('#jobID').val(LeftCellText);
if (col == '')
alert("Please pick another column");
else
$('#myForm').submit();
});
});
</script>
If you add more values to your form to send over to jobUpdate.php, just ensure that each element has a name, such as <input type="text" name="selectedJobType"> (this element, type="text", would be visible on screen).
In the jobUpdate.php file, you would get these values thus:
$SJT = $_POST['selectedJobType'];
$id = $_POST["yourJobID"];
//Use these vars in MySQL search, then display some HTML based on results
Note that the key referenced in the $_POST[] array (selectedJobType / yourJobID) is always identical to the name specified in the HTML tag. These names are case sensitive (and spelling counts, too).
Hope this isn't TMI, just wish to cover all the bases.
On your success function causing the window to reload will delete any of the variables passed in via .ajax.
What you can try is returning the data and use it in the existing page.
success: function(msg) {
$('#someDiv').append(msg);
}
The reason the index is not defined is because you are using a string in the data-argument, however, that is actually an array-like object. :)
data: { name: col }
that should be the line you need to change. Otherwise I have not seen any problems. Also if I can give you a little idea, I wouldn't use POST actually. In fact, I'd use GET. I can not confirm if that is saver or not, but using $_SERVER["HTTP_REFFERER"] you can check from where that request is coming to determine if you want to let it pass or not.
The way I would suggest is, that you sent the ID in a GET-request and have the PHP code return the data using json_decode(). Now in jQuery, you can use $.getJSON(url, function(data){}) - which is, for one, shorter and a bit faster.
Since you probably will crop the URL yourself here, make sure that you use a function like intVal() in JS to make sure you are sending an intenger instead of a malicious string :)
I am echoing out a list of content from my database and have a star icon next to each item. I tried to make it so that when the user clicks the star it will find that content in my database and change the 'popular' value in that field (a 'like' button). I have been trying to do this by having each star wrapped in a tag and then making the id of each form 'formWithId'x ...... x being the id of the content that is being displayed.
Here it is in code:
echo "<form method = 'post' class ='formId".$row['id']."' id = 'likePostWithId".$row['id']."'>";
//all inputs are hidden and send the 'id' value of the content so the php file will know which field of the table to like in the mysql database
echo "<input type ='text' name = 'email' style = 'display: none;' value= '".$row['email']."' >
<input type ='text' name = 'id' style = 'display: none;' value= '".$row['id']."' >
//this is the star icon
<i class = 'ss-icon' id = '".$row['id']."'>⋆ </i>";
echo "</form>";
So, now what i need is to be able to send the form by using jquery validate.... but the problem i am having is that I have always used jquery validation (using the submit handler) to submit specific forms whose id's are predefined and dont change based on the id of the content sent from the database.
Here is my example that i am trying to
$(document).ready(function(){
$(".ss-icon").click(function(){
var id= $(this).attr('id');
$("#likePostWithId"+id).submit();
});
});
$(function(){
$(".ss-icon").click(function(){
//this doesn't work...
$("#likePostWithId").validate({
submitHandler:function(data){
//do stuff
}
)};
)};
see where $("#likePostWithId")... i dont know how to make it choose the one with the correct id (example $("#likePostWithId"+id)) would interpret as #likePostWithId6 or $likePostWithId7 where the number is the id of the mysql content
anyway i have no clue if this will be clear to any of you... I don't really know how to ask this question.. But basically i need to send an id (the id of the content from mysql) to php form without reloading page
any help is appreciated.
thanks
You may achieve this using jQuery's Ajax. Simply give each star icon a unique id (this id should have some relation with the MySQL data, like index key). Pass this argument (the id) using jQuery's Ajax function to a php script which takes the data (unique for each MySQL entry, like index) which changes it's popularity field entry. On success function, you may give some animation or color change to star icon informing that the data is successfully posted. just give it a try.
try this
$(function(){
$(".ss-icon").click(function(){
var id= $(this).attr('id');
$("#likePostWithId" + id ).validate({ <--- here
submitHandler:function(data){
$("#likePostWithId"+id).submit();
}
)};
)};
this however submits the form... you can use ajax to submit the form wihtout reloading
Maybe you can use $.post() to solve your problem. Then you don't have to mess around with forms:
$(document).ready(function(){
$(".ss-icon").click(function(){
$.post('yourPHPUrl', { contentID: $(this).attr('id') }, successFunction);
});
});
function successFunction(data) {
if (data.success) { //just a sample, you can give a JSON-Object back to the success function
$('#' + data.ID).css() ... // do something with the clicked star
}
}
Your code:
$(function(){
$(".ss-icon").click(function(){
//this doesn't work...
$("#likePostWithId").validate({
submitHandler:function(data){
//do stuff
}
)};
}); // <-- this was missing
)};
You were missing a set of brackets but you still shouldn't implement it like that. You are merely re-initializing the plugin on every click. (The plugin already has the click event handler built-in and it's captured automatically.)
.validate() must be called once within the DOM ready to initialize the plugin. As per documentation, the submitHandler callback function is "the right place to submit a form via Ajax after it validated."
$(function(){
$("#likePostWithId").validate({ // initialize plugin
// other options & rules,
submitHandler: function(form){
// do ajax
return false; // blocks form redirection since you already did ajax
}
)};
)};
Play with a demo: http://jsfiddle.net/XnfDc/
I'm having a problem..
Actually I do have an issue when sending a value from a child page to the parent page.
I'm actually loading a page via JQuery and that page is getting refreshed to display new results, but one of these problems is that the function from the parent page doesn't get called from the child page.
Although this works perfect on Google Chrome, Opera and Safari, it doesn't seem to work on Firefox.
I heard Firefox doesn't manage events the same way as Safari or Google Chrome does?
I've been searching on answers for this but I couldn't find anything pretty much..
Alright, here's what I'm doing:
The child page calls another file which has all the functions that make my site work, this is what should trigger the function:
$like = "<a href='$comment_poster' id='$msgid' class='like'
onclick='parent.likecomment(this);'>Like</a>";
echo "$like";
And this is the function that gets fired from the onclick event which is located in the parent page (the function is in the parent page the onclick is in the child page):
This function is the one that receives the id from the child page to later on add the value to the database.
function likecomment(commentID)
{
event.preventDefault();
var likeid = commentID.id;
var author = ($(commentID).attr('href'));
// forming the queryString
var data = 'likeid='+ likeid + '&author=' + author;
if(likeid)
{
// ajax call
$.ajax({
type: "POST",
url: "likeprofmessage.php",
data: data,
beforeSend: function(html)
{
$(".word").html(likeid);
},
success: function(html){
$("#resultsprofcomments").fadeIn('slow');
$('#profcommentsdiv').load('showprofmessages.php?vprofile=<?php echo $row['1'];?>').fadeIn("slow");
$("#resultsprofcomments").append(html);
}
});
}
}
I've tried the Firefox console and I've received the error: event is undefined so this should be a problem on how Firefox manages events.
Again, any help is appreciated, thank you very much.
I think the following will work as long as you set the onclick handler inline in your HTML (as you did in your example):
<A href="..." onclick='parent.likecomment(event,this);'>blah</A>
<SCRIPT>
function likecomment(evt, commentID) {
evt.preventDefault();
var likeid = commentID.id;
// etc
}
</SCRIPT>
For event handlers not set inline in HTML, the standards compliant browsers (including FF) should automatically pass the event object as a parameter to your handler function. IE, up to version 8, anyway, uses a different event model and lets you reference event directly - really it is window.event but generally as with most window properties it works even if you omit window..
So if you assign your click handler on document ready (or onload) you can do this:
function yourOnloadFunction() {
document.getElementById('yourElementId').onclick = clickHandler;
}
function clickHandler(e) {
// check if event object was passed in, otherwise use window.event
if (!e) e = window.event;
// but how to get a reference to the clicked element?
// use the event object's target property, except (of course)
// in IE, which uses srcElement:
var elRef = e.srcElement ? e.srcElement : e.target;
// rest of your function here, e.g.
e.preventDefault();
}
You have managed to make a mess of your code, but try to change
onclick='parent.likecomment(this);'
to
onclick='parent.likecomment(this);return false;'
and then remove
event.preventDefault();
from your function likecomment(commentID).
Instead of using the in-line onClick, have you tried sending back a script that does something like
<Script>$('#{id}').click(function() {
var id = this.id;
likecomment(id);
return false;
})</Script>