I've got a 3x3 grid layout using divs which upon clicking a button I need the divs to rearrange randomly. The following link illustrates an idea of what I need to create.
I don't need help with the HTML layout nor CSS design of the assignment per-se, but rather how to create the onclick function using native Javascript or jQuery in order for the "shuffle" and "sort" buttons to work. If possible, preferably Jquery, as I am more comfortable with its syntax.
I thank all in advance for help and support. Any useful links for me to do my own research is highly appreciated.
I am not looking for others to per say do my work for me, although solutions are highly appreciated, but perhaps guide me in a pseudo-code sort of way.
There are a number of different algorithms that you can use to "shuffle" a list of items. However, one of my favorite methods is the following because it is very concise.
General Shuffle Algorithm:
Find a list of items to rearrange.
Remove a random element from the items to rearrange
Insert the element into a new list
Repeat steps 1-3 until there are no more items left in the original list
Code Example
Here is a function that should do the trick:
$container = $("#container");
$divList = $("div");
$("#shuffle").on("click", function(){
//copy and remove all divs
$divCopy = $divList.clone(true);
$("div").remove();
while($divCopy.length > 0){
//chose random index of div array
var randomIndex = Math.floor(Math.random() * $divList.length);
$container.append($divCopy.splice(randomIndex, 1));
}
});
There is a full working version at https://jsfiddle.net/oruq1qou/
If you are interested in looking for other methods of solving this problem, I would recommend doing some reading on the different types of shuffle algorithms around.
Related
In line with previous questions, I have another jQuery problem that's doing my head in.
I have an Elementor widget that's outputting a list of attributes that I'm using as a filterable list, so basically, it's a bunch of a tags inside li's.
The problem is, these are being pulled from a different system (long story, not relevant to the question) and it is passing them across in all caps. I want them displaying as capitalised, but because of the nature of text-transform, CSS can't help me.
I've used text-transform to make them all lower case, and now I just want to use jQuery to capitalise them. It needs to be every word as some entries have multiple words in them. However, I'm not getting any results.
The css selectors needed to target the a tags are as follows:
.woocommerce-widget-layered-nav-list__item.wc-layered-nav-term a
I've tried loads of different scripts and messed with them for a good hour or two now and managed to get rid of errors (like $ is not a function) but cannot get the text to captialise.
I've mostly been trying exampls from [this thread][1].
Here is what I think is the closest I've come:
<script>
jQuery.fn.capitalize = function() {
jQuery(this[0]).keyup(function(event) {
var box = event.target;
var txt = $(this).val();
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
jQuery(this).val(txt.replace(/^(.)|(\s|\-)(.)/g, function($word) {
return $word.toUpperCase();
}));
box.setSelectionRange(stringStart , stringEnd);
});
return this;
}
</script>
<script>
jQuery('.woocommerce-widget-layered-nav-list__item.wc-layered-nav-term a').capitalize();
</script>
I'm fully aware that it's not structured particularly well and I know it can be neater, but I have tried numerous ways around it to no avail.
This code is currently being run from a HTML widget in the Elementor archive template where this list appears.
I'd really appreciate it is someone could point out the probably really obvious problems so I can learn from how dumb I'm being.
Many thanks.
I'm trying to build an HTML component that will provide a pivottable-like view on my data, but with custom html elements inside the pivotarea rather than a sum or count; in the example below I'll just use a string of text, but I'd like it to be any HTML element (img, div, text etc.).
I'm finding it difficult to choose a direction, writing my own code to generate it (with jQuery) or using a library like Pivottable. I've tried the latter, but couldn't even find the proper direction w.r.t. customizing the aggregator function.
I could see myself re-using the html generated by js pivottable (with a simple count) and appending items afterwards in jQuery, but this seems like a rather hacky solution, along with a lack of customization options. Pros of this approach include the fact that at some point I'd like to include filtering/customization of the colums in the web-ui.
What am I looking for? Given a JSON array with multiple rows having attributes [Columngroup1, Columngroup2], and [Rowgroup 1, rowgroup2, rowgroup3], I'd like to layout it according as following (built in Tableau):
In the example above, [Businessline, Type, Product] are the Row-groups and [Active_or_roadmap, Roadmap Quarter] are the column groups. The granularity of the dataset is one level deeper, each 'Product' can consist of multiple subproducts, which should be placed either in the 'active' column (period header) or one of the roadmap quarter columns. This can be seen by subproducts 15.03 and 15.01 being grouped in the same 'row' visually.
What difficulties am I facing?
Do I use an HTML table for this, should I go with divs with classes indicating the rows/column, or a combination of both? Added complexity: at some point I'd like the non-header columns to be 'scrollable' horizontally (if too wide).
In a situation where I'd like to filter out some rows, should I regenerate the entire table or (mis)use visibility:hidden? In the latter case: how would I deal with a Product group being partially filtered (i.e. subproduct 15.01 should not be visible, subproduct 15.03 does need to be visible)
How would I 'embed' the object details in the DOM element? i.e., in the case of a hover/clickevent, how would I know which row in the JSON object corresponds to the name that was clicked?
Note that I'm not necessarily looking for an answer that fully does what I'm saying above, I'm primarily looking for a direction w.r.t. the code to go from the JSON to the above table in a structurally decent and flexible manner.
Any help is greatly appreciated, I have a codepen that contains some sample data and a rather poor attempt.
function load_data(callback){
$.getJSON('https://s3-us-west-2.amazonaws.com/s.cdpn.io/997352/data_portfolioroadmap.json', function(data){
callback(data)
});
}
I'm thinking something like this
{[
{productTitle:"Product 01.01",state:"Active","quarter":"2017Q1"},
{productTitle:"Product 01.02",state:"Roadmap","quarter":"none"}
]}
With this you should be able to loop over the array and place each element. I would use custom divs. First loop over the quarters and build those out. The loop over the state and filter grabbing the ones you need. Put the filtered results in a new var and sort it. The place each item in the proper column position as you are building out your rows. Then repeat with the next state.
Hope this make sense.
I think that managing that complex structure could force you to think of this table as a embeded components. Thinking of that maybe React (https://facebook.github.io/react/) could be appropriate solution for that.
Thinking about extending existing library is crucial for making this cost-effective, so please see https://react.rocks/example/orb (http://github.com/nnajm/orb) that maybe could be easier to extend using component matter of React that was used there.
Hi I want to have Layers sort control like on photoshop using FabricJS
I have this solution but it's not working well when you have more than 3 objects on canvas:
$("#containerLayers").sortable({
change: function(event, ui){
$( "#containerLayers li" ).each(function(index,list){
if(objectArray[$(list).attr('id')]){
canvas.moveTo(objectArray[$(list).attr('id')],index);
}
});
canvas.renderAll();
}
});
Here is other parts of code:
https://jsfiddle.net/peLcju2h/16/
does anyone have a better solution than this?
Best solution for Layer ordering using FabricJS is this one:
$("#containerLayers").sortable({
update: function(event, ui){
var items = $(this).children();
items.each(function(i,item){
canvas.sendToBack(objectArray[item.id]);
});
canvas.renderAll();
}
});
Instead of using canvas.moveTo() just use canvas.sendToBack() and it will work perfect
Here is link and you can see that ordering is working good
https://jsfiddle.net/peLcju2h/24/
First of all, you have some important refactorings to make in your code, mainly because of the fact that a lot of its snipets are duplicated.
I did it already, and the final working code is here: https://jsfiddle.net/peLcju2h/18/
Let's see some considerations:
All the Canvas object creations had the same code, so wrap it into a function;
You were adding objs to your array through push() function, which is not wrong, but it messed up with your UI sortable handling. That's because every time you change li's position, only the canvas and HTML are updated, but not the array itself.
You could use a reordering function for this, but it wouldn't fit the goal here once element positions don't have a predefined order or changing logic.
Instead, I decided to go with an auxiliary array, which is gonna be populated every time the items are sorted.
Push the items via [] operator into the array, using the object id as the key;
In the end, notice that I put a promise to guarantee the new objectArray will be rendered only after the canvas work has been done.
Note: JSFiddle only works with HTTPS external links, so make sure you
import them correctly in future attempts, even if you're doing this
via CSS #import.
I currently use the each formula to get around with looping between separate dependant elements such as below:
// #UL-container is on the html index (main) page
$('#UL-container').find('.UL').each(function(){
var ulrel = $(this).attr('rel');
var numChilds = $(this).find('li').length;
// #CAT-container is on an ajax-loaded same origin page
$('#CAT-container').find('.catlink[rel='+ulrel+']').each(function(){
$(this).parent().find('.catcontent-length').append(numChilds);
});
});
This works great: catcontent-length classes simply display image lengths from a static list of related image titles located in #UL-container, but am wondering if the above stacked each jQuery solution is as quick processing-wise -- regardless of amount of elements affected -- as any other possible jQuery / javascript leaner solution out there. Any better quicker solution bearing in mind the scenario above?
JS Fiddle (code)
This is more of a task I have set myself to learn Arrays but now I was wondering if any of you can think of a better cleaner way of doing this task. I simply want a list of projects which highlight when the user hovers over some links..
What I want to do
I have a list of projects, on each project I could have worked on the SEO, Develpment or Design. On the page there is also a list of links say: Design, Development and SEO. When hovering over a link I want some of the projects to highlight..(combinations). So some projects I might of done more then one task on will highlight for more then one link.....
How I currently tried to do this
I thought that I could make a 2d array with a list of on offs for the projects. Depending on what link you hovered over pulls out the correct array, if you see the JSfiddle link, that is as far as I could go.
An Example of something very similar
ID Design
Thank You for anyhelp or advice
I hope I explained that clearly, I know I could rip the code off for the example link, but I rather learn from doing then just cut and paste.. - see what others think and use jquery.
You can use 3 different styles for each project , let say : ".design", ".seo", ".development"
$("#link1").hover(
function ()
{
$(".design").each(function()
{
$(this).toggleClass("highlight");
});
},
function ()
{
$(".design").each(function()
{
$(this).toggleClass("highlight");
});
}
);
Explanation:
When mouse is hovered over link1 a class .highlight is toggled (added when mouseover,removed when mouseout) on elements that use .design class. You can do similar way to others 2 classes.