Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two listeners + Two API calls doesn't work #395

Open
jeekca opened this issue Apr 23, 2016 · 8 comments
Open

Two listeners + Two API calls doesn't work #395

jeekca opened this issue Apr 23, 2016 · 8 comments

Comments

@jeekca
Copy link

jeekca commented Apr 23, 2016

I have the weirdest bug right now. I've checked and re-checked everything 100 times.

I assign 2 listeners to a form. 1 fetches users with the "@" symbol, the other fetches events with the "event:" text.

The "tagUsersConfig" one works great, but the "tagEventsConfig" behaves weirdly. It fetches the first 5 events, then as soon as I start typing the first letter, the list dissapears, even if I know for a fact (in the console) that for each character I type, it's sending me back json objects from the API (all of which are accurate depending on the typed letter).

If I paste the users' API query in the tagEventsConfig (events) one, the "event:" now works. The weirdest part is (and you're going to have to take my word for it), the events API call and its variables are all perfectly correct and valid.

Thank you very much for your time.

    var userList;
    var eventList;

    var tagUsersConfig = {
      at: "@",
      displayTpl: "<li class='replyToAtWho-list-item clearfix'><div class='feed-replyTo-img' style='${imageId}'></div><div class='left'><div class='feed-replyTo-name'>${name}</div><div class='feed-replyTo-realName'>${realName}</div></div></li>",
      insertTpl: '<span class="feed-reply-to-name-link" data-userNameReplyTo="${name}" data-userIdReplyTo="${userId}">${name}</span>&nbsp;',
      callbacks: {
        remoteFilter: function(query, render_users) {

          $.getJSON(DOMAIN + '/Skeddy/rest/gem/v1/user?institutionid='+CAMPUS_ID+'&apitoken='+USER_TOKEN+'&limit=10&fullname=' + encodeURIComponent(query), function(data) {

            userList = $.map(data.listT, function(value, i) {
              var imageId = (parse_OBJ(value.i, "ImageId")) ? DOMAIN + '/Skeddy/rest/gem/v1/image/' + parse_OBJ(value.i, "ImageId") + '?sname=CampusSchema&apitoken=' + USER_TOKEN : '/' + ROOT + '/img/avatar-default.png';
              return {
                'userId': value.id,
                'realName': value.name,
                'name': parse_OBJ(value.i, "firstName") + " " + parse_OBJ(value.i, "lastName"),
                'imageId' : 'background-image : url("' + imageId + '")'
              };
            });

            render_users(userList);

          });
        },
        matcher: function(flag, subtext, should_start_with_space) {
          var match, regexp;
          flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
          if (should_start_with_space) {
            flag = '(?:^|\\s)' + flag;
          }
          regexp = new RegExp(flag + '([A-Za-z0-9_\\s\+\-\]*)$|' + flag + '([^\\x00-\\xff]*)$', 'gi');
          match = regexp.exec(subtext.replace(/\s/g, " "));
          if (match) {
            return match[2] || match[1];
          } else {
            return null;
          }
        }
      },
      delay: 20
    };

    var tagEventsConfig = {
      at: "event:",
      displayTpl: "<li class='itemAtWho-list-item clearfix'><div class='feed-item-img' style='${imageId}'></div><div class='left'><div class='feed-item-name'>${eventName}</div><div class='feed-replyTo-realName'>10-10</div></div></li>",
      insertTpl: '<a href="' + DOMAIN + '/website/event-details/' + CAMPUS_ID + '/${eventId}" class="fp-ext-link" target="_blank">${eventName}</span>&nbsp;',
      callbacks: {
        remoteFilter: function(query, render_events) {

          $.getJSON(DOMAIN + '/Skeddy/rest/gem/v1/event?institutionid='+CAMPUS_ID+'&apitoken='+USER_TOKEN+'&limit=10&state=published_expired&name=' + encodeURIComponent(query), function(data) {

            eventList = $.map(data.listT, function(value, i) {
              var imageId = (value.imageId) ? DOMAIN + '/Skeddy/rest/gem/v1/image/' + value.imageId + '?sname=CampusSchema&apitoken=' + USER_TOKEN : '/' + ROOT + '/img/avatar-default.png';
              return {
                'eventId': value.eventId,
                'eventName': value.name,
                'imageId' : 'background-image : url("' + imageId + '")'
              };
            });

            render_events(eventList);

          });
        },
        matcher: function(flag, subtext, should_start_with_space) {
          var match, regexp;
          flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
          if (should_start_with_space) {
            flag = '(?:^|\\s)' + flag;
          }
          regexp = new RegExp(flag + '([A-Za-z0-9_\\s\+\-\]*)$|' + flag + '([^\\x00-\\xff]*)$', 'gi');
          match = regexp.exec(subtext.replace(/\s/g, " "));
          if (match) {
            return match[2] || match[1];
          } else {
            return null;
          }
        }
      },
      delay: 20
    };

    $POST_FORM_MASTER.find(".feed-form.mention").atwho(tagEventsConfig).atwho(tagUsersConfig);
