-2

I have a form with many inputs but the two I am concerned with here are named attributes[] and options[$index][] This is what sample data in my attributes[] input looks like:

Array
(
    [0] => Size
    [1] => Color
    [2] => Material
)

Note: The above is the $_POST data visualized as PHP array
Below is what the HTML form would look like:

<input name="attributes[]" value="Size">
<input name="attributes[]" value="Color">
<input name="attributes[]" value="Material">

And this is what data from options[$index][] looks like:

Array
(
    [1] => Array
        (
            [0] => Small
            [1] => Medium
            [2] => Large
            [3] => 
        )

    [2] => Array
        (
            [0] => Red
            [1] => Blue
            [2] => Green
            [3] => 
        )

    [3] => Array
        (
            [0] => Cotton
            [1] => Wool
            [2] => 
        )

)

Note: The above is the $_POST data visualized as PHP array
Below is what the HTML form would look like:

<input name="options[1][]" value="Small">
<input name="options[1][]" value="Medium">
<input name="options[1][]" value="Large">

<input name="options[2][]" value="Red">
<input name="options[2][]" value="Blue">
<input name="options[2][]" value="Green">

<input name="options[3][]" value="Cotton">
<input name="options[3][]" value="Wool">

(note sometimes the index-value from attributes[] may not match the index-value on corresponding array on options[$index][])

I'm trying to create a table dynamically that has one column for every non-empty element in attributes[] and a row for every COMBINATION of options available so for the table above this is what a sample table would look like:

+-------+-------+----------+-----+
| Size  | Color | Material | SKU |
+-------+-------+----------+-----+
| Small | Red   | Cotton   | 100 |
| Small | Red   | Wool     | 101 |
| Small | Blue  | Cotton   | 102 |
| Small | Blue  | Wool     | 103 |
| Small | Green | Cotton   | 104 |
| ...   | ...   | ...      | ... |

I already have a function that computes the cartesian products of arrays which outputs an array of arrays with the combination (ref: https://stackoverflow.com/a/12305169/1043817)

I'm not really sure how I can get all the values from the inputs turn them into an array and feed them into the CartProd() function. My main concern at this point are the option[$index][] inputs.

From the sample data above, this this what I want to produce: [small, medium, large] [Red, Blue, Green] [Cotton, Wool]

Community
  • 1
  • 1
Zaki Aziz
  • 3,592
  • 11
  • 43
  • 61

1 Answers1

1

Here's the fiddle http://jsfiddle.net/0cool/d7n5h/.

var yourSampleData =
  (function (allInputs, _, _out, _trimstr, _attrIdxs, _safereg) {
  _attrIdxs(allInputs)
    .forEach(
      function (idx) {
        _out.push(
          _.filter.call(
            allInputs,
            function (input) {
              return (new RegExp("^options\\[" + _safereg(idx) + "\\]"))
                .test(String(input.name)) && _trimstr(input.value).length;
            }
          )
          .map(
            function (validinput) {
              return _trimstr(validinput.value);
            }
          )
        );
      }
  );
  return _out;
})(

  document.getElementsByTagName("input"),

  Array.prototype,

  [],

  // _trimstr
  (function () {
    var blanks = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
    return function (str) {
      return String(str).replace(blanks, "");
    };
  })(),

  // _attrIdxs
  (function () {

    var _ = Array.prototype;
    var attrMatcher = /^attributes/;
    var idxMatcher = /^attributes\[(.+?)\]/;

    return function (allInputs) {
      var out = [];
      _.filter.call(
        allInputs,
        function (input) {
          return attrMatcher.test(String(input.name));
        }
      )
        .forEach(
          function (input) {
            var ind;
            ( out
              .indexOf( ind = +String(input.name).match(idxMatcher)[1] ) ^ -1
            ) || out.push( ind );
          }
      );
      return out;
    };
  })(),

  // _safereg
  (function (REGEX_ESCAPER) {
    return function (strreg) {
      return String(strreg).replace(REGEX_ESCAPER, '\\$1');
    }
  })(/([.*+?\^=!:${}()|\[\]\/\\])/g)

);


//
// and with your cartesian function:
//
//   var
//      cProd = cartProd.apply( this, yourSampleData );
//

console.log( yourSampleData );
//
//
//
public override
  • 974
  • 8
  • 17
  • Thank you for the answer, but I have a small problem with this solution. I have to feed the data into the function as multiple array (not an array of arrays). Example: `cartProd([small, medium, large], [Red, Blue, Green], [Cotton, Wool])` – Zaki Aziz Oct 18 '13 at 21:51
  • use: Function.apply then with result array: cartProd.apply( this, data ); – public override Oct 18 '13 at 21:53
  • I understood the second part about `cart.Prod.apply( this, data )` but not the first. WHere would I use Function.apply? – Zaki Aziz Oct 18 '13 at 21:57
  • functions are object in javascript and they have methods. .apply method executes a function passing array's elements as parameters to function, so: cartProd([small, medium, large], [Red, Blue, Green], [Cotton, Wool]), is the same as cartProd.apply( this, [[small, medium, large], [Red, Blue, Green], [Cotton, Wool]]). check the fiddle again, I've just update it to demo it. – public override Oct 18 '13 at 22:05
  • or you can replace `return addTo([], Array.prototype.slice.call(arguments));` with `return addTo([], paramArray);`, and use function without .apply method: `cartProd( data )`. – public override Oct 18 '13 at 22:31
  • Thank you, this functions. But I have another issue: the function you've given me assumes that the array index of options[] is always attributes[] + 1. Sometimes the index may be the same sometimes the array index may differ, how can I address this? – Zaki Aziz Oct 18 '13 at 22:39
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/39532/discussion-between-xecure-and-nikola-vukovic) – Zaki Aziz Oct 18 '13 at 22:48
  • got something? 'attr_index' is auto-updated and you don't have much control over it, I see; it can do with idea you figured out; if your elements have same index to mix and match them, then you have a way to get at data you're after... check the solution update . – public override Oct 19 '13 at 01:42