From: Ray Cromwell Date: Thu, 14 May 2009 01:06:43 +0000 (+0000) Subject: Plugins X-Git-Tag: release-1.3.2~778 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7557842d252c50ca4751ba545abb1e52e2a7a285;p=gwtquery.git Plugins --- diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java index 14741f79..5354dfed 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/GQuery.java @@ -67,7 +67,7 @@ public class GQuery implements Lazy { } } - static final class DataCache extends JavaScriptObject { + protected static final class DataCache extends JavaScriptObject { protected DataCache() { } @@ -84,6 +84,10 @@ public class GQuery implements Lazy { return !!this[id]; }-*/; + public native Object getObject(String id) /*-{ + return this[id]; + }-*/; + public native JavaScriptObject get(String id) /*-{ return this[id]; }-*/; @@ -878,10 +882,11 @@ public class GQuery implements Lazy { /** * Stores the value in the named spot with desired return type. */ - public void data(String name, String value) { + public Object data(String name, Object value) { for (Element e : elements()) { data(e, name, value); } + return this; } /** @@ -2470,6 +2475,7 @@ public class GQuery implements Lazy { dataCache = JavaScriptObject.createObject().cast(); } item = item == window() ? windowData : item; + if(item == null) return value; int id = item.hashCode(); if (name != null && !dataCache.exists(id)) { dataCache.put(id, DataCache.createObject().cast()); @@ -2479,7 +2485,7 @@ public class GQuery implements Lazy { if (name != null && value != null) { d.put(name, value); } - return name != null ? d.get(name) : id; + return name != null ? d.getObject(name) : id; } private void dequeue(Element elem, String type) { diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java index ae0bbccd..e8ad798a 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Ratings.java @@ -1,18 +1,22 @@ package com.google.gwt.query.client.plugins; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.NodeList; +import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; -import com.google.gwt.query.client.Plugin; import com.google.gwt.query.client.JSArray; +import com.google.gwt.query.client.Plugin; import com.google.gwt.query.client.SelectorEngine; -import com.google.gwt.dom.client.Element; -import com.google.gwt.dom.client.NodeList; -import com.google.gwt.dom.client.InputElement; +import com.google.gwt.user.client.Event; /** * Star Rating plugin. */ public class Ratings extends GQuery { + private static int calls; + /** * Used to register the plugin. */ @@ -45,8 +49,9 @@ public class Ratings extends GQuery { if (size() == 0) { return this; } + calls++; not(".star-rating-applied").addClass("star-rating-applied"); - Control control; + Control control = null; for (Element e : elements()) { GQuery input = $(e); String eid = SelectorEngine @@ -54,17 +59,438 @@ public class Ratings extends GQuery { .replaceAll("\\[|\\]", "_").replaceAll("^\\_+|\\_$", ""); GQuery context = $(getContext(e)); Raters raters = (Raters) context.data("rating"); + if (raters == null || raters.getCalls() != calls) { + raters = new Raters(0, calls); + } + GQuery rater = raters.get(eid); + if (rater != null) { + control = (Control) rater.data("rating"); + } + if (rater != null && control != null) { + control.bumpCount(); + } else { + control = new Control(); + control.setSerial(raters.bumpCount()); + // create rating element + rater = $(""); + input.before(rater); + + // Mark element for initialization (once all stars are ready) + rater.addClass("rating-to-be-drawn"); + + // Accept readOnly setting from 'disabled' property + if (input.attr("disabled") != null) { + control.setReadOnly(true); + } + + // Create 'cancel' button + GQuery query = $( + ""). + mouseover(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).drain(); + $(e).addClass("star-rating-hover"); + return true; + } + }). + mouseout(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).draw(); + $(e).removeClass("star-rating-hover"); + return true; + } + }). + click(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).selectStar(); + return true; + } + }); + control.cancelButton = query; + query.data("rating", control); + rater.append(query); + } + // insert rating star + GQuery star = $(""); + rater.append(star); + + // inherit attributes from input element + if (e.getId() != null) { + star.attr("id", e.getId()); + } + if (e.getClassName() != null) { + star.addClass(e.getClassName()); + } + + // Half-stars? + if (control.isHalf()) { + control.setSplit(2); + } + + // Prepare division control + if (control.getSplit() > 0) { + int stw = star.width(); + if (stw == 0) { + stw = control.getStarWidth(); + } + + int spi = (control.getCount() % control.getSplit()); + int spw = (int) Math.floor(stw / control.getSplit()); + + star.width(spw).find("a").css("margin-left", "-" + (spi * spw) + "px"); + } + ; + + // readOnly? + if (control.isReadOnly())//{ //save a byte! + // Mark star as readOnly so user can customize display + { + star.addClass("star-rating-readonly"); + } + //} //save a byte! + else//{ //save a byte! + // Enable hover css effects + { + star.addClass("star-rating-live") + // Attach mouse events + .mouseover(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).fill(); + $(e).as(Ratings).focusStar(); + return true; + } + }).mouseout(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).draw(); + $(e).as(Ratings).blurStar(); + + return true; + } + }).click(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).selectStar(); + return true; + } + }); + } + // set current selection + if (e.getPropertyBoolean("checked")) { + control.setCurrent(star); + } + + // hide input element + input.hide(); + + // backward compatibility, form element to plugin + input.change(new Function() { + @Override + public boolean f(Event e) { + $(e).as(Ratings).selectStar(); + return true; + } + }); + + // attach reference to star to input element and vice-versa + star.data("rating.input", input.data("rating.star", star)); + + // store control information in form (or body when form not available) + control.addStar(star.get(0)); + control.addInput(input.get(0)); + control.setRater(rater); + raters.put(eid, rater); + control.setContext(context); + + input.data("rating", control); + rater.data("rating", control); + star.data("rating", control); + context.data("rating", raters); + + // Initialize ratings (first draw) + $(".rating-to-be-drawn").as(Ratings).draw() + .removeClass("rating-to-be-drawn"); + } + + return this; + } + + public Ratings blurStar() { + return this; + } + + public Ratings focusStar() { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } +// GQuery input = data("rating.input"); + return this; + } + + public Ratings fill() { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } + // do not execute when control is in read-only mode + if (control.isReadOnly()) { + return this; + } + // Reset all stars and highlight them up to this element + drain(); + this.prevAll().andSelf().filter(".rater-" + control.getSerial()) + .addClass("star-rating-hover"); + return this; + } + + public Ratings draw() { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } + // do not execute when control is in read-only mode + if (control.isReadOnly()) { + return this; + } + // Clear all stars + this.drain(); + // Set control value + if (control.getCurrent() != null) { + ((GQuery) control.current.data("rating.input")) + .attr("checked", "checked"); + control.current.prevAll().andSelf().filter(".rater-" + control.serial) + .addClass("star-rating-on"); + } else { + $(control.getInputs()).removeAttr("checked"); + } + + // Show/hide 'cancel' button +// control.cancel[control.readOnly || control.required?'hide':'show'](); + // Add/remove read-only classes to remove hand pointer + this.siblings().toggleClass("star-rating-readonly", control.isReadOnly()); + return this; + } + + public Ratings selectStar(int value) { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } + // do not execute when control is in read-only mode + if (control.isReadOnly()) { + return this; + } + control.setCurrent(null); + return $(control.getStar(value)).as(Ratings).selectStar(); + } + + public Ratings selectStar() { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } + // do not execute when control is in read-only mode + if (control.isReadOnly()) { + return this; + } + + control.current = get(0).getTagName().equalsIgnoreCase("INPUT") + ? (GQuery) data("rating.star") + : is(".rater-" + control.getSerial()) ? this : null; + + // Update rating control state + data("rating", control); + // Update display + this.draw(); + // find data for event + GQuery input = $( + control.current != null ? (GQuery) control.current.data("rating.input") + : null); + // click callback, as requested here: http://plugins.jquery.com/node/1655 +// if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event + return this; + } + + public Ratings selectStar(String value) { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } + // do not execute when control is in read-only mode + if (control.isReadOnly()) { + return this; + } + control.setCurrent(null); + + NodeList stars = control.getStars(); + + for (int i = 0; i < stars.getLength(); i++) { + String val = ((GQuery) $(stars.getItem(i)).data("rating.input")).val(); + if (val != null && val.equals(value)) { + $(stars.getItem(i)).as(Ratings).selectStar(); + } } + return this; + } + public Ratings drain() { + Control control = (Control) this.data("rating"); + if (control == null) { + return this; + } + // do not execute when control is in read-only mode + if (control.isReadOnly()) { + return this; + } + control.rater.children().filter(".rater-" + control.getSerial()) + .removeClass("star-rating-on").removeClass("star-rating-hover"); return this; } public static class Control { + private int count; + + private String cancel = "Cancel Rating"; + + private String cancelValue = ""; + + private int split = 0; + + private int starWidth = 16; + + private int serial; + + private boolean readOnly; + + private boolean half; + + private GQuery current; + + private GQuery context; + + private JsArray stars = JsArray.createArray().cast(); + + private JsArray inputs = JsArray.createArray().cast(); + + private GQuery rater; + + public GQuery cancelButton; + + public int bumpCount() { + return count++; + } + + public void setSerial(int serial) { + this.serial = serial; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + + public int getSerial() { + return serial; + } + + public boolean isHalf() { + return half; + } + + public void setSplit(int split) { + this.split = split; + } + + public int getSplit() { + return split; + } + + public int getStarWidth() { + return starWidth; + } + + public int getCount() { + return count; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setCurrent(GQuery current) { + this.current = current; + } + + public void setContext(GQuery context) { + this.context = context; + } + + public void addStar(Element element) { + stars.set(stars.length(), element); + } + + public void addInput(Element element) { + inputs.set(inputs.length(), element); + } + + public void setRater(GQuery rater) { + this.rater = rater; + } + + public Object getCurrent() { + return current; + } + + public NodeList getInputs() { + return inputs.cast(); + } + + public Element getStar(int value) { + return stars.get(value); + } + + public NodeList getStars() { + return stars.cast(); + } } public static class Raters { + private int calls; + + private int count; + + private GQuery.DataCache cache = GQuery.DataCache.createObject().cast(); + + public Raters(int count, int calls) { + this.count = count; + this.calls = calls; + } + + public int getCalls() { + return calls; + } + + public GQuery get(String eid) { + return (GQuery) cache.getObject(eid); + } + + public void put(String eid, GQuery q) { + cache.put(eid, q); + } + + public int bumpCount() { + return count++; + } } private static native Element getContext(Element e) /*-{ diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/public/gquery-star-ratings.css b/gwtquery-core/src/main/java/com/google/gwt/query/public/gquery-star-ratings.css new file mode 100644 index 00000000..deb7d060 --- /dev/null +++ b/gwtquery-core/src/main/java/com/google/gwt/query/public/gquery-star-ratings.css @@ -0,0 +1,12 @@ +/* jQuery.Rating Plugin CSS - http://www.fyneworks.com/jquery/star-rating/ */ +div.rating-cancel,div.star-rating{float:left;width:17px;height:15px;text-indent:-999em;cursor:pointer;display:block;background:transparent;overflow:hidden} +div.rating-cancel,div.rating-cancel a{background:url(delete.gif) no-repeat 0 -16px} +div.star-rating,div.star-rating a{background:url(star.gif) no-repeat 0 0px} +div.rating-cancel a,div.star-rating a{display:block;width:16px;height:100%;background-position:0 0px;border:0} +div.star-rating-on a{background-position:0 -16px!important} +div.star-rating-hover a{background-position:0 -32px} +/* Read Only CSS */ +div.star-rating-readonly a{cursor:default !important} +/* Partial Star CSS */ +div.star-rating{background:transparent!important;overflow:hidden!important} +/* END jQuery.Rating Plugin CSS */ diff --git a/samples/src/main/java/gwtquery/samples/client/GwtQuerySampleModule.java b/samples/src/main/java/gwtquery/samples/client/GwtQuerySampleModule.java index 0562206d..9ab09fcf 100644 --- a/samples/src/main/java/gwtquery/samples/client/GwtQuerySampleModule.java +++ b/samples/src/main/java/gwtquery/samples/client/GwtQuerySampleModule.java @@ -4,6 +4,7 @@ import com.google.gwt.core.client.EntryPoint; import com.google.gwt.query.client.Effects; import com.google.gwt.query.client.Function; import com.google.gwt.query.client.GQuery; +import com.google.gwt.query.client.plugins.Ratings; import static com.google.gwt.query.client.GQuery.$; import static com.google.gwt.query.client.GQuery.$$; import static com.google.gwt.query.client.GQuery.lazy; @@ -43,6 +44,6 @@ public class GwtQuerySampleModule implements EntryPoint { $(".note").click(lazy().fadeOut().done()); $(".note").append(" Hello"); - + $("input").as(Ratings.Ratings).rating(); } } diff --git a/samples/src/main/java/gwtquery/samples/public/GwtQuerySample.html b/samples/src/main/java/gwtquery/samples/public/GwtQuerySample.html index b15701a7..db6fbc95 100644 --- a/samples/src/main/java/gwtquery/samples/public/GwtQuerySample.html +++ b/samples/src/main/java/gwtquery/samples/public/GwtQuerySample.html @@ -2,6 +2,8 @@ GQuery Demo + +
@@ -15,6 +17,724 @@
Foo bar baz
+
+

What is this?

+

+ The Star Rating Plugin is a plugin + for the jQuery Javascript library that creates a non-obstrusive + star rating control based on a set of radio input boxes. +

+ +

What does it do?

+
    +
  • + It turns a collection of radio boxes into a neat star-rating control. +
  • +
  • + It creates the interface based on standard form elements, which means the + basic functionality will still be available even if Javascript is disabled. +
  • +
  • + NEW (12-Mar-08): + In read only mode (using the 'readOnly' option or disabled property), the plugin is a neat way of + displaying star-like values without any additional code +
  • +
+ +

How do I use it?

+

+ Just add the star class to your radio boxes +

+ + + + + + +
+
<input name="star1" type="radio" class="star"/>
+  <input name="star1" type="radio" class="star"/>
+  <input name="star1" type="radio" class="star"/>
+  <input name="star1" type="radio" class="star"/>
+  <input name="star1" type="radio" class="star"/>
+
» + + + + + +
+ +

+ Use the checked property to specify the initial/default value of the control +

+ + + + + + +
+
<input name="star2" type="radio" class="star"/>
+  <input name="star2" type="radio" class="star"/>
+  <input name="star2" type="radio" class="star" checked="checked"/>
+  <input name="star2" type="radio" class="star"/>
+  <input name="star2" type="radio" class="star"/>
+
» + + + + + +
+ +

+ Use the disabled property to use a control for display purposes only +

+ + + + + + +
+
<input name="star3" type="radio" class="star" disabled="disabled"/>
+  <input name="star3" type="radio" class="star" disabled="disabled"/>
+  <input name="star3" type="radio" class="star" disabled="disabled" checked="checked"/>
+  <input name="star3" type="radio" class="star" disabled="disabled"/>
+  <input name="star3" type="radio" class="star" disabled="disabled"/>
+
» + + + + + +
+ +

What about split stars and 'half ratings'???

+

+ Use metadata plugin to pass advanced settings to the plugin via the class property. +

+ + + + + + +
+
<input name="adv1" type="radio" class="star {split:4}"/>
+  <input name="adv1" type="radio" class="star {split:4}"/>
+  <input name="adv1" type="radio" class="star {split:4}"/>
+  <input name="adv1" type="radio" class="star {split:4}"/>
+  <input name="adv1" type="radio" class="star {split:4}" checked="checked"/>
+  <input name="adv1" type="radio" class="star {split:4}"/>
+  <input name="adv1" type="radio" class="star {split:4}"/>
+  <input name="adv1" type="radio" class="star {split:4}"/>
+
» + + + + + + + + +
+ +

+ Use custom selector +

+ + + + + + +
+ +
$(function(){ // wait for document to load
+   $('input.wow').rating();
+  });
+
<input name="adv2" type="radio" class="wow {split:4}"/>
+  <input name="adv2" type="radio" class="wow {split:4}"/>
+  <input name="adv2" type="radio" class="wow {split:4}"/>
+  <input name="adv2" type="radio" class="wow {split:4}"/>
+  <input name="adv2" type="radio" class="wow {split:4}" checked="checked"/>
+  <input name="adv2" type="radio" class="wow {split:4}"/>
+  <input name="adv2" type="radio" class="wow {split:4}"/>
+  <input name="adv2" type="radio" class="wow {split:4}"/>
+
» + + + + + + + + +
+
+ +
+

Test Suite

+ + + +
 
+
+ Test 1 - A blank form + + + + + +
+ + + + + +
+
+ Rating 1: + (N/M/Y) + + + +
+
+
+ Rating 2: + (10 - 50) + + + + + +
+
+
+ Rating 3: + (1 - 7) + + + + + + + +
+
+
+ Rating 4: + (1 - 5) + + + + + +
+
+
+ Rating 5: + (1 - 5) + + + + + +
+
+
+ Rating 6 (readonly): + (1 - 5) + + + + + +
+
+
  +   + Test results:

+
+ Results will be displayed here +
+
+
+ +
 
 
+ +
+ Test 2 - With defaults ('checked') + + + + + +
+ + + + + +
+
+ Rating 1: + (N/M/Y, default M) +
+
+ + + +
+
+ Rating 2: + (10 - 50, default 30) +
+
+ + + + + +
+
+ Rating 3: + (1 - 7, default 4) +
+
+ + + + + + + +
+
+
+ Rating 4: + (1 - 5, default 1) +
+
+ + + + + +
+
+ Rating 5: + (1 - 5, default 5) +
+
+ + + + + +
+
+ Rating 6 (readonly): + (1 - 5, default 3) +
+
+ + + + + +
+
+
  +   + Test results:

+
+ Results will be displayed here +
+
+
+ +
 
 
+ +
+ + Test 3-A - With callback + + + + + +
+
+ Rating 1: + (1 - 3, default 2) + + + +
+
+
$('.auto-submit-star').rating({
+callback: function(value, link){
+  alert(value);
+}
+  });
+
+
  +   + Test results:

+
+ Results will be displayed here +
+
+
+ +
 
 
+ + +
+ Test 3-B - With hover effects + + + + + +
+
+ Rating 1: + (1 - 3, default 2) +
+ + + + + + Hover tips will appear in here +
+
+
+
$('.hover-star').rating({
+focus: function(value, link){
+  var tip = $('#hover-test');
+  tip[0].data = tip[0].data || tip.html();
+  tip.html(link.title || 'value: '+value);
+},
+blur: function(value, link){
+  var tip = $('#hover-test');
+  $('#hover-test').html(tip[0].data || '');
+}
+  });
+
+
  +   + Test results:

+
+ Results will be displayed here +
+
+
+ +
 
 
+ +
+ Test 4 - Half Stars and Split Stars + + + + + +
+ + + + + +
+
+ Rating 1: + (N/M/Y/?) +
<input class="star {half:true}"
+ + + + +
+
+
+ Rating 2: + (10 - 60) +
<input class="star {split:3}"
+ + + + + + +
+
+
+ Rating 3: + (0-5.0, default 3.5) +
<input class="star {split:2}"
+ + + + + + + + + + +
+
+
+ Rating 4: + (1-6, default 5) +
<input class="star {split:2}"
+ + + + + + +
+
+
+ Rating 5: + (1-20, default 11) +
<input class="star {split:4}"
+ + + + + + + + + + + + + + + + + + + + +
+
+
+ Rating 6 (readonly): + (1-20, default 13) +
<input class="star {split:4}"
+ + + + + + + + + + + + + + + + + + + + +
+
+
  +   + Test results:

+
+ Results will be displayed here +
+
+
+
+ +
+

API

+

NEW to v3

+ +

API methods can be invoked this this:

+
$(selector).rating(
+   'method', // method name
+   [] // method arguments (not required)
+  );
+ +


+ +

$().rating('select', index / value)

+

+ Use this method to set the value (and display) of the star rating control + via javascript. It accepts the index of the star you want to select (0 based) + or its value (which must be passed as a string. +

+

+ Example: (values A/B/C/D/E) +

+
+ + + + + + + +
+ By index: + + + + + + eg.: $('input').rating('select',3) +
+ By value: + + + + + + eg.: $('input').rating('select','C') +
+ +


+ +

$().rating('readOnly', true / false)

+

+ Use this method to set the value (and display) of the star rating control + via javascript. It accepts the index of the star you want to select (0 based) + or its value (which must be passed as a string. +

+

+ Example: (values 1,2,3...10) +

+
+ + + + + + + + + + + + +
+ + eg.: $('input').rating('readOnly',true) +
+ + eg.: $('input').rating('readOnly',false) or simply $('input').rating('readOnly'); +
+ +


+ +

$().rating('disable') / $().rating('enable')

+

+ These methods bahve almost exactly as the readOnly method, however + they also control whether or not the select value is submitted with + the form. +

+

+ Example: (values 1,2,3...10) +

+
+ + + + + + + + + + + + +
+ + eg.: $('input').rating('disable') +
+ + eg.: $('input').rating('enable'); +
+
+ \ No newline at end of file