0

I am trying to create a loop that removes JSON objects from my JSON array based on whether any <p> elements have the selected class.

So, how I want it to work is when the form is submitted I check to see if any <p> elements have the selected class. If any of the elements are selected I loop through them using their text value to remove them from the JSON array, then I console.log() the array.

I am able to remove a single object from the array using the code inside the loop but I can't seem to get it to work with my loop. How can I achieve this?

JS

$('#form').on('submit', function(e){
    e.preventDefault();

    if( $('.postcodes p.selected').length ){
        $('.postcodes p.selected').each(function(){
            var data_filter = area_json.filter((element) => {
                return element.Sector !== $(this).text();
            });
        });
    }

    console.log(data_filter); 
}); 

var area_json = [
    {
       "Sector": "AB10 1",
       "Locality": "Thistle Court,Aberdeen",
       "Residential": 1147
    },
    {
       "Sector": "AB10 6",
       "Locality": "Great Western Road,Aberdeen",
       "Residential": 4596
    },
    {
       "Sector": "AB10 7",
       "Locality": "Holburn Street,Aberdeen",
       "Residential": 4380
    }
]

HTML

<form id="form" action="" method="post">
    <div class="postcodes">
        <p class="selected">AB10 1</p>
        <p class="selected">AB10 6</p>
    </div>
    <input type="submit" value="submit">
</form>
0

4 Answers 4

2

Try like this. in your .each loop try push the data and in filter you can check .indexOf(). this will give you the result.

I moved .filter out of .each loop. because loop inside loop is a bad idea and it will consume time.

var area_json = [
    {
       "Sector": "AB10 1",
       "Locality": "Thistle Court,Aberdeen",
       "Residential": 1147
    },
    {
       "Sector": "AB10 6",
       "Locality": "Great Western Road,Aberdeen",
       "Residential": 4596
    },
    {
       "Sector": "AB10 7",
       "Locality": "Holburn Street,Aberdeen",
       "Residential": 4380
    }
];
$('#form').on('submit', function(e){
    e.preventDefault();

    if( $('.postcodes p.selected').length ){
      var data = [];
        $('.postcodes p.selected').each(function(){
            data.push($(this).text());
        });
       var data_filter = area_json.filter((element) => {
        return (data.indexOf(element.Sector)<0)
       });
    }

    console.log(data_filter); 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form" action="" method="post">
    <div class="postcodes">
        <p class="selected">AB10 1</p>
        <p class="selected">AB10 6</p>
    </div>
    <input type="submit" value="submit">
</form>

Sign up to request clarification or add additional context in comments.

Comments

1

You may retrieve selected options .text() by simply doing [...$('.selected')].map(p => $(p).text()), than you may filter out those area_json array items that are already selected by means of includes() method

var area_json = [
    {
       "Sector": "AB10 1",
       "Locality": "Thistle Court,Aberdeen",
       "Residential": 1147
    },
    {
       "Sector": "AB10 6",
       "Locality": "Great Western Road,Aberdeen",
       "Residential": 4596
    },
    {
       "Sector": "AB10 7",
       "Locality": "Holburn Street,Aberdeen",
       "Residential": 4380
    }
];

const res = area_json.filter(item => ![...$('.selected')].map(p => $(p).text()).includes(item.Sector));

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form" action="" method="post">
    <div class="postcodes">
        <p class="selected">AB10 1</p>
        <p class="selected">AB10 6</p>
    </div>
    <input type="submit" value="submit">
</form>

5 Comments

Seems to work perfectly thanks. But what are the three dots about just before $('.selected')? if I remove them it doesn't work properly
That's a spread syntax to turn iterable jQuery object into array, so you can apply .map() method
You may do Array.from($('.selected')) instead, if you don't like that tripple dot thing for some reason
...or, even $('.selected').toArray() ...somebody, stop me, please
And just one more little thing, if the number of selected <p> is large enough and you're willing to sacrifice conciseness for performance, you may assign [...$('.selected')].map(p => $(p).text()) to the variable outside of .filter() not to do extra looping
1

You need use each(function(index, item) and $(item).text() , move console inside each.

 if( $('.postcodes p.selected').length ){
        $('.postcodes p.selected').each(function(index, item){
            var data_filter = area_json.filter((element) => {
                return element.Sector !== $(item).text();
            });
             console.log(data_filter); 
        });
    }

$('#form').on('submit', function(e){
    e.preventDefault();
    var data_filter = [];
    if( $('.postcodes p.selected').length ){
        $('.postcodes p.selected').each(function(index, item){
            data_filter = area_json.filter((element) => {
                return element.Sector !== $(item).text();
            });
            
        });
    }

    console.log(data_filter); 
}); 

var area_json = [
    {
       "Sector": "AB10 1",
       "Locality": "Thistle Court,Aberdeen",
       "Residential": 1147
    },
    {
       "Sector": "AB10 6",
       "Locality": "Great Western Road,Aberdeen",
       "Residential": 4596
    },
    {
       "Sector": "AB10 7",
       "Locality": "Holburn Street,Aberdeen",
       "Residential": 4380
    }
]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form" action="" method="post">
    <div class="postcodes">
        <p class="selected">AB10 1</p>
        <p class="selected">AB10 6</p>
    </div>
    <input type="submit" value="submit">
</form>

2 Comments

Thanks but I need to return a single JSON array so I can filter it again without any of the selected values inside it
I update answer, create a variable outside of each scope
1

here is a working version I threw together:

$(document).ready(function() {

  var data_filter = [];
  var data_filterChecked = [];

  $('#form').on('submit', function(e) {
    e.preventDefault();
    data_filterChecked = [];

    if ($('.postcodes p.selected').length) {
      $('.postcodes p.selected').each(function(i, element) {
        var lookingFor = $(element).text();
        data_filter = area_json.filter((element) => {
          if (element.Sector !== lookingFor) {
            data_filterChecked.push(element);
          }

        });

      });
      data_filter = data_filterChecked;
    }

    console.log(data_filter);
  });

  var area_json = [{
      "Sector": "AB10 1",
      "Locality": "Thistle Court,Aberdeen",
      "Residential": 1147
    },
    {
      "Sector": "AC10 6",
      "Locality": "Great Western Road,Aberdeen",
      "Residential": 4596
    },
    {
      "Sector": "AB10 7",
      "Locality": "Holburn Street,Aberdeen",
      "Residential": 4380
    }
  ]

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<form id="form" action="" method="post">
  <div class="postcodes">
    <p class="selected">AB10 1</p>
    <p class="selected">AB10 1</p>
  </div>
  <input type="submit" value="submit">
</form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.