jQWidgets Forums
jQuery UI Widgets › Forums › ASP .NET MVC › ASP.NET Core with Javascript
Tagged: grid tag helper
This topic contains 13 replies, has 3 voices, and was last updated by Pietervk 7 years, 10 months ago.
-
Author
-
Hi Peter,
I am trying to have server processing and paging using Javascript only (so no Tag Helpers). I have come a long way in implementing this. Looking at your ASP.NET Core Tag Helper demo, you are submitting the parameters combined in one JSON string, to avoid issues with model binding on the controller:[HttpPost] public string GetPageData(string jsonData) { JToken token = JObject.Parse(jsonData);
What I need is to understand how I can combine the outgoing parameters in a JSON string as in the Tag Helper example. Can you help me with this?
Thanks
Pieter
Hi Pieter,
Thanks for contacting us. My colleagues here in the office feel happy that you wrote my name so they can skip that topic 🙂
I suggest you to look at our ASP .NET demos which demonstrate that process with Javascript. In the tag helpers, these things are built-in.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
you seem to be the most active person, so your colleagues can only try to compete 🙂ASP.NET Core has a different type of model binding. On a Post, you can only supply one parameter: a model or a simple type. That is why, in the Tag Helper version, you take the filterGroups, pageSize, pageNum, sortField and sortOrder and serialise them all in one string, which is what I need to do as well. The other demo’s don’t do that.
I assume there is an event of some sort that you react to, and then stringify the arguments.The tag helpers are very nice when the integration in Javascript is either not needed or simple. In more complex case, they do not cover the complete functionality. For example I want to change the column layout depending on the page size. And I want to invoke the databinding every 30s. And I have multiple things going on depending on the selected row. All of this is working in my javascript code now, but without an answer to my question here, I can’t implement server processing.
Thanks,
PieterHi Pieter,
You can still use Javascript with the asp .net mvc tag helpers, too. For example, you have access to the Grid’s instance and so to the Grid’s methods. Anyway, with pure javascript, you can use the dataAdapter’s formatData callback function to send additional params to the server. For more info, visit: http://www.jqwidgets.com/community/topic/asp-net-core-with-javascript/
Hope this helps.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comHi Peter,
unfortunately, I am not looking how to add additional parameters, but how to combine them. If it helps, I can raise a formal incident, so one of the developers can take a deeper look into this?Thanks
Pieter
Well, I got the Tag Helpers working as I want. I know documentation is not high on the list of any developer, but can I vote for more information? There are many undocumented parameters, some obvious, some keep you guessing. I love how the jqxWidgets work, but trial and error discovering the capabilities is not ideal.
Thanks for your help Peter
Hi Pieter,
What kind of information are you looking for and which params are not documented?
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comWell for starters, the DataAdapter only has a getting started, but no API reference documentation like the other widgets.
For the TagHelpers, I found this:
That is a nice overview, but there is no API reference here either. The descriptions are pointers, more than descriptions. Like:
sourceId – {{String}} which determines the data source’s ID member.
sourceId-for – {{ModelExpression}} used for model binding and determines the data source’s ID member.I have no idea what the second line means, it is too short (for me). I know what model binding is, but sourceId also determines the data source’s ID member. It seems to work when you omit sourceId-for.
In the JavaScript version, I had some datafields that I did not include as columns, so I could get the content when a row is selected. Trying to find how to do this with TagHelpers, I found an undocumented attribute “hidden” which seems to do the job. There are many other attributes that are not documented. There is also a “Hideable” attribute, interesting, but what does it do?
Looking at the demo sourcecode, the model gets first filled with all Employees, and then in the view you have:
@{ var employee = Model.FirstOrDefault(); }
Which takes only the first employee, and than passes on the var employee in source-model=”employee”.
I tried filling the model with only the first page worth of data, but that does not work. So in spite of have server processing, you still need to first provide the whole dataset?Kind regards,
PieterPietervk, the dataAdapter’s API is listed in the getting started. It does not need to have duplicated topic. I suggest you to see the Grid’s API documentation about columns, because these attributes are already documented. Also you don’t need to provide the full data set. As you see the Grid’s tag helper demos have server paging – http://aspcore.jqwidgets.com/mvc/TagHelpers/GridServerPaging/light
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comPeter,
this is the controller method used in the demo:public ActionResult GridServerEditPagingSortingFiltering(string theme) { ViewData["Theme"] = theme; return View("Grid/GridServerPaging", _context.SalesEmployees.ToList()); }
This supplies all employees to the model. I tried it with supplying only 10 records, but then the grid does not get the total number of records. After paging it does, as this is supplied in the JSONData model that is returned from GetPageData. But if I do not supply the total number of records initially as done in the demo, the grid thinks it only has 10 rows, so it does not want to page.
I found the columns documentation, thank you.
May I jump in (I am not quite expert but I did spent a lot time implmentig servr side paging using jqwidgets).
But if I do not supply the total number of records initially as done in the demo, the grid thinks it only has 10 rows, so it does not want to page.
If you download jqerywidgets under
C:\jquery\jqwidgets-ver4.5.0\demos\asp.net-core-mvc-tag-helpers
there is controller whih methodpublic string GetPageData(string jsonData) { //lot of code /in th end JSONData data = new JSONData(); data.TotalRecords = allEmployees.Count; data.Employees = employees; return JsonConvert.SerializeObject(data); }
you see data total records that is param whic tells GridHelper how many record do you have.
This is quite good working when grid preforms remootlyThanks Adopilot,
I had a capitalization issue with TotalRecords. In source, I havebeforeprocessing: function (data) { source.totalrecords = data.TotalRecords; },
The second TotalRecords should be capatilized as shown here.
For some reason it works when pageing, but it did not work when filling the initial grid with less than the full number. As the demo also fills the grid with the full data set, I got confused.
Do you have experience with the sql query? I now use Fetch to only get the 10 records that are needed. But the timing I see does not make a whole lot of difference when fetching the whole set, and then filtering them server side as the ASP.NET Core example is doing. There is an improvement in speed and network bandwith compared to filtering the page client side.
For sql I try two approaches:
When using linq langine by skip and take arguments.
And for total records showing total record of table.
That works when grid shows full table in grid and when ther is not filters.For paging with filters I do sql like this
ALTER PROCEDURE [dbo].[grid_docs] @page_size int = 10 ,@page_num int = 0 ,@sort_dir varchar(10) ='desc' ,@sort varchar(100) = 'id' ,@valutaId int =null AS BEGIN set transaction isolation level read uncommitted; SET NOCOUNT ON; select redova , id , datum , skladiste_id , mjenjacnica , tipDokumenta , broj , serija , valutaId , valutaOznaka , valutaNaziv , uValuti , uBam , korisnik from ( select redova =count(*) over (partition by 1) ,rwn = ROW_NUMBER() over (order by case when @sort_dir='DESC' then case when @sort = 'datum' then cast( cast(MJE_DOC.DATUM AS int) as varchar(30)) when @sort = 'mjenjacnica' then SKLADISTE.SIFRA when @sort = 'tipDokumenta' then MJE_DOC.TIP when @sort = 'broj' then MJE_DOC.BROJ when @sort = 'serija' then MJE_DOC.serija when @sort = 'valutaOznaka' then mje_valute.oznaka_valute when @sort = 'valutaNaziv' then mje_valute.zemlja_valute when @sort = 'uValuti' then cast(round(mje_doc.iznos_u_valuti,0) AS VARCHAR(30)) when @sort = 'uBam' then cast(round(mje_doc.iznos_u_bam,0) AS VARCHAR(30)) when @sort = 'user' then mje_users.name end end desc, case when @sort_dir='ASC' then case when @sort = 'datum' then cast( cast(MJE_DOC.DATUM AS int) as varchar(30)) when @sort = 'mjenjacnica' then SKLADISTE.SIFRA when @sort = 'tipDokumenta' then MJE_DOC.TIP when @sort = 'broj' then MJE_DOC.BROJ when @sort = 'serija' then MJE_DOC.serija when @sort = 'valutaOznaka' then mje_valute.oznaka_valute when @sort = 'valutaNaziv' then mje_valute.zemlja_valute when @sort = 'uValuti' then cast(round(mje_doc.iznos_u_valuti,0) AS VARCHAR(30)) when @sort = 'uBam' then cast(round(mje_doc.iznos_u_bam,0) AS VARCHAR(30)) when @sort = 'user' then mje_users.name end end ) ,id = mje_doc.id ,datum = mje_doc.datum ,skladiste_id = mje_doc.skladiste_id ,mjenjacnica = SKLADISTE.SIFRA+ ' '+SKLADISTE.NAZIV ,tipDokumenta = mje_dokumenti.tip ,broj = mje_doc.broj ,serija = mje_doc.serija ,valutaId = mje_doc.valuta_id ,valutaOznaka = mje_valute.oznaka_valute ,valutaNaziv = mje_valute.zemlja_valute ,uValuti = mje_doc.iznos_u_valuti ,uBam = mje_doc.iznos_u_bam ,korisnik = mje_users.name+' '+mje_users.surname from mje_doc where (@valutaId is null or mje_doc.valuta_id = @valutaId) ) as engin where rwn > @page_num*@page_size and rwn <= @page_num*@page_size+@page_size
Here I do select of select in first select I do select all data without paging and do count(*) over (partition by 1) to get total number of records inside where clue when there is no paging applied.
Also I do row_number() in combination whit case so in next query I can take only records that is on current page.When I initaly wrote this it was slow then I put it on sql execution plans and make index covering my select from table and now it works pretty fast on table whit 263K records.
if you make sql fillde whit scema I can try to hepl you write sql
Hi Admir,
thanks for the additional information. As I do not get an email when someone posts on this forum, I did not see your post earlier, which is unfortunate.Since some of the data that needs to be sorted or filtered needs to be decrypted first, I can’t use a SQL query. However, when I did some tests earlier, I found that it does not really make a difference when you sort and filter in the query, or whether you do that in the server code. It makes a huge difference in user perceived performance when the paging is handled server side (virtual mode) compared to client side.
Below the code I use to filter the items server side. The code is reusable. It accepts the jsonData coming from the grid query, and a list of row classes. It returns a filtered list of classes, and in the ref count parameter, the total number of records.
public static List<T> FilterItems<T>(string jsonData, List<T> allItems, ref int count) { int pageSize = 10; int pageNum = 0; if (jsonData != "{}") { JToken token = JObject.Parse(jsonData); List<JToken> filterGroups = token.SelectToken("filterGroups").Children().ToList(); pageSize = (int)token.SelectToken("pagesize"); pageNum = (int)token.SelectToken("pagenum"); string sortField = (string)token.SelectToken("sortdatafield") ?? ""; string sortOrder = (string)token.SelectToken("sortorder") ?? ""; //filter all items of class T in the List<T> allItems if (sortField != "") { if (sortOrder == "asc") { allItems = (from p in allItems orderby (p.GetType().GetProperty(sortField).GetValue(p)) select p).ToList(); } else if (sortOrder == "desc") { allItems = (from p in allItems orderby (p.GetType().GetProperty(sortField).GetValue(p)) descending select p).ToList(); } } if (filterGroups.Count > 0) { List<T> filteredItems = allItems; for (int j = 0; j < filterGroups.Count; j++) { List<JToken> filters = filterGroups[j].SelectToken("filters").Children().ToList(); List<T> filterGroup = filteredItems; List<T> filterGroupResult = new List<T>(); for (int i = 0; i < filters.Count; i++) { string filterLabel = (string)filters[i].SelectToken("label"); string filterValue = (string)filters[i].SelectToken("value"); string filterDataField = (string)filters[i].SelectToken("field"); string filterCondition = (string)filters[i].SelectToken("condition"); string filterType = (string)filters[i].SelectToken("type"); string filterOperator = (string)filters[i].SelectToken("operator"); List<T> currentResult = new List<T>(); switch (filterCondition) { case "NOT_EMPTY": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)) != null) select p).ToList(); break; case "NOT_NULL": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString() != "") select p).ToList(); break; case "NULL": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)) == null) select p).ToList(); break; case "EMPTY": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString() == "") select p).ToList(); break; case "CONTAINS_CASE_SENSITIVE": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().Contains(filterValue)) select p).ToList(); break; case "CONTAINS": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().IndexOf(filterValue, StringComparison.CurrentCultureIgnoreCase) != -1) select p).ToList(); break; case "DOES_NOT_CONTAIN_CASE_SENSITIVE": currentResult = (from p in filterGroup where (!(p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().Contains(filterValue)) select p).ToList(); break; case "DOES_NOT_CONTAIN": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().IndexOf(filterValue, StringComparison.CurrentCultureIgnoreCase) == -1) select p).ToList(); break; case "EQUAL_CASE_SENSITIVE": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString() == filterValue) select p).ToList(); break; case "EQUAL": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().IndexOf(filterValue, StringComparison.CurrentCultureIgnoreCase) == 0) select p).ToList(); break; case "NOT_EQUAL_CASE_SENSITIVE": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString() != filterValue) select p).ToList(); break; case "NOT_EQUAL": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().IndexOf(filterValue, StringComparison.CurrentCultureIgnoreCase) != 0) select p).ToList(); break; case "GREATER_THAN": currentResult = (from p in filterGroup where (float.Parse(p.GetType().GetProperty(filterDataField).GetValue(p).ToString()) > float.Parse(filterValue)) select p).ToList(); break; case "LESS_THAN": currentResult = (from p in filterGroup where (float.Parse(p.GetType().GetProperty(filterDataField).GetValue(p).ToString()) < float.Parse(filterValue)) select p).ToList(); break; case "GREATER_THAN_OR_EQUAL": currentResult = (from p in filterGroup where (float.Parse(p.GetType().GetProperty(filterDataField).GetValue(p).ToString()) >= float.Parse(filterValue)) select p).ToList(); break; case "LESS_THAN_OR_EQUAL": currentResult = (from p in filterGroup where (float.Parse(p.GetType().GetProperty(filterDataField).GetValue(p).ToString()) <= float.Parse(filterValue)) select p).ToList(); break; case "STARTS_WITH_CASE_SENSITIVE": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().StartsWith(filterValue)) select p).ToList(); break; case "STARTS_WITH": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().StartsWith(filterValue, StringComparison.CurrentCultureIgnoreCase)) select p).ToList(); break; case "ENDS_WITH_CASE_SENSITIVE": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().EndsWith(filterValue)) select p).ToList(); break; case "ENDS_WITH": currentResult = (from p in filterGroup where ((p.GetType().GetProperty(filterDataField).GetValue(p)).ToString().EndsWith(filterValue, StringComparison.CurrentCultureIgnoreCase)) select p).ToList(); break; } if (filterOperator == "or") { filterGroupResult.AddRange(currentResult); } else { filterGroup = currentResult; filterGroupResult = currentResult; } } filteredItems = filterGroupResult; } allItems = filteredItems; } } count = allItems.Count; List<T> items = new List<T>(); int startpageindex = pageNum * pageSize; int pagecount = (startpageindex + pageSize <= count) ? pageSize : count - startpageindex; items = allItems.GetRange(startpageindex, pagecount); return items; }
This is Controller method called by the grid as defined in the source object:
[HttpGet] public async Task<string> getUsers([FromQuery] string jsonData) { List<StateUser> allUsers = await GetUserList(); //get a list of objects that we want displayed in the grid int count = 0; StateUserData stateUserData = new StateUserData() { Tests = FilterItems(jsonData, allUsers , ref count), //filter the data TotalRecords = count }; return JsonConvert.SerializeObject(stateUserData ); }
-
AuthorPosts
You must be logged in to reply to this topic.