Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""Base class for data types.""" 

2 

3from config import Config as C, Names as N 

4from control.html import HtmlElements as H 

5 

6from control.utils import pick as G, E 

7 

8 

9CW = C.web 

10 

11QQ = H.icon(CW.unknown[N.generic]) 

12Qq = H.icon(CW.unknown[N.generic], asChar=True) 

13 

14WRONG_TYPE = CW.messages 

15 

16 

17class TypeBase: 

18 """The base class for functions on typed values. 

19 

20 This class is meant to be extended by classes dealing with specific types. 

21 It will be extended by Text and Numeric type classes, who in turn will be extended 

22 by concrete type classes. And there are the classes Value and Master which 

23 will be exteded by type classes for each value table and type classes for 

24 each master table respectively. 

25 

26 See the config file tables.yaml, under keys `scalarTypes` and `boolTypes`. 

27 

28 Attributes 

29 ---------- 

30 widgetType: string 

31 The type of widget that this type needs to edit its value. E.g. `text`. 

32 rawType: type 

33 The Python type that is used to represent values of this type. 

34 If it is None, the rawType is not relevant. 

35 pattern: string(re) 

36 For text widgets, this is a regular expression that constrains what is legal 

37 input in the text input field. 

38 needsContext: boolean 

39 Whether methods of this type need to be supplied with the Context singleton. 

40 

41 !!! note 

42 In order to compute the representation of a user, the Auth singleton inside the 

43 Context singleton is needed to detemine what parts of the user identifiaction 

44 the current user is allowed to see. 

45 """ 

46 

47 widgetType = None 

48 pattern = None 

49 rawType = None 

50 needsContext = False 

51 

52 @staticmethod 

53 def validationMsg(tp): 

54 """A validation error message for a specific type. 

55 

56 Parameters 

57 ---------- 

58 tp: string 

59 The name under which a type is registered. 

60 

61 Returns 

62 ------- 

63 string 

64 An error message. See web.yaml under key `wrongType`. 

65 """ 

66 

67 return G(WRONG_TYPE, tp) 

68 

69 def normalize(self, strVal): 

70 """Normalizes a string representation of a value. 

71 

72 Parameters 

73 ---------- 

74 strVal: string 

75 The string rep that must be normalized. 

76 

77 Returns 

78 ------- 

79 string 

80 A normalized equivalent representation of the same value. 

81 """ 

82 

83 return str(strVal).strip() 

84 

85 def fromStr(self, editVal): 

86 """Turns the output from an edit widget into a real value that can be saved. 

87 

88 Parameters 

89 ---------- 

90 editVal: string 

91 The output of an edit widget. 

92 

93 Returns 

94 ------- 

95 mixed 

96 A value of the type in question, corresponding to `editVal`. 

97 """ 

98 

99 if not editVal: 99 ↛ 100line 99 didn't jump to line 100, because the condition on line 99 was never true

100 return None 

101 val = self.normalize(editVal) 

102 cast = self.rawType 

103 return val if cast is None else cast(val) 

104 

105 def toDisplay(self, val, markup=True): 

106 """Turns a real value into a HTML code for readonly display. 

107 

108 Parameters 

109 ---------- 

110 val: mixed 

111 A value of this type. 

112 

113 Returns 

114 ------- 

115 string(html) 

116 Possibly with nice formatting depending on the nature of the value. 

117 """ 

118 

119 if val is None: 

120 return None if markup is None else QQ if markup else Qq 

121 valBare = val if markup is None else H.he(self.normalize(str(val))) 

122 return H.span(valBare) if markup else valBare 

123 

124 def toEdit(self, val): 

125 """Turns a real value into a string for editable display. 

126 

127 Parameters 

128 ---------- 

129 val: mixed 

130 A value of this type. 

131 

132 Returns 

133 ------- 

134 string 

135 """ 

136 

137 return E if val is None else self.normalize(str(val)) 

138 

139 def toOrig(self, val): 

140 """Turns a real value into an (original) value. 

141 

142 The resulting value can be used for comparison with newly entered values 

143 in an edit widget at the client side. 

144 

145 Parameters 

146 ---------- 

147 val: mixed 

148 A value of this type. 

149 

150 Returns 

151 ------- 

152 boolean | string | None 

153 """ 

154 

155 if val is None: 155 ↛ 156line 155 didn't jump to line 156, because the condition on line 155 was never true

156 return None 

157 return str(val) 

158 

159 def widget(self, val): 

160 """Constructs and edit widget around for this type. 

161 

162 Parameters 

163 ---------- 

164 val: string 

165 The initial value for the widget. 

166 

167 Returns 

168 ------- 

169 string(html) 

170 Dependent on a batch of Javascript in `index.js`, look for `const widgets`. 

171 """ 

172 

173 atts = {} 

174 if self.pattern: 

175 atts[N.pattern] = self.pattern 

176 validationMsg = TypeBase.validationMsg(self.name) 

177 

178 widgetElem = H.input(self.toEdit(val), type=N.text, cls="wvalue", **atts) 

179 validationElem = H.span(E, valmsg=validationMsg) if validationMsg else E 

180 return H.join([widgetElem, validationElem])