Honestly, I'm not even sure the best way to go about this, but essentially, I have a function in an include file that takes a $type parameter and then will retrieve/print results from my db based on the $type passed into it... What I'm trying to do is have a series of links on a page that, when you click on a certain link, will run the function and display the results accordingly...
So, on the initial load of the page, there is a table that displays everything (and I'm simplifying the table greatly...)
<table>
<tr><th>Item</th><th>Type</th></tr>
<tr><td>Milk</td><td>Dairy</td></tr>
<tr><td>Yogurt</td><td>Dairy</td></tr>
<tr><td>Chicken</td><td>Meat</td></tr>
<tr><td>Zucchini</td><td>Vegetable</td></tr>
<tr><td>Cucumber</td><td>Vegetable</td></tr>
</table>
And, then, in a sidebar, I have a series of links:
Dairy
Meat
Vegetable
I'd like to filter the initial table (and back and forth, etc.) based on the link that is clicked, so that if the user clicks "Vegetable", the function from my include file will run and filter the table to show only "Vegetable" types...
The first idea that comes to mind is to add a class attribute to the <tr> tags and id attribs to the <a> tags so that you can easily filter that way:
<tr class="dairy"><td>Milk</td><td>Dairy</td></tr>
<tr class="meat"><td>Chicken</td><td>Meat</td></tr>
Dairy
Meat
Then in your JavaScript (I'm using jQuery here):
$('a').click(function(evt){
var myId = $(this).attr('id');
$('tr').each(function(idx, el){
if ($(el).hasClass(myId))
{
$(el).show();
}
else
{
$(el).hide();
}
});
});
This has the added benefit of allowing you to localize the text without having to change your code.
Ok I created a proper answer. You can do it the way Darrel proposed it. This is just an extension for the paging thing to avoid cookies:
$('a').click(function(evt){
var myId = $(this).attr('id');
// append a idndicator to the current url
var location = "" + document.location + "";
location = location.split('#',1);
document.location = location + '#' + $(this).attr('id');
//append to next and previous links
$('#nextlink').attr({
'href': $('#nextlink').attr('href') + '#' + $(this).attr('id')
});
$('#previouslink').attr({
'href': $('#previouslink').attr('href') + '#' + $(this).attr('id')
});
$('tr').each(function(idx, el){
if ($(el).hasClass(myId))
{
$(el).show();
}
else
{
$(el).hide();
}
});
});
Some code that is executed after page load:
var filter = window.location.hash ? '[id=' + window.location.hash.substring(1, window.location.hash.length) + ']' : false;
if(filter)
$('a').filter(filter).click();
This simulates/executes a click on page load on the link with the specific id.
But in general, if you have a large database, you should filter it directly with SQL in the backend. This would make the displayed table more consistent. For example if page 1 may only have 3 rows of class 'dairy' and on page 2 10 of class 'dairy'.
If youre printing out the whole tabel up front there is no need to go back to the server you can simple hide all teh rows of a given type. For example with jQuery:
$('#sidebar a').click(function(){
// grab the text content of the a tag conver to lowercase
var type = $(this).text().toLowerCase();
/* filter all the td's in the table looking for our specified type then hid the
* row that they are in
*/
$('#my_data_table td').contents().filter(function(){
return this.nodeType == 3 && this.toLowerCase() == type;
}).parent('tr').hide();
return false;
});
Really though the suggestion abotu adding a class to the TR is better because filtering on text content can get tricky if there is content youre not expecting for some reason (hence my conversion to all lower case to help with this).
Related
I currently have a table in the current format:
ID Client Info Case Detail Accident Date Case Opened No Days Function
-- ----------- ----------- ------------- ----------- ------- --------
which contains dynamic information being pulled out of the database.
The ID column is of particular importance because I need to extract the data from this cell when the user clicks on the "Manage" button under the function column.
Right now this is the code that runs when the user clicks on the "Manage" button.
<script>
$(document).ready(function () {
$(".manage").click(function () {
$('#casesHeading').hide("slow");
$('#casesTable').hide("slow");
$('#results').load('components/manage.php');
});
});
</script>
A heading and table is hidden and the page "manage.php" is loaded in results div.
But I was just wondering if there was anyway for me to transfer the content of the ID cell (this varies per row) obviously into the manage.php file (which is currently empty).
So if the user clicks on a row with the ID cell data 233-cv then this information would be transferred over into the manage.php file. Hopefully I'm making sense. I read up on the jQuery .find function and it made some sense but I have no idea how to incorporate it in this instance.
UPDATE 1
I'm trying to accomplish somethng similar to this http://jsfiddle.net/ZjvAz/.
UPDATE 2
I've tried the following code but it doesn't seem to be working.
<script>
$(document).ready(function () {
$(".manage").click(function() {
var clickedButton = $(this);
clickedButton.parent().find(".result").text(
clickedButton.parent().parent().parent().find('.caseID').text()
);
});
});
</script>
I would have my manage.php file take the case ID as an argument. It would be called in a manner such as manage.php?caseId=123.
If you have control over the generated data, you could generate the required information to go in the button. There is no need for jquery code to traverse the DOM to the ID field. I would just generate something like this in the table source
<tr>
<td class="id">123</td>
...
<td class="function">
<button class="manage" onclick="loadManagementPage(123)">manage</button>
</td>
</tr>
If you cannot control the HTML source and do need to navigate, your best friend is probably using closest() which navigates up the dom. Use this to find the row element tr
For self-documenting purposes, i am not using chaining here
$( '.manage' ).click(function(){
// find the row we are in
var $self = $( this );
var $row = $self.closest( 'tr' );
// read the id
var $idCell = $row.find( 'td.id' );
var caseId = $idCell.text();
// locate an area on the page and dynamically load in some content
var $target = $row.find( 'td.result' ); // find the result cell
var $target = $( '#knownId' ) // *OR* find a div with a known id
$target.load( 'manage.php?caseId=' + caseId );
});
jQuery.load( handler(eventObject) ) Returns: jQuery
Description: Bind an event handler to the "load" JavaScript event.
As 'components/manage.php' isn't an event-handler – what are you trying to do?
If you want to request data from the server (also with sending smoe ID to it), you should read about the jQuery.ajax( url [, settings] ) function.
http://api.jquery.com/jQuery.ajax/
http://api.jquery.com/load-event/
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>
Here is my situation. I have a webpage (not quite finished):
http://grapplingbasics.com/beta.php
I have the page slide to a specific div which puts a a url with a hash in the URL bar. If the user refers to this URL they can hit that specific part of the page.
However, I would like to allow them to hit that part of the page AND load a specific video with one address.
It doesn't seem that you can put a query string and hash dealy together like so: www.blah.com/index.php#BLAH?neat=one
originally i tried turning the hash into part of the querystring, and then using split in jquery to assign it into a hash on the fly. However, the problem with this, is that if I return false to the nav, it wont show the querystring on the URL bar, and if i don't return false, then it wants to navigate to something that isnt there!
What's a possible solution here?
I created a little example for you which should explain how you can get this fixed.
<script type="text/javascript">
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if (results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
$(function () {
$('a').click(function (event) {
var thisHash = document.location.hash;
$('body').animate({ scrollTop: $(thisHash).offset().top }, function () {
if (getParameterByName('neat') != null) {
alert('I will play video ' + getParameterByName('neat'));
}
});
});
});
</script>
Html:
<a href='?neat=one#end'>Go</a>
<p id='end'>Imagine this is a panel you are going to in your example.</p>
The code above firstly has a getParameterByName function which looks into your URL to find your query string value pairs. and if its not null it returns its value.
in the section below that ...imagine that the anchor tag is your navigation and I clicked on it, then the page animates to the correct hash section. Once the animation is completed in the callback section is asks for the query string value. if it you have set a value for "neat" then your code for playing the video should sit where the alert is now.
You can put the querystring before the hash:
www.blah.com/index.php?neat=one#BLAH
Or for a more complex solution, look into the querying aspect of ben alman's jquery bbq plugin:
http://benalman.com/projects/jquery-bbq-plugin/
I'm working on a CMS at the moment and have been looking for a suitable Jquery/Php image manager but can't find anything that really suits my needs. So I've decided to have a go at building the image manager myself. The bad news is I'm not particularly up to speed with my Jquery...actually I know very little. But I'm working my way through it.
The end result will display an unordered list of images.
<ul>
<li><img src="imgsrc" /></li>
<ul>
When the user clicks on an image the ID of that image is sent to a Jquery function and stored in an array. The image is highlighted with a border added by addclass(). If the user clicks on a subsequent image that image ID is also sent to the Jquery array and the second image is also highlighted.
This continues until the user doesnt click on any further images. Naturally if the user clicks on an image that is already contained in the Jquery array then it is removed and the highlighted effect is also removed.
Following this the user will select a catalogue item from a select menu that sits below the image list. The ID of that item is also passed to Jquery.
When the user clicks submit the Jquery array and select ID are sent to a PHP script that updates a MySQL table, linking the image ID to the catalogue item ID.
Where I'm up to currently is...I have a lovely unordered list of images.
My questions are
How do I send the image id to the jquery array, and subsequently remove that id if the same image is clicked again
How do I send the Jquery array to the PHP script to be executed
I have got some of this working in code snippets at the moment, but as Jquery is far from my forte Im just rinsing and repeating until I get the code right. Any help would be great.
Mark
So Ive been trying this code snippet, but I think i could be written better.
$(document).ready(function() {
$("img").click(function(event) {
var test = (event.target.id);
if($('img[id=' + test + ']').is('.error'))
$('img[id=' + test + ']').removeClass("error");
else
$('img[id=' + test + ']').addClass("error");
});
});
</script>
Surely there's another way to target the img id without having to use 'img[id=' + test + ']'
Mark
Edited again
$(document).ready(function() {
$("img").click(function(event) {
var img_id = (event.target.id);
var imgArray = new Array();
if($('img[id=' + img_id + ']').is('.selected')) {
$('img[id=' + img_id + ']').removeClass("selected");
$('span[id=check_' + img_id + ']').removeClass("check-ok");
removeArray();
}
else {
$('img[id=' + img_id + ']').addClass("selected");
$('span[id=check_' + img_id + ']').addClass("check-ok");
addArray();
}
function removeArray() {
alert('Removing from the array');
}
function addArray() {
alert('Adding into the array');
}
});
});
Trying to figure out how to insert the images into the array, and then remove them from the array.
I'm not really sure what all the bits of your code are doing, but something like this should at least make it a bit more DRY:
function showMessage(selected) {
if( true === selected )
{
alert('Removing from the array');
}
else
{
alert('Adding to the array');
}
}
$(document).ready(function() {
$('img').click(function(event, ui)
{
$(this).toggleClass('selected');
var id = $(this).attr('id');
$('#check_' + id).toggleClass('check-ok');
showMessage( $(this).hasClass('selected') );
});
});
And in jsfiddle (although I replaced img with div for speed).
I want users on my website to be able to "move" div tags once they are 'unlocked' and then for a php script to store the positions in mysql database. So once the user re-logs in the div tags are positioned in the correct place.
I know how to postion div tags in css, and am using php varibles within css to pull the data from the database. I just dont know how to get the position of the div tag in order to store it? Maybe using ajax or something?
any ideas welcome, thanks.
What do you mean by position? Is it "left, right, center..." or the position in pixels?
If it's in pixels, just use the top and bottom css property. If it's a custom position, just do a callback when you change the position.
You can easily get the position using javascript and once you have it you want to save that asynchronously, so yeah ajax is nice. Look up jquery for that one: http://docs.jquery.com/Ajax/jQuery.post
$.post("test.php", { func: "getNameAndTime" },
function(data){
alert(data.name); // John
console.log(data.time); // 2pm
}, "json");
Also, from the way your formulated your question it looks that you don't have a lot experience with ajax. I suggest you look up some documentation online or find a nice book (search SO, there's a bunch of topics about this)
When the position of an element changes, you will want to post the pixel values to a PHP script using AJAX. Here is a brief example using jQuery...
function storeElementPosition(elem) {
var off = $(elem).offset();
$.post("storeElementPosition.php",
{ elem : $(elem).attr("id"), left : off.left, top : off.top },
function(resp) {
alert(resp);
}
);
}
Use jQuery, it'll make life a whole lot easier. ..
HTML:
Save
JavaScript:
$('#savelayout').click(function(){
var postData = {};
$('.xy').each(function(){
var id = $(this).attr('id');
var pos = $(this).position();
if (id && id.length){
postData[$(this).attr('id')] = pos.left.toString() + ',' + pos.top.toString();
}
});
$.post('savelayout.php', postData, function(data, textStatus){
if(textStatus == 'success'){
alert('Positions saved successfully.');
}
});
});
Replace .xy in $('.xy') with the CSS selector that will target all the elements you want saved. Once you do that, if you have two savable elements with with "divid1" and "divid2" id's, the data posted to PHP ($_POST) will look like this:
array(
'divid1' => '123,351',
'divid2' => '512,136'
);
You can then explode each string by the comma and grab each int as the x and y coordinate.