1

I'm trying to do the next thing:

getChatListMessageString: function(dateObject, userID, userName, userRole, messageID, messageText, channelID, ip) {
            var rowClass = this.DOMbufferRowClass,
                userClass = this.getRoleClass(userRole),
                colon = ': ';
            if(messageText.indexOf('/action') === 0 || messageText.indexOf('/me') === 0 || messageText.indexOf('/privaction') === 0) {
                userClass += ' action';
                colon = ' ';
            }
            if (messageText.indexOf('/privmsg') === 0 || messageText.indexOf('/privmsgto') === 0 || messageText.indexOf('/privaction') === 0) {
                rowClass += ' private';
            }

            var dateTime = this.settings['dateFormat'] ? '<span class="dateTime">'
                            + this.formatDate(this.settings['dateFormat'], dateObject) + '</span> ' : '';
            return  '<div id="'
                    + this.getMessageDocumentID(messageID)
                    + '" class="'
                    + rowClass
                    + '">'
                    + this.getDeletionLink(messageID, userID, userRole, channelID)
                    + dateTime

                    //start of the code i added

                    + '<a href="http://hostname.x/report_chat.php?usernameR='
                    + userName
                    + '/&useridR='
                    + userID
                    + '">'
                    + '<img src="img/excl.png"></img></a>'

                    // end of the code i added
                    + '<a href="http://www.hostname.x/'
                    + userID
                    + '" target="_blank"'
                    + this.getChatListUserNameTitle(userID, userName, userRole, ip)
                    + ' dir="'
                    + this.baseDirection
                    + '" onclick="ajaxChat.insertText(this.firstChild.nodeValue);">'
                    + userName
                    + '</a>'
                    + colon
                    + this.replaceText(messageText)
                    + '</div>';
        },

If I remove the portion that I added , the page works just fine. When I add it back , I get an Aw Snap error(cache reloaded -> incognito mode )

I'm pretty new with javascript so I can't really tell what I did wrong.

Thank you!

EDIT: THE AW SNAP ERROR comes from the <img> tag for whatever reason.

JohnMonro
  • 33
  • 5

2 Answers2

0

Ouch! The best approach is not to build your HTML elements in this manner in the first place and use the DOM to construct and inject them into your document.

This makes the code MUCH easier to read and modify and removes the concatenation issue entirely.

Now, if you have errors, you can focus on the values your are assigning to the properties and not the syntax of the HTML.

// Create the div element in memeory
var div = document.createElement("div");

// Configure the attributes of that div
div.id = this.getMessageDocumentID(messageID);
div.classList.add(rowClass);

// Now, begin populating the div
div.innerHTML = this.getDeletionLink(messageID, userID, userRole, channelID) + dateTime;

// A new element belongs inside the div. Repeat the process:
var a1 = document.createElement(a);
a1.href = "http://hostname.x/report_chat.php?usernameR=" + userName + "/&useridR=" + userID;

var img = document.createElement("img");
img.src = "img/excl.png";

// Place the image into the anchor
a1.appendChild(img);

// Place the anchor into the div
div.appendChild(a1);

// Another anchor is now needed
var a2 = document.createElement(a);
a2.href = "http://www.hostname.x/" + userID;
a2.target = "_blank";

// It is unclear what the following line is based on the fact that whatever it returns, you have that 
// being inserted where attributes go. It is commented here for that reason.
//this.getChatListUserNameTitle(userID, userName, userRole, ip) + " dir='" + this.baseDirection;

// Set up event handler for the anchor
a2.addEventListener("click", function(){
  ajaxChat.insertText(this.firstChild.nodeValue);
});

// Populate the anchor
a2.innerHTML = userName;

// Insert this anchor into the div
div.appendChild(a2);

// Insert the final contents into the div
div.innerHTML += colon + this.replaceText(messageText);

// Return the final construct
return div;
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • I'm using AJAX Chat with few thousands of lines in a js file so doing these kind of changes will affect its all functionality. – JohnMonro May 10 '17 at 13:16
  • @JohnMonro Why? This produces the exact same HTML that you are manually building. It just does it the proper way. – Scott Marcus May 10 '17 at 13:17
0

//Here a  simple test

