QAFormViewer.cs 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using System.Threading;
  5. using System.Linq;
  6. using Xamarin.Forms;
  7. using XF.Material.Forms.UI.Dialogs;
  8. using InABox.Core;
  9. using InABox.Clients;
  10. using System.IO;
  11. using InABox.Mobile;
  12. using Syncfusion.XForms.SignaturePad;
  13. using comal.timesheets.Tasks;
  14. using Comal.Classes;
  15. using PRSClasses;
  16. namespace comal.timesheets.QAForms
  17. {
  18. public class QAFormViewer : Grid, IDFRenderer
  19. {
  20. #region Fields
  21. public Dictionary<DFLayoutField, View> pairs = new Dictionary<DFLayoutField, View>();
  22. public Dictionary<String, String> results = new Dictionary<String, String>();
  23. public Dictionary<String, String> propertyResults = new Dictionary<String, String>();
  24. Dictionary<String, String> loadData = new Dictionary<String, String>();
  25. public Dictionary<DFLayoutLookupField, Dictionary<Guid, string>> dfLayoutLookupFieldLookupOptions = new Dictionary<DFLayoutLookupField, Dictionary<Guid, string>>();
  26. DFLayout dfLayout = null;
  27. public IDigitalFormDataModel model = null;
  28. const string nullOrInvalidType = "Null or Invalid Type";
  29. int rbGroup;
  30. private Guid userID;
  31. bool isRequired = false;
  32. bool readOnly = false;
  33. bool isSecure = false;
  34. bool loadRetainedForm = false;
  35. List<string> useSavedSignatures = new List<string>();
  36. public List<string> errors = new List<string>();
  37. public bool isRequiredEmpty { get; set; }
  38. public string isRequiredMessage { get; set; }
  39. InABox.Core.Location location = new InABox.Core.Location();
  40. Guid digitalFormID = Guid.Empty;
  41. Color isRequiredColor = Color.DarkOrange;
  42. public string FormData = "";
  43. public DateTime FormCompleted = DateTime.MinValue;
  44. public Guid JobID = Guid.Empty;
  45. DateTime timeStarted = DateTime.MinValue;
  46. List<DigitalFormsHeader> headersToCollapse = new List<DigitalFormsHeader>();
  47. int collapsedHeaderCount = 1;
  48. #endregion
  49. #region Constructor
  50. public QAFormViewer(IDigitalFormDataModel _model, DFLayout _dfLayout, bool newForm, bool _readOnly, Guid _jobid = default(Guid))
  51. {
  52. GetLocation();
  53. timeStarted = DateTime.Now;
  54. userID = ClientFactory.UserGuid;
  55. model = _model;
  56. dfLayout = _dfLayout;
  57. dfLayout.Renderer = this;
  58. readOnly = _readOnly;
  59. isRequiredEmpty = false;
  60. loadRetainedForm = false;
  61. isRequiredMessage = "";
  62. JobID = _jobid;
  63. if (RetainedResults.IsFormRetained)
  64. {
  65. loadRetainedForm = true;
  66. }
  67. if (newForm)
  68. {
  69. LoadForm();
  70. }
  71. else if (!newForm)
  72. {
  73. loadData.Clear();
  74. Dictionary<String, Object> data = Serialization.Deserialize<Dictionary<String, Object>>(model.Instance.FormData);
  75. if (data != null)
  76. {
  77. foreach (KeyValuePair<string, object> keyValuePair in data)
  78. {
  79. loadData.Add(keyValuePair.Key, keyValuePair.Value.ToString());
  80. }
  81. }
  82. LoadForm();
  83. }
  84. }
  85. #endregion
  86. #region Location
  87. private async void GetLocation()
  88. {
  89. await Task.Run(() =>
  90. {
  91. LocationServices locationServices = new LocationServices();
  92. locationServices.OnLocationFound += LocationFound;
  93. locationServices.OnLocationError += LocationError;
  94. locationServices.GetLocation();
  95. });
  96. }
  97. private async void LocationFound(LocationServices sender)
  98. {
  99. location.Latitude = sender.Latitude;
  100. location.Longitude = sender.Longitude;
  101. }
  102. private async void LocationError(LocationServices sender, Exception error)
  103. {
  104. errors.Add("Location error: " + error.Message);
  105. }
  106. #endregion Location
  107. #region Load Form Layout
  108. private async void LoadForm()
  109. {
  110. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading Form"))
  111. {
  112. LoadRowsAndColumns();
  113. LoadElements();
  114. }
  115. }
  116. private async void LoadRowsAndColumns()
  117. {
  118. LoadRows();
  119. LoadColumns();
  120. }
  121. private void LoadRows()
  122. {
  123. foreach (var row in dfLayout.RowHeights)
  124. {
  125. RowDefinition def = new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) };
  126. if (int.TryParse(row, out int rowHeight))
  127. {
  128. def = new RowDefinition { Height = new GridLength(rowHeight, GridUnitType.Absolute) };
  129. if (def.Height.Value < 60)
  130. {
  131. def.SetValue(RowDefinition.HeightProperty, 60);
  132. }
  133. }
  134. else if (row == "*")
  135. {
  136. def = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) };
  137. }
  138. Device.BeginInvokeOnMainThread(() => { RowDefinitions.Add(def); });
  139. }
  140. }
  141. private void LoadColumns()
  142. {
  143. foreach (var col in dfLayout.ColumnWidths)
  144. {
  145. ColumnDefinition def = new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) };
  146. if (int.TryParse(col, out int colWidth))
  147. def = new ColumnDefinition { Width = new GridLength(colWidth, GridUnitType.Absolute) };
  148. else if (col == "*")
  149. {
  150. def = new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) };
  151. }
  152. Device.BeginInvokeOnMainThread(() => { ColumnDefinitions.Add(def); });
  153. }
  154. }
  155. private async void LoadElements()
  156. {
  157. rbGroup = 0; //used for customboolean - has to be outside of foreach loop
  158. foreach (DFLayoutControl element in dfLayout.Elements)
  159. {
  160. if (!string.IsNullOrEmpty(element.Description))
  161. {
  162. LoadViewAccordingToElement(element);
  163. }
  164. }
  165. Task.Run(() =>
  166. {
  167. Thread.Sleep(1000);
  168. foreach (var header in headersToCollapse)
  169. {
  170. Device.BeginInvokeOnMainThread(() =>
  171. {
  172. AdjustHeaderSection(header, false);
  173. header.Collapse();
  174. });
  175. }
  176. });
  177. }
  178. #endregion
  179. #region Load Element Methods
  180. private void LoadViewAccordingToElement(DFLayoutControl element)
  181. {
  182. View view = null;
  183. isSecure = false;
  184. string value = "";
  185. if (element is DFLayoutBooleanField)
  186. {
  187. var tuple = LoadCustomBoolean(view, element, value);
  188. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  189. }
  190. else if (element is DFLayoutLabel)
  191. {
  192. var tuple = LoadLabel(view, element);
  193. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  194. }
  195. else if (element is DFLayoutStringField || element is DFLayoutIntegerField || element is DFLayoutDoubleField)
  196. {
  197. var tuple = LoadEditor(view, element, value);
  198. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  199. }
  200. else if (element is DFLayoutDateField)
  201. {
  202. var tuple = LoadDatePicker(view, element, value);
  203. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  204. }
  205. else if (element is DFLayoutTimeField)
  206. {
  207. var tuple = LoadTimePicker(view, element, value);
  208. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  209. }
  210. else if (element is DFLayoutOptionField)
  211. {
  212. var tuple = LoadOptionPicker(view, element, value);
  213. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  214. }
  215. else if (element is DFLayoutImage)
  216. {
  217. var tuple = LoadImage(view, element);
  218. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  219. }
  220. else if (element is DFLayoutLookupField)
  221. {
  222. var tuple = LoadLookupPicker(view, element, value);
  223. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  224. }
  225. else if (element is DFLayoutSignaturePad)
  226. {
  227. var tuple = LoadSignaturePad(view, element, value);
  228. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  229. }
  230. else if (element is DFLayoutEmbeddedImage)
  231. {
  232. var tuple = LoadEmbeddedImage(view, element, value);
  233. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  234. }
  235. else if (element is DFLayoutMultiImage)
  236. {
  237. var tuple = LoadMultiImage(view, element, value);
  238. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  239. }
  240. else if (element is DFLayoutMultiSignaturePad)
  241. {
  242. var tuple = LoadMultiSignaturePad(view, element, value);
  243. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  244. }
  245. else if (element is DFLayoutAddTaskField)
  246. {
  247. var tuple = LoadAddTaskField(view, element, value);
  248. FormatAndAddView(tuple.Item1, element, tuple.Item2);
  249. }
  250. else if (element is DFLayoutHeader)
  251. {
  252. FormatAndAddView(LoadHeader(view, element), element, false);
  253. }
  254. }
  255. private View LoadHeader(View view, DFLayoutControl element)
  256. {
  257. DFLayoutHeader dFLayoutHeader = (DFLayoutHeader)element;
  258. DigitalFormsHeader header = new DigitalFormsHeader(dFLayoutHeader.Collapsed);
  259. if (dFLayoutHeader.Collapsed)
  260. header = AddNumberToHeader(header);
  261. header.SetHeaderValue(dFLayoutHeader.Header);
  262. header.OnTapped += (bCollapsed) =>
  263. {
  264. AdjustHeaderSection(header, bCollapsed);
  265. };
  266. view = header;
  267. return view;
  268. }
  269. private DigitalFormsHeader AddNumberToHeader(DigitalFormsHeader header)
  270. {
  271. header.Number = collapsedHeaderCount;
  272. collapsedHeaderCount++;
  273. return header;
  274. }
  275. private void AdjustHeaderSection(DigitalFormsHeader header, bool collapsed)
  276. {
  277. var thisHeaderRow = GetRow(header);
  278. var headerRows = GetOtherHeaders(thisHeaderRow);
  279. if (headerRows.Any())
  280. AdjustHeightsToNextHeader(headerRows, thisHeaderRow, collapsed);
  281. else
  282. AdjustHeightsBelowHeader(headerRows, thisHeaderRow, collapsed);
  283. }
  284. private List<int> GetOtherHeaders(int thisHeaderRow)
  285. {
  286. List<int> headerRows = new List<int>();
  287. foreach (var child in Children)
  288. {
  289. if (child is DigitalFormsHeader)
  290. {
  291. var dfheader = (DigitalFormsHeader)child;
  292. if (GetRow(dfheader) > thisHeaderRow)
  293. {
  294. headerRows.Add(GetRow(dfheader));
  295. }
  296. }
  297. }
  298. return headerRows;
  299. }
  300. private void AdjustHeightsToNextHeader(List<int> headerRows, int thisHeaderRow, bool collapsed)
  301. {
  302. headerRows.Sort();
  303. int nextHeaderRow = headerRows[0];
  304. for (int i = thisHeaderRow + 1; i < nextHeaderRow; i++)
  305. {
  306. AdjustHeight(i, collapsed);
  307. }
  308. }
  309. private void AdjustHeightsBelowHeader(List<int> headerRows, int thisHeaderRow, bool collapsed)
  310. {
  311. for (int i = thisHeaderRow + 1; i < RowDefinitions.Count; i++)
  312. {
  313. AdjustHeight(i, collapsed);
  314. }
  315. }
  316. private async void AdjustHeight(int i, bool collapsed)
  317. {
  318. var rowdef = RowDefinitions[i];
  319. if (collapsed)
  320. {
  321. rowdef.Height = 60;
  322. AnimateChildren(i, 0, 250);
  323. }
  324. else
  325. {
  326. AnimateChildren(i, -60, 500);
  327. rowdef.Height = 0;
  328. }
  329. }
  330. private async void AnimateChildren(int i, int movement, int length)
  331. {
  332. foreach (var child in Children)
  333. {
  334. if (GetRow(child) == i)
  335. {
  336. await child.TranslateTo(0, movement, 250);
  337. }
  338. }
  339. }
  340. private Tuple<View, Boolean> LoadCustomBoolean(View view, DFLayoutControl element, String value)
  341. {
  342. rbGroup++;
  343. CustomBoolean item = new CustomBoolean(rbGroup);
  344. DFLayoutBooleanField dfLayoutBooleanField = element as DFLayoutBooleanField;
  345. if (!string.IsNullOrWhiteSpace(dfLayoutBooleanField.Properties.TrueValue))
  346. item.trueBtn.Content = dfLayoutBooleanField.Properties.TrueValue;
  347. if (!string.IsNullOrWhiteSpace(dfLayoutBooleanField.Properties.FalseValue))
  348. item.falseBtn.Content = dfLayoutBooleanField.Properties.FalseValue;
  349. if (loadData.TryGetValue(dfLayoutBooleanField.Name, out value))
  350. {
  351. item.Value = bool.Parse(value);
  352. }
  353. if (loadRetainedForm)
  354. {
  355. if (RetainedResults.Results.TryGetValue(dfLayoutBooleanField.Name, out value))
  356. {
  357. item.Value = bool.Parse(value);
  358. }
  359. }
  360. if (dfLayoutBooleanField.Properties.Required)
  361. {
  362. item.trueBtn.BackgroundColor = isRequiredColor;
  363. item.falseBtn.BackgroundColor = isRequiredColor;
  364. }
  365. item.OnCustomBooleanValueChanged += (boolvalue) =>
  366. {
  367. dfLayout.ChangeField(dfLayoutBooleanField.Name);
  368. };
  369. view = item;
  370. return new Tuple<View, Boolean>(view, dfLayoutBooleanField.Properties.Required);
  371. }
  372. private Tuple<View, Boolean> LoadLabel(View view, DFLayoutControl element)
  373. {
  374. DFLayoutLabel label = element as DFLayoutLabel;
  375. Label item = new Label();
  376. item.Text = label.Caption;
  377. item.FontSize = Device.GetNamedSize(NamedSize.Medium, item);
  378. item.TextColor = Color.Black;
  379. item.LineBreakMode = LineBreakMode.WordWrap;
  380. item.VerticalOptions = LayoutOptions.FillAndExpand;
  381. item.VerticalTextAlignment = TextAlignment.Center;
  382. item.MinimumHeightRequest = 60;
  383. if (ColumnDefinitions.Count == 1)
  384. {
  385. item.HorizontalOptions = LayoutOptions.CenterAndExpand;
  386. item.HorizontalTextAlignment = TextAlignment.Center;
  387. }
  388. view = item;
  389. return new Tuple<View, Boolean>(view, false);
  390. }
  391. private Tuple<View, Boolean> LoadEditor(View view, DFLayoutControl element, string value)
  392. {
  393. Editor item = new Editor();
  394. var isrequired = false;
  395. var issecure = false;
  396. if (element is DFLayoutStringField)
  397. {
  398. DFLayoutStringField dfLayoutStringField = element as DFLayoutStringField;
  399. item.TextColor = Color.Black;
  400. item.Placeholder = "Enter answer";
  401. isrequired = dfLayoutStringField.Properties.Required;
  402. issecure = dfLayoutStringField.Properties.Secure;
  403. if (loadData.TryGetValue(dfLayoutStringField.Name, out value))
  404. {
  405. item.Text = value;
  406. }
  407. if (loadRetainedForm)
  408. {
  409. if (RetainedResults.Results.TryGetValue(dfLayoutStringField.Name, out value))
  410. {
  411. item.Text = value;
  412. }
  413. }
  414. item.TextChanged += (object sender, TextChangedEventArgs e) =>
  415. {
  416. dfLayout.ChangeField(dfLayoutStringField.Name);
  417. };
  418. view = item;
  419. }
  420. else if (element is DFLayoutIntegerField)
  421. {
  422. DFLayoutIntegerField dfLayoutIntegerField = element as DFLayoutIntegerField;
  423. item.TextColor = Color.Black;
  424. item.Placeholder = "Enter number";
  425. item.Keyboard = Keyboard.Numeric;
  426. isrequired = dfLayoutIntegerField.Properties.Required;
  427. issecure = dfLayoutIntegerField.Properties.Secure;
  428. if (loadData.TryGetValue(dfLayoutIntegerField.Name, out value))
  429. {
  430. item.Text = value;
  431. }
  432. if (loadRetainedForm)
  433. {
  434. if (RetainedResults.Results.TryGetValue(dfLayoutIntegerField.Name, out value))
  435. {
  436. item.Text = value;
  437. }
  438. }
  439. item.TextChanged += (object sender, TextChangedEventArgs e) =>
  440. {
  441. dfLayout.ChangeField(dfLayoutIntegerField.Name);
  442. };
  443. view = item;
  444. }
  445. else if (element is DFLayoutDoubleField)
  446. {
  447. DFLayoutDoubleField dfLayoutDoubleField = element as DFLayoutDoubleField;
  448. item.TextColor = Color.Black;
  449. item.Placeholder = "Enter number";
  450. item.Keyboard = Keyboard.Numeric;
  451. isrequired = dfLayoutDoubleField.Properties.Required;
  452. issecure = dfLayoutDoubleField.Properties.Secure;
  453. if (loadData.TryGetValue(dfLayoutDoubleField.Name, out value))
  454. {
  455. item.Text = value;
  456. }
  457. if (loadRetainedForm)
  458. {
  459. if (RetainedResults.Results.TryGetValue(dfLayoutDoubleField.Name, out value))
  460. {
  461. item.Text = value;
  462. }
  463. }
  464. item.TextChanged += (object sender, TextChangedEventArgs e) =>
  465. {
  466. dfLayout.ChangeField(dfLayoutDoubleField.Name);
  467. };
  468. view = item;
  469. }
  470. if (isrequired) view.BackgroundColor = isRequiredColor;
  471. if (readOnly || issecure)
  472. {
  473. Label label = new Label();
  474. label.Text = item.Text;
  475. label.FontSize = Device.GetNamedSize(NamedSize.Medium, item);
  476. label.TextColor = Color.DarkGray;
  477. label.LineBreakMode = LineBreakMode.WordWrap;
  478. label.MaxLines = 5;
  479. label.VerticalTextAlignment = TextAlignment.Center;
  480. label.HorizontalTextAlignment = TextAlignment.Center;
  481. label.MinimumHeightRequest = 60;
  482. label.VerticalOptions = LayoutOptions.FillAndExpand;
  483. label.Margin = 9;
  484. view = label;
  485. }
  486. return new Tuple<View, Boolean>(view, isrequired);
  487. }
  488. private Tuple<View, Boolean> LoadDatePicker(View view, DFLayoutControl element, string value)
  489. {
  490. DFLayoutDateField dfLayoutDateField = element as DFLayoutDateField;
  491. DatePicker item = new DatePicker();
  492. item.Format = "dd MMM yyyy";
  493. if (dfLayoutDateField.Properties.Required)
  494. item.BackgroundColor = isRequiredColor;
  495. item.HorizontalOptions = LayoutOptions.CenterAndExpand;
  496. if (loadData.TryGetValue(dfLayoutDateField.Name, out value))
  497. {
  498. item.Date = DateTime.Parse(value);
  499. }
  500. if (loadRetainedForm)
  501. {
  502. if (RetainedResults.Results.TryGetValue(dfLayoutDateField.Name, out value))
  503. {
  504. item.Date = DateTime.Parse(value);
  505. }
  506. }
  507. item.DateSelected += (object sender, DateChangedEventArgs e) =>
  508. {
  509. dfLayout.ChangeField(dfLayoutDateField.Name);
  510. };
  511. view = item;
  512. return new Tuple<View, Boolean>(view, dfLayoutDateField.Properties.Required);
  513. }
  514. private Tuple<View, Boolean> LoadTimePicker(View view, DFLayoutControl element, string value)
  515. {
  516. DFLayoutTimeField dfLayoutTimeField = element as DFLayoutTimeField;
  517. TimePicker item = new TimePicker();
  518. if (dfLayoutTimeField.Properties.Required)
  519. item.BackgroundColor = isRequiredColor;
  520. item.HorizontalOptions = LayoutOptions.Center;
  521. if (loadData.TryGetValue(dfLayoutTimeField.Name, out value))
  522. {
  523. item.Time = DateTime.Parse(value).TimeOfDay;
  524. }
  525. if (loadRetainedForm)
  526. {
  527. if (RetainedResults.Results.TryGetValue(dfLayoutTimeField.Name, out value))
  528. {
  529. item.Time = DateTime.Parse(value).TimeOfDay;
  530. }
  531. }
  532. item.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) =>
  533. {
  534. if (e.PropertyName == "Time")
  535. dfLayout.ChangeField(dfLayoutTimeField.Name);
  536. };
  537. view = item;
  538. return new Tuple<View, Boolean>(view, dfLayoutTimeField.Properties.Required);
  539. }
  540. private Tuple<View, Boolean> LoadOptionPicker(View view, DFLayoutControl element, string value)
  541. {
  542. var isrequired = false;
  543. DFLayoutOptionField dfLayoutOptionField = element as DFLayoutOptionField;
  544. isrequired = dfLayoutOptionField.Properties.Required;
  545. if (GlobalVariables.DeviceString == "i" || GlobalVariables.DeviceString == "I")
  546. {
  547. CustomPickeriOS item = new CustomPickeriOS();
  548. string s = dfLayoutOptionField.Properties.Options;
  549. string[] substrings = s.Split(',');
  550. var optionList = substrings.ToList();
  551. item.AddItems(optionList);
  552. if (!string.IsNullOrEmpty(dfLayoutOptionField.Properties.Default))
  553. {
  554. int index = optionList.IndexOf(dfLayoutOptionField.Properties.Default);
  555. item.SelectedIndex = index;
  556. item.SelectedItem = optionList[index];
  557. item.SetDefault(optionList[index]);
  558. }
  559. if (loadData.TryGetValue(dfLayoutOptionField.Name, out value))
  560. {
  561. int index = optionList.IndexOf(value);
  562. item.SelectedIndex = index;
  563. item.SelectedItem = optionList[index];
  564. item.SetDefault(optionList[index]);
  565. }
  566. if (loadRetainedForm)
  567. {
  568. if (RetainedResults.Results.TryGetValue(dfLayoutOptionField.Name, out value))
  569. {
  570. int index = optionList.IndexOf(value);
  571. item.SelectedIndex = index;
  572. item.SelectedItem = optionList[index];
  573. item.SetDefault(optionList[index]);
  574. }
  575. }
  576. if (isrequired)
  577. {
  578. item.BackgroundColor = isRequiredColor;
  579. item.SetBackGroundColor(isRequiredColor);
  580. }
  581. item.CustomPickeriOSValueChanged += () =>
  582. {
  583. dfLayout.ChangeField(dfLayoutOptionField.Name);
  584. };
  585. view = item;
  586. }
  587. else
  588. {
  589. Picker picker = new Picker();
  590. picker.Title = "Select an option";
  591. picker.VerticalTextAlignment = TextAlignment.Center;
  592. picker.HorizontalTextAlignment = TextAlignment.Center;
  593. string s = dfLayoutOptionField.Properties.Options;
  594. string[] substrings = s.Split(',');
  595. var optionList = substrings.ToList();
  596. picker.ItemsSource = optionList;
  597. if (!string.IsNullOrEmpty(dfLayoutOptionField.Properties.Default))
  598. {
  599. int index = optionList.IndexOf(dfLayoutOptionField.Properties.Default);
  600. picker.SelectedIndex = index;
  601. picker.SelectedItem = optionList[index];
  602. }
  603. if (loadData.TryGetValue(dfLayoutOptionField.Name, out value))
  604. {
  605. int index = optionList.IndexOf(value);
  606. picker.SelectedIndex = index;
  607. picker.SelectedItem = optionList[index];
  608. }
  609. if (loadRetainedForm)
  610. {
  611. if (RetainedResults.Results.TryGetValue(dfLayoutOptionField.Name, out value))
  612. {
  613. int index = optionList.IndexOf(value);
  614. picker.SelectedIndex = index;
  615. picker.SelectedItem = optionList[index];
  616. }
  617. }
  618. if (isrequired)
  619. {
  620. picker.BackgroundColor = isRequiredColor;
  621. }
  622. picker.SelectedIndexChanged += (object sender, EventArgs e) =>
  623. {
  624. dfLayout.ChangeField(dfLayoutOptionField.Name);
  625. };
  626. view = picker;
  627. }
  628. return new Tuple<View, Boolean>(view, isrequired);
  629. }
  630. private Tuple<View, Boolean> LoadImage(View view, DFLayoutControl element)
  631. {
  632. DFLayoutImage dfLayoutImage = element as DFLayoutImage;
  633. Image img = new Image();
  634. CoreTable table = new Client<Document>().Query(
  635. new Filter<Document>(x => x.ID).IsEqualTo(dfLayoutImage.Image.ID),
  636. null,
  637. null);
  638. if (table.Rows.Any())
  639. {
  640. CoreRow row = table.Rows.FirstOrDefault();
  641. byte[] data = row.Get<Document, byte[]>(x => x.Data);
  642. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  643. img.MinimumHeightRequest = 150;
  644. img.MinimumWidthRequest = 150;
  645. img.Aspect = Aspect.AspectFit;
  646. img.Source = src;
  647. img.HorizontalOptions = LayoutOptions.FillAndExpand;
  648. img.VerticalOptions = LayoutOptions.FillAndExpand;
  649. img.GestureRecognizers.Add(new TapGestureRecognizer
  650. {
  651. Command = new Command(OnTap),
  652. CommandParameter = src,
  653. NumberOfTapsRequired = 1
  654. });
  655. if (img != null)
  656. {
  657. view = img;
  658. }
  659. }
  660. return new Tuple<View, Boolean>(view, false);
  661. }
  662. private void OnTap(object obj)
  663. {
  664. ImageViewer viewer = new ImageViewer(obj as ImageSource);
  665. Navigation.PushAsync(viewer);
  666. }
  667. private Tuple<View, Boolean> LoadLookupPicker(View view, DFLayoutControl element, string value)
  668. {
  669. DFLayoutLookupField dfLayoutLookupField = element as DFLayoutLookupField;
  670. var isrequired = dfLayoutLookupField.Properties.Required;
  671. Dictionary<Guid, string> lookupFieldOptions = new Dictionary<Guid, string>();
  672. string type = dfLayoutLookupField.Properties.LookupType;
  673. Type lookuptype = CoreUtils.GetEntity(type);
  674. if (lookuptype == typeof(DrawingTemplate))
  675. {
  676. view = LoadDrawingTemplateLookupButton(lookuptype, dfLayoutLookupField, lookupFieldOptions, element);
  677. }
  678. else if (!string.IsNullOrWhiteSpace(dfLayoutLookupField.Properties.Filter))
  679. {
  680. view = LoadGenericLookupButton(lookuptype, dfLayoutLookupField, lookupFieldOptions, element);
  681. }
  682. else if (lookuptype == typeof(Product))
  683. {
  684. view = LoadProductLookupPicker(view, dfLayoutLookupField, value);
  685. }
  686. else if (lookuptype != null)
  687. {
  688. view = LoadGenericLookupButton(lookuptype, dfLayoutLookupField, lookupFieldOptions, element);
  689. }
  690. return new Tuple<View, Boolean>(view, isrequired);
  691. }
  692. private View LoadGenericLookupButton(Type lookuptype, DFLayoutLookupField dfLayoutLookupField, Dictionary<Guid, string> lookupFieldOptions, DFLayoutControl element)
  693. {
  694. string value = "";
  695. CoreTable table = new CoreTable();
  696. var client = ClientFactory.CreateClient(lookuptype);
  697. var columns = LookupFactory.DefineColumns(lookuptype);
  698. var sort = LookupFactory.DefineSort(lookuptype);
  699. var filter = LookupFactory.DefineFilter(lookuptype);
  700. if (!string.IsNullOrWhiteSpace(dfLayoutLookupField.Properties.Filter))
  701. filter = ReturnFilter(dfLayoutLookupField, lookuptype);
  702. if (lookuptype == typeof(ProductStyle) && JobID != Guid.Empty)
  703. table = ReturnJobStyleProducts(table, client, columns, sort);
  704. if (table.Rows.Count == 0)
  705. table = client.Query(filter, columns, sort); // do generic query if a specific one hasn't already been done
  706. foreach (var row in table.Rows)
  707. {
  708. Guid id = row.Get<Guid>("ID");
  709. Dictionary<string, object> values = row.ToDictionary(new string[] { "ID" });
  710. string display = LookupFactory.FormatLookup(lookuptype, values, new string[] { });
  711. lookupFieldOptions[id] = display;
  712. }
  713. dfLayoutLookupFieldLookupOptions[element as DFLayoutLookupField] = lookupFieldOptions;
  714. List<string> itemList = lookupFieldOptions.Values.ToList();
  715. DataButtonControl button = new DataButtonControl()
  716. {
  717. Text = "Choose Option",
  718. HorizontalOptions = LayoutOptions.FillAndExpand,
  719. VerticalOptions = LayoutOptions.Center,
  720. Margin = 0,
  721. BackgroundColor = Color.FromHex("#15C7C1"),
  722. FontAttributes = FontAttributes.Bold,
  723. TextColor = Color.White,
  724. CornerRadius = 5,
  725. Padding = 1,
  726. };
  727. button.Clicked += (object sender, EventArgs eventArgs) =>
  728. {
  729. ListSelectionPage selectionPage = new ListSelectionPage(itemList);
  730. selectionPage.OnItemTapped += (s) =>
  731. {
  732. button.Data = s;
  733. button.Text = s;
  734. dfLayout.ChangeField(dfLayoutLookupField.Name);
  735. };
  736. Navigation.PushAsync(selectionPage);
  737. };
  738. if (loadData.TryGetValue(dfLayoutLookupField.Name, out value))
  739. {
  740. button.Data = value;
  741. button.Text = value;
  742. }
  743. if (loadRetainedForm)
  744. {
  745. if (RetainedResults.Results.TryGetValue(dfLayoutLookupField.Name, out value))
  746. {
  747. button.Data = value;
  748. button.Text = value;
  749. }
  750. }
  751. if (isRequired)
  752. {
  753. button.BackgroundColor = isRequiredColor;
  754. }
  755. return button;
  756. }
  757. private View LoadDrawingTemplateLookupButton(Type lookuptype, DFLayoutLookupField dfLayoutLookupField, Dictionary<Guid, string> lookupFieldOptions, DFLayoutControl element)
  758. {
  759. string value = "";
  760. var columns = new Columns<DrawingTemplate>(x => x.Code, x => x.Document.ID);
  761. CoreTable table = new Client<DrawingTemplate>().Query(null, columns);
  762. Dictionary<string, Guid> dictionary = new Dictionary<string, Guid>();
  763. foreach (var row in table.Rows)
  764. {
  765. List<object> list = row.Values;
  766. if (list[0] != null && list[1] != null)
  767. dictionary.Add(list[0].ToString(), Guid.Parse(list[1].ToString()));
  768. }
  769. DataButtonControl button = new DataButtonControl()
  770. {
  771. Text = "Choose Option",
  772. HorizontalOptions = LayoutOptions.FillAndExpand,
  773. VerticalOptions = LayoutOptions.Center,
  774. Margin = 0,
  775. BackgroundColor = Color.FromHex("#15C7C1"),
  776. FontAttributes = FontAttributes.Bold,
  777. TextColor = Color.White,
  778. CornerRadius = 5,
  779. Padding = 1,
  780. };
  781. button.Clicked += (object sender, EventArgs eventArgs) =>
  782. {
  783. ListSelectionPage selectionPage = new ListSelectionPage(dictionary);
  784. selectionPage.OnItemTapped += (s) =>
  785. {
  786. button.Data = s;
  787. button.Text = s;
  788. dfLayout.ChangeField(dfLayoutLookupField.Name);
  789. };
  790. Navigation.PushAsync(selectionPage);
  791. };
  792. if (loadData.TryGetValue(dfLayoutLookupField.Name, out value))
  793. {
  794. button.Data = value;
  795. button.Text = value;
  796. }
  797. if (loadRetainedForm)
  798. {
  799. if (RetainedResults.Results.TryGetValue(dfLayoutLookupField.Name, out value))
  800. {
  801. button.Data = value;
  802. button.Text = value;
  803. }
  804. }
  805. if (isRequired)
  806. {
  807. button.BackgroundColor = isRequiredColor;
  808. }
  809. return button;
  810. }
  811. private IFilter ReturnFilter(DFLayoutLookupField dfLayoutLookupField, Type lookuptype)
  812. {
  813. var propertyFilter = dfLayoutLookupField.Properties.Filter;
  814. var filtertype = typeof(Filter<>).MakeGenericType(lookuptype);
  815. var deserialised = Serialization.Deserialize(filtertype, propertyFilter);
  816. IFilter filter = deserialised as IFilter;
  817. return filter;
  818. }
  819. private CoreTable ReturnJobStyleProducts(CoreTable table, IClient client, IColumns columns, ISortOrder sort)
  820. {
  821. CoreTable jobStyleTable = new Client<JobStyle>().Query(new Filter<JobStyle>(x => x.Job.ID).IsEqualTo(JobID),
  822. new Columns<JobStyle>(x => x.Style.ID));
  823. if (jobStyleTable.Rows.Any())
  824. {
  825. Guid firstID = Guid.Parse(jobStyleTable.Rows.FirstOrDefault().Values[0].ToString());
  826. var stylefilter = new Filter<ProductStyle>(x => x.ID).IsEqualTo(firstID);
  827. foreach (CoreRow jobStyleRow in jobStyleTable.Rows)
  828. {
  829. if (jobStyleRow != jobStyleTable.Rows.FirstOrDefault())
  830. {
  831. stylefilter = stylefilter.Or(x => x.ID).IsEqualTo(Guid.Parse(jobStyleRow.Values[0].ToString()));
  832. }
  833. }
  834. table = client.Query(stylefilter, columns, sort);
  835. }
  836. return table;
  837. }
  838. private View LoadProductLookupPicker(View view, DFLayoutLookupField dfLayoutLookupField, string value)
  839. {
  840. FrameButton framebutton = new FrameButton();
  841. if (loadData.TryGetValue(dfLayoutLookupField.Name, out value))
  842. {
  843. framebutton.SetButtonText(value);
  844. framebutton.Data = value + "," + (GlobalVariables.ProductShells.FirstOrDefault(x => x.Code == value)).ID.ToString();
  845. CoreTable productTable = new Client<Product>().Query(new Filter<Product>(x => x.Code).IsEqualTo(value),
  846. new Columns<Product>(x => x.Image.ID));
  847. if (productTable.Rows.Any())
  848. {
  849. CoreTable imageTable1 = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(Guid.Parse(productTable.Rows.First().Values[0].ToString())),
  850. new Columns<Document>(x => x.Data));
  851. CoreRow docrow = imageTable1.Rows.FirstOrDefault();
  852. if (docrow != null)
  853. {
  854. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  855. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  856. if (src != null)
  857. {
  858. framebutton.SetImage(src);
  859. }
  860. }
  861. }
  862. }
  863. framebutton.OnFrameButtonClicked += (() =>
  864. {
  865. ProductList productList = new ProductList(GlobalVariables.ProductShells, true);
  866. productList.OnProductSelected += () =>
  867. {
  868. framebutton.SetButtonText(productList.SelectedProduct.Code);
  869. framebutton.Data = productList.SelectedProduct.Code + "," + productList.SelectedProduct.ID.ToString();
  870. CoreTable imageTable = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(productList.SelectedProduct.ImageID),
  871. new Columns<Document>(x => x.Data));
  872. CoreRow docrow = imageTable.Rows.FirstOrDefault();
  873. if (docrow != null)
  874. {
  875. byte[] data = docrow.Get<Document, byte[]>(x => x.Data);
  876. ImageSource src = ImageSource.FromStream(() => new MemoryStream(data));
  877. if (src != null)
  878. {
  879. framebutton.SetImage(src);
  880. }
  881. }
  882. dfLayout.ChangeField(dfLayoutLookupField.Name);
  883. };
  884. Navigation.PushAsync(productList);
  885. });
  886. view = framebutton;
  887. return view;
  888. }
  889. private Tuple<View, Boolean> LoadSignaturePad(View view, DFLayoutControl element, string value)
  890. {
  891. DFLayoutSignaturePad dFLayoutSignaturePad = element as DFLayoutSignaturePad;
  892. var isrequired = dFLayoutSignaturePad.Properties.Required;
  893. if (loadData.TryGetValue(dFLayoutSignaturePad.Name, out value))
  894. {
  895. EmbeddedImageCapture embeddedImageCapture = new EmbeddedImageCapture();
  896. byte[] data = Convert.FromBase64String(value);
  897. embeddedImageCapture.DataToImage(data);
  898. view = embeddedImageCapture;
  899. view.IsEnabled = false;
  900. }
  901. else
  902. {
  903. SfSignaturePad signaturePad = new SfSignaturePad();
  904. EmbeddedImageCapture hiddenEmbeddedImageCapture = new EmbeddedImageCapture() { HeightRequest = 200, IsVisible = false, IsEnabled = false };
  905. if (isrequired) signaturePad.BackgroundColor = isRequiredColor;
  906. signaturePad.MinimumHeightRequest = 200;
  907. signaturePad.MinimumStrokeWidth = 0.2;
  908. signaturePad.MaximumStrokeWidth = 17;
  909. Button clearButton = new Button()
  910. {
  911. Text = "Clear",
  912. HorizontalOptions = LayoutOptions.FillAndExpand,
  913. VerticalOptions = LayoutOptions.End,
  914. Margin = 0,
  915. BackgroundColor = Color.FromHex("#15C7C1"),
  916. FontAttributes = FontAttributes.Bold,
  917. TextColor = Color.White,
  918. CornerRadius = 5,
  919. Padding = 1
  920. };
  921. clearButton.Clicked += (object sender, EventArgs e) =>
  922. {
  923. signaturePad.IsVisible = true;
  924. hiddenEmbeddedImageCapture.IsVisible = false;
  925. useSavedSignatures.Remove(dFLayoutSignaturePad.Name);
  926. signaturePad.Clear();
  927. };
  928. Grid.SetColumn(clearButton, 2);
  929. Button signNowButton = new Button()
  930. {
  931. Text = "Apply Saved",
  932. HorizontalOptions = LayoutOptions.FillAndExpand,
  933. VerticalOptions = LayoutOptions.End,
  934. Margin = 0,
  935. BackgroundColor = Color.FromHex("#15C7C1"),
  936. FontAttributes = FontAttributes.Bold,
  937. TextColor = Color.White,
  938. CornerRadius = 5,
  939. Padding = 1
  940. };
  941. signNowButton.Clicked += (object sender, EventArgs e) =>
  942. {
  943. if (Application.Current.Properties.ContainsKey("SavedSignature"))
  944. {
  945. Task.Run(() =>
  946. {
  947. hiddenEmbeddedImageCapture.DataToImage((Application.Current.Properties["SavedSignature"]) as byte[]);
  948. });
  949. Thread.Sleep(1000);
  950. signaturePad.IsVisible = false;
  951. hiddenEmbeddedImageCapture.IsVisible = true;
  952. if (!useSavedSignatures.Contains(dFLayoutSignaturePad.Name))
  953. useSavedSignatures.Add(dFLayoutSignaturePad.Name);
  954. }
  955. };
  956. Grid.SetColumn(signNowButton, 1);
  957. Button createSignatureButton = new Button()
  958. {
  959. Text = "Save New",
  960. HorizontalOptions = LayoutOptions.FillAndExpand,
  961. VerticalOptions = LayoutOptions.End,
  962. Margin = 0,
  963. BackgroundColor = Color.FromHex("#15C7C1"),
  964. FontAttributes = FontAttributes.Bold,
  965. TextColor = Color.White,
  966. CornerRadius = 5,
  967. Padding = 1
  968. };
  969. createSignatureButton.Clicked += (object sender, EventArgs e) =>
  970. {
  971. SignatureSaver saver = new SignatureSaver();
  972. saver.OnSignatureSaved += () =>
  973. {
  974. Task.Run(() =>
  975. {
  976. hiddenEmbeddedImageCapture.DataToImage((Application.Current.Properties["SavedSignature"]) as byte[]);
  977. });
  978. Thread.Sleep(1000);
  979. signaturePad.IsVisible = false;
  980. hiddenEmbeddedImageCapture.IsVisible = true;
  981. if (!useSavedSignatures.Contains(dFLayoutSignaturePad.Name))
  982. useSavedSignatures.Add(dFLayoutSignaturePad.Name);
  983. };
  984. Navigation.PushAsync(saver);
  985. };
  986. Grid.SetColumn(createSignatureButton, 0);
  987. Grid buttonsGrid = new Grid { Margin = 0, Padding = 0, VerticalOptions = LayoutOptions.End };
  988. buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  989. buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  990. buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  991. buttonsGrid.Children.Add(createSignatureButton);
  992. buttonsGrid.Children.Add(signNowButton);
  993. buttonsGrid.Children.Add(clearButton);
  994. Grid grid = new Grid() { Margin = 0, Padding = 0 };
  995. grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(200, GridUnitType.Absolute) });
  996. Grid.SetRow(signaturePad, 0);
  997. Grid.SetRow(hiddenEmbeddedImageCapture, 0);
  998. grid.Children.Add(hiddenEmbeddedImageCapture);
  999. grid.Children.Add(signaturePad);
  1000. grid.Children.Add(buttonsGrid);
  1001. view = grid;
  1002. }
  1003. return new Tuple<View, Boolean>(view, isrequired);
  1004. }
  1005. private Tuple<View, Boolean> LoadEmbeddedImage(View view, DFLayoutControl element, string value)
  1006. {
  1007. bool disableLibrary = false;
  1008. DFLayoutEmbeddedImage dfLayoutEmbeddedImage = element as DFLayoutEmbeddedImage;
  1009. try
  1010. {
  1011. disableLibrary = dfLayoutEmbeddedImage.Properties.DisableLibrary;
  1012. }
  1013. catch { }
  1014. EmbeddedImageCapture embeddedImageCapture = new EmbeddedImageCapture(disableLibrary);
  1015. if (disableLibrary)
  1016. embeddedImageCapture.LibraryButton.BackgroundColor = Color.LightGray;
  1017. if (loadData.TryGetValue(dfLayoutEmbeddedImage.Name, out value))
  1018. {
  1019. byte[] data = Convert.FromBase64String(value);
  1020. embeddedImageCapture.DataToImage(data);
  1021. }
  1022. else
  1023. {
  1024. if (dfLayoutEmbeddedImage.Properties.Required)
  1025. {
  1026. embeddedImageCapture.CameraButton.BackgroundColor = isRequiredColor;
  1027. embeddedImageCapture.CameraButton.BorderWidth = 1;
  1028. embeddedImageCapture.CameraButton.BorderColor = Color.Black;
  1029. if (!disableLibrary)
  1030. {
  1031. embeddedImageCapture.LibraryButton.BackgroundColor = isRequiredColor;
  1032. embeddedImageCapture.LibraryButton.BorderWidth = 1;
  1033. embeddedImageCapture.LibraryButton.BorderColor = Color.Black;
  1034. }
  1035. }
  1036. }
  1037. view = embeddedImageCapture;
  1038. return new Tuple<View, Boolean>(view, dfLayoutEmbeddedImage.Properties.Required);
  1039. }
  1040. private Tuple<View, Boolean> LoadMultiImage(View view, DFLayoutControl element, string value)
  1041. {
  1042. bool disableLibrary = false;
  1043. DFLayoutMultiImage dfLayoutMultiEmbeddedImage = element as DFLayoutMultiImage;
  1044. try
  1045. {
  1046. disableLibrary = dfLayoutMultiEmbeddedImage.Properties.DisableLibrary;
  1047. }
  1048. catch { }
  1049. MultiImageCapture multiImageCapture = new MultiImageCapture(disableLibrary);
  1050. if (loadData.TryGetValue(dfLayoutMultiEmbeddedImage.Name, out value))
  1051. {
  1052. List<string> values = Serialization.Deserialize<List<string>>(value);
  1053. foreach (string s in values)
  1054. {
  1055. byte[] data = Convert.FromBase64String(s);
  1056. multiImageCapture.DataToImage(data);
  1057. }
  1058. }
  1059. view = multiImageCapture;
  1060. return new Tuple<View, bool>(view, dfLayoutMultiEmbeddedImage.Properties.Required);
  1061. }
  1062. private Tuple<View, bool> LoadMultiSignaturePad(View view, DFLayoutControl element, string value)
  1063. {
  1064. DFLayoutMultiSignaturePad dfLayoutMultiSignaturePad = element as DFLayoutMultiSignaturePad;
  1065. DataButtonControl button = new DataButtonControl
  1066. {
  1067. Text = "Add Signatures",
  1068. TextColor = Color.White,
  1069. HorizontalOptions = LayoutOptions.FillAndExpand,
  1070. CornerRadius = 0,
  1071. BackgroundColor = Color.FromHex("#15C7C1"),
  1072. FontAttributes = FontAttributes.Bold
  1073. };
  1074. if (loadData.TryGetValue(dfLayoutMultiSignaturePad.Name, out value))
  1075. {
  1076. button.Data = value;
  1077. }
  1078. MultiSignaturePad multiSignaturePad = new MultiSignaturePad(button.Data);
  1079. multiSignaturePad.OnMultiSignatureSaved += (result) =>
  1080. {
  1081. button.Data = result;
  1082. };
  1083. button.Clicked += (object sender, EventArgs e) =>
  1084. {
  1085. Navigation.PushAsync(multiSignaturePad);
  1086. };
  1087. view = button;
  1088. return new Tuple<View, bool>(view, dfLayoutMultiSignaturePad.Properties.Required);
  1089. }
  1090. private Tuple<View, bool> LoadAddTaskField(View view, DFLayoutControl element, string value)
  1091. {
  1092. DFLayoutAddTaskField field = element as DFLayoutAddTaskField;
  1093. DFCreateTaskView taskView = new DFCreateTaskView();
  1094. taskView.OnAddTaskButtonClicked += () =>
  1095. {
  1096. AddEditTask addEditTask = new AddEditTask(Guid.Empty, "New task from Digital Form");
  1097. if (field.Properties.TaskType != null)
  1098. {
  1099. addEditTask.kanban.Type.ID = field.Properties.TaskType.ID;
  1100. try
  1101. {
  1102. addEditTask.kanban.Type.Description = new Client<KanbanType>().Query
  1103. (new Filter<KanbanType>(x => x.ID).IsEqualTo(field.Properties.TaskType.ID),
  1104. new Columns<KanbanType>(x => x.Description)).Rows.FirstOrDefault().Values[0].ToString();
  1105. }
  1106. catch { }
  1107. addEditTask.UpdateScreen(true);
  1108. }
  1109. addEditTask.OnTaskSaved += (taskNumber) =>
  1110. {
  1111. taskView.DisableButton();
  1112. taskView.TaskNumber = taskNumber.ToString();
  1113. };
  1114. Navigation.PushAsync(addEditTask);
  1115. };
  1116. if (loadData.TryGetValue(field.Name, out value))
  1117. {
  1118. taskView.TaskNumber = value;
  1119. taskView.DisableButton();
  1120. }
  1121. return new Tuple<View, bool>(taskView, field.Properties.Required);
  1122. }
  1123. private void FormatAndAddView(View view, DFLayoutControl element, bool isrequired)
  1124. {
  1125. if (element is DFLayoutField)
  1126. {
  1127. pairs[element as DFLayoutField] = view;
  1128. if (isSecure || readOnly)
  1129. view.IsEnabled = false;
  1130. Frame frame = new Frame
  1131. {
  1132. Content = view,
  1133. BorderColor = Color.FromHex("#15C7C1"),
  1134. BackgroundColor = Color.Default,
  1135. CornerRadius = 5,
  1136. Padding = 2,
  1137. HasShadow = false,
  1138. };
  1139. if (readOnly || isSecure)
  1140. {
  1141. frame.BorderColor = Color.Gray;
  1142. frame.BackgroundColor = Color.LightGray;
  1143. frame.VerticalOptions = LayoutOptions.FillAndExpand;
  1144. frame.MinimumHeightRequest = 60;
  1145. }
  1146. if (isrequired)
  1147. {
  1148. frame.BackgroundColor = isRequiredColor;
  1149. }
  1150. view = frame;
  1151. }
  1152. if (element.Row > 0) SetRow(view, element.Row - 1); //rows and columns coming in from the desktop designer start from 1, not 0 (most of the time??)
  1153. else if (element.Row == 0) SetRow(view, dfLayout.RowHeights.Count + 1);
  1154. if (element.RowSpan > 0) SetRowSpan(view, element.RowSpan);
  1155. else if (element.RowSpan == 0) SetRowSpan(view, 1);
  1156. if (element.Column > 0) SetColumn(view, element.Column - 1); //rows and columns coming in from the desktop designer start from 1, not 0 (most of the time??)
  1157. if (element.ColumnSpan > 0) SetColumnSpan(view, element.ColumnSpan);
  1158. if (element.ColumnSpan > 1)
  1159. {
  1160. view.HorizontalOptions = LayoutOptions.FillAndExpand;
  1161. if (view is Label)
  1162. {
  1163. view.HorizontalOptions = LayoutOptions.CenterAndExpand;
  1164. Label lblView = view as Label;
  1165. lblView.HorizontalTextAlignment = TextAlignment.Center;
  1166. view = lblView;
  1167. }
  1168. }
  1169. else if (element.ColumnSpan == 0) SetColumnSpan(view, 1);
  1170. view.SetValue(Grid.MarginProperty, 0.01);
  1171. if (element is DFLayoutSignaturePad)
  1172. {
  1173. view.Margin = new Thickness(25, 0, 25, 0);
  1174. }
  1175. Device.BeginInvokeOnMainThread(() => { Children.Add(view); });
  1176. if (element is DFLayoutHeader)
  1177. if ((element as DFLayoutHeader).Collapsed)
  1178. headersToCollapse.Add(view as DigitalFormsHeader);
  1179. }
  1180. #endregion
  1181. #region Save
  1182. public void SaveData(bool saveForLater)
  1183. {
  1184. try
  1185. {
  1186. results.Clear();
  1187. propertyResults.Clear();
  1188. isRequiredEmpty = false;
  1189. isRequiredMessage = "";
  1190. foreach (DFLayoutField field in pairs.Keys)
  1191. {
  1192. View view = pairs[field];
  1193. String userInput = AddResultsToDictionary(field, view);
  1194. if (isRequiredEmpty)
  1195. {
  1196. if (!saveForLater)
  1197. return;
  1198. }
  1199. AddPropertyToDictionary(field, userInput);
  1200. }
  1201. UpdateInstanceAndModel(saveForLater);
  1202. }
  1203. catch (Exception ex)
  1204. {
  1205. errors.Add(ex.Message);
  1206. }
  1207. }
  1208. #region Adding Results to dictionaries
  1209. private string AddResultsToDictionary(DFLayoutField field, View view, bool AddToDictionary = true) //"results" dictionary is the data to be saved in Form.Data
  1210. {
  1211. string userInput = "";
  1212. if (field is DFLayoutStringField || field is DFLayoutIntegerField || field is DFLayoutDoubleField)
  1213. {
  1214. userInput = (view as Editor).Text;
  1215. }
  1216. else if (field is DFLayoutBooleanField)
  1217. {
  1218. if ((view as CustomBoolean).ValueChanged)
  1219. {
  1220. userInput = (view as CustomBoolean).Value.ToString();
  1221. }
  1222. }
  1223. else if (field is DFLayoutDateField)
  1224. {
  1225. userInput = ((view as DatePicker).Date).ToString("dd-MM-yyyy");
  1226. }
  1227. else if (field is DFLayoutTimeField)
  1228. {
  1229. userInput = ((view as TimePicker).Time).ToString("c");
  1230. }
  1231. else if (field is DFLayoutOptionField)
  1232. {
  1233. userInput = GetStringFromOptionField(view);
  1234. }
  1235. else if (field is DFLayoutLookupField)
  1236. {
  1237. if (view is DataButtonControl)
  1238. {
  1239. var button = view as DataButtonControl;
  1240. userInput = FindIDForDesignLookupField(button); //userinput is used to set guid later on for properties, but will not get added to form data only for lookupfields
  1241. results.Add(field.Name, button.Data);
  1242. if (RetainedResults.IsFormRetained)
  1243. if ((field as DFLayoutLookupField).Properties.Retain)
  1244. RetainedResults.Results.Add(field.Name, button.Data);
  1245. }
  1246. else if (view is FrameButton) //currently only used for Products - we already have the Product.ID in Framebutton.Data (saved as Code,ID)
  1247. {
  1248. FrameButton framebutton = view as FrameButton;
  1249. if (!string.IsNullOrWhiteSpace(framebutton.Data))
  1250. {
  1251. string[] buttonData = framebutton.Data.Split(',');
  1252. if (AddToDictionary)
  1253. results.Add(field.Name, buttonData[0]); //[0] is product.code
  1254. userInput = buttonData[1]; //[1] is product id as string
  1255. if (RetainedResults.IsFormRetained)
  1256. if ((field as DFLayoutLookupField).Properties.Retain)
  1257. RetainedResults.Results.Add(field.Name, buttonData[0]);
  1258. }
  1259. }
  1260. }
  1261. else if (field is DFLayoutSignaturePad)
  1262. {
  1263. string value = "";
  1264. var grid = view as Grid;
  1265. var signaturePad = grid.Children.OfType<SfSignaturePad>().FirstOrDefault();
  1266. DFLayoutSignaturePad dFLayoutSignaturePad = field as DFLayoutSignaturePad;
  1267. if (loadData.TryGetValue(dFLayoutSignaturePad.Name, out value))
  1268. {
  1269. userInput = value;
  1270. }
  1271. else
  1272. {
  1273. if (useSavedSignatures.Contains(dFLayoutSignaturePad.Name))
  1274. {
  1275. ImageSource src = ImageSource.FromStream(() => new MemoryStream((Application.Current.Properties["SavedSignature"]) as byte[]));
  1276. userInput = ImageSourceToBase64(src);
  1277. }
  1278. else
  1279. {
  1280. signaturePad.Save();
  1281. if (signaturePad.ImageSource != null)
  1282. {
  1283. userInput = ImageSourceToBase64(signaturePad.ImageSource);
  1284. }
  1285. }
  1286. }
  1287. }
  1288. else if (field is DFLayoutEmbeddedImage)
  1289. {
  1290. var embeddedImage = view as EmbeddedImageCapture;
  1291. if (embeddedImage.Image.Source != null)
  1292. {
  1293. try
  1294. {
  1295. userInput = ImageSourceToBase64(embeddedImage.Image.Source);
  1296. }
  1297. catch (Exception e)
  1298. {
  1299. userInput = "";
  1300. }
  1301. }
  1302. }
  1303. else if (field is DFLayoutMultiImage)
  1304. {
  1305. var multiImage = view as MultiImageCapture;
  1306. if (multiImage.Images.Count > 0)
  1307. {
  1308. try
  1309. {
  1310. userInput = ImagesToBase64(multiImage.Images);
  1311. }
  1312. catch (Exception e)
  1313. {
  1314. userInput = "";
  1315. }
  1316. }
  1317. }
  1318. else if (field is DFLayoutAddTaskField)
  1319. {
  1320. var addTaskButton = view as DFCreateTaskView;
  1321. if (!string.IsNullOrWhiteSpace(addTaskButton.TaskNumber))
  1322. {
  1323. userInput = addTaskButton.TaskNumber;
  1324. }
  1325. }
  1326. else if (field is DFLayoutMultiSignaturePad)
  1327. {
  1328. var databutton = view as DataButtonControl;
  1329. if (!string.IsNullOrWhiteSpace(databutton.Data))
  1330. userInput = databutton.Data;
  1331. }
  1332. //add the field name and input to 'results' dictionary for processing outside of QAFormViewer
  1333. if (!String.IsNullOrWhiteSpace(userInput) && AddToDictionary)
  1334. {
  1335. if (field is DFLayoutLookupField)
  1336. { /*do nothing as results have already been added*/ }
  1337. else
  1338. {
  1339. try
  1340. {
  1341. results.Add(field.Name, userInput);
  1342. }
  1343. catch (Exception e)
  1344. {
  1345. errors.Add(e.Message);
  1346. }
  1347. if (RetainedResults.IsFormRetained)
  1348. {
  1349. AddRetainedToDictionary(field, userInput);
  1350. }
  1351. }
  1352. }
  1353. else CheckRequired(field);
  1354. return userInput;
  1355. }
  1356. private void AddPropertyToDictionary(DFLayoutField field, String userInput)
  1357. {
  1358. if (!string.IsNullOrWhiteSpace(userInput))
  1359. {
  1360. try
  1361. {
  1362. string property = "";
  1363. if (field is DFLayoutStringField)
  1364. property = (field as DFLayoutStringField).Properties.Property;
  1365. else if (field is DFLayoutIntegerField)
  1366. property = (field as DFLayoutIntegerField).Properties.Property;
  1367. else if (field is DFLayoutDoubleField)
  1368. property = (field as DFLayoutDoubleField).Properties.Property;
  1369. else if (field is DFLayoutBooleanField)
  1370. property = (field as DFLayoutBooleanField).Properties.Property;
  1371. else if (field is DFLayoutDateField)
  1372. property = (field as DFLayoutDateField).Properties.Property;
  1373. else if (field is DFLayoutTimeField)
  1374. property = (field as DFLayoutTimeField).Properties.Property;
  1375. else if (field is DFLayoutOptionField)
  1376. property = (field as DFLayoutOptionField).Properties.Property;
  1377. else if (field is DFLayoutLookupField)
  1378. property = (field as DFLayoutLookupField).Properties.Property;
  1379. //'propertyResults' dictionary for processing outside of QAFormViewer
  1380. if (!string.IsNullOrWhiteSpace(property)) propertyResults.Add(property, userInput);
  1381. }
  1382. catch (Exception e)
  1383. {
  1384. errors.Add(e.Message);
  1385. return;
  1386. }
  1387. }
  1388. }
  1389. private async void AddRetainedToDictionary(DFLayoutField field, string userInput)
  1390. {
  1391. await Task.Run(() =>
  1392. {
  1393. try
  1394. {
  1395. if (field is DFLayoutStringField)
  1396. {
  1397. if ((field as DFLayoutStringField).Properties.Retain)
  1398. RetainedResults.Results.Add(field.Name, userInput);
  1399. }
  1400. else if (field is DFLayoutIntegerField)
  1401. {
  1402. if ((field as DFLayoutIntegerField).Properties.Retain)
  1403. RetainedResults.Results.Add(field.Name, userInput);
  1404. }
  1405. else if (field is DFLayoutDoubleField)
  1406. {
  1407. if ((field as DFLayoutDoubleField).Properties.Retain)
  1408. RetainedResults.Results.Add(field.Name, userInput);
  1409. }
  1410. else if (field is DFLayoutBooleanField)
  1411. {
  1412. if ((field as DFLayoutBooleanField).Properties.Retain)
  1413. RetainedResults.Results.Add(field.Name, userInput);
  1414. }
  1415. else if (field is DFLayoutDateField)
  1416. {
  1417. if ((field as DFLayoutDateField).Properties.Retain)
  1418. RetainedResults.Results.Add(field.Name, userInput);
  1419. }
  1420. else if (field is DFLayoutTimeField)
  1421. {
  1422. if ((field as DFLayoutTimeField).Properties.Retain)
  1423. RetainedResults.Results.Add(field.Name, userInput);
  1424. }
  1425. else if (field is DFLayoutOptionField)
  1426. {
  1427. if ((field as DFLayoutOptionField).Properties.Retain)
  1428. RetainedResults.Results.Add(field.Name, userInput);
  1429. }
  1430. }
  1431. catch (Exception e)
  1432. {
  1433. errors.Add("Retained results error: " + e.Message);
  1434. }
  1435. });
  1436. }
  1437. #endregion
  1438. #region Checks / Custom methods
  1439. private void CheckRequired(DFLayoutField field)
  1440. {
  1441. if (field is DFLayoutStringField)
  1442. {
  1443. if ((field as DFLayoutStringField).Properties.Required)
  1444. {
  1445. isRequiredEmpty = true;
  1446. isRequiredMessage = (field as DFLayoutStringField).Description;
  1447. }
  1448. }
  1449. else if (field is DFLayoutIntegerField)
  1450. {
  1451. if ((field as DFLayoutIntegerField).Properties.Required)
  1452. {
  1453. isRequiredEmpty = true;
  1454. isRequiredMessage = (field as DFLayoutIntegerField).Description;
  1455. }
  1456. }
  1457. else if (field is DFLayoutDoubleField)
  1458. {
  1459. if ((field as DFLayoutDoubleField).Properties.Required)
  1460. {
  1461. {
  1462. isRequiredEmpty = true;
  1463. isRequiredMessage = (field as DFLayoutIntegerField).Description;
  1464. }
  1465. }
  1466. }
  1467. else if (field is DFLayoutBooleanField)
  1468. {
  1469. if ((field as DFLayoutBooleanField).Properties.Required)
  1470. {
  1471. {
  1472. isRequiredEmpty = true;
  1473. isRequiredMessage = (field as DFLayoutBooleanField).Description;
  1474. }
  1475. }
  1476. }
  1477. else if (field is DFLayoutDateField)
  1478. {
  1479. if ((field as DFLayoutDateField).Properties.Required)
  1480. {
  1481. {
  1482. isRequiredEmpty = true;
  1483. isRequiredMessage = (field as DFLayoutDateField).Description;
  1484. }
  1485. }
  1486. }
  1487. else if (field is DFLayoutTimeField)
  1488. {
  1489. if ((field as DFLayoutTimeField).Properties.Required)
  1490. {
  1491. {
  1492. isRequiredEmpty = true;
  1493. isRequiredMessage = (field as DFLayoutTimeField).Description;
  1494. }
  1495. }
  1496. }
  1497. else if (field is DFLayoutOptionField)
  1498. {
  1499. if ((field as DFLayoutOptionField).Properties.Required)
  1500. {
  1501. {
  1502. isRequiredEmpty = true;
  1503. isRequiredMessage = (field as DFLayoutOptionField).Description;
  1504. }
  1505. }
  1506. }
  1507. else if (field is DFLayoutLookupField)
  1508. {
  1509. if ((field as DFLayoutLookupField).Properties.Required)
  1510. {
  1511. {
  1512. isRequiredEmpty = true;
  1513. isRequiredMessage = (field as DFLayoutLookupField).Description;
  1514. }
  1515. }
  1516. }
  1517. else if (field is DFLayoutSignaturePad)
  1518. {
  1519. if ((field as DFLayoutSignaturePad).Properties.Required)
  1520. {
  1521. {
  1522. isRequiredEmpty = true;
  1523. isRequiredMessage = (field as DFLayoutSignaturePad).Description;
  1524. }
  1525. }
  1526. }
  1527. else if (field is DFLayoutEmbeddedImage)
  1528. {
  1529. if ((field as DFLayoutEmbeddedImage).Properties.Required)
  1530. {
  1531. {
  1532. isRequiredEmpty = true;
  1533. isRequiredMessage = (field as DFLayoutEmbeddedImage).Description;
  1534. }
  1535. }
  1536. }
  1537. else if (field is DFLayoutMultiImage)
  1538. {
  1539. if ((field as DFLayoutMultiImage).Properties.Required)
  1540. {
  1541. {
  1542. isRequiredEmpty = true;
  1543. isRequiredMessage = (field as DFLayoutMultiImage).Description;
  1544. }
  1545. }
  1546. }
  1547. else if (field is DFLayoutMultiSignaturePad)
  1548. {
  1549. if ((field as DFLayoutMultiSignaturePad).Properties.Required)
  1550. {
  1551. {
  1552. isRequiredEmpty = true;
  1553. isRequiredMessage = (field as DFLayoutMultiSignaturePad).Description;
  1554. }
  1555. }
  1556. }
  1557. }
  1558. private string ImagesToBase64(List<Image> images)
  1559. {
  1560. List<string> strings = new List<string>();
  1561. foreach (Image image in images)
  1562. {
  1563. strings.Add(ImageSourceToBase64(image.Source));
  1564. }
  1565. return Serialization.Serialize(strings);
  1566. }
  1567. private string ImageSourceToBase64(ImageSource source)
  1568. {
  1569. StreamImageSource streamImageSource = (StreamImageSource)source;
  1570. System.Threading.CancellationToken cancellationToken = System.Threading.CancellationToken.None;
  1571. Task<Stream> task = streamImageSource.Stream(cancellationToken);
  1572. Stream stream = task.Result;
  1573. byte[] bytes = new byte[stream.Length];
  1574. stream.Read(bytes, 0, bytes.Length);
  1575. string s = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
  1576. return s;
  1577. }
  1578. private string FindIDForDesignLookupField(DataButtonControl button)
  1579. {
  1580. try
  1581. {
  1582. string userInputValue = button.Data;
  1583. string guidString = "";
  1584. if (userInputValue != nullOrInvalidType)
  1585. {
  1586. foreach (KeyValuePair<DFLayoutLookupField, Dictionary<Guid, string>> pair in dfLayoutLookupFieldLookupOptions)
  1587. {
  1588. foreach (KeyValuePair<Guid, string> innerPair in pair.Value)
  1589. {
  1590. if (innerPair.Value == userInputValue)
  1591. {
  1592. guidString = innerPair.Key.ToString();
  1593. }
  1594. }
  1595. }
  1596. }
  1597. return guidString;
  1598. }
  1599. catch
  1600. {
  1601. return "";
  1602. }
  1603. }
  1604. #endregion
  1605. #region Save Completion
  1606. //point of determination for whether or not QA form gets completed or saved for later
  1607. private void UpdateInstanceAndModel(bool saveForLater)
  1608. {
  1609. if (results.Count != 0)
  1610. {
  1611. if (!saveForLater)
  1612. {
  1613. CompleteForm();
  1614. }
  1615. model.Instance.FormCompletedBy.ID = userID;
  1616. if (digitalFormID != Guid.Empty) model.Instance.Form.ID = digitalFormID;
  1617. model.Instance.FormData = Serialization.Serialize(results);
  1618. FormData = model.Instance.FormData;
  1619. if (model.Instance.FormStarted == DateTime.MinValue)
  1620. {
  1621. model.Instance.FormStarted = timeStarted;
  1622. }
  1623. TimeSpan span = DateTime.Now - timeStarted;
  1624. model.Instance.FormOpen = model.Instance.FormOpen + span;
  1625. model.Update(null);
  1626. }
  1627. }
  1628. private void CompleteForm()
  1629. {
  1630. model.Instance.FormCompleted = DateTime.Now;
  1631. FormCompleted = model.Instance.FormCompleted;
  1632. model.Instance.Location.Longitude = location.Longitude;
  1633. model.Instance.Location.Latitude = location.Latitude;
  1634. model.Instance.Location.Timestamp = model.Instance.FormCompleted;
  1635. }
  1636. #endregion
  1637. #endregion
  1638. #region Expressions
  1639. public object GetFieldValue(string field)
  1640. {
  1641. try
  1642. {
  1643. Tuple<DFLayoutField, View> tuple = FindView(field);
  1644. return GetValueFromView(tuple.Item1, tuple.Item2);
  1645. }
  1646. catch
  1647. {
  1648. return "";
  1649. }
  1650. }
  1651. public void SetFieldValue(string field, object value)
  1652. {
  1653. try
  1654. {
  1655. Tuple<DFLayoutField, View> tuple = FindView(field);
  1656. SetValueOfView(tuple.Item1, tuple.Item2, value);
  1657. }
  1658. catch { }
  1659. }
  1660. private void SetValueOfView(DFLayoutField field, View view, object value)
  1661. {
  1662. if (field is DFLayoutBooleanField)
  1663. (view as CustomBoolean).Value = (bool)value;
  1664. else if (field is DFLayoutStringField || field is DFLayoutIntegerField || field is DFLayoutDoubleField)
  1665. (view as Editor).Text = value.ToString();
  1666. else if (field is DFLayoutDateField)
  1667. (view as DatePicker).Date = (DateTime)(value as DateTime?);
  1668. else if (field is DFLayoutDateTimeField)
  1669. (view as TimePicker).Time = (TimeSpan)(value as TimeSpan?);
  1670. else if (field is DFLayoutOptionField)
  1671. AssignPickerOption(view, field as DFLayoutOptionField, value as string);
  1672. else if (field is DFLayoutLookupField)
  1673. AssignLookupOption(view, value as string);
  1674. }
  1675. private void AssignLookupOption(View view, string value)
  1676. {
  1677. if (view is DataButtonControl)
  1678. {
  1679. (view as DataButtonControl).Text = value;
  1680. (view as DataButtonControl).Data = value;
  1681. }
  1682. else if (view is FrameButton) //currently only used for Products - we already have the Product.ID in Framebutton.Data (saved as Code,ID)
  1683. {
  1684. (view as FrameButton).SetButtonText(value);
  1685. (view as FrameButton).Data = value + "," + Guid.Empty.ToString();
  1686. }
  1687. }
  1688. private Tuple<DFLayoutField, View> FindView(string field)
  1689. {
  1690. DFLayoutField dflayoutfield = pairs.Keys.FirstOrDefault(x => x.Name == field);
  1691. View view = pairs[dflayoutfield];
  1692. return new Tuple<DFLayoutField, View>(dflayoutfield, view);
  1693. }
  1694. private void AssignPickerOption(View view, DFLayoutOptionField field, string value)
  1695. {
  1696. string s = field.Properties.Options;
  1697. string[] substrings = s.Split(',');
  1698. var optionList = substrings.ToList();
  1699. if (GlobalVariables.DeviceString == "i" || GlobalVariables.DeviceString == "I")
  1700. {
  1701. var iOSPicker = view as CustomPickeriOS;
  1702. iOSPicker.SelectedIndex = optionList.IndexOf(value);
  1703. }
  1704. else
  1705. {
  1706. var picker = view as Picker;
  1707. picker.SelectedIndex = optionList.IndexOf(value);
  1708. }
  1709. }
  1710. private object GetValueFromView(DFLayoutField field, View view)
  1711. {
  1712. if (field is DFLayoutBooleanField)
  1713. return (view as CustomBoolean).Value;
  1714. if (field is DFLayoutStringField)
  1715. return (view as Editor).Text;
  1716. else if (field is DFLayoutIntegerField)
  1717. return int.Parse((view as Editor).Text);
  1718. else if (field is DFLayoutDoubleField)
  1719. return double.Parse((view as Editor).Text);
  1720. else if (field is DFLayoutDateField)
  1721. return (view as DatePicker).Date;
  1722. else if (field is DFLayoutDateTimeField)
  1723. return (view as TimePicker).Time;
  1724. else if (field is DFLayoutOptionField)
  1725. return GetStringFromOptionField(view);
  1726. else if (field is DFLayoutLookupField)
  1727. return GetStringFromLookupField(view);
  1728. else if (field is DFLayoutSignaturePad)
  1729. return GetByteArrayFromSignaturePad(view, field.Name);
  1730. else if (field is DFLayoutEmbeddedImage)
  1731. return GetByteArrayFromEmbeddedImage(view);
  1732. else if (field is DFLayoutMultiImage)
  1733. return GetByteArrayListFromMultiImage(view);
  1734. else return "";
  1735. }
  1736. private object GetByteArrayListFromMultiImage(View view)
  1737. {
  1738. List<byte[]> list = new List<byte[]>();
  1739. var multiImage = view as MultiImageCapture;
  1740. if (multiImage.Images.Count > 0)
  1741. {
  1742. foreach (Image image in multiImage.Images)
  1743. {
  1744. string base64 = ImageSourceToBase64(image.Source);
  1745. list.Add(Convert.FromBase64String(base64));
  1746. }
  1747. }
  1748. return list;
  1749. }
  1750. private object GetByteArrayFromEmbeddedImage(View view)
  1751. {
  1752. var embeddedImage = view as EmbeddedImageCapture;
  1753. if (embeddedImage.Image.Source != null)
  1754. {
  1755. string base64 = ImageSourceToBase64(embeddedImage.Image.Source);
  1756. return Convert.FromBase64String(base64);
  1757. }
  1758. else
  1759. return null;
  1760. }
  1761. private byte[] GetByteArrayFromSignaturePad(View view, string name)
  1762. {
  1763. var grid = view as Grid;
  1764. var signaturePad = grid.Children.OfType<SfSignaturePad>().FirstOrDefault();
  1765. if (useSavedSignatures.Contains(name))
  1766. {
  1767. return Application.Current.Properties["SavedSignature"] as byte[];
  1768. }
  1769. else
  1770. {
  1771. signaturePad.Save();
  1772. if (signaturePad.ImageSource != null)
  1773. {
  1774. string base64 = ImageSourceToBase64(signaturePad.ImageSource);
  1775. return Convert.FromBase64String(base64);
  1776. }
  1777. else
  1778. return null;
  1779. }
  1780. }
  1781. private object GetStringFromLookupField(View view)
  1782. {
  1783. string value = "";
  1784. if (view is DataButtonControl)
  1785. {
  1786. var button = view as DataButtonControl;
  1787. value = FindIDForDesignLookupField(button); //userinput is used to set guid later on for properties, but will not get added to form data only for lookupfields
  1788. }
  1789. else if (view is FrameButton) //currently only used for Products - we already have the Product.ID in Framebutton.Data (saved as Code,ID)
  1790. {
  1791. FrameButton framebutton = view as FrameButton;
  1792. if (!string.IsNullOrWhiteSpace(framebutton.Data))
  1793. {
  1794. string[] buttonData = framebutton.Data.Split(',');
  1795. value = buttonData[1]; //[1] is product id as string
  1796. }
  1797. }
  1798. return value;
  1799. }
  1800. private string GetStringFromOptionField(View view)
  1801. {
  1802. if (GlobalVariables.DeviceString == "i" || GlobalVariables.DeviceString == "I")
  1803. {
  1804. var iOSPicker = view as CustomPickeriOS;
  1805. if (iOSPicker.SelectedIndex != -1)
  1806. {
  1807. return iOSPicker.SelectedItem.ToString();
  1808. }
  1809. else
  1810. return "";
  1811. }
  1812. else
  1813. {
  1814. var picker = view as Picker;
  1815. if (picker.SelectedIndex != -1)
  1816. {
  1817. return picker.SelectedItem.ToString();
  1818. }
  1819. else
  1820. return "";
  1821. }
  1822. }
  1823. public object GetFieldData(string fieldName, string dataField)
  1824. {
  1825. return new object();
  1826. }
  1827. #endregion
  1828. }
  1829. }