Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have created a function, that will search for different tags, tags like [image] and [gallery] inside a JSON file. If there is a match, it will return and replace it with a new output. Like an image object or a slideshow.

A JSON object can contain multiple tags of the same type, or contain different ones at the same time. So an object can contain two [image] tags for e.g.

JSON

http://snippi.com/s/bzrx3xi

The problem was, if there are multiple [image] tags found, it was replaced with the same content. I was looking for a script that is searching for the tags, until there will no matches anymore. Many thanks to @debatanu for the solution.

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

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

Search for tags

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 function will search for tags inside a while loop. This script is called, when the user clicked on an item, that will open a popup screen.

The script that is called by the getDataPopup function when the user clicked on an item, will search for a match, when there is a match found, it will call the function shortcodeController.image(data) that return the new output to the variable: parsedHTML.

The function that generates a 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 doesn't exists return empty string
            return '';
        }

    }, 

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

Maybe it does not work like properly, because the while loop, however, only looks for the gallery and image tags and if there is a match, running it once, because he already saw the tag. Then it will be called again and replaces the first image tag again with the second image object within the media array. Should there might be a while loop added in the if statements on whether it is a gallery or image, so for each tag within the text object is the function called?

Also I noticed, when I console logged tagArr it will give me an value of null when I past it after the while loop and a empty array [] when I paste it directly after the array is created. Beside that, when I console log tag directly after the while loop is started, it only console log tag once, while there are two image tags set inside the JSON.

like image 513
Caspert Avatar asked Nov 26 '15 08:11

Caspert


1 Answers

You can use exec and loop through 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 find more about it in MDN With each loop the exec will give you the next match untill no match is left.

EDIT

I have added the entire filter code from the beginning. You see the raw_data variable should be assigned before the loop. Once that is done, the code below with the image function should give you the proper result.

EDIT 2

First the filterText function will return the parsed html post completion of 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 parse through 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 '';
    }

}
like image 178
debatanu Avatar answered Nov 12 '22 06:11

debatanu