Creating list of divs by class - php

I'm not sure whether I should be doing this with jquery or php, but I have a html page with several divs of the same class, but different ids. ie:
<div class="something" id="furniture">contents</div>
<div class="something" id="lighting">contents</div>
<div class="something" id="homewares">contents</div>
What I'm looking at doing is creating a <ul> generated by the ids of any div with the class "something".
Would I be best doing this using jquery? and how would I best go about creating a list/menu of these divs?

You would use PHP if that is an option (i.e. you know the ids when you load the page and are generating them from your PHP already), otherwise only the people with JavaScript enabled are going to see your page content (and search engines would probably punish this "hidden" content).
If you have the list of ids in a PHP array you would do something like this:
<?php
$ids = array('furniture, 'lighting', 'homewares');
?>
<ul>
<?php foreach ($ids as $id) : ?>
<li><?=$id?></li>
<?php endforeach; ?>
</ul>
If you wanted to use jQuery you could do this:
$('body').append('<ul id="yourID"></ul>');
$('div.something').each(function() {
$('ul#yourID').append('<li>' + $(this).id + '</li>');
});
Update (you want to replace the div tags and put the ids on the li tags)
$('body').append('<ul id="yourID"></ul>');
$('div.something').each(function() {
var $id = $(this).id;
$(this).remove();
$('ul#yourID').append('<li id="' + $id + '">' + $id + '</li>');
});

well, to "convert" that structure into ul's, code should look like:
var $target = $('.something'),
$parent = $target.parent(),
$list = $('<ul/>', {
id: 'your_id_here',
css: {
backgroundColor: 'red'
// more css attributes, or use class: to assign a css class
}
});
$target.each(function(){
$list.append('<li>' + $(this)[0].id + '</li>');
});
$target.remove();
$parent.append($list);
That would replace the divs with ul's. Importan thing in this example is to remove
the original div because of the ids, which have to be unique in a valid html markup.

Assuming the HTML you've provided is rendered, and that you have an available UL element on the page, you can use JQuery to do (something like) the following
jQuery('.something').each(
function(index, Element) {
var newListElement = jQuery(document.createElement('li'));
newListElement.html(Element.html());
jQuery('#myul').append(newListElement);
});
It's a bit unclear as to the restrictions that are imposed upon you, but I hope this helps.

Related

expand/collapse div (toggle) when clicking on header

I have the following jQuery code to toggle the view of more information in a div.
$(".expandCollapse").click(function () {
var bidValue = this.id,
expandArea = $("#"+bidValue+'_status')
expandArea.slideToggle(500);
});
The code works to toggle the view of displaying more information when the submission header is clicked. The div IDs of $moreInfo are dynamically created.
$moreInfo = $bidValue.''."_status";
echo "<div class='expandCollapse' id='$bidValue'>Submission</div>";
echo "<div id='$moreInfo'>$displayComments</div>";
However I want to open only one view/div at a time. If a div is open when a submission is clicked it should be closed before the other one is opened.
I've tried several things but it closes or hides all divs. Searching the web only show a solution using anchor tags.
Any thoughts...?
Thanks.
To achieve this you can put a common class on the second div element to allow you to hide them all before showing the next, like this:
echo '<div id="$moreInfo" class="expand-area">$displayComments</div>';
$(".expandCollapse").click(function () {
var bidValue = this.id,
expandArea = $("#" + bidValue + '_status').slideToggle(500)
$('.expand-area').not(expandArea).hide();
});
Also note that you can make your code much more simple and generic by usnig DOM traversal to select the elements, instead of building selector strings based on related id attributes, like this:
$(".expandCollapse").click(function () {
var expandArea = $(this).next('.expand-area').slideToggle(500);
$('.expand-area').not(expandArea).hide();
});
The code above assumes that the elements are siblings, but you can easily amend the next() to traverse however is required.
Assuming the header and content divs are siblings you may use:
$(.expandCollapse + div)
// All <div>s that are immediately after an .expandCollapse
$(".expandCollapse").click(function () {
var bidValue = this.id,
expandArea = $("#"+bidValue+'_status')
expandArea.slideToggle(500);
$('.expandCollapse + div').not(expandArea).hide();
});
$('[id$="_status"]').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='expandCollapse' id='bidValue1'>Submission1</div>
<div id='bidValue1_status'>displayComments</div>
<div class='expandCollapse' id='bidValue2'>Submission2</div>
<div id='bidValue2_status'>displayComments</div>
<div class='expandCollapse' id='bidValue3'>Submission3</div>
<div id='bidValue3_status'>displayComments</div>

Ajax GET passing the incorrect data

i have this HTML / PHP code:
$notes.='<div class="note '.$color.'" ';
if($row["xyz"] == '') {
$notes.='style="left:45%; top:10%; z-index:0;"><h3 align="center">New Note</h3>';
} else {
$notes.='style="left:'.$left.'px;top:'.$top.'px;z-index:'.$zindex.'">';
}
$notes.=htmlspecialchars($row['text']).'
<a class="closeMessage">X</a><div class="addedby">'.htmlspecialchars($row['addedby']).'</div>
<span class="data">'.$row['sequence'].'</span>
</div>';
there are multiple containing different data from the database
i would like to use ajax to send data to a PHP page using GET, i currently have this:
$('.closeMessage').live('click',function(){
//alert("close");
alert($('span.data').html());
$.get('/includes/sticky_notes/closeMessage.php',{
sequence : $('span.data').html()
});
alert("close");
});
but its passing the incorrect sequence each time. its passing the sequence number of a different row
As your HTML code for the notes have several elements with the class 'data', when you call for $('span.data').html() you will always get the inner html of the first span with the data class.
You can traverse the dom tree and use something like the siblings function.
$(document).ready( function(){
$('.closeMessage').on('click',function(){
//alert("close");
this_data = $(this).siblings('.data').html();
alert(this_data);
$.get('/includes/sticky_notes/closeMessage.php',{
sequence : this_data
});
alert("close");
});
});
In this example we store the data in a variable this_data = $(this).siblings('.data').html(), so we refer to the element that was clicked - $(this) and then go down in the tree until the next element with the class data.
One last thing - consider to use $('.closeMessage').on instead of live as it has been deprecated - http://api.jquery.com/live/

jQuery UI Sortable, then write order into a database

I want to use the jQuery UI sortable function to allow users to set an order and then on change, write it to the database and update it. Can someone write an example on how this would be done?
The jQuery UI sortable feature includes a serialize method to do this. It's quite simple, really. Here's a quick example that sends the data to the specified URL as soon as an element has changes position.
$('#element').sortable({
axis: 'y',
update: function (event, ui) {
var data = $(this).sortable('serialize');
// POST to server using $.post or $.ajax
$.ajax({
data: data,
type: 'POST',
url: '/your/url/here'
});
}
});
What this does is that it creates an array of the elements using the elements id. So, I usually do something like this:
<ul id="sortable">
<li id="item-1"></li>
<li id="item-2"></li>
...
</ul>
When you use the serialize option, it will create a POST query string like this: item[]=1&item[]=2 etc. So if you make use - for example - your database IDs in the id attribute, you can then simply iterate through the POSTed array and update the elements' positions accordingly.
For example, in PHP:
$i = 0;
foreach ($_POST['item'] as $value) {
// Execute statement:
// UPDATE [Table] SET [Position] = $i WHERE [EntityId] = $value
$i++;
}
Example on jsFiddle.
Thought this might help as well. A) it was designed to keep payload to its minimum while sending back to server, after each sort. (instead of sending all elements each time or iterating through many elements that server might chuck out) B) I needed to send back custom id without compromising the id / name of the element. This code will get the list from asp.net server and then upon sorting only 2 values will be sent back: The db id of sorted element and db id of the element next to which it was dropped. Based on those 2 values, server can easily identify the new postion.
<div id="planlist" style="width:1000px">
<ul style="width:1000px">
<li plid="listId1">List 1</li>
<li plid="listId2">List 1</li>
<li plid="listId3">List 1</li>
<li plid="listId4">List 1</li>
</ul>
<div id="pl-1"></div>
<div id="pl-2"></div>
<div id="pl-3"></div>
<div id="pl-4"></div>
</div>
<script type="text/javascript" language="javascript">
$(function () {
var tabs = $("#planlist").tabs();
tabs.find(".ui-tabs-nav").sortable({
axis: "x",
stop: function () {
tabs.tabs("refresh");
},
update: function (event, ui) {
//db id of the item sorted
alert(ui.item.attr('plid'));
//db id of the item next to which the dragged item was dropped
alert(ui.item.prev().attr('plid'));
//make ajax call
}
});
});
</script>
You're in luck, I use the exact thing in my CMS
When you want to store the order, just call the JavaScript method saveOrder(). It will make an AJAX POST request to saveorder.php, but of course you could always post it as a regular form.
<script type="text/javascript">
function saveOrder() {
var articleorder="";
$("#sortable li").each(function(i) {
if (articleorder=='')
articleorder = $(this).attr('data-article-id');
else
articleorder += "," + $(this).attr('data-article-id');
});
//articleorder now contains a comma separated list of the ID's of the articles in the correct order.
$.post('/saveorder.php', { order: articleorder })
.success(function(data) {
alert('saved');
})
.error(function(data) {
alert('Error: ' + data);
});
}
</script>
<ul id="sortable">
<?php
//my way to get all the articles, but you should of course use your own method.
$articles = Page::Articles();
foreach($articles as $article) {
?>
<li data-article-id='<?=$article->Id()?>'><?=$article->Title()?></li>
<?
}
?>
</ul>
<input type='button' value='Save order' onclick='saveOrder();'/>
In saveorder.php; Keep in mind I removed all verification and checking.
<?php
$orderlist = explode(',', $_POST['order']);
foreach ($orderlist as $k=>$order) {
echo 'Id for position ' . $k . ' = ' . $order . '<br>';
}
?>
This is my example.
https://github.com/luisnicg/jQuery-Sortable-and-PHP
You need to catch the order in the update event
$( "#sortable" ).sortable({
placeholder: "ui-state-highlight",
update: function( event, ui ) {
var sorted = $( "#sortable" ).sortable( "serialize", { key: "sort" } );
$.post( "form/order.php",{ 'choices[]': sorted});
}
});
I can change the rows by following the accepted answer and associated example on jsFiddle. But due to some unknown reasons, I couldn't get the ids after "stop or change" actions. But the example posted in the JQuery UI page works fine for me. You can check that link here.
Try with this solution: http://phppot.com/php/sorting-mysql-row-order-using-jquery/
where new order is saved in some HMTL element.
Then you submit the form with this data to some PHP script,
and iterate trough it with for loop.
Note: I had to add another db field of type INT(11) which is updated(timestamp'ed) on each iteration - it serves for script to know which row is recenty updated, or else you end up with scrambled results.

Dynamic Selectors with Jquery with php while loop

I have a while loop which creates a list of anchor tags each with a unique class name counting from 1 to however many items there are. I would like to change a css attriubute on a specific anchor tag and class when it is clicked so lets say the background color is changed. Here is my code
while($row = mysql_fetch_array($results)){
$title = $row['title'];
$i++;
echo "<a class='$i'>$title</a>
}
I would like my jquery to look something like this, it is obviously going to be more complicated than this I am just confused as where to start.
$(document).ready(function() {
$('a .1 .2 .3 .4 and so on').click(function() {
$('a ./*whichever class was clicked*/').css('background':'red');
});
});
Can you give the class a more consistent name? Like myClass_1, myClass_2, etc.
Then you could do:
$(document).ready(function() {
$('a[class^=myClass_]').click(function() { // Assign handler to elements with a
// class that starts with 'myClass_'
$(this).css('background','red'); // Change background of clicked one.
});
});
Here, a "starts with" selector is used to assign the event to all classes that start with myClass.
You could still retrieve the index number if needed.
Within the event handler, $(this) refers to the one that was clicked.
Live Example: http://jsfiddle.net/Jurv3/
Docs for "starts with" selector: http://api.jquery.com/attribute-starts-with-selector/
EDIT: I had a missing ] in the selector. Fixed now.
You can use an iterator over an array like this:
var myclasses = [".1",".2",".3"]; // generated by php
$.each(myclasses, function(index, value) {
$('a '+value).click(function() {
$(this).css('background':'red');
});
});
Note: I think you might be better off using unique ID for each item in your list of anchor tags and have them all share a single class. That's more what classes and IDs are for.
Just give them all the same class, say, myClass. Then:
$('a.myClass').click(function () {
$(this).css('background':'red');
});
This will work as long as you're having the links operate on themselves, or on their parents - as long as the relationship between link and target is the same for each. To operate on the parent, it would be $(this).parent().css(...), and to operate on the next element it would be $(this).next().css(...) and so on.
have you tried something like this?
while($row = mysql_fetch_array($results)){
$title = $row['title'];
$i++;
echo '<a class="anchor_link" id="'.$i.'">'.$title.'</a>';
}
And then for the jQuery:
$(document).ready(function() {
$('a.anchor_link').click(function() {
var thisAnchor = $(this).attr('id');
$(this).css('background':'red');
});
});
The reason for my adding the js var 'thisAnchor' is because I am assuming that you need that $i php variable as the anchor marker? if so you can just take the js var and use it however you need. if you can't use ID because the anchored content is marked by id, use a diferent attr, such as 'title' or 'alt'.
I hope this was helpful.

