# Help with adding autocomplete to a sketch

**URL:** <https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440>\
**Category:** Coding Questions\
**Created:** [August 21, 2022, 2:37pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440 "2022-08-21T14:37:53Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [August 21, 2022, 2:37pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/1 "2022-08-21T14:37:53Z")

</div>

Hi all-

Im hoping someone might be able to help point me in the right direction. Im creating a sketch that acts as an interactive inventory map for the shop that i work in. For example, when a person types in a search term such as “hammers” and either clicks the submit button or presses the enter key on the keyboard, a simple animation plays on the location (a picture of the shop floor layout) of the item in the shop. So far the sketch works really pretty well (i think), however, I want to add suggestions for key search words after the first few letters are typed. So, lets say a user types in the letters “h”, and “a”, a list of all items that begin with those letters would be listed to make it a little easier for people. My sketch uses google sheets for its data and each “location” (i.e. cabinet #1 or table#4, etc.) is arranged in the google sheet in columns. (Not sure if this tidbit of info is relevant or not to anyone trying to help)

I did find one sketch from a google search, unfortunately Im just not skilled enough to take the example i found and use it in my sketch.

Heres my sketch

```auto
let dia = 0;
let growAmount = 0.5;
let grow = true;

let input, button, greeting, img, data;

let url =
  "https://docs.google.com/spreadsheets/d/e/2PACX-1vRmua9Ue9Uv2olN_0kOvTbAPPBkJ3ckciRbDUs_jUr9eMv43sgdFrzmcluQGd4MQrsiYemarPqLsjVj/pub?gid=0&single=true&output=csv";

///////////////////////////////////////////////////////////////////////////

function preload() {
  data = loadTable(url, "csv", "header");
}

///////////////////////////////////////////////////////////////////////////

function setup() {
  // create canvas
  createCanvas(1794, 600);

  img = loadImage("LMP Map2.png");
  name = null;

  input = createInput();
  input.position(20, 600);

  button = createButton("submit");
  button.position(input.x + input.width, 600);
  button.mousePressed(greet);

  greeting = createElement("h2", "Search (Press Esc to clear)");
  greeting.position(20, 550);

  // textAlign(LEFT);
  // textSize(50);
}

///////////////////////////////////////////////////////////////////////////

function draw() {
  background(255);
  image(img, 0, 0);

  if (keyIsPressed) {
    if (keyCode == ENTER || keyCode == RETURN) {
      greet();
    } else if (keyCode == 51) {
      input.value("screwdrivers"); // test
    } else if (keyCode == 27) {
      input.value(null);
      name = null;
    }
  }

  c1 = data.getColumn("1");
  c2 = data.getColumn("2");
  c3 = data.getColumn("3");
  c4 = data.getColumn("4");
  c5 = data.getColumn("5");
  c6 = data.getColumn("6");

  if (c1.includes(name)) {
    anim1();
  }

  if (c2.includes(name)) {
    anim2();
  }
  // if (c3.includes(name)) {
  // anim3();
  // }

  // if (c4.includes(name)) {
  // anim4();
  // }

  // if (c5.includes(name)) {
  // anim5();
  // }

  // if (c6.includes(name)) {
  // anim6();
  // }
}

///////////////////////////////////////////////////////////////////////////

function greet() {
  

  //Changes input.value to uppercase in console, NEED TO MAKE NOT CASE SENSITIVE
  name = input.value().toUpperCase();
  string =
    name.charAt(0).toUpperCase() + name.substr(1, name.length).toUpperCase();
  print(string);

}

///////////////////////////////////////////////////////////////////////////

// function smallReset() { //THIS MAY NOT NE NECESSARY, SUPPOSED TO BE FOR RESETTING ANIMATION
// //resets animation
// var dia = 0;
// var growAmount = 0;
// var grow = 0;
// }

///////////////////////////////////////////////////////////////////////////

function anim1() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(200, 200, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}

function anim2() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(400, 400, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}

```

`  
Any help is greatly appreciated! Many, many thanks in advance!

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [August 22, 2022, 7:15am UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/2 "2022-08-22T07:15:00Z")

</div>

Hi @zara2355,

Look here for an example…  
The steps are

- Add event listener for input on your textbook.
- Search for data on input
- Display suggestions if matches found

> **[p5.js Web Editor](https://editor.p5js.org/mnse_forum/sketches/q777Jmcg8)**
>
> A web editor for p5.js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners.

Cheers  
— mnse

EDIT: I’ve modified the code from example formerly linked as it was imo not sufficient and rewrited it based on the original to add a datalist so user can select on filter.  
EDIT: Sorry was still fiddling now it is ok 🙂

---

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [September 10, 2022, 6:07pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/3 "2022-09-10T18:07:36Z")

</div>

Sorry for the delay here, and thank you for the response.

I think what im having a hard time with is the example you give sort of ignores the google sheet and instead uses a JSON file. Is it possible to create the autocomplete without using an event listener? That is, i see the event listener looks in the html part for an input field, but the input field I created is all made within the P5 part.

Sorry for the noob questions, but well, am a noob

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 10, 2022, 8:12pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/4 "2022-09-10T20:12:01Z")

</div>

```auto
// ["ENDMILL", "HAMMER", "SCREWS", "CLAMPS", "SCREWDRIVERS"]

let dia = 0;
let growAmount = 0.5;
let grow = true;

let input1, button, greeting, img, data;

let resultContinuousSearch = "";

let url =
  "https://docs.google.com/spreadsheets/d/e/2PACX-1vRmua9Ue9Uv2olN_0kOvTbAPPBkJ3ckciRbDUs_jUr9eMv43sgdFrzmcluQGd4MQrsiYemarPqLsjVj/pub?gid=0&single=true&output=csv";

///////////////////////////////////////////////////////////////////////////

function preload() {
  data = loadTable(url, "csv", "header");
}

///////////////////////////////////////////////////////////////////////////

function setup() {
  // create canvas
  createCanvas(1794, 300);

  // img = loadImage("LMP Map2.png");
  name = null;

  input1 = createInput();
  input1.position(20, 600);
  input1.input(myInputEvent);

  button = createButton("submit");
  button.position(input1.x + input1.width, 600);
  button.mousePressed(greet);

  greeting = createElement("h2", "Search (Press Esc to clear)");
  greeting.position(20, 550);

  rcs = createElement("rcs");
  rcs.position(20, 450);

  // textAlign(LEFT);
  // textSize(50);
}

///////////////////////////////////////////////////////////////////////////

function draw() {
  background(255);
  // image(img, 0, 0);

  // console.log(input1.getText());

  if (keyIsPressed) {
    if (keyCode == ENTER || keyCode == RETURN) {
      greet();
    } else if (keyCode == 51) {
      input1.value("screwdrivers"); // test
    } else if (keyCode == 27) {
      input1.value(null);
      name = null;
    }
  }

  c1 = data.getColumn("1");
  c2 = data.getColumn("2");
  c3 = data.getColumn("3");
  c4 = data.getColumn("4");
  c5 = data.getColumn("5");
  c6 = data.getColumn("6");

  if (c1.includes(name)) {
    anim1();
  }

  if (c2.includes(name)) {
    anim2();
  }
  // if (c3.includes(name)) {
  // anim3();
  // }

  // if (c4.includes(name)) {
  // anim4();
  // }

  // if (c5.includes(name)) {
  // anim5();
  // }

  // if (c6.includes(name)) {
  // anim6();
  // }
}

///////////////////////////////////////////////////////////////////////////

function myInputEvent() {
  if (this.value().length >= 1) {
    resultContinuousSearch = "";
    c1 = data.getColumn("1");

    for (let i = 0; i < c1.length; i++) {
      if (contains(c1[i], this.value())) {
        // console.log(c1[i]);
        resultContinuousSearch += c1[i] + "\n";
      } //if
    }
    //
    rcs.html(resultContinuousSearch);
  } //if
} //func

function contains(s1, s2) {
  for (let i = 0; i < s2.length; i++) {
    if (s1[i].toUpperCase() != s2[i].toUpperCase()) return false;
  } //for
  return true;
} //func

function greet() {
  //Changes input1.value to uppercase in console, NEED TO MAKE NOT CASE SENSITIVE
  name = input1.value().toUpperCase();
  string =
    name.charAt(0).toUpperCase() + name.substr(1, name.length).toUpperCase();
  print(string);
}

///////////////////////////////////////////////////////////////////////////

// function smallReset() { //THIS MAY NOT NE NECESSARY, SUPPOSED TO BE FOR RESETTING ANIMATION
// //resets animation
// var dia = 0;
// var growAmount = 0;
// var grow = 0;
// }

///////////////////////////////////////////////////////////////////////////

function anim1() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(200, 200, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}

function anim2() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(400, 400, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 10, 2022, 8:25pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/5 "2022-09-10T20:25:27Z")

</div>

new version without an event function - we just control the input throughout

- see resultContinuousSearch and rcs

```auto
// ["ENDMILL", "HAMMER", "SCREWS", "CLAMPS", "SCREWDRIVERS"]

let dia = 0;
let growAmount = 0.5;
let grow = true;

let input1, button, greeting, img, data;

let resultContinuousSearch = "";

let url =
  "https://docs.google.com/spreadsheets/d/e/2PACX-1vRmua9Ue9Uv2olN_0kOvTbAPPBkJ3ckciRbDUs_jUr9eMv43sgdFrzmcluQGd4MQrsiYemarPqLsjVj/pub?gid=0&single=true&output=csv";

///////////////////////////////////////////////////////////////////////////

function preload() {
  data = loadTable(url, "csv", "header");
}

///////////////////////////////////////////////////////////////////////////

function setup() {
  // create canvas
  createCanvas(1794, 300);

  // img = loadImage("LMP Map2.png");
  name = null;

  input1 = createInput();
  input1.position(20, 600);

  button = createButton("submit");
  button.position(input1.x + input1.width, 600);
  button.mousePressed(greet);

  greeting = createElement("h2", "Search (Press Esc to clear)");
  greeting.position(20, 550);

  rcs = createElement("rcs");
  rcs.position(20, 450);

  // textAlign(LEFT);
  // textSize(50);
}

///////////////////////////////////////////////////////////////////////////

function draw() {
  background(255);
  // image(img, 0, 0);

  if (keyIsPressed) {
    if (keyCode == ENTER || keyCode == RETURN) {
      greet();
    } else if (keyCode == 51) {
      input1.value("screwdrivers"); // test
    } else if (keyCode == 27) {
      input1.value(null);
      name = null;
    }
  }

  c1 = data.getColumn("1");
  c2 = data.getColumn("2");
  c3 = data.getColumn("3");
  c4 = data.getColumn("4");
  c5 = data.getColumn("5");
  c6 = data.getColumn("6");

  if (c1.includes(name)) {
    anim1();
  }

  if (c2.includes(name)) {
    anim2();
  }
  // if (c3.includes(name)) {
  // anim3();
  // }

  // if (c4.includes(name)) {
  // anim4();
  // }

  // if (c5.includes(name)) {
  // anim5();
  // }

  // if (c6.includes(name)) {
  // anim6();
  // }

  checkInput();
}

function checkInput() {
  // NOT an event

  resultContinuousSearch = "";

  if (input1.value().length >= 1) {
    c1 = data.getColumn("1");

    for (let i = 0; i < c1.length; i++) {
      if (contains(c1[i], input1.value())) {
        // console.log(c1[i]);
        resultContinuousSearch += c1[i] + "\n";
      } //if
    }
    //
  } //if
  rcs.html(resultContinuousSearch);
}

///////////////////////////////////////////////////////////////////////////

function contains(s1, s2) {
  for (let i = 0; i < min(s1.length, s2.length); i++) {
    if (s1[i].toUpperCase() != s2[i].toUpperCase()) return false;
  } //for
  return true;
} //func

function greet() {
  //Changes input1.value to uppercase in console, NEED TO MAKE NOT CASE SENSITIVE
  name = input1.value().toUpperCase();
  string =
    name.charAt(0).toUpperCase() + name.substr(1, name.length).toUpperCase();
  print(string);
}

///////////////////////////////////////////////////////////////////////////

// function smallReset() { //THIS MAY NOT NE NECESSARY, SUPPOSED TO BE FOR RESETTING ANIMATION
// //resets animation
// var dia = 0;
// var growAmount = 0;
// var grow = 0;
// }

///////////////////////////////////////////////////////////////////////////

function anim1() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(200, 200, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}

function anim2() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(400, 400, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}
//

```

---

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [September 10, 2022, 10:36pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/6 "2022-09-10T22:36:42Z")

</div>

[Chrisir](https://discourse.processing.org/u/Chrisir)

Wow! Thank you! I’ve been struggling to try to combine the two methods and I think this really simplifies it a lot. That said, ive learned a ton, both on the html/css side as well a p5.js.

i will look deeply into your example and try to figure out WHY everything does what it does so that I can really understand.

Again, thank you!

---

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [September 11, 2022, 12:26am UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/7 "2022-09-11T00:26:41Z")

</div>

One more question, specifically with line # 107 in the sketch example, is there a way that the `resultContinuousSearch += c1[i] + "\n";` is able to separate the results not in a continuous line of text, but rather in a column as if you were to hit “enter” after each result?

---

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [September 11, 2022, 2:03am UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/8 "2022-09-11T02:03:49Z")

</div>

Ok, so i think i’ve figured it out by using split. I then increased the canvas size a bit (from 600 to 800 on the Y axis) to allow for a handful of suggestions to search for. If anyone has input to make this more efficient, please let me know! I think ive got some minor changes (i.e. i have an idea to make the data formatting better), but i think this might be close to a workable sketch. Thank you all so much!

```auto
// ["ENDMILL", "HAMMER", "SCREWS", "CLAMPS", "EXT", "SCREWDRIVERS", "HELL"]

let dia = 0;
let growAmount = 0.5;
let grow = true;

let input1, button, greeting, img, data;

let resultContinuousSearch = "";

let url =
  "https://docs.google.com/spreadsheets/d/e/2PACX-1vRmua9Ue9Uv2olN_0kOvTbAPPBkJ3ckciRbDUs_jUr9eMv43sgdFrzmcluQGd4MQrsiYemarPqLsjVj/pub?gid=0&single=true&output=csv";

///////////////////////////////////////////////////////////////////////////

function preload() {
  data = loadTable(url, "csv", "header");
}

///////////////////////////////////////////////////////////////////////////

function setup() {
  
    

  
  // create canvas
  createCanvas(1794, 1000);

  img = loadImage("LMP Map2.png");
  name = null;

  input1 = createInput();
  input1.position(20, 600);

  button = createButton("submit");
  button.position(input1.x + input1.width, 600);
  button.mousePressed(greet);

  greeting = createElement("h2", "Search (Press Esc to clear)");
  greeting.position(20, 550);

  rcs = createElement("rcs");
  rcs.position(20, 620);

  // textAlign(LEFT);
  // textSize(50);
}

///////////////////////////////////////////////////////////////////////////

function draw() {
  

  
  
  background(255);
  image(img, 0, 0);

  if (keyIsPressed) {
    if (keyCode == ENTER || keyCode == RETURN) {
      greet();
    } else if (keyCode == 51) {
      input1.value("screwdrivers"); // test
    } else if (keyCode == 27) {
      input1.value(null);
      name = null;
    }
  }

  c1 = data.getColumn("1");
  c2 = data.getColumn("2");
  c3 = data.getColumn("3");
  c4 = data.getColumn("4");
  c5 = data.getColumn("5");
  c6 = data.getColumn("6");

  if (c1.includes(name)) {
    anim1();
  }

  if (c2.includes(name)) {
    anim2();
  }
  // if (c3.includes(name)) {
  // anim3();
  // }

  // if (c4.includes(name)) {
  // anim4();
  // }

  // if (c5.includes(name)) {
  // anim5();
  // }

  // if (c6.includes(name)) {
  // anim6();
  // }

  checkInput();
}

function checkInput() {
  // NOT an event

  resultContinuousSearch = "";

  if (input1.value().length >= 1) {
    c1 = data.getColumn("1");

    for (let i = 0; i < c1.length; i++) {
      if (contains(c1[i], input1.value())) {
        // console.log(c1[i]);
        let A = split(resultContinuousSearch, ',');
        resultContinuousSearch += c1[i] + "\n" ;
        
let names = resultContinuousSearch;
let splitString = split(names, ',');
        
text(splitString[0], 5, 650);
        textSize(20);
        fill(0, 0, 0);
// text(splitString[1], 5, 670);
// text(splitString[2], 5, 690);

      } //if
    }
    //
  } //if
  // rcs.html(resultContinuousSearch) ;
}

///////////////////////////////////////////////////////////////////////////

function contains(s1, s2) {
  for (let i = 0; i < min(s1.length, s2.length); i++) {
    if (s1[i].toUpperCase() != s2[i].toUpperCase()) return false;
  } //for
  return true;
} //func

function greet() {
  //Changes input1.value to uppercase in console, NEED TO MAKE NOT CASE SENSITIVE
  name = input1.value().toUpperCase();
  string =
    name.charAt(0).toUpperCase() + name.substr(1, name.length).toUpperCase();
  print(string);
}

///////////////////////////////////////////////////////////////////////////

// function smallReset() { //THIS MAY NOT NE NECESSARY, SUPPOSED TO BE FOR RESETTING ANIMATION
// //resets animation
// var dia = 0;
// var growAmount = 0;
// var grow = 0;
// }

///////////////////////////////////////////////////////////////////////////

function anim1() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(200, 200, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}

function anim2() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(400, 400, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 11, 2022, 4:22pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/9 "2022-09-11T16:22:07Z")

</div>

Yeah, next step would be to make the autocomplete suggestions clickable by mouse.

Like a list you chose from.

Or cursor keys.

- when you have a lot of items you want to increase the required minimum length to 3 or so

- why do you have c1 and c2? Because of upper case? This seems like two different columns

---

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [September 12, 2022, 2:19am UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/10 "2022-09-12T02:19:18Z")

</div>

[Chrisir](https://discourse.processing.org/u/Chrisir)

I completely agree with the idea of the clickable selections or selecting a suggestion using cursor keys. I think that may well be the real polish on it and will try to figure that out.

Not sure you mean by

> when you have a lot of items you want to increase the required minimum length to 3 or so

Can you clarify what you mean here?

In the meantime, ive rearranged my data a bit to try to make this both easier on myself (im responsible for this code) and easier on the person(s) keeping the inventory. Im sort of wondering what might be the most efficient way of organizing eith the spreadsheet or writing a clunky sketch. Specifically, if i put the burden on the person updating the inventory spreadsheet, they might have to also update the new columns (“X Coordinate” and “Y Coordinate”) This doesnt seem like it will be a good idea at all and will end badly for me. On the other hand, i could write a bunch of “if” statements where the people keeping inventory only need to enter in what cabinet number it is, and then in my sketch my “if” statements then assign new var for x and x for the location of the animation. THis too is bad, since theres about 60 different cabinets, and therefore 60 “if” statements in the sketch, which seems really super clunky and not efficient at all. To be perfectly honest, not sure which is the less-worse, but i have to think theres a better solution that i just dont know from lack of experience

Heres the new sketch so you can look at both the spreadsheet (and see the new columns) as well as the “if” statements. (lines 142 - 155 in the sketch)

```auto
let dia = 0;
let growAmount = 0.5;
let grow = true;

let input1, button, greeting, img, data;

let resultContinuousSearch = "";

let url =
  "https://docs.google.com/spreadsheets/d/e/2PACX-1vRmua9Ue9Uv2olN_0kOvTbAPPBkJ3ckciRbDUs_jUr9eMv43sgdFrzmcluQGd4MQrsiYemarPqLsjVj/pub?gid=0&single=true&output=csv";

///////////////////////////////////////////////////////////////////////////

function preload() {
  data = loadTable(url, "csv", "header");
}

///////////////////////////////////////////////////////////////////////////

function setup() {
  createCanvas(1794, 1000);

  img = loadImage("LMP Map2.png");
  name = null;

  input1 = createInput();
  input1.position(20, 600);

  button = createButton("submit");
  button.position(input1.x + input1.width, 600);
  button.mousePressed(greet);

  greeting = createElement("h2", "Search (Press Esc to clear)");
  greeting.position(20, 550);

  rcs = createElement("rcs");
  rcs.position(20, 620);
}

///////////////////////////////////////////////////////////////////////////

function draw() {
  background(255);
  image(img, 0, 0);

  if (keyIsPressed) {
    if (keyCode == ENTER || keyCode == RETURN) {
      greet();
    } else if (keyCode == 51) {
      input1.value("screwdrivers"); // test
    } else if (keyCode == 27) {
      input1.value(null);
      name = null;
      dia = 0;
    }
  }

  getData();

  checkInput();
}

///////////////////////////////////////////////////////////////////////////

function checkInput() {
  // NOT an event

  resultContinuousSearch = "";

  if (input1.value().length >= 1) {
    c1 = data.getColumn("TOOL");

    for (let i = 0; i < c1.length; i++) {
      if (contains(c1[i], input1.value())) {
        // console.log(c1[i]);
        let A = split(resultContinuousSearch, ",");
        resultContinuousSearch += c1[i] + "\n";

        let names = resultContinuousSearch;
        let splitString = split(names, ",");
        fill(0, 0, 0);
        textSize(20);
        text(splitString[0], 25, 650);
      }
    }
  }
}

///////////////////////////////////////////////////////////////////////////

function contains(s1, s2) {
  for (let i = 0; i < min(s1.length, s2.length); i++) {
    if (s1[i].toUpperCase() != s2[i].toUpperCase()) return false;
  }
  return true;
}

function greet() {
  //Changes input1.value to uppercase in console, NEED TO MAKE NOT CASE SENSITIVE
  name = input1.value().toUpperCase();
  string =
    name.charAt(0).toUpperCase() + name.substr(1, name.length).toUpperCase();
  print(string);
}

///////////////////////////////////////////////////////////////////////////

function anim1() {
  //Creates the animation for location of item
  fill(0, 255, 0);
  ellipse(c, xLoc, dia, dia);

  if (dia > 50) {
    grow = false;
  }
  if (dia < 0) {
    grow = true;
  }

  if (grow == true) {
    dia += growAmount;
  } else {
    dia -= growAmount;
  }
}

///////////////////////////////////////////////////////////////////////////

function getData() {
  for (let i = 0; i < data.getRowCount(); i++) {
    let row = data.getRow(i);
    let c = row.getString("TOOL");
    let l = row.getNum("LOCATION");
    let xLoc = row.getNum("X Coordinate");
    let yLoc = row.getNum("Y Coordinate");

    
    
  
    
// if (l == 1){
// var xLoc = 500;
// var yLoc = 200;
// }
    
// if (l == 2){
// var xLoc = 350;
// var yLoc = 200;
// }
    
// if (l == 3){
// var xLoc = 200;
// var yLoc = 500;
// }
    
 
    
    
    // print(xLoc);
    // noLoop();

    if (name == c) {
      fill(0, 255, 0);
      ellipse(xLoc, yLoc, dia, dia);

      if (dia > 50) {
        grow = false;
      }
      if (dia < 0) {
        grow = true;
      }

      if (grow == true) {
        dia += growAmount;
      } else {
        dia -= growAmount;
      }
    }
  }
}

```

Thanks a million, once again

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 12, 2022, 7:25am UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/11 "2022-09-12T07:25:15Z")

</div>

> [@zara2355](#):
>
> Can you clarify what you mean here?

There is an if clause when we start to compare the input to the list. Long list would be Time consuming.  
Hence, you can say just search when length \> 3

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 12, 2022, 7:27am UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/12 "2022-09-12T07:27:51Z")

</div>

> [@zara2355](#):
>
> if i put the burden on the person updating the inventory spreadsheet, they might have to also update the new columns (“X Coordinate” and “Y Coordinate”) This doesnt seem like it will be a good idea at all

Remember in one of my previous versions (other thread) I had a shelf name (for example “Cabinet 1”) and the coordinates where there.  
You can make also a separate table to give your shelf name and x and y. So the poor soul can work with shelf name mainly and ignore x,y since it’s read from this separate table.

So when you have many items in ONE shelf  
this might work.

- Besides: my contains function is probably a built-in function somewhere but I couldn’t find it.

---

<div class="post-metadata">

**Author:** ![zara2355](https://avatars.discourse-cdn.com/v4/letter/z/b5a626/32.png) [@zara2355](https://discourse.processing.org/u/zara2355)\
**Post date:** [September 14, 2022, 1:02pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/13 "2022-09-14T13:02:52Z")

</div>

[Chrisir](https://discourse.processing.org/u/Chrisir)

Hi again, and thanks for the helpful response!

Im wondering, regarding your suggestion to add in the “clickable by mouse/cursor keys” are there any tips or tutorials that might help in this instance? Im asking about this specifically because of the way the new autocomplete is written (that is, entirely in the p5js sketch and not utilizing the html/css side).

Also, im still trying to figure out the best way to approach the data tables issue i spoke about before (requiring the inventory person to update the item location as well as the X and Y coordinates, OR write ~60 “if” statement). I think part of the fun with this project is trying to see if i can figure these solutions from research and trial and error.

As usual, many many thanks to you and everyone here!

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 14, 2022, 1:24pm UTC](https://discourse.processing.org/t/help-with-adding-autocomplete-to-a-sketch/38440/14 "2022-09-14T13:24:03Z")

</div>

> [@zara2355](#):
>
> Im wondering, regarding your suggestion to add in the “clickable by mouse/cursor keys” are there any tips or tutorials that might help in this instance?

this comes to mind: [reference | p5.js](https://p5js.org/reference/#/p5/createSelect)

or [reference | p5.js](https://p5js.org/reference/#/p5/createRadio)

these you could fill dynamically with the suggestions.

You can also make a couple of buttons underneath each other.

* * *

> [@zara2355](#):
>
> Also, im still trying to figure out the best way to approach the data tables issue i spoke about before (requiring the inventory person to update the item location as well as the X and Y coordinates, OR write ~60 “if” statement).

I hoped to have answered this in my previous post with the separate table.

- You can of course make a separate Sketch where the poor guy can click with the mouse in the ground floor plan to store x,y for each cabinet/ regal / product. Store the result in the said separate table.
