Forum Discussion

ELOUPEI's avatar
ELOUPEI
Community Member
27 days ago
Solved

Drag and Drop With Feedback Layers BUT NOT Correct or Incorrect

I'm trying to figure out a drag and drop where the user has nine dragable items and seven drop zones. The goal isn't to find the seven correct items of the nine. The user can drag any of the nine in an order into the drop zones. They'll snap into place and/or return to their original spot if something else gets put on top of them. When I converted my slide to freeform drag & drop, that part all worked fine.

The feedback for the user is represented by two layers and a button (that's hidden and waiting to be revealed). If the learner selects less than four items, they get the layer saying too few selected. If the learner fills up all seven slots, they get the too many layer. If they select between four and six items, the next button becomes visible and they are able to move onto the next slide. The goal is the user needs to keep submitting then fixing their response until they have between four and six items dragged into the drop zones. And I've been able to set all of that up on the slide in a way that I think works. But I don't know for sure...and here's why... 

The problem: I can't figure out how to get Storyline to keep count of the number of items the user has dragged and dropped so that when they click the finish button, they get one of the feedback layers or they see the next button. Everything I've tried leads to either the variable I'm using to tally not moving from zero, or changing to one but to no other increment/decrement no matter how many items I drag and drop or remove. File attached.

  • Although ThierryEMMANUEL has figured out a solution, I would still like to try a simpler version without using a tons of triggers.

    I use the built‑in drag‑and‑drop function so that objects can return to the start area when a target is occupied. I also prefer using "state" for counting the TotalPlaced value and rely on two triggers to change the state.


    What the built‑in model cannot change is that when another item is dropped on the same target, the original item still remains in the "placed" state even after returning to its initial position. Since this is the only issue in my solution, I thought—why not use the new AI assistant to solve the problem? Below is the prompt I gave the AI assistant, and it worked as expected. A single JavaScript snippet solved it.

    Change the state of crit# to normal when they moves onto hotspot1 area. For example, change crit9 to normal when it moves onto hotspot1.

    Here is my version3. As Nedim said, I also value discussions like this and gracful learn something from each other. Thank you! 

23 Replies

  • Silverfire's avatar
    Silverfire
    Community Member

    Hi, I downloaded the story and previewed it. At first, the Finish button wasn't displaying, so I disabled that trigger. I didn't see where TotalPlaced was incremented at all, though. Even with the Finish button displaying, I always got the "Too Few" slide, because TotalPlaced remained at zero. 

  • Nedim's avatar
    Nedim
    Community Member

    I wanted to help, but when I opened your story file, a lot of “unassigned” values popped up, and I’m not sure what they’re supposed to represent. 

     

  • Hi ELOUPEI,

    You can use states to identify whether an object is dropped. If the object isn’t normal, then add 1 to TotalPlaced; if the state is normal, subtract 1 from TotalPlaced. I also added a new variable called ActivityBegin to prevent subtracting a value from TotalPlaced, since the object states are normal at the very beginning. So other than the first trigger below, for each drag item, you will need two triggers for counting:

    1. Set ActivityBegin to True when TotalPlaced changes.
    2. Add 1 to TotalPlaced when the state of crit# isn’t normal.
    3. Subtract 1 from TotalPlaced when the state of crit# is normal, if the ActivityBegin value is true.

     

    However, if users drag the crit# out of the drop zone, its state won’t return to normal and the counting will be incorrect. So each crit# should have a trigger to return its state to normal to ensure the counting is correct.

    • Change the state to normal when crit# stops intersecting with the hotspot (table area).

     

    • ThierryEMMANUEL's avatar
      ThierryEMMANUEL
      Community Member

      Unfortunately, JoanneChen​ , I've run into another problem. If I move the proposals WITHOUT taking them out of the starting area (I know, it's stupid), the variable increases to possibly 9. And I can't bring the variable back down.

      • ELOUPEI's avatar
        ELOUPEI
        Community Member

        Yeah, it doesn't seem to be following the triggers of subtracting one from the count or setting the state of the criteria back to normal. And here's a video showing some of the other things that are happening with the count when you try adding and removing various criteria. The "argument/purpose" criteria is acting the weirdest of them all. 

        https://360.articulate.com/review/content/62098877-4d92-421d-ad04-494ef090f311/review

  • Hello ELOUPEI​ 

    I explored (like JoanneChen​) and abandoned solutions using states. Too complicated, because in addition, you want to use a built-in drag & drop to use the “automatic return of a movable element to its starting point if the learner places another element on top of it” function.

    I suggest another way of doing this, which I have used before.

    When you press the Finish button, you trigger the motion path of an element (mobile counter) that adds the value 1 to your TotalPlaced variable each time it encounters an element moved by the learner. If the mobile counter crosses 3 elements placed in the drop zone, TotalPlaced = 3, and the message “Too few” is displayed. Etc. Watch and study the attached demo, slide 2.

    It's a bit of a DIY job, you have to make sure that the elements don't touch each other so that the mobile crosses each one of them, and not a bunch of elements, and the speed must not be too fast so that Storyline has time to trigger the triggers (yes, really!).

    Here, the trajectory is straight, but imagine an activity where objects are dragged&dropped all over the screen. The mobile device can follow a very complex zigzag motion path to cross paths with the objects and count them. That's what I used a while ago.

    Note: there is a small error in your triggers panel. The FINISH button ONLY appears/is active when the variable is between 4 and 6. It therefore cannot trigger other actions whose condition is that the variable is <3 or >6.

    I hope this helps.

     

     

  • Hi ThierryEMMANUEL,

    I didn’t realize that the state would change to dropIncorrect when the item dropped outside the designated drop areas. This should be taken into account because it could happen in the real world—we never know what users might do, LOL. So, I moved the hotspot to the start area and changed the trigger to:

    • Change the state to normal when crit# is dropped on the hotspot (inital area).

     
    ELOUPEI, I hope this fixed the issue you encountered.

    • ThierryEMMANUEL's avatar
      ThierryEMMANUEL
      Community Member

      Thank you very much for continuing to update your work JoanneChen​  (unfortunately, I feel like I'm the only one who noticed...). I checked your demo and, not quite, there's still a small problem 🙂. If I move a proposition (for example, number 2 in the screenshot) and then move it back to the starting area because I changed my mind (which is more “normal” behavior than what I did in my previous response), the “Total Placed” counter remains at 1 even though the drop zone is empty. I can do this four times in a row with four different proposals and set the “Total Placed” to 4 and get the Next button...

       

      • JoanneChen's avatar
        JoanneChen
        Super Hero

        Hi ThierryEMMANUEL,

        Thanks for checking! I realized I hadn’t uploaded my second version of the file. In this version, users can change their mind and move the item back to the start zone without affecting the counter.
        I also took a look at your file—well done! You used a different approach and really nailed it.

    • ThierryEMMANUEL's avatar
      ThierryEMMANUEL
      Community Member

      Hello Nedim​ 

      Glad to see you here. When I saw that you had posted a solution, I thought to myself, “I'm going to learn something today.” I thought, “What a brilliant idea to use a (virtually invisible) trajectory just to trigger something. I hadn't thought of that.” But actually, I'm studying the file, and I'm still studying it, and I don't understand what it's for. (Maybe to avoid placing 8 and 9 elements). It's beyond my understanding and logic. I should understand since everything is in the triggers panel. But no. It's very strange and intriguing.🙃

      Anyway, it works perfectly... except that... ELOUPEI wanted “The user can drag any of the nine in an order into the drop zones. They'll snap into place and/or return to their original spot if something else gets put on top of them.” With only one drop zone, the second one is not respected. Was it very important? Maybe not. And, it's true, it's not very clear whether a maximum of 7 or up to 9 items could be selected (even though there were only 7 zones in the original file).

      So, if I were to try to simplify your proposal, I would use only 2 triggers for each movable element to adjust var TotalPlaced: “Add the value 1 to TotalPlaced when Crit1 crosses DROP(zone).” "Subtract the value 1 from TotalPlaced when Crit1 has finished crossing DROP(zone). And that works too.

      Once again, I'm happy to brainstorm with you.

      • Nedim's avatar
        Nedim
        Community Member

        Hi ThierryEMMANUEL​! Nice to see you again!

        I initially gave up on this when I first opened the file and saw a number of unassigned lines, mostly connected to the slider. I didn’t have time to dig into that at the time, so I moved on. Since this post kept popping up at the top, I decided to give it another try—especially after noticing that the proposed solutions didn’t work as expected and that everyone seemed to ignore the slider, assuming it wasn’t relevant to the interaction.

        When I took a closer look, I realized this wasn’t anything particularly complex (so, no “wow” moment this time 🙂.) In fact, I had built a very similar interaction a long time ago, so I reused a few triggers from my old .story file and continued from there. The only real challenge was figuring out how to convert an object back to its normal state after it had been dropped and moved elsewhere, while also ensuring proper tracking as it was moved back and forth.

        Yes, the additional conditions in my “Add to” variable are there to ensure that the total number of dropped items does not exceed seven. Further down, if the count reaches seven and another criterion is dropped, one item is removed to maintain the limit, and so on.

        You may also be right that I misunderstood the original concept of having seven separate drop zones rather than a single one, which I chose to implement instead to simplify the process. That said, I don’t really understand the need for seven drop zones if the interaction is only validated when four, five, or six items are dropped and the Finish button is pressed.

        If the priority or order of the items matters (meaning the sequence in which they are presented or dropped), then multiple drop zones make sense. If so, what exactly constitutes an order or a correct sequence? However, if the interaction only checks how many items are dropped, and not which zone they are in or their order, then the number of drop zones (whether one, seven, or even nine) doesn’t really matter.

        "I would use only 2 triggers for each movable element to adjust var TotalPlaced: “Add the value 1 to TotalPlaced when Crit1 crosses DROP(zone).” "Subtract the value 1 from TotalPlaced when Crit1 has finished crossing DROP(zone)."
        Yes, I could have done that as well and it would have worked. I chose the state-based approach because the Placed state was already created in the downloaded file, so I went with that. I also find the state option more reliable than relying on intersecting events in more complex interactions.

        I’ve now downloaded your solution as well, and I’m actually surprised that it required over 120 triggers and too many conditions spread between the base layer and an additional calculation layer (although I do like the approach of having a separate layer that runs for about a second, does its job, and then closes automatically). I haven’t studied it closely yet to understand why, but I’ll take a look. I assume it’s because you went with the multiple drop-zone approach. But as you’ve already figured out, the secret sauce here was implementing motion path animations to help objects return to their Normal state before being dragged or moved again, ensuring that the calculations remain accurate.

        The solution I provided uses only about 54 triggers (six per draggable object). I also always like to have a real-time counter so I know exactly what will happen before I even test it with another button. It’s a kind of debugging aid that I can’t really live without.

        Once again, I'm happy to brainstorm with you.
        Likewise, and thank you. I value discussions like this. There are only a few people in the community who truly dig into the reasoning, explore alternatives, and genuinely explore different approaches and seek to understand the why, not just the how.

  • I think I've finally got it!

    ELOUPEI​ JoanneChen​ Nedim​ 

    Look at the third slide of the attached demo.

    The principle: No built-in drag and drop. Each Crit gets the “Placed” state when it is dropped on one of the 7 drop zones OR onto of one of the other Crits (in case a drop zone is already occupied by another Crit). When you click the Finish button, it adds 1 to the ‘TotalPlaced’ variable for each “Placed” Crit. Done!

    How to do : “They'll snap into place and/or return to their original spot if something else gets put on top of them.” ?

    This is where Nedim​'s idea of using a motion path really helped me. Each Crit has a motion path of 0px (meaning it will return to its original spot). I trigger this motion path if the learner replaces the Crit on the starting area OR if the learner places another Crit on top of it (the new Crit stays and the previous Crit returns to its place). At the end of the 0px motion path, the Crit returns to its normal state. This way, only Crits with a “Placed” state are counted when you click Finish. It works...

    What do you think ?

  • Although ThierryEMMANUEL has figured out a solution, I would still like to try a simpler version without using a tons of triggers.

    I use the built‑in drag‑and‑drop function so that objects can return to the start area when a target is occupied. I also prefer using "state" for counting the TotalPlaced value and rely on two triggers to change the state.


    What the built‑in model cannot change is that when another item is dropped on the same target, the original item still remains in the "placed" state even after returning to its initial position. Since this is the only issue in my solution, I thought—why not use the new AI assistant to solve the problem? Below is the prompt I gave the AI assistant, and it worked as expected. A single JavaScript snippet solved it.

    Change the state of crit# to normal when they moves onto hotspot1 area. For example, change crit9 to normal when it moves onto hotspot1.

    Here is my version3. As Nedim said, I also value discussions like this and gracful learn something from each other. Thank you! 

    • ThierryEMMANUEL's avatar
      ThierryEMMANUEL
      Community Member

      I love this team effort!!! 😁  Obviously, the JS code does the job very efficiently JoanneChen​.

      What the built-in model cannot change is that when another item is dropped on the same target, the original item still remains in the ‘placed’ state even after returning to its initial position.” was my kryptonite. That's why I looked for a workaround (with lots of triggers). Well done!

      And I'm learning from your prompt how to better talk to the AI thingy.

      • ELOUPEI's avatar
        ELOUPEI
        Community Member

        JoanneChen​ ThierryEMMANUEL​ Nedim​ Thank you for the help thus far. I've tried to follow along with this conversation as best I could. I've used JoanneChen​'s V3 file as the solution for my project.

        However, there's more to fix that I need assistance with...

        The interaction is a build-your-own rubric and the user can choose between an analytic rubric template or a single-point rubric template. That is what the slider at the top of the slide is there for. The user can toggle the slider (which activates a jump to slide trigger that moves the user between the two different rubric templates).

        The problem: When I toggle the slider from Analytic to Single-Point, the slide does change correctly BUT the slider does something unexpected. Instead of the button now positioning under Single-Point, it jumps back to position under Analytic. I am looking at the Single-Point rubric template slide but the slider button suggests I am on the Analytic rubric template slide. If I want to go back to the Analytic rubric template slide, I first have to drag the slider button back over to Single-Point and then toggle back to Analytic, at which point the trigger fires properly and I jump back to the Analytic rubric template slide.

        What am I missing to get the slider button to stay at the correct end of the slider for what's showing on the screen?