@jeekca
Copy link
Author

jeekca commented Apr 23, 2016

I've just spent the last hour testing and testing, and I just wanted to confirm that the API sends me the correct data. It's just that for some weird reason, the atwho HTML dom element goes "display:none" after the first character, even if it is populated with the correct HTML list (<li>). Super strange :\

@Mottie
Copy link
Contributor

Mottie commented Apr 24, 2016

I encountered a similar issue when I wrote this emoji userscript.

I found that the regular expression within the matcher callback wouldn't return a match consistently and the dropdown would disappear on every other character typed. What I ended up doing was adding a second regular expression match which seemed to fix the problem. Here is the code (ref) I ended up using:

matcher: function(flag, subtext) {
  var regexp = ghe.regex.emojiImgFilter,
    match = regexp.exec(subtext);
  // this next line does some magic...
  // for some reason, without it, moving the caret from "p" to "r" in
  // ":_people,fear," opens & closes the popup with each letter typed
  subtext.match(regexp);
  if (match) {
    return match[2] || match[1];
  } else {
    return null;
  }
}

@jeekca
Copy link
Author

jeekca commented Apr 24, 2016

Hey! First of all, thank you so much for your assistance! Looking at the small amount of answers in here, I actually did not expect anyone to help.

I've just tried combining my code and yours, and I wasn't able to get it to work :-( This got me wondering how much of the emoji code should I bring in my code (the emojiImgFilter regex, but then this is includes within the imgParts[] array), or should I just keep my code and simply add the "subtext.match(regexp);" line?

Again, thank you so much for your help. I'm going to try merging my code with your reference some more.

@jeekca
Copy link
Author

jeekca commented Apr 24, 2016

This is what I have right now (after trying to merge both codes) :

        matcher: function(flag, subtext, should_start_with_space) {
          var match, regexp;
          flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
          if (should_start_with_space) {
            flag = '(?:^|\\s)' + flag;
          }
          regexp = new RegExp(flag + '([a-zA-Z\u00c0-\u00ff0-9_,\'\.\+\-]*)$|' + flag + '([^\\x00-\\xff]*)$', 'gi');
          match = regexp.exec(subtext.replace(/\s/g, " "));
          subtext.match(regexp);
          if (match) {
            return match[2] || match[1];
          } else {
            return null;
          }
        }

Unfortunately doesn't work. Still closes unexpectedly when typing "event:Fo...".

@jeekca
Copy link
Author

jeekca commented Apr 25, 2016

@Mottie By no means do I want to annoy you with this, please don't respond if you weren't initially going to reply to my response, no hard feelings. I'm just tagging you because I have no idea if you were notified of my response or not. Again, thanks a million for your help. I'm still fiddling with the snippet of code you gave me.

@Mottie
Copy link
Contributor

Mottie commented Apr 25, 2016

Sorry, I did see your post. I don't think I have any thing else to contribute at this time.

Maybe if you modify this demo to duplicate the problem, I can attempt to help further.

@jeekca
Copy link
Author

jeekca commented Apr 25, 2016

@Mottie Hey, no worries. Again, thanks a million for your assistance. I'll keep trying things and post the solution here when I find it. Thanks for the demo's link, I'll give it a shot.

@jeekca
Copy link
Author

jeekca commented Apr 26, 2016

Oh. Wow. I figured it out.

Before:

    eventList = $.map(data.listT, function(value, i) {
      var imageId = ...
      return {
        'eventId': value.eventId,
        'eventName': value.name, // ********** Here was my mistake **********
        'imageId' : 'background-image : url("' + imageId + '")'
      };
    });

After :

    eventList = $.map(data.listT, function(value, i) {
      var imageId = ...
      return {
        'eventId': value.eventId,
        'name': value.name, // ********** Here is the fix **********
        'imageId' : 'background-image : url("' + imageId + '")'
      };
    });

I didn't realize that the variables (ex: '${name}') in the 'displayTpl'/'insertTpl' had to be the actual objects' keys, and not the key names I was giving them in my eventList array ('eventName').

But again, this doesn't make 100% sense, since I'm naming/labeling my own keys in the tagUsersConfig options and inserting those into the 'displayTpl'/'insertTpl' and it's all working fine... So confusing.

Damn. Took me a whole day to figure that out. Oh well.

Thanks again @Mottie.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants