I am trying to create a section using dragula js just like this:
http://bevacqua.github.io/dragula/
What I want is, the drag and drop should be dynamic. So that on each drag and drop the position of each element should be saved. How can I do that?
I know it can be done with php and ajax. But no idea on how the position should be manipulated
This question can be broken down into 2 different problems.
How do I keep track of the order of elements?
From what I can tell, dragula does not have a concept of tracking positioning of elements. You will have to devise a way to identify the parent container and the draggable items element. (div in the example). If you need to create the parent containers dynamically, you will need to track their order too. If you have a predefined layout, then all you need to do is track elements order and what parent they belong too. (for example, left or right, if we use the dragula example).
Create an id for each draggable element. You will have something like this.
<div id="left">
<div id="element1">Some text</div>
<div id="element2">Some other text</div>
</div>
When an element is dropped you will need to capture the element that was dropped and it's order to the parent container. To do this, you can use the jQuery index function to find the new index relative to the parent container. You will then need to reorder the list as you have it saved on the server side.
draggableElements.on('drop',function(el)
{
var parentElId = $(el).parent().attr('id');
var droppedElIndex = $(el).index();
var droppedElId = $(el).attr('id');
$.ajax({
url: "itemDropped.php",
type: 'GET',
data: { parentIdParam: parentElId,
droppedIndexParam: droppedElIndex,
droppedIdParam: droppedElId }
}).done(function() {
//do something else
});
});
How do I save the ordering of the elements?
This depends on your requirements. If you are saving the heirarchy to a database you will need to save the parent container ID for each element, the order or position it is in and the elements ID.
To rerender the page with the elements in the same order they were dropped in you would simply loop over all the elements in each container and render them in the order they are saved.
Review this [http://codepen.io/rachelslurs/pen/EjKmLG]
Also other example mostly similar with your dragula js example
sample code for to check and customize
Related
I've got a WP portfolio site using isotope to filter and sort. It works well; however, one thing I want to do is just not working.
When I hover over an image on the portfolio page, I want it to highlight all other images that are in that category. I can do it by adding each category manually using jQuery. The person whose portfolio it will be will be adding a lot more categories and won't be able to go in and fiddle with the .js file every time he adds something.
I'm sure there's a way, I just don't know how to write code. I've got this and it works nicely, but I'd rather it be able to work dynamically and not have to define the category specifically.
$('.portfolio_categories-mood-images').bind('hover', function(e){
$('.portfolio_categories-mood-images').each(function(i){
$(this).toggleClass('highlight-all');
}, function() { $(this).removeClass('highlight-all'); }); });
I'm not sure if I'm making sense. I'm still fairly new with jQuery and Javascript, so thanks in advance for your patience.
REDO:
Based on your response regarding what your <div> code looks like per image, see if this revision works better. I have notated for clarity:
<script>
// Use a more general selection type that will grab portfolio images
$(".portfolio_item").hover(
function() {
// Get the data contained in category
var ThisData = $(this).data('category');
// Split it with spaces since there are multiple space-separated tags
var GetClass = ThisData.split(" ");
// Since you have same-name classes as the array value 0 (presumably)
// you can just use the category value 0 for class name
$("."+GetClass[0]).addClass('highlight-all');
},
function() {
// Just remove the class from all elements
$(".portfolio_item").removeClass('highlight-all');
});
</script>
I'm trying to add this script to my site but there are a list of the same element generated by the script "voucherCode" so am struggling here because when I test it, only the first element will 'reveal' no matter which one is clicked...
<!--EDIT-->
tried calling the script using a class which works but now all of them reveal:
Like Blazemonger said, browsers will not pick up multiple elements with the same ID. Id should be unique, and if you need something that repeats then uses classes.
Update
well first of all you need to add the class instead of ID
<div class="voucherCode">
if you use jquery (call it in the header first, google jquery)
$('.trigger_class').click(function(){
//do what you need to do here when clicked
//to access all of the voucherCode class you use $('.voucherCode').css('display', 'block');
});
Update 2:
if you only want specific ones to reveal then you need identifiers on those ones (class(2 or more) or id(only 1)) then target the ones you want to show. To make it more dynamic, you can add a rev or title attribute to the trigger anchor tag, and use jquery to grab that attribute and use it as the element you want to reveal
<a class="trigger_class" rev="reveal_class_or_ID">....</a>
then in the javascript
$('.trigger_class').click(function(){
//grab the rev from the a, this is use a class (hence the . if it is using id it would be #)
$("." + $(this).attr("rev")).css('display','block');
});
Lastly don't forget to add the reveal_class_or_ID to your items
Update:
I am not good with php but it seems like you have the option to add the iterator or index to
<div class="revealVoucher" id="reveal_dynamicID">
Reveal Code
</div>
<div class="voucherCode" id="show_dynamicID">
<?=$voucher_code?>
</div>
I don't know how iterator works in php but if you know php this should make sense
Here's a somewhat complex puzzle, I'd love some feedback on how others would approach this.
This site is basically a free regional news blog. The image at the bottom demonstrates the layout (ignore the date overlap glitch). It's coded in PHP, jQuery and xajax.
My question has to do with dynamic content loading. As is, on page-load, I assign the arrows to the URL of the prev/next articles. No prob. The URLs are friendly, the page reloads to the next article, and I can cycle through them all day long.
But ... I'd like to turn the arrows into a slider (not an href) with the following behavior:
Clicking the right arrow will ...
Begin loading the new content offscreen via xajax,
Cause the old content to slide left (from onscreen to offscreen)
flush with the new content also sliding left (from offscreen to
onscreen).
Why? Sliders are awesome, and I think it would look pro. And this is basic slider stuff (like this jQuery scrollLeft slider) except with content being dynamically loaded on click of the arrow, which raises some questions:
What's the best approach for this?
Do I use PHP to pre-populate ALL empty hidden article DIVs?
Do I use jQuery to append/prepend/remove article DIVs with each arrow click?
What would the jQuery "scrollLeft" offset look like? The content DIV is static width, but would I be better off with jQuery scrollTo?
I hope my question is clear ... Any suggestions would be most appreciated!
Here's the solution I came up with.
http://jsfiddle.net/tXUwZ/
If anyone has ideas on how to clean it up or make it tighter, please let me know!
Many thanks to #Jamie for the push in the right direction!
You have two options in my opinion:
Populate each slider on page load so that a jQuery click function animates the content
Populating the data on a per slide basis using an AJAX call
If it's only a few items/slides, then I'd populate on page load. If you're looking at lots of slides (which you might expect with a daily news blog) or if each slide will contain a lot of data (such as high-res images, etc.) I'd go with the second option.
The second option is easy to do. All you'd need is three divs (one for the onscreen slide and two for the flanking offscreen slides that will 'replace' the onscreen one when either arrow is clicked). I'd use something like this:
<div class="container">
<div class="inner-container">
<div class="back"></div>
<div class="content off_screen_left" id="1"></div>
<div class="content on_screen" id="2"></div>
<div class="content off_screen_right" id="3"></div>
<div class="next"></div>
</div>
</div>
And the required CSS:
.container{width:200px;height:150px;overflow:hidden}
.inner-container{width:600px;height:150px;margin-left:-200px}
.content{float:left;width:200px;height:150px}
And as for jQuery:
$(".next").live('click', function(){
var current_id=$(this).prev(".on_screen").attr("id"); // get current page ID
$(".content").css("float","right"); // float all elements to the right
$(".off_screen_right").animate({display:none;}); // make the furthest right disappear gradually
$(".on_screen").attr("class","off_screen_right"); // make on_screen the new off_screen_right and add the correct ID attribute
$(".off_screen_left").attr("class","content on_screen"); // make off_screen_left the new on_screen
$(".container").prepend('<div class="content off_screen_left" id="'+current_id-1+'"></div>'); // add the new off_screen_left element and add the correct ID attribute
$(".off_screen_left").load("load-content.php?page_id="+current_id-1); // populate the new off_screen_left element
});
$(".back").live('click', function(){
var current_id=$(this).next(".on_screen").attr("id"); // get current page ID
$(".content").css("float","left"); // float all elements to the left
$(".off_screen_left").animate({display:none;}); // make the furthest left disappear gradually
$(".on_screen").attr("class","off_screen_left"); // make on_screen the new off_screen_left and add the correct ID attribute
$(".off_screen_right").attr("class","content on_screen"); // make off_screen_right the new on_screen
$(".container").append('<div class="content off_screen_right" id="'+current_id+1+'"></div>'); // add the new off_screen_left element and add the correct ID attribute
$(".off_screen_right").load("load-content.php?page_id="+current_id+1); // populate the new off_screen_left element
});
But that's just one option. You can use a slider out of the box but I prefer to custom code things so that I know exactly what I'm doing.
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);
}
}
I use this to toggle my div elements, and hide all them when the DOM is ready...
$('div[class*="showhide"]').hide();
$('input:image').click( function() {
var nr = $(this).attr('id').substr(7,2);
$('div.showhide' + nr).toggle(400);
});
I have dynamically created div elements with class showhide0;showhide1;showhide2...etc...
Inside the DIV tags I have search boxes.
First when page is loaded all DIV tags hide.
I toggle one of them to show.
Start a search, so the page is reloaded with the result of the query.
Of course all DIV is hide again, because the page is reloaded. Unfortunately...
Is it possible to not hide again after I searched for something? It would be nice when I open the page, all the divs are hidden, but after then just when I toggle it...
If you need a specific element or elements to stay visible upon a page reload, then you're going to need to do something to maintain state across requests, and then modify your jQuery to utilize that state information when initializing the visible state of the elements.
This can be done in numerous ways which include but are not necessarily limited to
Include it in the query string
Include it in the URL hash
Use a cookie
Well, yeah, you just don't run the initial hide() if there's a search request. I'd just exclude that line from the output if, on the PHP level, you know you're executing a search.
We do something similar to this where I work.
We opted instead of have the class name just be hide for all elements and instead have the ids named.
So, we'd have it something like:
<div id="hide1" class="hide"> </div>
along with this CSS to hide all those divs by default
.hide {
display: none;
}
Finally, we use something like this to show them:
$('input:image').click( function() {
var nr = $(this).attr('id').substr(7,2);
$('#hide' + nr).toggle(400);
});
}
This works because of CSS precedence rules. The toggle()/hide()/show() method overrides the hide class's style.
As for the unhiding part, if you pass the ID to unhide to your script, you can parse it and unhide the appropriate div.
You can read and process the query string from window.location.search. Unfortunately, you then have to manually parse it or use a plugin, such as jQuery Query String Object or jQuery URL Utils.
var id = $.query.get('unhide_id'); // This is using Query String Object
$('#' + id).show(400);