0

This may seem a little odd, but I need to randomize the order of 4 flexbox items. These need to be randomized onInit.

I could randomize the numbers in javascript, but how do I bind that property to CSS?

This is my code:

CSS:

.buttons {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-around;
    margin: 2rem;
}

HTML:

  <div class="buttons">
    <button>{{ mcqs.answer1 }}</button>
    <button>{{ mcqs.answer2 }}</button>
    <button>{{ mcqs.answer3 }}</button>
    <button>{{ mcqs.answer4 }}</button>
  </div>

Basically I just need a really simple way to randomize the order of the answers (for a multiple choice test application). Thanks!

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Thjen
  • 527
  • 1
  • 9
  • 18
  • I think you can repeat your buttons like this: ``. Then you can consider adding some dynamic class with `ng-class="get_random_class($index)"`, etc. – Aleksey Solovey Oct 31 '18 at 15:57

3 Answers3

1

You'll want to conditionally apply classes to your elements using a function in your AngularJS controller. Add CSS rules for those classes.

<style>
.col-order-1 {
    order: 1;
}
.col-order-2 {
    order: 2;
}
</style>

<div class="buttons" ng-class="getOrderClass($index)"> ... </div>

Don't try to modify the CSS directly. You could also build the entire button list markup in the controller and bind that instead.

isherwood
  • 58,414
  • 16
  • 114
  • 157
  • The $index parameter would require me to loop the buttons in ng-repeat, correct? I will only ever have 4 buttons, so is it possible to randomize which class it collects from the function, based on a parameter of (lets say) 1,2,3 or 4? This i just my initial idea at least, I don't need to loop the buttons. – Thjen Oct 31 '18 at 16:37
  • Yep. I didn't indicate a repeat, but that might be the simplest approach. Simplifying your markup is nice, and you already have the array (or can easily create one). – isherwood Oct 31 '18 at 16:38
  • Adding a class won't change the order that flexbox displays content. It's always going to display content in the order of the markup UNLESS you specify `flex-order` – Bryce Howitson Oct 31 '18 at 16:46
  • @BryceHowitson, [order can be applied via CSS classes](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items), no? – isherwood Oct 31 '18 at 16:49
  • @isherwood the link you referenced doesn't allow random order it's based on markup order and can only define if the presentation starts with the first or the last item. – Bryce Howitson Oct 31 '18 at 16:52
  • Of course it doesn't refer to randomizing--that's done in the JavaScript. – isherwood Oct 31 '18 at 16:54
  • I'm not sure I understand your point, though. [Here's more](https://developer.mozilla.org/en-US/docs/Web/CSS/order) on specifying order in class rules. – isherwood Oct 31 '18 at 16:55
  • @isherwood, my point is that the OP specifically asked about randomizing the order of flexbox display in CSS – Bryce Howitson Oct 31 '18 at 16:58
  • Yep, and not only is that practically infeasible, it's not a good practice in the first place. – isherwood Oct 31 '18 at 16:59
1

try this, you wont need to randomize numbers :

var answers  = $("button");
for(var i = 0; i < answers .length; i++){
    var target = Math.floor(Math.random() * answers .length -1) + 1;
    var target2 = Math.floor(Math.random() * answers .length -1) +1;
    answers .eq(target).before(answers .eq(target2));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
    <button>{{ mcqs.answer1 }}</button>
    <button>{{ mcqs.answer2 }}</button>
    <button>{{ mcqs.answer3 }}</button>
    <button>{{ mcqs.answer4 }}</button>
  </div>

original answer here : Random Div Order on Page Load

Imad El Haj
  • 101
  • 5
-1

Add a flex-order to the buttons to force them to display in any order independent of the markup.

Here's the basic use case:

.flex-item {
   order: 1;
}

Or you can add the CSS inline like so:

<div class="buttons">
    <button ng-style="{'order': randomIndexNum}">{{ mcqs.answer1 }</button>
    <button ng-style="{'order': randomIndexNum}">{{ mcqs.answer2 }</button>
    <button ng-style="{'order': randomIndexNum}">{{ mcqs.answer3 }</button>
    <button ng-style="{'order': randomIndexNum}">{{ mcqs.answer4 }</button>
</div>

This can be done with Angular or any other tools that can modify the HTML onInit.

Documentation from CSS-Tricks

Bryce Howitson
  • 7,339
  • 18
  • 40