2

Hi Is there a shorter way of writing the following code?

(data === "item1" || data === "item2" || data === "item3" || data === "item4")

like

(data === "item1" to data === "item4")

as my list will be over 100 items.

Heres a jsfiddle with the code in it.

Please note this only has to work on IE11. Here is the piece of code

ar list = document.querySelectorAll("#dragsource li");
for (i = 0; i < list.length; i++) {
  list[i].draggable = true;
  list[i].ondragstart = function(event) {
    var event = event || window.event;
    var dt = event.dataTransfer;
    dt.setData("text", event.target.id);
    dt.effectAllowed = "move";
    var data = dt.getData("text");

    if ((document.getElementById("onoff").value == "On") && (data === "item1" || data === "item2" || data === "item3" || data === "item4")) {
      (document.getElementById("fruit").style.color = "red") && (document.getElementById("veg").style.color = "black") && (document.getElementById("games").style.color = "black");
    } else if ((document.getElementById("onoff").value == "On") && (data === "item5" || data === "item6" || data === "item7" || data === "item8")) {
      (document.getElementById("veg").style.color = "red") && (document.getElementById("fruit").style.color = "black") && (document.getElementById("games").style.color = "black");
    } else if ((document.getElementById("onoff").value == "On") && (data === "item9" || data === "item10" || data === "item11" || data === "item12")) {
      (document.getElementById("games").style.color = "red") && (document.getElementById("fruit").style.color = "black") && (document.getElementById("veg").style.color = "black");
    } else if ((document.getElementById("onoff").value == "Off") && (data === "item1" || data === "item2" || data === "item3" || data === "item4" || data === "item5" || data === "item6" || data === "item7" || data === "item8" || data === "item9" || data === "item10" || data === "item11" || data === "item12")) {
      (document.getElementById("fruit").style.color = "black") && (document.getElementById("veg").style.color = "black") && (document.getElementById("games").style.color = "black");
    }

  };
}

rojo - I have tried to shorten this :-

target1.ondrop=function(event) {
var event=event||window.event;
var dt=event.dataTransfer;
event.preventDefault();
var data = dt.getData("text");
if(data === "item1" || data === "item2" || data === "item3" || data ===     "item4"){
target1.appendChild(document.getElementById(data));
}
};

By doing this this but does not work, no D&D & button not working. Where am I going wrong

target1.ondrop=function(event) {
var event=event||window.event;
var dt=event.dataTransfer;
event.preventDefault();
var data = dt.getData("text")num;
if (num = /^item(\d+)$/.exec(data)) num = num[1] * 1;
if(num <= 4){
target1.appendChild(document.getElementById(data));
}
};

**Not Quite Worked it out - comma missing after ("text") and bracket in wrong place ,should be in front off - if (num <= 4)

target1.ondrop=function(event) {
var event=event||window.event;
var dt=event.dataTransfer;
event.preventDefault();
var data = dt.getData("text"), num;
if (num = /^item(\d+)$/.exec(data)) num = num[1] * 1;
{if (num <= 4)
target1.appendChild(document.getElementById(data));
}
};

REVISED ELSE IF SOLUTION

target1.ondrop=function(event) {
var event=event||window.event;
var dt=event.dataTransfer;
event.preventDefault();
var data = dt.getData("text"), num;
if (num = /^item(\d+)$/.exec(data)) num = num[1] * 1;
if (num <= 4){
target1.appendChild(document.getElementById(data));
}
else if (num <= 8){
target2.appendChild(document.getElementById(data));
}
else if (num <= 12){
target3.appendChild(document.getElementById(data)); 
}
else if (num <= 60){
target4.appendChild(document.getElementById(data));  
}
else if (num <= 86){
target5.appendChild(document.getElementById(data));
}
};
};
aceuk007
  • 85
  • 7

2 Answers2

2

You could regexp scrape and math your way out of the problem pretty easily.

var data = 'item12'; // demo value

if (num = /^item(\d+)$/.exec(data)) {
    num = num[1] * 1;
}

