0

I am trying to use javascript to find duplicate values in form elements (input boxes and select drop downs) based on class. This is what I have, but it is not working. Is there a better way to do this? I am new to javascript and saw this as a solution on a different post.

EDIT: Only the inner functions are not called. If I break them out, they get called. Why is this?

    <%@ taglib prefix="s" uri="/struts-tags"%>

<s:include value="Header.jsp">
<s:param name="pageScript">
        <script type="text/javascript">

    function checkForDuplicates() {
              var hasDuplicates = false;
                  $('.class_name').each(function () {
                      var inputsWithSameValue = $(this).val();
                      hasDuplicates = $('.class_name').not(this).filter(function () {
                              return $(this).val() === inputsWithSameValue;
                      }).length > 0;
                      if (hasDuplicates){
                      alert("cannot have duplicates")
                  }
                  });

          }

        </script>
    </s:param>
</s:include>

<div id="container-content">
    <div id="content">
        <s:form action="someAction" theme="simple" method="get" id="theForm">

                        <s:textfield theme="simple" class="class_name"/>

                        <s:textfield theme="simple" class="class_name" />

                        <s:select headerKey="" headerValue="Select Value" 
                        list="values" listKey="value" class="class_name" size="1"/>

            <s:submit action="" value="Save" onclick="return checkForDuplicates()"/>

        </s:form>

        <%-- end content --%>
    </div>
    <%-- end container-content --%>
</div>

<s:include value="Footer.jsp" />

I am importing these:

<script src="scripts/jquery-1.4-min.js"></script>
<script src="scripts/jquery.maskedinput.min.js" type="text/javascript"></script>
<script src="scripts/jquery.supertextarea.min.js" type="text/javascript"></script>

What is the problem? I put a breakpoint inside the first innerfunction after the .each, but it never goes in there.

Thanks

Seephor
  • 1,692
  • 3
  • 28
  • 50
  • Is `checkForDuplicates` being invoked? Do you have elements whose `class='class_name'`? – ray May 24 '16 at 23:51
  • @ray I have a submit button invoking it via "onclick" and I have elements with "class_name". It is being invoked because the breakpoint on "var hadDuplicates = false" is being hit, but nothing beyond that. – Seephor May 24 '16 at 23:53
  • this kind of code is just awful. how the people can like such a mess ? – reuns May 24 '16 at 23:53
  • 1
    @user19252009 please help with suggestion then? – Seephor May 24 '16 at 23:54
  • Can we see your html? – ray May 24 '16 at 23:55
  • @ray I updated it with code from the jsp page. jsp is a requirement. header.jsp contains the imports of the other scripts. – Seephor May 25 '16 at 00:03

2 Answers2

4

This is based on ROX's answer, however, i think we can check if the next element's input is inside the array without the need of a second function.

function checkDuplicates() {
  // get all input elements
  var $elems = $('.class_name');

  // we store the inputs value inside this array
  var values = [];
  // return this
  var isDuplicated = false;
  // loop through elements
  $elems.each(function () {
    //If value is empty then move to the next iteration.
    if(!this.value) return true;
    //If the stored array has this value, break from the each method
    if(values.indexOf(this.value) !== -1) {
       isDuplicated = true;
       return false;
     }
    // store the value
    values.push(this.value);
  });   
return isDuplicated;     
}

You might want to check if the input is empty somewhere in your code but that's up to you.

Edit : https://jsfiddle.net/65ss1cxj/

Yanaro
  • 345
  • 4
  • 16
  • Nice idea. I think you make a typo: `===` should be `!==` – dashtinejad May 25 '16 at 04:24
  • Also you *should* check empty values, and don't store them inside the array. – dashtinejad May 25 '16 at 04:26
  • @Izumi Yanaro the size of $elems is always zero even though my fields are marked with "class=class_name".... I can't figure out why – Seephor May 25 '16 at 04:44
  • Ah yeah my bad, it should've been !==, I think it's a good idea to check if value is empty, i initially thought that OP should check if value is empty first before running this function. – Yanaro May 25 '16 at 04:46
  • @Seephor It works fine for me, see my updated function, it has nothing to do with empty $elems though, have you try with internal/external event listener for your button, like what i do in my JsFiddle? Personally i'm not a fan of inline event listener, and JsFiddle won't let me use inline onclick. – Yanaro May 25 '16 at 05:27
  • @IzumiYanaro I figured it out. I had to use cssClass="class_name" in struts. – Seephor May 25 '16 at 19:10
1

Your could make your function much better, there is no need to loop all over your elements inside your first loop.

Just store your all inputs values into an array, then make that array unique values, and compare the length of them.

// a function to make an array values unique 
// http://stackoverflow.com/a/840849/3971911
function eliminateDuplicates(arr) {
  var i,
      len=arr.length,
      out=[],
      obj={};

  for (i=0;i<len;i++) {
    obj[arr[i]]=0;
  }
  for (i in obj) {
    out.push(i);
  }
  return out;
}


function checkDuplicates() {
  // get all input elements
  var $elems = $('.class_name');
  
  // we store the inputs value inside this array
  var values = [];
  
  // loop through elements
  $elems.each(function () {
    // if the value is empty, just pass it
    if (this.value == '') {
      return true;
    }
    
    // store the value
    values.push(this.value);
  });
  
  // make the values array unique
  var uniqueValues = eliminateDuplicates(values);
  
  // return false if the unique array length is not equal to the original array
  return uniqueValues.length == values.length;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<form>
  <div><input type="text" class="class_name" /></div>  
  <div><input type="text" class="class_name" /></div>
  <div><input type="text" class="class_name" /></div>
  <div><input type="text" class="class_name" /></div>
  
  <input type="submit" value="Go" onclick="return checkDuplicates()" />
</form>
dashtinejad
  • 6,193
  • 4
  • 28
  • 44