]> source.dussan.org Git - gwtquery.git/commitdiff
Fix val() methods to behave identical to jquery. This could break apps. Thanks to...
authorManolo Carrasco <manolo@apache.org>
Fri, 26 Aug 2011 10:42:25 +0000 (10:42 +0000)
committerManolo Carrasco <manolo@apache.org>
Fri, 26 Aug 2011 10:42:25 +0000 (10:42 +0000)
gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTest.java

index fcf4017258c4f69d0d0d09dfb3beb7e5424d6482..97489f0f2ec90aaf3a6f0ed20417713d8bbee0c5 100644 (file)
@@ -180,6 +180,13 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
   public static GQuery $() {\r
     return new GQuery(JsNodeArray.create());\r
   }\r
+  \r
+  /**\r
+   * Wrap a GQuery around an existing element.\r
+   */\r
+  public static GQuery $(Function f) {\r
+    return new GQuery(f.getElement());\r
+  }\r
 \r
   /**\r
    * Wrap a GQuery around an existing element.\r
@@ -469,6 +476,10 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
                return array;\r
   }-*/;\r
 \r
+  private static native void setElementValue(Element e, String value) /*-{\r
+    e.value = value;\r
+  }-*/;\r
+  \r
   private static native void scrollIntoViewImpl(Node n) /*-{\r
                if (n)\r
                        n.scrollIntoView()\r
@@ -3725,56 +3736,103 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
    * array of all values in multivalues elements use vals()\r
    * \r
    * When the first element is a radio-button and is not checked, then it looks\r
-   * for the first checked radio-button that has the same name in the list of\r
+   * for the first checked radio-button that has the same name in the list of\r
    * matched elements.\r
+   * \r
+   * When there are not matched elements it returns null.\r
    */\r
   public String val() {\r
+    if (isEmpty()) {\r
+      return null;\r
+    }\r
     String[] v = vals();\r
-    return (v != null && v.length > 0) ? v[0] : "";\r
+    return v == null ? null : v.length > 0 ? v[0] : "";\r
   }\r
