Unable to get Id of draggable divs in jQuery (using jQuery UI) - php

For some reason the script below is unable to get the id of the draggable divs using attr('id'), but it works on the other static elements on the page. I am totally confused as to why this wont work and if anyone has a solution for me it would me much appreciated.
$(document).ready(function(){
//$(".draggable").draggable();
$(".draggable").draggable({ containment: '#container', scroll: false });
$(".draggable").draggable({ stack: { group: '#container', min: 1 } });
$("*", document.body).click(function (e) {
var offset = $(this).offset();// get the offsets of the selected div
e.stopPropagation();
var theId = $(this).attr('id');// get the id of the selceted div
$("#result").text(this.tagName + " id=" + theId + " (" + offset.left + "," + offset.top +")");
$.post("http://localhost/index.php", "id=" + theId + "&x=" + offset.left + "&y=" + offset.top); //post x,y to php (and the id of the elemnt)
});
var req = function () {
$.ajax({
url: "out.php",
cache: false,
success: function(html){
$("#stuff").empty().append(html);
var css_attr = html.split(",");
$('#1').css('left', css_attr[0] + 'px').css('top', css_attr[1] + 'px');
},
complete: function(){
req();
}
});
};
req();
});
Note: This script is dependent on the following JavaScript sources.
jquery.js
http://jqueryui.com/latest/ui/ui.core.js
http://jqueryui.com/latest/ui/ui.draggable.js
http://jqueryui.com/latest/ui/ui.droppable.js