That will perform an assignment if the regexp is matched, coercing the value from a string into a number. If not matched, the assignment coerces as false, and num is null. With the given value of data='item12', the value of num is 12. From there, it's just a simple check of greater than / less than.

switch (true) {
    case (num < 5):
        /* relevant stuff here */
        break;
    case (num < 10):
        /* other relevant stuff here */
        break;
    case (num < 20):
        /* do something else */
        break;
    default:
        /* not matched by any of the conditions above */
}

With that switch statement, num with a value of 12 would trigger the third condition (num < 20).


Extra credit

Instead of this repetitive stuff:

document.getElementById("fruit").style.color = "black" && document.getElementById("veg").style.color = "black" && document.getElementById("games").style.color = "black"

Try this:

var colors = {
    "fruit": "black",
    "veg": "red",
    "games": "black"
}

for (var i in colors) {
    document.getElementById(i).style.color = colors[i];
}

Or, since you're doing a lot of color changes, write a function.

function color(id, foreground, background) {
    document.getElementById(id).style.color = foreground;
    document.getElementById(id).style.backgroundColor = background;
}

color('fruit','black','gold');
color('veg','red','black');
color('games','black','gold');

Here is your script rewritten with my suggested changes. Let this serve as an example of how writing functions to handle repetitive tasks can result in much less typing.

// arguments: {"id":"color", "id2":"color2", "id3":"color3", etc.}
function color(paramObj) {
    for (var i in paramObj) {
        document.getElementById(i).style.color = paramObj[i];
    }
}

