001package gwt.material.design.client.base; 002 003/* 004 * #%L 005 * GwtMaterial 006 * %% 007 * Copyright (C) 2015 GwtMaterialDesign 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import com.google.gwt.cell.client.AbstractEditableCell; 024import com.google.gwt.cell.client.ValueUpdater; 025import com.google.gwt.dom.client.BrowserEvents; 026import com.google.gwt.dom.client.Document; 027import com.google.gwt.dom.client.Element; 028import com.google.gwt.dom.client.InputElement; 029import com.google.gwt.dom.client.NativeEvent; 030import com.google.gwt.event.dom.client.KeyCodes; 031import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 032import com.google.gwt.safehtml.shared.SafeHtmlUtils; 033 034public class MaterialCheckBoxCell extends AbstractEditableCell<Boolean, Boolean> { 035 036 private final boolean dependsOnSelection; 037 private final boolean handlesSelection; 038 039 public MaterialCheckBoxCell() { 040 this(false); 041 } 042 043 @Deprecated 044 public MaterialCheckBoxCell(boolean isSelectBox) { 045 this(isSelectBox, isSelectBox); 046 } 047 048 public MaterialCheckBoxCell(boolean dependsOnSelection, boolean handlesSelection) { 049 super(BrowserEvents.CHANGE, BrowserEvents.KEYDOWN, BrowserEvents.CLICK); 050 this.dependsOnSelection = dependsOnSelection; 051 this.handlesSelection = handlesSelection; 052 } 053 054 @Override 055 public boolean dependsOnSelection() { 056 return dependsOnSelection; 057 } 058 059 @Override 060 public boolean handlesSelection() { 061 return handlesSelection; 062 } 063 064 @Override 065 public boolean isEditing(Context context, Element parent, Boolean value) { 066 // A checkbox is never in "edit mode". There is no intermediate state 067 // between checked and unchecked. 068 return false; 069 } 070 071 @Override 072 public void onBrowserEvent(Context context, Element parent, Boolean value, NativeEvent event, ValueUpdater<Boolean> valueUpdater) { 073 String type = event.getType(); 074 075 boolean enterPressed = (BrowserEvents.KEYDOWN.equals(type) && event.getKeyCode() == KeyCodes.KEY_ENTER) 076 || event.getType().equals(BrowserEvents.CLICK); 077 078 if (BrowserEvents.CHANGE.equals(type) || enterPressed) { 079 InputElement input = parent.getFirstChild().getFirstChild().cast(); 080 Boolean isChecked = input.isChecked(); 081 082 /* 083 * Toggle the value if the enter key was pressed and the cell handles selection or doesn't depend on selection. If the cell depends on selection but doesn't handle selection, then ignore 084 * the enter key and let the SelectionEventManager determine which keys will trigger a change. 085 */ 086 if (enterPressed && (handlesSelection() || !dependsOnSelection())) { 087 isChecked = !isChecked; 088 input.setChecked(isChecked); 089 } 090 091 /* 092 * Save the new value. However, if the cell depends on the selection, then do not save the value because we can get into an inconsistent state. 093 */ 094 if (value != isChecked && !dependsOnSelection()) { 095 setViewData(context.getKey(), isChecked); 096 } else { 097 clearViewData(context.getKey()); 098 } 099 100 if (valueUpdater != null) { 101 valueUpdater.update(isChecked); 102 } 103 } 104 } 105 106 @Override 107 public void render(Context context, Boolean value, SafeHtmlBuilder sb) { 108 Object key = context.getKey(); 109 Boolean viewData = getViewData(key); 110 if (viewData != null && viewData.equals(value)) { 111 clearViewData(key); 112 viewData = null; 113 } 114 115 String state = ""; 116 if (value != null && ((viewData != null) ? viewData : value)) { 117 state = "checked"; 118 } 119 String id = Document.get().createUniqueId(); 120 121 sb.append(SafeHtmlUtils.fromSafeConstant( 122 "<span class=\"gwt-CheckBox\">" + 123 "<input type=\"checkbox\" class=\"filled-in\" tabindex=\"-1\" value=\"on\" id=\"" + id + "\" " + state + "/>" + 124 "<label for=\"" + id + "\"></label>" + 125 "</span>")); 126 127 } 128}