Replacing div html() by echoing PHP - how to?

I have a multiple product elements that get their class and ID from PHP:
$product1["codename"] = "product-1";
$product1["short"] = "Great Product 1";
$product2["codename"] = "product-2";
$product2["short"] = "Great Product 2";
<div class="leftMenuProductButton" id="'. $product1["codename"].'" >'. $product1["short"].'</div>
<div class="leftMenuProductButton" id="'. $product2["codename"].'" >'. $product2["short"].'</div>
These display as:
<div class="leftMenuProductButton" id="product-1" > Great Product 1</div>
<div class="leftMenuProductButton" id="product-2" > Great Product 2</div>
In the page, I have an element that I want to replace the HTML:
<div id="productPopupTop">
//Replace this content
</div>
Using jquery, I have tried the following:
$( '.leftMenuProductButton' ).hover (
function () {
var swapNAME = $(this).attr("id"); //gets the ID, #product-1, #product-2 etc. This works.
$("#productPopupTop").html(' <? echo $' + swapNAME + '["short"] ?>'); //This is supposed to get something like <? echo $product-1["short"] ?> This doesn't appear to work.
},
function () {
//this is just here for later
});
If I try to do an alert('<? echo $' + swapNAME + '["short"] ?>'); it will literally display something like <? echo $product-1["short"] ?>
Please note that both the Javascript and the PHP are externally linked in a PHP file (index.php <<< (js.js, products.php)
QUESTION: How do I replace the HTML() of #productPopupTop with the ["short"] of a product? If I should use Ajax, how would I code this?
try this:
$( '.leftMenuProductButton' ).hover (
function () {
$("#productPopupTop").html($(this).html());
},
function () {
//this is just here for later
});
As knittl mentioned, php is a pre-processor on the server, and can't do anything once the page has been sent to the client.
The options I can think of are
Store the product information in javascript on the client (i.e. a javascript array that is populated with php)
Use ajax to query the server with a codename and receive the corresponding data (i.e. server.com/getshort.php?codename=product-2, which would respond with Great Product 2).
If the text within the tag is always the same, #Kasia's answer will work, and is simpler.

Categories