-\r
+  \r
+  /**\r
+   * Sets the value attribute of every matched element based in the return\r
+   * value of the function evaluated for this element.\r
+   * \r
+   * NOTE: in jquery the function receives the arguments in different\r
+   * way, first index and them the actual value, but we use the normal way\r
+   * in gquery Function, first the element and second the index.\r
+   */\r
+  public GQuery val(Function f) {\r
+    for (int i = 0; i < size(); i++){\r
+      eq(i).val(f.f(get(i), i).toString());\r
+    }\r
+    return this;\r
+  }\r
+  \r
+  /**\r
+   * Sets the 'value' attribute of every matched element, but\r
+   * does not set the checked flag to checkboxes or radiobuttons.\r
+   * \r
+   * If you wanted to set values in collections of checkboxes o radiobuttons \r
+   * use val(String[]) instead\r
+   */\r
+  public GQuery val(String value) {\r
+    for (Element e : elements) {\r
+      setElementValue(e, value);\r
+    }\r
+    return this;\r
+  }\r
+  \r
   /**\r
-   * Sets the value attribute of every matched element In the case of multivalue\r
-   * elements, all values are setted for other elements, only the first value is\r
-   * considered.\r
+   * Sets the value of every matched element.\r
+   * \r
+   * There is a different behaviour depending on the element type:\r
+   * <ul>\r
+   *  <li>select multiple: options whose value match any of the passed values will be set.\r
+   *  <li>select single: the last option whose value matches any of the passed values will be set.\r
+   *  <li>input radio: the last input whose value matches any of the passed values will be set.\r
+   *  <li>input checkbox: inputs whose value match any of the passed values will be set.\r
+   *  <li>textarea, button, and other input: value will set to a string result of joining with coma, all passed values \r
+   * </ul>\r
+   * \r
+   * NOTE: if you wanted call this function with just one parameter, you have to\r
+   * pass an array signature to avoid call the overloaded val(String) method:\r
+   * \r
+   * $(...).val(new String[]{"value"});\r
    */\r
   public GQuery val(String... values) {\r
+    String value = values.length > 0 ? values[0] : "";\r
+    for (int i = 1; i < values.length; i++) {\r
+      value += "," + values[i];\r
+    }\r
     for (Element e : elements) {\r
       String name = e.getNodeName();\r
       if ("select".equalsIgnoreCase(name)) {\r
         SelectElement s = SelectElement.as(e);\r
         s.setSelectedIndex(-1);\r
-        if (values.length > 1 && s.isMultiple()) {\r
-          for (String v : values) {\r
+        for (String v : values) {\r
+          if (s.isMultiple()) {\r
             for (int i = 0, l = s.getOptions().getLength(); i < l; i++) {\r
               if (v.equals(s.getOptions().getItem(i).getValue())) {\r
                 s.getOptions().getItem(i).setSelected(true);\r
               }\r
             }\r
+          } else {\r
+            s.setValue(v);\r
           }\r
-        } else {\r
-          s.setValue(values[0]);\r
         }\r
       } else if ("input".equalsIgnoreCase(name)) {\r
         InputElement ie = InputElement.as(e);\r
         String type = ie.getType();\r
-        \r
         if ("radio".equalsIgnoreCase((type))\r
             || "checkbox".equalsIgnoreCase(type)){\r
           ie.setChecked(false);\r
-          for (String val : values) {\r
-            if (ie.getValue().equals(val)) {\r
+          for (String v : values) {\r
+            if (ie.getValue().equals(v)) {\r
               ie.setChecked(true);\r
               break;\r
             }\r
           }\r
         } else {\r
-          ie.setValue(values[0]);\r
+          ie.setValue(value);\r
         }\r
-      } else if ("textarea".equalsIgnoreCase(name)) {\r
-        TextAreaElement.as(e).setValue(values[0]);\r
-      } else if ("button".equalsIgnoreCase(name)) {\r
-        ButtonElement.as(e).setValue(values[0]);\r
+      } else {\r
+        setElementValue(e, value);\r
       }\r
     }\r
     return this;\r
@@ -3804,29 +3862,29 @@ public class GQuery implements Lazy<GQuery, LazyGQuery> {
               result.set(result.length(), oe.getValue());\r
             }\r
           }\r
-          return jsArrayToString(result);\r
+          return result.length() > 0 ? jsArrayToString(result) : null;\r
         } else if (se.getSelectedIndex() >= 0) {\r
           return new String[]{se.getOptions().getItem(se.getSelectedIndex()).getValue()};\r
         }\r
       } else if (e.getNodeName().equalsIgnoreCase("input")) {\r
         InputElement ie = InputElement.as(e);\r
-        if ("radio".equalsIgnoreCase(ie.getType())) {\r
-          for (Element e2 : elements) {\r
-            if ("input".equalsIgnoreCase(e2.getNodeName())) {\r
-              InputElement ie2 = InputElement.as(e2);\r
-              if ("radio".equalsIgnoreCase(ie2.getType()) && ie2.isChecked()\r
-                  && ie.getName().equals(ie2.getName())) {\r
-                return new String[]{ie2.getValue()};\r
-              }\r
-            }\r
-          }\r
-        } else if ("checkbox".equalsIgnoreCase(ie.getType())) {\r
-          if (ie.isChecked()) {\r
-            return new String[]{ie.getValue()};\r
-          }\r
-        } else {\r
-          return new String[]{ie.getValue()};\r
-        }\r
+        return new String[]{ie.getValue()};\r
+//        if ("radio".equalsIgnoreCase(ie.getType())) {\r
+//          for (Element e2 : elements) {\r
+//            if ("input".equalsIgnoreCase(e2.getNodeName())) {\r
+//              InputElement ie2 = InputElement.as(e2);\r
+//              if ("radio".equalsIgnoreCase(ie2.getType()) && ie2.isChecked()\r
+//                  && ie.getName().equals(ie2.getName())) {\r
+//                return new String[]{ie2.getValue()};\r
+//              }\r
+//            }\r
+//          }\r
+//          if (ie.isChecked()) {\r
+//            return new String[]{ie.getValue()};\r
+//          }\r
+//        } else {\r
+//          return new String[]{ie.getValue()};\r
+//        }\r
       } else if (e.getNodeName().equalsIgnoreCase("textarea")) {\r
         return new String[]{TextAreaElement.as(e).getValue()};\r
       } else if (e.getNodeName().equalsIgnoreCase("button")) {\r
index 7a308d17987b085e1b59b3a902184a5ba63e4ca4..163dc03d1febf1c3db3391762008ae79813762a7 100644 (file)
@@ -265,7 +265,7 @@ public class GQueryCoreTest extends GWTTestCase {
     $("p", e).empty();
     assertHtmlEquals(expected, $(e).html());
   }
-
+  
   public void testInputValueMethods() {
     // imput text
     $(e).html("<input type='text'/>");
@@ -286,8 +286,8 @@ public class GQueryCoreTest extends GWTTestCase {
     $(e).html(
         "<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2'>2</option><option value='v3'>3</option></select>");
     gq = $("select", e);
-    assertEquals(0, gq.vals().length);
-    assertEquals("", gq.val());
+    assertNull(gq.vals());
+    assertNull(gq.val());
 
     $(e).html(
         "<select name='n' multiple='multiple'><option value='v1'>1</option><option value='v2' selected='selected'>2</option><option value='v3'>3</option></select>");
@@ -307,22 +307,24 @@ public class GQueryCoreTest extends GWTTestCase {
     $(e).html(
         "<input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input>");
     gq = $("input", e);
-    assertEquals("v2", gq.val());
-    gq.val("v1");
     assertEquals("v1", gq.val());
-    gq.val("v2");
-    assertEquals("v2", gq.val());
+    assertEquals("v2", $("input:checked", e).val());
+    gq.val(new String[]{"v1"});
+    assertEquals("v1", $("input:checked", e).val());
+    gq.val(new String[]{"v2"});
+    assertEquals("v2", $("input:checked", e).val());
 
     // input checkbox
     $(e).html(
         "<input type='checkbox' name='n1' value='v1'>1</input><input type='checkbox' name='n2' value='v2' checked='checked'>2</input>");
     gq = $("input", e);
-    assertEquals("", gq.val());
-    gq.val("v1");
     assertEquals("v1", gq.val());
+    assertEquals("v2", $("input:checked", e).val());
+    gq.val(new String[]{"v1"});
+    assertEquals("v1", $("input:checked", e).val());
   }
-
-  public void testIssue23() {
+  
+   public void testIssue23() {
     $(e).html(
         "<table><tr><td><input type='radio' name='n' value='v1'>1</input><input type='radio' name='n' value='v2' checked='checked'>2</input></td><td><button>Click</button></tr><td></table>");
     $("button").click(new Function() {
@@ -897,57 +899,92 @@ public class GQueryCoreTest extends GWTTestCase {
     assertFalse(JsUtils.truth(""));
   }
   
-  public void testVal(){
-    //HTML code used in this test
-    $(e).html("<select id='single'>"
-              +    "<option>Single</option>"
-              +    "<option>Single2</option>"
-              +"</select>"
-              +"<select id='multiple' multiple='multiple'>"
-              +    "<option selected='selected'>Multiple</option>"
-              +    "<option>Multiple2</option>"
-              +    "<option selected='selected'>Multiple3</option>"
-              +"</select>"
-              +"<input id='check1' type='checkbox' name='checkboxname' value='check1'> check1"
-              +"<input id='check2' type='checkbox' name='checkboxname' value='check2'> check2"
-              +"<input id='check3' type='checkbox' name='checkboxname' value='check3'> check3"
-              +"<input id='radio1' type='radio' name='r' value='radio1'> radio1"
-              +"<input id='radio2' type='radio' name='r' value='radio2'> radio2"
-              +"<input id='text'   type='text'></input>");
-    
-    $("#single",e).val("Single2");
-    SelectElement single =  SelectElement.as($("#single",e).get(0));
-    assertEquals(1, single.getSelectedIndex());
-    
-    $("#multiple",e).val("Multiple2", "Multiple3"); 
-    NodeList<OptionElement>options = SelectElement.as($("#multiple",e).get(0)).getOptions();
-    
-    assertEquals(false, options.getItem(0).isSelected());
-    assertEquals(true, options.getItem(1).isSelected());
-    assertEquals(true, options.getItem(2).isSelected());
-    
-    $("input",e).val("check1","check2", "radio1", "radio2" );
-    assertEquals(true, InputElement.as($("#check1", e).get(0)).isChecked());
-    assertEquals(true, InputElement.as($("#check2", e).get(0)).isChecked());
-    assertEquals(false, InputElement.as($("#check3", e).get(0)).isChecked());
-    
-    //radio1 should not be selected
-    assertEquals(false, InputElement.as($("#radio1", e).get(0)).isChecked());
-    //radio1 should be selected
-    assertEquals(true, InputElement.as($("#radio2", e).get(0)).isChecked());
-    
-    //radio1 should not be selected
-    assertEquals("check1", InputElement.as($("#text", e).get(0)).getValue());
-
+  public void testVal_issue98() {
+    $(e).html(""
+      +"<input type='text' id='inputText' name='inputText' value='original' />"
+      +"<textarea id='textArea' name='textArea'>original</textarea>"
+      +"<button id='button' name='button'value='original'>Click</button>"
+    
+      +"<select id='selectSingle' name='selectSingle'>"
+      +"<option value='v0'>Single0</option>"
+      +"<option value='v1'>Single1</option>"
+      +"<option value='v2'>Single2</option>"
+      +"</select>"
+    
+      +"<select id='selectMultiple' name='selectMultiple' multiple='multiple'>"
+      +"<option value='v0'>Multiple0</option>"
+      +"<option value='v1'>Multiple1</option>"
+      +"<option value='v2'>Multiple2</option>"
+      +"</select><br/>"
+
+      +"<input type='checkbox' name='c' value='v0'/> check0"
+      +"<input type='checkbox' name='c' value='v1'/> check1"
+      +"<input type='checkbox' name='c' value='v2'/> check2"
+    
+      +"<input type='radio'  name='r' value='v0'/> radio0"
+      +"<input type='radio'  name='r' value='v1'/> radio1"
+      +"<input type='radio'  name='r' value='v2'/> radio2"
+    );
+    
+    assertNull($().val());
+    assertEquals(0, $().vals().length);
+
+    assertEquals("original", $("#inputText", e).val());
+    assertEquals("original", $("#textArea", e).val());
+    assertEquals("original", $("#button", e).val());
+    $("#inputText, #textArea, #button", e).val("newval");
+    assertEquals("newval", $("#inputText", e).val());
+    assertEquals("newval", $("#textArea", e).val());
+    assertEquals("newval", $("#button", e).val());
+    
+    assertEquals("v0", $("#selectSingle", e).val());
+    assertNull($("#selectMultiple", e).val());
+    $("#selectSingle, #selectMultiple", e).val("v2");
+    assertEquals("v2", $("#selectSingle", e).val());
+    assertEquals("v2", $("#selectMultiple", e).val());
+
+    assertEquals("v0", $("input[type='checkbox']", e).val());
+    assertNull($("input[type='checkbox']:checked", e).val());
+    // val(String) changes the value attribute, but not set it as checked
+    $("input[type='checkbox']", e).eq(0).val("n0");
+    assertEquals("n0", $("input[type='checkbox']", e).val());
+    assertNull($("input[type='checkbox']:checked", e).val());
+    // val(array) set the checked property to true if the value name matches
+    $("input[type='checkbox']", e).val(new String[]{"n0"});
+    assertEquals("n0", $("input[type='checkbox']", e).val());
+    assertNotNull($("input[type='checkbox']:checked", e).val());
+    
+    assertEquals("v0", $("input[type='radio']", e).val());
+    assertNull($("input[type='radio']:checked", e).val());
+    $("input[type='radio']").eq(0).val("n0");
+    assertEquals("n0", $("input[type='radio']", e).val());
+    assertNull($("input[type='radio']:checked", e).val());
+  
+//    evalJQuery("$('input, select, textarea, button').val(['whatever', 'v1', 'v2'])");
+    $("input, select, textarea, button").val("whatever", "v1", "v2");
+    
+    String joinVals = "whatever,v1,v2";
+    assertEquals(joinVals, $("#inputText", e).val());
+    assertEquals(joinVals, $("#textArea", e).val());
+    assertEquals(joinVals, $("#button", e).val());
+    assertEquals("v2", $("#selectSingle", e).val());
+    assertEquals("v1", $("#selectMultiple", e).vals()[0]);
+    assertEquals("v2", $("#selectMultiple", e).vals()[1]);
+    assertEquals(2, $("input[type='checkbox']:checked", e).size());
+    assertEquals("v1", $("input[type='checkbox']:checked", e).eq(0).val());
+    assertEquals("v2", $("input[type='checkbox']:checked", e).eq(1).val());
+    assertEquals(1, $("input[type='radio']:checked", e).size());
+    assertEquals("v2", $("input[type='radio']:checked", e).val());
   }
   
+  
   public void testCheckedAttr_Issue97() {
     $(e).html("<input type='checkbox' id='cb' name='cb' value='1' />");
-    assertEquals("", $("#cb").val());
-    $("#cb").attr("checked", "checked");
-    assertEquals("1", $("#cb").val());
-    $("#cb").removeAttr("checked");
-    assertEquals("", $("#cb").val());
+    assertNull($("#cb:checked", e).val());
+    $("#cb", e).attr("checked", "checked");
+    assertEquals("1", $("#cb:checked", e).val());
+    $("#cb", e).removeAttr("checked");
+    assertNull($("#cb:checked", e).val());
   }
   
   public void testWidthHeight() {