How to check and return data until there are no matches?

I created a function that will look for various tags, tags such as [image] and [gallery] inside the JSON file. If there is a coincidence, he will return and replace it with a new conclusion. As an object of an image or slide show.

A JSON object can contain multiple tags of the same type or contain different tags at the same time. Thus, an object can contain two [image] tags, for example,

Json

http://snippi.com/s/bzrx3xi

The problem was that if several [image] tags were found, it was replaced with the same content. I was looking for a script that searches for tags until there are no more matches. Many thanks to @debatanu for the solution.

Unfortunately, I have some additional suggestions for the script, because now tags like the image will be replaced with the last image object of the media array inside JSON, and it will only capture and replace the first tag.

I was wondering if it is possible to check each tag and replace each tag with new output.

Tag Search

filterText: function(data) { // Loop through JSON data // Check if [tag] in data.text exists var dataText = data.text; var tags = { "gallery": /\[gallery\]/ig, "image": /\[image\]/ig }; if (dataText != undefined) { var raw_data = dataText; for (var key in tags) { if (tags.hasOwnProperty(key)) { var tag = tags[key]; var tagArr = []; // Check if [tag] in data.text exists while ( (tagArr = tag.exec(dataText)) !== null ) { // Call functions if (key == "gallery") { console.error('GALLERY'); parsedHTML = raw_data.replace(tagArr[0], shortcodeController.gallery(data)); raw_data = parsedHTML; return parsedHTML; } if (key == "image") { console.error('IMAGE'); parsedHTML = raw_data.replace(tagArr[0], shortcodeController.image(data)); raw_data = parsedHTML; return parsedHTML; // model.find('p').html(parsedHTML); } } } } }; 

Call the filterText function

 getDataPopup: function(data) { if (data.text != undefined) { $('.js-popup .article').html(data.text); var parsed = dataController.filterText(data); console.log('parsed: ', parsed); $('.js-popup .article').html(parsed); } else { $('.js-popup .article').html(data.intro); } }, 

Above, the function will look for tags inside the while loop. This script is called when the user clicks on an item that opens a pop-up window.

The script that is called by the getDataPopup function when the user clicks an item will look for a match; if a match is found, he calls the shortcodeController.image(data) function, which returns the new output of the variable: parsedHTML .

The function that generates the new output will look like this:

 image: function(data) { // Development console.log('shortcodeController.image'); var raw_data = data.text; var outputHTML; if (data.media != undefined) { for (var i = 0; i < data.media.length; i++) { if (data.media[i].image != undefined) { outputHTML = '<div class="image">'; // Extract filename var url = data.media[i].image.src; var filename = url.substring( url.lastIndexOf('/') + 1, url.lastIndexOf('.') ); // console.log(filename); outputHTML += '<img src="' + url + '" alt="' + filename + '" />'; //data.media[i].image = undefined; outputHTML +='</div>'; } }; return outputHTML; } else { // If media does not exists return empty string return ''; } }, 

Debatanu mentioned that I should use data.media[i].image = undefined; immediately after outputHTML, which contains the actual image object, but this will lead to an undefined error. The first [image] tag is replaced with undefined . When I comment out this line, it will be replaced by the last image object inside the media array, as mentioned earlier.

It may not work properly, because the while loop, however, only searches for gallery tags and images and, if there is a match, starts it once because it already saw the tag. Then it will be called again and again will replace the first image tag with the second image object in the multimedia array. Can a while loop be added in if statements about whether it is a gallery or an image, so a function is called for each tag in a text object?

I also noticed that when I registered the tagArr console, it will give me null when I skip it after the while loop, and an empty array [] when I insert it right after the array is created. In addition, when I log-console console immediately after starting the while loop, it only log log-console once, while two image tags are set inside JSON.

+6
source share
1 answer

You can use exec and scroll it using

  var dataText = data.text; var tags = { "gallery": /\[gallery\]/ig, "image": /\[image\]/ig, }; if (dataText != undefined) { var raw_data = dataText; for (var key in tags) { if (tags.hasOwnProperty(key)) { var tag = tags[key]; var arr=[]; while ((arr= tag.exec(dataText)) !== null) { //arr[0] will contain the first match //var newTag=newTags[key]; //you need to replace the matched output //so no need for newTag if (key == "gallery") { console.error('GALLERY'); //replace the matched output arr[0] //instead tag or newTag //Since u have [] to replace we need to ommit the regex literal format /<<exp>>/ parsedHTML = raw_data.replace(arr[0], Triptube.shortcodeController.gallery(data)); //Need to add this line for reflecting the changed data raw_data=parsedHTML; model.find('p').html(parsedHTML); } if (key == "image") { console.error('IMAGE'); //replace the matched output arr[0] //instead tag or newTag //Since u have [] to replace we need to ommit the regex literal format /<<exp>>/ parsedHTML = raw_data.replace(arr[0], Triptube.shortcodeController.image(data)); console.log(parsedHTML); //Need to add this line for reflecting the changed data raw_data=parsedHTML; model.find('p').html(parsedHTML); } } } } } 

You can learn more about this in MDN. In each exec loop, you will receive the next match until there is no match.

EDIT

I added all the filter code from the very beginning. You see, the raw_data variable must be assigned before the loop. Once this is done, the image function code below should give you the correct result.

EDIT 2

First, the filterText function will return the processed html message after parsing the html

  filterText: function(data) { // Loop through JSON data // Check if [tag] in data.text exists var dataText = data.text; var tags = { "gallery": /\[gallery\]/ig, "image": /\[image\]/ig }; if (dataText != undefined) { var raw_data = dataText, newData=JSON.parse(JSON.stringify(data));//Copy of the data object for (var key in tags) { if (tags.hasOwnProperty(key)) { var tag = tags[key]; var tagArr = []; // Check if [tag] in data.text exists while ( (tagArr = tag.exec(dataText)) !== null ) { // Call functions if (key == "gallery") { console.error('GALLERY'); parsedHTML = raw_data.replace(tagArr[0], shortcodeController.gallery(newData)); raw_data = parsedHTML; //return parsedHTML; } if (key == "image") { console.error('IMAGE'); parsedHTML = raw_data.replace(tagArr[0], shortcodeController.image(newData)); raw_data = parsedHTML; //return parsedHTML; we will return the parsed HTML only when all the tags have been replaced // model.find('p').html(parsedHTML); } } } } return parsedHTML; //return the parsed HTML here }; 

Next is the image function, which will analyze the images,

  image: function(data) { // Development console.log('shortcodeController.image'); var raw_data = data.text; var outputHTML; if (data.media != undefined) { for (var i = 0; i < data.media.length; i++) { if (data.media[i].image != undefined) { outputHTML = '<div class="image">'; // Extract filename var url = data.media[i].image.src; var filename = url.substring( url.lastIndexOf('/') + 1, url.lastIndexOf('.') ); // console.log(filename); outputHTML += '<img src="' + url + '" alt="' + filename + '" />'; outputHTML +='</div>'; data.media[i].image = undefined; //Uncommented the above code, because now the operation will be done on the copy of the original data object } }; return outputHTML; } else { // If media doesn't exists return empty string return ''; } } 
+4
source

All Articles