Currently you're attaching the click handler to all elements in the DOM with * (very very bad, don't do this!), including any children in those draggables.
You are correctly stopping the event from bubbling up using .stopPropagation(), but it's likely a child of a .draggable you've clicked, not the draggable itself. What you want is actually listening on the .draggable element themselves, like this:
$(".draggable").click(function (e) {
var offset = $(this).offset(),
theId = this.id;
e.stopPropagation();
$("#result").text(this.tagName + " id=" + theId + " (" + offset.left + "," + offset.top +")");
$.post("http://localhost/index.php", { id: theId, x: offset.left, y: offset.top });
});
The other changes here are id can be accessed directly, via this.id, and passing an object to $.post() is safer for serialization, like I have above.
Even the above isn't quite there though, you likely want to send the position when you stop dragging, by changing this:
$(".draggable").click(function (e) {
To this:
$(".draggable").bind("dragstop", function (e) {
...or in newer versions of jQuery (1.4.2+):
$(document.body).delegate(".draggable", "dragstop", function (e) {

Your click function works for me on a test page. Out of curiosity, if you move the 'e.stopPropogation()' line to the bottom of your click function, does it behave differently?

Be careful with *, you know, all means all, if you have <div><p><span><a></a></span></p></div> it means that the action is set to every single element. I'd specify classes or tags that should be affected by your function, to be always sure that you get what you want to be clicked.
Try your code replacing * with the object you think it's ID isn't get, and see if it works..

This may seem pretty obvious but are you sure that all the elements that your selecting actually have IDs. If your including everything (with the *) then it is likely that some elements don't have IDs.

Related

Generic jquery structuration question

please take a look of this:
$(function () {
$("#add").click(function() {
val = $('#add_lang').val();
val1 = $('#add_lang_level').val();
listitem_html = '<li>';
listitem_html += val + ' <strong>('+ val1 + '/100)</strong>';
$.ajax({ url: 'addremovelang.php', data: {addname: val,addlevel: val1}, type: 'post', success: function(output) { alert(output); }});
listitem_html += 'Remove'
listitem_html += '</li>';
$('#langs').append(listitem_html);
});
$('.remove_lang').live('click', function(e) {
e.preventDefault();
$(this).parent().remove();
$.ajax({ url: 'addremovelang.php', data: {delname: val}, type: 'post', success: function(output) { alert(output); }});
});
});
This simple jquery script adds strings to a html list when the user hits the button with the id add. Also, it puts a remove link to each line, so when the user hits remove it triggers the function remove_lang and the string is deleted.
When the users add a string, this text comes from a text field, and i stored it on the variable val (as you can see on the 5 line of the code). Then i call a php script via Ajax to add this info to my mysql database.
But, when the user remove the string, i dont know how to know what string was removed, i mean, the name of this one, that i need to send to my php script in order to remove it from the database.
Take a look of this version of my code without the ajax call: http://jsfiddle.net/wnFsE/
Thanks for any help!!!
When you click remove you can do something like this:
val = $(this).parent().find('input').val();
That will get the value from hidden input you added:
Demo Here
You need to think about the string as instead a group of elements:
var li = $('<li/>');
var strong = $('<strong/>', { text: '(' + val1 + '/100)' });
var link = $('<a/>');
link.click(function()
{
// Insert code here for the link click
});
li.append(strong).append(link);
$('#langs').append(li)
There are other patterns that would work too, like:
$(listitem_html').find('a').click(function()
{
// Insert code here for the link click
});
Just get a reference to the element, and then attach the click event handler.
An Object Oriented Programming approach would help keep the actions very organized. You basically store the actions for each given language in an object, modifying the action for that language whenever it's removed or added.
Here's a live example that will print that "storage" object out to the console every time you add or remove a language so that you can clearly see what's going on.
And here's just the JS code (you'll notice that I barely changed a thing):
languageActions = {}
$(function () {
$("#add").click(function() {
val = $('#add_lang').val();
listitem_html = '<li>';
listitem_html += val;
listitem_html += '<input type="hidden" name="languages[]" value="' + val + '" /> ';
listitem_html += 'Remove'
listitem_html += '</li>';
$('#langs').append(listitem_html);
//now add it to our object
languageActions[val] = 'add';
console.log(languageActions);
});
$('.remove_lang').live('click', function(e) {
e.preventDefault();
val = $(this).prev().val();
$(this).parent().remove();
//now change it's value in languageActions
languageActions[val] = 'remove';
console.log(languageActions);
});
});
The only other thing I'll point out is that you don't really need that hidden input element since you're doing this via AJAX rather than a standard form submit. Instead, you could just do <li><span>Spanish</span><a class="remove_lang">Remove</a></li> for your HTML and then the click event on .remove_lang would do $(this).prev().text() rather than $(this).prev().val(). Not a huge deal, but you're HTML will be a little cleaner.
I guess that would be a simple:
$i = 1;
while(xxx){
//get the list with a different value for each element
echo '<div id="add_' . $i . '>$whatever</div>';
$i++;
}

jQuery ajax callback not firing jQuery code

I have a checkbox on a webpage that when you click it, updates the value in the database as well as the editedBy and editedDate columns in a table in the database. I am doing the update via an ajax call to a php page. I am trying to get the updated editedDate and editedBy data in the callback on success so i can update the sorresponding span tags that hold this information. I'm trying to use jQuery to accomplish this. This is what i have so far:
var updateUserDate = function(data){
var table = data.table;
var rowId = data.rowId;
var editedDate = data.editedDate;
var editedBy = data.editedBy;
//alert(table+' - '+rowId+' - '+editedDate+' - '+editedBy);
$('"#'+table+' .row'+rowId+' .newEditedDate"').html('"'+editedDate+'"');
}
var submitDataCheckbox = function(target){
var project = target.attr('project');
var tableName = target.attr('table');
var rowId = target.attr('rowId');
var checkboxValue = (target.attr('checked'))?true:false;
$.ajax({
type: 'GET',
url: '/checklistpost.php?projectId='+project+'&table='+tableName+'&rowId='+rowId+'&value='+checkboxValue,
success: function(data){
updateUserDate(data);
},
error: function(){
alert('There was an error submitting data to the database.');
},
dataType: 'json'
});
}
The checklistpost.php page takes the variables that are in the query string and posts them to the database. It also then puts the variables in an array which is then encoded in json so that i have a json object to work with. Basically, i am trying to take that json object that gets called back and use it to update the span as mentioned above. When i have used an alert() inside of the updateUserDate function before to verify that i can see the variables and they all have the right data (you can see the code i used to do this is commented out). However, whenever i try and use the variables with jQuery as you see on the 6th line of the code. It doesn't do anything. BTW, The jQuery code that should be output based on what is written above should look like this $("#tableName .row1 .newEditedDate").html("April 14, 2011 # 5:15pm") What am i missing? Thanks in advance for any help!
Your selector is broken, you've got extra quotes in there:
'"#' + table+' .row' + rowId + ' .newEditedDate"'
should be:
'#' + table + ' .row' + rowId + ' .newEditedDate'
So:
// you're surrounding editedDate with extra quotes too, or is that intentional?
$('#' + table + ' .row' + rowId + ' .newEditedDate').html(editedDate);
Why are you using single and double quotes? The command you are passing to jQuery will evaluate to this:
$('"#tableName .row1 .newEditedDate"').html('"April 14, 2011 # 5:15pm"')
instead of this:
$("#tableName .row1 .newEditedDate").html("April 14, 2011 # 5:15pm")

jQuery - Using :contains for instant search with nested divs/classes?

I have a search box. I'm using jQuery and keyup to filter repeating divs.
Each div looks like this:
<div class="searchCell" id="searchCell' . $id . '">';
<div class="friendName">
// someNameOutputWithPHP.
</div>
</div>
Now, I want to filter based on the name text. If someNameOutputWithPHP contains the search query, the entire searchCell should show(). If it doesn't, the entire searchCell should hide().
This doesn't work, though:
<script type="text/javascript">
$(document).ready(function() {
$("#searchbox").keyup(function() {
var searchValue = $(this).val();
if(searchValue === "") {
$(".searchCell").show();
return;
}
$(".searchCell").hide();
$(".searchCell > .friendName:contains(" + searchValue + ")").show();
});
});
</script>
EDIT
New problem: I got the divs show() to show how I want. But the :contains isn't working exactly right.
For instance: say one of the name's is Ryan. When I search for 'Ryan', I get nothing. But when I search for 'yan' I get the Ryan div.
What's wrong?
Here's the :contains code:
$(".friendName:contains(" + searchValue + ")").parent().show();
That is because you are hiding the .searchCell and then showing its children .friendName divs, which though get display property will not show up because parent is hidden.
Try this:
<script type="text/javascript">
$(document).ready(function() {
$("#searchbox").keyup(function() {
var searchValue = $(this).val();
if(searchValue === "") {
$(".searchCell").show();
return;
}
$(".searchCell").hide();
//$(".searchCell:has(.friendName:contains(" + searchValue + "))").show();
// OR
//$(".friendName:contains(" + searchValue + ")").parents(".searchCell").show();
// OR
$(".friendName:contains(" + searchValue + ")").parent().show(); // If .searchCell is always a direct parent
});
});
</script>
Your selector
$(".searchCell > .friendName:contains(" + searchValue + ")")
will select all .friendName divs that contain the text from searchValue. That works just fine, but you need to .show() the parent element. Just invoke the .parent() method for that:
$(".searchCell > .friendName:contains(" + searchValue + ")").parent().show();
Demo: http://jsfiddle.net/d3ays/3/
And by the way, you HTML markup looks messed up too. There is a ; behind your div.searchCell for instance.

jQuery not generating correct queryString

I have been working on a website that uses a combination of PHP, jQuery, MySQL and XHTML in order to register students for a piano recital. This has no official purpose other than a learning exercise for me in getting all of these to work together. However, I have had a lot of problems getting the PHP to talk with the database and I'm not sure what my problem is. But before that can be tackled there is a really annoying issue that I've run across. For some reason my jQuery is not building a complete post URL for the PHP.
I am using jQuery version: 1.4.2 from Google. The query string is being built by using:
var ajaxOpts = {
type: "post",
url: "../php/addRecital.php",
data: "&performance=" + $("#performanceType :selected").text() +
"&groupName=" + $("#groupName").val() +
"&student1fName=" + $("#firstName").val() +
"&student1lname=" + $("#lastName").val() +
"&student1id=" + $("#studentID").val() +
"&student2fname=" + $("#Second_Student_firstName").val() +
"&student2lname=" + $("#Second_Student_lastName").val() +
"&student2id=" + $("#Second_Student_studentID").val() +
"&skillSelect=" + $("#skillSelect :selected").text() +
"&instrument1=" + $("#instument1 :selected").text() +
"&otherInstrument1=" + $("#otherInstrument1").val() +
"&instrument2=" + $("#Instument2 :selected").text() +
"&otherInstrument2=" + $("#otherInstrument2").val() +
"&location=" + $("#locationSelect :selected").text() +
"&roomNumber=" + $("#roomNumber").val() +
"&time=" + $("#timeSlotSelect :selected").text()
,
success: function(data) { ...
There is more than the above function, but I didn't think that it would pertain to here. I then call the code using:
$.ajax(ajaxOpts);
However, instead of creating the entire query string I get:
http://sterrcs123.mezoka.com/schoolProject/assign/assign13.html?groupName=&firstName=Samuel&lastName=Terrazas&studentID=23-343-3434&Second_Student_firstName=&Second_Student_lastName=&Second_Student_studentID=&otherInstrument=&Second_Student_Instrument=&roomNumber=2
Which as you can tell is missing a number of keys and their values. I would appreciate any help I can get because this is really driving me insane. Thanks.
It appears that your form is simply submitting itself without using your AJAX operation. Did you attach to the form's submit event and THEN run your ajax call? You will also want to return false from the submit event handler to prevent the default behavior you are seeing above.
Example:
$('#formid').submit(function(){
//your ajax code here.
return false;
});
If you're talking to an ASP.Net web service then you would need data to be a JSON string of your arguments. Otherwise, you can pass your data in by using an object literal (truncated for brevity):
var ajaxOpts = {
type: "post",
url: "../php/addRecital.php",
data: {
performance: $("#performanceType :selected").text(),
groupName: $("#groupName").val(),
student1fName: $("#firstName").val(),
student1lname: $("#lastName").val()
},
success: function(data)
}
As per the missing values, make sure you're capturing the button click / form submit.
$('form').submit(function (e) {
$.ajax(ajaxOpts);
return false;
});

Print the value in loop in Jquery ready function

somehow still not able to do what I’m inted to do. It gives me the last value in loop on click not sure why. Here I want the value which is been clicked.
Here is my code:
$(document).ready(function() {
var link = $('a[id]').size();
//alert(link);
var i=1;
while (i<=link)
{
$('#payment_'+i).click(function(){
//alert($("#pro_path_"+i).val());
$.post("<?php echo $base; ?>form/setpropath/", {pro_path: $("#pro_path_"+i).val()}, function(data){
//alert(data);
$("#container").html(data);
});
});
i++;
}
});
Here the placement_1, placement_2 .... are the hrefs and the pro_path is the value I want to post, the value is defined in the hidden input type with id as pro_path_1, pro_path_2, etc. and here the hrefs varies for different users so in the code I have $('a[id]').size(). Somehow when execute and alert I get last value in the loop and I don’t want that, it should be that value which is clicked.
I think onready event it should have parsed the document and the values inside the loop
I’m not sure where I went wrong. Please help me to get my intended result.
Thanks, all
I would suggest using the startsWith attribute filter and getting rid of the while loop:
$(document).ready(function() {
$('a[id^=payment_]').each(function() {
//extract the number from the current id
var num = $(this).attr('id').split('_')[1];
$(this).click(function(){
$.post("<?php echo $base; ?>form/setpropath/", {pro_path: $("#pro_path_" + num).val()},function(data){
$("#container").html(data);
});
});
});
});
You have to use a local copy of i:
$('#payment_'+i).click(function(){
var i = i; // copies global i to local i
$.post("<?php echo $base; ?>form/setpropath/", {pro_path: $("#pro_path_"+i).val()}, function(data){
$("#container").html(data);
});
});
Otherwise the callback function will use the global i.
Here is a note on multiple/concurrent Asynchronous Requests:
Since you are sending multiple requests via AJAX you should keep in mind that only 2 concurrent requests are supported by browsers.
So it is only natural that you get only the response from the last request.
What if you added a class to each of the links and do something like this
$(function() {
$('.paymentbutton').click(function(e) {
$.post("<?php echo $base; ?>form/setpropath/",
{pro_path: $(this).val()},
function(data) {
$("#container").html(data);
});
});
});
});
Note the use of $(this) to get the link that was clicked.

Categories