var Obj = (function(){
  return{

     DOMbufferRowClass : 'DOMbufferRowClass',
     getRoleClass : function()
     {
       return 'roleClass';
     },
     settings : '',
     getMessageDocumentID : function(){
      return '123';
     },
     getDeletionLink : function(messageID, userID, userRole, channelID) 
     {
      return 'DeletiongLink'
     },
     replaceText : function()
     {
     
     },
     getChatListMessageString : function(dateObject, userID, userName, userRole, messageID, messageText, channelID, ip) {
                var rowClass = this.DOMbufferRowClass,
                    userClass = this.getRoleClass(userRole),
                    colon = ': ';
                if(messageText.indexOf('/action') === 0 || messageText.indexOf('/me') === 0 || messageText.indexOf('/privaction') === 0) {
                    userClass += ' action';
                    colon = ' ';
                }
                if (messageText.indexOf('/privmsg') === 0 || messageText.indexOf('/privmsgto') === 0 || messageText.indexOf('/privaction') === 0) {
                    rowClass += ' private';
                }

                var dateTime = this.settings['dateFormat'] ? '<span class="dateTime">'
                                + this.formatDate(this.settings['dateFormat'], dateObject) + '</span> ' : '';
                return  `<div id="${this.getMessageDocumentID(messageID)}" class="${rowClass}">
                         ${this.getDeletionLink(messageID, userID, userRole, channelID)}  ${dateTime}
                         <a href="http://hostname.x/report_chat.php?usernameR='${userName}/&useridR=${userID}">
                         <img src="img/excl.png"/></a><a href="http://www.hostname.x/${userID} target="_blank"
                          this.getChatListUserNameTitle(userID, userName, userRole, ip) dir="{this.baseDirection}
                onclick="ajaxChat.insertText(this.firstChild.nodeValue);">${userName}</a>${colon}${this.replaceText(messageText)}</div>`;
            }     
  };      
})();
console.log(Obj.getChatListMessageString("05102017", '1234',"admin", '456',  'Test','11', '127.0.0.1'));

I would simplify your code with template literals and avoiding all the concatenation mess.

getChatListMessageString : function(dateObject, userID, userName, userRole, messageID, messageText, channelID, ip) {
   var rowClass = this.DOMbufferRowClass,
       userClass = this.getRoleClass(userRole),
       colon = ': ';
       if(messageText.indexOf('/action') === 0 || messageText.indexOf('/me') === 0 || messageText.indexOf('/privaction') === 0) {
            userClass += ' action';
                colon = ' ';
       }
       if (messageText.indexOf('/privmsg') === 0 || messageText.indexOf('/privmsgto') === 0 || messageText.indexOf('/privaction') === 0) {
                rowClass += ' private';
       }

      var dateTime = this.settings['dateFormat'] ? '<span class="dateTime">'
                            + this.formatDate(this.settings['dateFormat'], dateObject) + '</span> ' : '';
            return  `<div id="${this.getMessageDocumentID(messageID)}" class="${rowClass}">
                     ${this.getDeletionLink(messageID, userID, userRole, channelID)}  ${dateTime}
                     <a href="http://hostname.x/report_chat.php?usernameR='${userName}/&useridR=${userID}">
                     <img src="img/excl.png"/></a><a href="http://www.hostname.x/${userID} target="_blank"
                      this.getChatListUserNameTitle(userID, userName, userRole, ip) dir="{this.baseDirection}

        onclick="ajaxChat.insertText(this.firstChild.nodeValue);">${userName}</a>${colon}${this.replaceText(messageText)}</div>`;
  } 
funcoding
  • 741
  • 6
  • 11
  • Any ideas why next isnt working: ` return '';` – JohnMonro May 10 '17 at 15:47
  • What do you mean by next? Did you update your code? Did my previous answer help you? – funcoding May 10 '17 at 15:52
  • Well , in html I get the actual string -- ${userID} -- not what the variable contains so I'll keep using concatenation. What I discovered though , when trying to put the second get parameter like this +'&testest=' , the script crashes again. Is it thanks to that ' = ' that expects an opening " and ending " ?? ? – JohnMonro May 10 '17 at 15:57
  • Beacuse you have to start the line with " ` " character. My advice to you, stop using concatenation! It's difficult to track! In your last comment, use an event to handle the onclick instead of doing it inline – funcoding May 10 '17 at 16:01
  • check my edited comment above about the GET parameter . – JohnMonro May 10 '17 at 16:03
  • I don't see it! Would you mind sharing the whole code? – funcoding May 10 '17 at 16:06
  • return ``; //// IT WILL ONLY WORK IF I remove second GET parameter useridR . Is it thanks to that '=' that expects an opening " and ending " ? – JohnMonro May 10 '17 at 16:12
  • Again @JohnMonro, no need to make it hard! Do this: `‌` Then register a click event like: `$(document).on('click', '.class', yourFunction);` – funcoding May 10 '17 at 16:18
  • inline js is not the problem here. The problem is second GET parameter that crashes the whole js when I add it: ‌​‌ WILL WORK WHEN a class="flag" title="Report" href="orriz.com/report_chat.php?useridR=${userID}&reasonmsg‌‌​​=${messageID}">‌​‌ WONT – JohnMonro May 10 '17 at 16:27
  • Show me the whole code, I'll tell you where the problem is! – funcoding May 10 '17 at 16:28