0

I want to create a map from multiple strings. And whenever the input string changes, the map changes accordingly.

I'm having a simple issue I can't seem to fix. Below is a simplified version:

HTML:

<div class="boo-card-link" data-href="card-1">
    <input type="text" id="filter_tags" name="filter_tags" value="tags11,tags12">
</div>
<div class="boo-card-link" data-href="card-2">
    <input type="text" id="filter_tags" name="filter_tags" value="tags21,tags22">
</div>
<div class="boo-card-link" data-href="card-3">
    <input type="text" id="filter_tags" name="filter_tags" value="tags31,tags32">
</div>

JS Idea: Part1: Merge all the #filter_tags value into window.hint_arr value

var $ = jQuery;
window.hint_arr = function(){
    var array_filter_tags       = [];
    var count                   = 1;
    $(".boo-card-link").each(function(){
        var id                  = count;
        var tmp_filter_tags     = $("#txtfilter_tags").val();
        tmp_filter_tags         = tmp_filter_tags.replace(/\s/g, '');
        var json_filter_tags    = tmp_filter_tags.split(',');
        count++;
        array_filter_tags       = $.merge(array_filter_tags, json_filter_tags).unique();
    });
    array_filter_tags = array_filter_tags.join();
    return array_filter_tags;
};
window.hint_arr(); //result: tags11,tags12,tags21,tags22,tags31,tags32

Part2: Convert string value to a map

var Convert = function() {
    var json = [];
    var to = ""+window.hint_arr();
    var toSplit = to.split(",");
    for (var i = 0; i < toSplit.length; i++) {
        json.push({"num":toSplit[i]});
    }
    a = function() {
        console.log(json);
    };

    return {
        init: function() {
            a()
        }
    }
}();
Convert.init(); //result: [{num:'tags11'},{num:'tags12'},{num:'tags21'},{num:'tags22'}...]

Until this step, everything is fine. The problem I encountered is that when changing the value of any input, a map called "json" does not change accordingly.

$('#filter_tags').on('change', function() {
    console.log(window.hint_arr());
});
$('#filter_tags').trigger('change');

For example when the first input changes the value from value = "tags11, tags12" to value = "tags11, tags12, tags13", the result of window.hint_arr () has changed to 'tags11,tags12,tags13,tags21,tags22,tags31,tags32' but the map json constant. I've tried to recall the Convert() Function but nothing seems to return what I'm looking for

Any ideas of how I can accomplish this?.

  • Why are you using `$('#txtfilter_tags').on` when you have **filter_tags** as id. Another thing, don't repeat ids like classes, use a changed id for every element. – abdul-wahab Jan 17 '18 at 17:20
  • oh, I'm sorry for my typo mistake. Because I use 1 element input id and clone it each time I add other elements with different values. Then merge all the values back into the array. This does not cause the problem that I encountered – Ha Doan Thanh Jan 17 '18 at 17:35

1 Answers1

0

I feel like you can simplify your logic by a lot by just using Array.map() and (jQuery) .map()

The onchange event occurs when the value of an element has been changed but after you leave the element.

// taken from another post
Array.prototype.unique = function() {
  var a = [];
  for (var i = 0, l = this.length; i < l; i++)
    if (a.indexOf(this[i]) === -1)
      a.push(this[i]);
  return a;
}

// note 1: json is defined globally

var json = [];

$(function() {

  var inputs = $('input[name=filter_tags]').on('change', function() {
    // get all values e.g. 'tags11,tags12,tags21,tags22,tags31,tags11'

    // note 2: .get() is to convert jQuery array to normal array
    // note 3: .join() is to join all the values in the normal array

    var values = inputs.map(function() {
      return this.value.replace(/\s/g, '');
    }).get().join(',');

    // console.log(values);

    // split all values and remove dups e.g. ['tags11','tags12','tags21','tags22','tags31']

    var tags = values.split(',').unique();

    // console.log(tags);

    // convert tags e.g. [{ num: 'tags11' }, { num: 'tags12' }, ...]

    // note 4: this is not jQuery .map(), but Array.map()


    json = tags.map(function(tag) {
      return {
        'num': tag
      };
    });

    console.log(json);

  });

  // trigger change
  inputs.eq(0).change();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="boo-card-link" data-href="card-1">
  <input type="text" name="filter_tags" value="tags11 ,tags12  ">
</div>
<div class="boo-card-link" data-href="card-2">
  <input type="text" name="filter_tags" value="tags21,tags22">
</div>
<div class="boo-card-link" data-href="card-3">
  <input type="text" name="filter_tags" value="  tags31, tags11">
</div>

Array.unique() is taken from this answer.

Mikey
  • 6,728
  • 4
  • 22
  • 45