var list = document.querySelectorAll("#dragsource li");
for (var i = 0; i < list.length; i++) {
    list[i].draggable = true;
    list[i].ondragstart = function(event) {
        var event = event || window.event,
            dt = event.dataTransfer;
        dt.setData("text", event.target.id);
        dt.effectAllowed = "move";
        var data = dt.getData("text"), num;

        if (num = /^item(\d+)$/.exec(data)) num = num[1] * 1;

        if (document.getElementById('onoff').value == 'On') {
            if (num <= 4) color({'fruit':'red','veg':'black','games':'black'});
            else if (num <= 8) color({'fruit':'black','veg':'red','games':'black'});
            else if (num <= 12) color({'fruit':'black','veg':'black','games':'red'});
        } else {    // #onoff value is "Off"
            if (num <= 12) color({'fruit':'black','veg':'black','games':'black'});
        }
    };
}
Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
  • @rojo- thank you for replying. I really don't understand this coding. could you show/tell me what this replace's. Re extra credit the colours used will be red & black. The box names will only change to red when the hint button is on and drag a item begins. It is just to help where the item should go. when the button is off then the names will stay black. Cheers – aceuk007 Feb 08 '16 at 11:10
  • @aceuk007 See my edit. Hopefully, seeing my suggestions within the context of your "the code" will provide some illumination. – rojo Feb 09 '16 at 01:59
  • @rojo- I have expanded the drop targets to 5 and it works. Thank you for showing me how.If you don't mind could you look at main post above from - rojo - I have tried to shorten this :- Just can't get this bit to work. Cheers – aceuk007 Feb 09 '16 at 13:10
  • I worked it out - solution above I had a missing comma and bracket in wrong place. Once again thanks for you help. – aceuk007 Feb 09 '16 at 15:51
  • seems I jumped the gun . need to find out how to write 1 to 4 ,5 to 8, 9 to 12 , 13 to 60 , 61 to 86 as <= is less than – aceuk007 Feb 09 '16 at 16:58
  • It's less than or equal to. Just add `else if (num <= 60)` and `else if (num <= 86)` – rojo Feb 09 '16 at 17:05
  • Hi would you mind looking at ELSE IF SOLUTION above in main post (sorry I don't know how to put it here).I have tried the else if as shown above but it is not working. can you spot where I have gone wrong . I tried to copy else if layout. Thank you – aceuk007 Feb 10 '16 at 09:18
  • Well, it looks maybe a little odd all left-justified, your `if` statements inexplicably in a braced block for no reason, and your `if` statement actions in parentheses instead of braces; but I don't see any major stop-error issues off-hand. You do have an extra `};` at the end. (Count them. You have 2 `{` and three `}`.) Maybe that's halting your script? Are you checking your browser's console for errors? in Firefox, hit Ctrl+Shift+k. In IE, hit F12. In Chrome, hit Ctrl+Shift+i. – rojo Feb 10 '16 at 12:36
  • can you pass your expect eye over this .I've spent ages looking at examples and trying different things, but still can't get it to work. What is happening is everything will only go into fruit target. I have posted a revised else if solution above which seems to look right to me. As for the extra }; at the end, if this is removed the whole script does not work. Tried it in the fiddle - link above. Cheers – aceuk007 Feb 11 '16 at 13:08
  • @rojo- I should add that I did not get any errors when I pressed F12 – aceuk007 Feb 11 '16 at 16:45
  • I would like to say thank you for all you help. The effort you put into rewriting the script to make it work is much appreciated. I have very little knowledge of coding most of it just baffles me. All that I had done was finding bits of code that did what I wanted and put it together, which is why it was proberly not very well written. – aceuk007 Feb 12 '16 at 13:13
  • My project is near complete now. It's a training program to help new employees learn which dept staff are in. I work in a Post Room and have a name list with 1000+ names. So the Target areas will become Depts and the drag items will be Names. I have added some code to only display 60 names and to shuffle the list with a refresh button ,added 2 more target areas plus made the list up to 86 names. Can i ask one last thing - How do you make the HINT button be Red for off & Green for On. Thank again - Paul – aceuk007 Feb 12 '16 at 13:13
  • @aceuk007 What you're describing, "finding bits of code and putting it together", is called learning to code. Enjoy the adventure. `:)` Finding other people's code and figuring out how to make it work for your own evil purposes is the first step to learning any language. Anyway, see http://jsfiddle.net/8mw1s2zj/9/ -- in particular, the HTML frame with the changes to the ` – rojo Feb 12 '16 at 13:51
  • Thanks for the kind words. Top notch service as always. Thank you – aceuk007 Feb 12 '16 at 15:30
  • Hope you don't mind I discovered strange effects when testing.If drop a drag item on grey background get green border aroung section area.If start to drag item but drop it on another name you end up with green border around name and if you drop item on blue background you get a green border around it. Drop an item inbetween the names and you get a border around al of them.I have had a look to see if I can see what is causing this but nothing stands out. It happens in this fiddle HERE If you have a moment would you have a look cheers. – aceuk007 Feb 23 '16 at 13:24
  • Sorry my link is not working ,but it is yours from post above – aceuk007 Feb 23 '16 at 13:31
  • @aceuk007 Sorry, I just now saw this. Tag me with "@rojo" if you want me to be notified that you commented. Anyway, change line 84 to `if (e.target.className == 'droptarget') el.style.border = "2px solid green"`. Also, see [comment formatting](http://meta.stackoverflow.com/editing-help#comment-formatting) for the markdown syntax needed to put hyperlinks in comments. – rojo Feb 26 '16 at 16:35
  • I have always replied with "@rojo" but sometines it don't show. Like now .Anyway Thank you again. Just got the boring task off putting all the names in.Still glad I got to this stage. All be it with help. Cheers Paul – aceuk007 Mar 01 '16 at 13:45
1

put the criteria values into an array.

var dataArray = ["item1", "item2", "item3"...]

then:

var targetValue = "item3";
if (dataArray.indexOf(targetValue) != -1)....
davidWazy
  • 61
  • 6
  • thank you for the reply. I have very little understanding of this coding. Is it possible you could show it in the piece of code I have just displayed above. cheers – aceuk007 Feb 03 '16 at 14:51
  • If this is indeed JScript and not JavaScript, be advised that `Array.prototype.indexOf` is not defined in the JScript 5.7 feature set imposed by Chakra without invoking [IActiveScriptProperty::SetProperty](http://stackoverflow.com/a/34966337/1683264). – rojo Feb 04 '16 at 16:44
  • @rojo- sorry I thought jscript was just a short way of writing javescript. – aceuk007 Feb 08 '16 at 11:02