jQuery Selection Out Of Multiple Elements - php

there's a php scripts which create multiple <p>text</p> elements due to user's query.
I'd like to create an option that every time user clicks on a certain element , the text in this elements will appear in a text box.
The intuitive way to do such task is:
<p class="c1"> textA...</p>
<p class="c2"> textB...</p>
<p class="c3"> textC...</p>
<p class="c4"> textD...</p>
and the jQuery code will be :
$("p.c1").click(function(){ code... }
$("p.c2").click(function(){ code... }
etc ...
Is there any elegant method of implementing this functionality ?
Any suggestion will be helpful,
Thanks in advance

Event delegation.
$('body').on('click', 'p[class^=c]', function(evt) {
var clickedPara = $(this);
});
There, I filter on paragraphs whose class attribute starts with c. This is just demonstrative but is ultimately likely not very watertight. You should give your elements a common class. If this class was, say, 'clickablePara', you could instead use
$('body').on('click', 'p.clickablePara', function(evt) {
Event delegation means you bind one event and evaluate the trigger element when it fires, rather than binding lots of events to each possible element. If this is new to you, it's worth looking into. If you happen to be in the UK, the upcoming edition of .NET Magazine has an article by me discussing it.

you can assign multiple classes to HTML elements. You can change your PHP script to output mutliple classes. i.e.
<p class="c1 clickable"> textA...</p>
<p class="c2 clickable"> textB...</p>
<p class="c3 clickable"> textC...</p>
<p class="c4 clickable"> textD...</p>
Then you can use the click function.
$("p.clickable").click(function () {
$('#yourtextbox').val($(this).text());
});
JSFIDDLE

It does'nt say anything about dynamic elements inserted with ajax, so I'm guessing the elements are created serverside before the page is outputted and that delegation is'nt neccessary ?
$("p[class^='c']").on('click', function() {
$("#textboxID").val(this.innerHTML);
});
FIDDLE

Related

How to embed a submit form within link?

In the following code, I would like to change the value of data-filter to a user-submitted field, and then, incorporate that input into the link.
<a href="#" id="gallery_filter" class="sidebar-search"
data-filter="(get user input here)">
So far I've tried ajax objects, jquery mobile filters and regular HTML. I've tried about 20 different approaches, the most recent with jQuery mobile filters.
<ul data-role="listview" data-filter="true" data-filter-reveal="true" data-filter-placeholder="Search tags..." data-inset="true">
<!-- foreach $tags as $tag [get all tags loop] -->
<li>$tag[0]</li>
</ul>
If I understand the question, you want to modify the DOM (in your case, a link), based on user input. If that's the case, you don't have to submit the form and you should basically take a straightforward approach, using simple jQuery:
$(function() {
var input_el = $("#user_input");
var link_el = $("#link");
input_el.keyup(function() {
var value = input_el.val();
link_el.attr('data-filter', value);
});
});
You can see this in action here, in this example: http://jsfiddle.net/4bBSF/
However, if you really have to submit a form, you can also add a function to be executed onsubmit:
<form onsubmit="updateLink()"> ... </form>
onsubmit functions are executed before the form is sent. Then the updateLink function would do something similar to the example above, adding the value of the input to the link.
Now, if you really want to go further and try something fancy, read about data-binding. There are a bunch of libraries and frameworks supporting data binding, including AngularJS, Ember and Meteor.

How to show/hide one dynamic element (div) at a time with jQuery

This is my first attempt at jQuery and I'm using a basic tutorial I found here: http://papermashup.com/simple-jquery-showhide-div/#
This is my current code and how the jQuery works: http://jsfiddle.net/mZQsu/
As you can see, when you click the '+/-' it opens all 4 of the tables/DIVs.
How can I modify this code to open just the relevant secondary table/div according to the original table?
(Please note the secondary tables are generated dynamically from PHP and SQL data)
Thanks.
P.S all my code is here http://jsfiddle.net/mZQsu/ instead of clogging up this question page :)
DEMO fiddle
$('.toggler').click(function() { // had to differentiate the main togglers with a new class
var ind = $(this).parents('tr').index()-1; // could change
$(".slidingDiv").eq(ind).slideToggle();
});
$('.show_hide').click(function() { // this are the 'togglers' inside the big menus
$(this).parents(".slidingDiv").slideToggle();
});
The best solution would be if you tag each of your div's with an id. E.g.
<div class="slidingDiv" id="ip_127_0_0_1">
and then modify the equivalent links to do
$("#ip_127_0_0_1").slideToggle();
so just the associated div gets expanded.
See my updated fiddle: http://jsfiddle.net/mZQsu/1/
You can use the index of the row, and toggle only the matching row of the other table using jQuery index and eq
See the relivant docs here:
jQuery index
jQuery eq
This should work:
$('.show_hide').click(function() {
$(this).parents(".slidingDiv").slideToggle();
});
Since the slidingDiv class is a direct parent of the show_hide link, I could have used "parent" rather than "parents". The latter provides more flexibility because it traverses all ancestors looking for the class.
Here is a modified code - http://jsfiddle.net/mZQsu/3/
I have added show-hide1, show-hide2, show-hide3, show-hide4.
And clicking on it opens respectively slidingDiv1, slidingDiv2, slidingDiv3, slidingDiv4.
When you are binding to an event: You can always grab that event target and reference it.
$('.show_hide').click(function(e) {
$(e.target).parent("div.slidingDiv").slideToggle();
});
.parent() is a good place to start, but .closest() also might work. That being said, this is the preferred way to go about it.
On a side note if you ever want to do the opposite you could use .not(e.target) and all the other elements except for the one your click will be called.
Since your html is PHP-generated, it should not be a problem to include unique IDs for both +- links and sliding divs, for example:
a href="#" class="show_hide" id="show_hide2"
And
div class="slidingDiv" id="slidingDiv2"
Then in your click function you get the index of the div that you want to open:
$(.show_hide).click(function(){
var $str = $(this).attr('id');
var $index = $str.charAt( $str.length-1 );
});
Now you can use index to open the div:
var divName = "#slidingDiv" + $index;
$(divName).slideToggle();

Handling jQuery click events on divs produced in a foreach loop

I have an HTML div:
<div id='text_icon_<?php $i++; ?>' class="text_icon">Some Text</div>
that I print inside a foreach loop. I am using ajax to handle the click() event on it and change its text to Done!, so I have an output like:
<div class="text">Done!</div>
If I run the loop 4 times and I click on one of the divs (i.e. the one with class text_icon) then only first one is working while the rest of the divs are not working.
Update:
Your update indicates the below is not the problem, the IDs are unique.
Without your jQuery code it's hard to help you debug, so here's an example of how it can be done:
HTML:
<div id='text_icon1' class='text_icon'>Div #1</div>
<div id='text_icon2' class='text_icon'>Div #2</div>
<div id='text_icon3' class='text_icon'>Div #3</div>
<div id='text_icon4' class='text_icon'>Div #4</div>
JavaScript code using jQuery:
$("div.text_icon").click(function() {
// Within the `click` handler, `this` points to the
// DOM element. If you're kicking off some ajax something,
// you'll probably be doing something like this:
// Grab `this` to a variable we can access from the
// `success` closure
var theDiv = this;
// Do our call
$.ajax({
url: "your_url_here",
success: function() {
// It worked, udate the div
$(theDiv).text("Done!");
}
});
});
Live copy
Original answer:
If you're really using "DIV id='text_icon' class="text_icon..../DIV", e.g.:
<DIV id='text_icon' class="text_icon">....</DIV>
...then the problem is that the id is not unique. ID values must be unique on the page (reference). That would seem to fit with the symptom you describe, with "only the first one" working. Most browsers, when given invalid HTML with multiple IDs, will use the ID on the first element in document order and ignore the remaining ones.
If you don't need the div to have an ID at all, you can just remove it. Otherwise, just ensure the ID is unique, e.g.:
<DIV id='text_icon1' class="text_icon">....</DIV>
<DIV id='text_icon2' class="text_icon">....</DIV>
<DIV id='text_icon3' class="text_icon">....</DIV>
<DIV id='text_icon4' class="text_icon">....</DIV>
As far as I can tell, you are giving your divs the same ID. Targetting multiple elements with the same ID is impossible, the IDs need to be unique.
Try this:
$i = 1;
foreach ($array as $al) {
echo "<div id='text_icon_$i'>blablabla</div>";
$i++;
}
Of course, you'll need to modify your jQuery code too to include a potentially unlimited number of such IDs (I don't know whether performance will be good this way, but I remember doing it once for a comments list on a blog).
Another way would be to use a common class rather than unique IDs :).
Apart from the arguments about unique IDs, could it also be that the click handlers need to be hooked up again after the ajax call? If so, it'd be better to use .live rather than .click.
$("div.text_icon").live("click",
function(event) {
var icon = $(this);
}
}

How can I add a jQuery Dialog for each row in an HTML table

I am generating an HTML table with PHP (using the codeigniter framework) and I'm trying to add a link that will open a jquery dialog with some information that is specific to that row. Sort of a 'More Info' type link that simply opens the dialog.
When I add the dialog div to that row and encapsulate the required information in it, it breaks the table (cannot have a div in the table).
Plus, it seems I would need to add an unknown amount of jquery dialog functions declared... I'm assuming some sort of a function is needed and the ID of the element that opens the dialog as well as the ID for the dialog would be passed to the function. But, it seems there should be something built into jQuery for something like this.
Am I missing something, and if so does anybody have any tips to get me pointed in the right direction?
Embed the information as metadata on the row, a la…
<tr data-foo="additional data here" data-bar="even more data">…</tr>
And in your javascript, a little magic called .live():
$('#your_table .show_dialog').live('click', function(){
var data_for_dialog = {
foo: $(this).closest('tr').attr('data-foo'),
bar: $(this).closest('tr').attr('data-bar')
}
show_dialog(data); // your own code to show the dialog
});
Where you have an <a> tag with the class "show_dialog". Note that this isn't very efficient if you have a lot of attributes or any of them contain data that needs to contain newlines. You could improve this by iterating over each attribute defined on that <tr> and automatically including the attributes starting with data-. That's out of the scope of this question though.
As far as showing the dialog, something like this would be sufficient:
function show_dialog(data) {
var $dialog = $('#dialog');
for(var attr in data) {
$dialog.find("." + attr).html(data[attr]);
}
$dialog.show();
}
<div id="dialog">
<p class="data-foo"></p>
<p class="data-bar"></p>
</div>
That's untested, but should illustrate what's happening well enough.
Note: You can define custom attributes in HTML5 so long as they are prefixed with "data-", hence that showing up everywhere above.
I agree with Tomalak's comment to use one box and change the content in it.
If you wanted to do what I think you are trying to do(without seeing your code) it seems that you might be putting the dialog div in the <table> tag instead of a <td> tag, that would be the first thing to check.
Secondly to open the dialog you can just reference the div next to the link:
<table>
<tr>
<td>
<span class="MoreInfo">More info</span>
<div>stuff for dialog</div>
</td>
</tr>
</table>
$(document).ready(function(){
$('.MoreInfo').next().dialog({ autoOpen: false })
$('.MoreInfo').click(function(){
$(this).next().dialog('open');
});
});
Edit: Sorry messed up the Jquery I am assuming you are using the JqueryUI Dialog

jQuery .live fireing multiple times!

Greetings Guru's, This is a little hard to explain, but I'll give it a shot.
I have a quick question regarding to the .live() function in JQuery. I'm going to simplify the example here. I have a page "index.php" that has a container "#display_files_container" which is populated with anchor links that are generated dynamically by a different page "process.php". The links are loaded into that same <div> when those links are selected based on the attributes of that link. See Examples:
INDEX.PHP
<html>
<head><title>index.php</title>
<!-- this function below loads process.php and passes it the dirid variable via post. I then use this post variable inside of process.php to pull other links from the database -->
<script language="text/javascript">
$('.directory').live("click", function() {
$('#display_files_container').load('plugins/project_files/process.php', {dirid: $(this).attr('dirid')});
});
</script>
</head>
<?php
/*This code initial populates the link array so we have the first links populated before the users clicks for the first time*/
some code to fetch the $current_directory_list array from the database initially....
>?
<body>
<div id='display_files_container'>
<?php
/*Cycle through the array and echo out all the links which have been pulled from DB*/
for($i=0;$i<$current_directory_count;$i++) {
echo "<a href='#' class='directory' dirid='".$current_directory_list[$i]['id']." '>".$current_directory_list[$i]['directory_name'].
"</a> ";
}
?>
</div>
</body>
</html>
PROCESS.PHP
this file includes code to populate the $current_directory_list[] array from the database based on the post variable "$_POST['dirid']" that was sent from the .click() method in index.php. It then echo's the results out and we display them in the #display_files_container container. When you click on those links the process repeats.
This works..... you can click though the directory tree and it loads the new links every time. However, it seems to want to .load() the process.php file many times over for one click. The number of times process.php is loaded seems to increase the more the links are clicked. So for example you can click on a link and firebug reports that process.php was loaded 23 times..... Eventually I would imagine I would record a stackoverflow. Please let me know if you have any ideas. Are there any ways that I can assure that .live() loads the process.php file only once?
Thanks,
-cs
What happens, is that everytime you click a link, you bind new click event handler to every link. This is possible because there can be multiple handlers for the particular event. You must return false in your handler to stop the event bubbling.
Update: I'm not sure why the handler gets bound multiple times, but my guess is that it has something to do with the special nature of 'live event' implementation. See chapter Event Delegation from the docs:
The handler passed to .live() is never bound to an element; instead, .live() binds a special handler to the root of the DOM tree.
Another solution is to use bind() or click() instead of live() and call it explicitly after the ajax has been loaded:
function bind_link_handler() {
$('.directory').click(function() {
$('#display_files_container').load('...', bind_link_handler);
})
}
Just so everyone is in the loop my new line of .live() code looks like this:
$('.directory').live("click", function() {
$('#display_files_container').load('plugins/project_files/process.php', {dirid: $(this).attr('dirid')});
return false;
});

Categories