Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Simon Dingley 1470 posts 3427 karma points c-trib
    Nov 26, 2015 @ 12:52
    Simon Dingley
    0

    Expose Data Held in Grid Editor Control

    We have a site in which a whole bunch of custom Grid Editors have been developed for the site editors. One of which is a map editor and stores sizeable blobs of JSON mapping data. This data needs to be pulled into the public facing page(s) on request and so I'm looking for some ideas on how best to approach this.

    My first thought was to write an API controller that would essentially take a nodeId and JSON path for the control and attempt to navigate through a Grid JSON object to pull out the data required. On further thought this potentially could expose more than just the required data.

    Am I over-thinking this and is there a more obvious solution?

    Thanks, Simon

  • Carl Jackson 139 posts 478 karma points
    Nov 26, 2015 @ 13:03
    Carl Jackson
    0

    Hi Simon.

    If you are not outputting the map into a grid..... Why is it in a grid editor again? :)

    The grid editor is quite specific in the way data is stored and traversed in a hierarchical way. Looking at the bootstrap grid view file will show you how the data is normally iterated over.

    You could maybe use this with some strategically placed "if" statements to get the data you want?

    If you know linq, you could get the data out of the Jobject (same as in the view) with a linq query? http://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm

    Thanks

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Nov 26, 2015 @ 13:14
    Simon Dingley
    0

    Hi Carl,

    If you are not outputting the map into a grid..... Why is it in a grid editor again? :)

    It IS being output into a grid however the data is being used to render heatmaps for 5+ years of data, the map needs to load with only the current year and the user then selects alternate years and only then do we want to load the other years data but ideally without posting back to the server. At the moment we are spitting out a huge chunk of data into the page for just a single year, loading in all of the other years is just not viable due to the size.

    The following gets me pretty much to where I need to in terms of navigating the Grid JSON:

    [PluginController("MyPlugin")]
    public class JsonApiController : UmbracoApiController
    {
        public JObject GetHeatMapData(int nodeId, string path)
        {
            IPublishedContent node = Umbraco.TypedContent(nodeId);
            var grid = JObject.Parse(node.GetPropertyValue<string>("Grid"));
    
            return (JObject)grid.SelectToken(path);
        }
    }
    

    This can then be called via jQuery or similar simply using the url format:

    http://localhost:0000/umbraco/MyPlugin/jsonapi/GetHeatMapData?nodeid=1074&path=sections[1].rows[0].areas[0].controls[4]
    

    The problem is that this could potentially be abused and expose other data just by manipulating the path.

    Simon

  • Carl Jackson 139 posts 478 karma points
    Nov 26, 2015 @ 15:53
    Carl Jackson
    0

    I think the scope for abuse is limited. it can only return json data from within the grid property (which I imagine is meant for public consumption anyway?)

    You could lock it down by document type?

    if(node.ContentType.Alias == "mapPageType")

    Or an you just hard code the path (or a few if you need more than one which can be aliased with a switch statement)?

  • Simon Dingley 1470 posts 3427 karma points c-trib
    Nov 27, 2015 @ 08:15
    Simon Dingley
    0

    I couldn't hard code any paths because editors can insert grid editors anywhere on the grid, the heatmaps can be inserted on any page with a grid.

  • Carl Jackson 139 posts 478 karma points
    Nov 26, 2015 @ 15:58
    Carl Jackson
    0

    Sorry I see why the path needs to be dynmic.

    However each control has an editor alias (can't exactly remember the property) but something like

    var control = (JObject)grid.SelectToken(path);
    
    if(control.EditorAlias == "mapEditor"){
        return control;
    }
    return null;
    
  • Simon Dingley 1470 posts 3427 karma points c-trib
    Nov 27, 2015 @ 08:13
    Simon Dingley
    101

    I finally managed to get this working yesterday and my code is as follows:

    IPublishedContent node = Umbraco.TypedContent(nodeId);
    var grid = JObject.Parse(node.GetPropertyValue<string>("Grid"));
    
    var ctrl = grid.SelectTokens("..editor").FirstOrDefault(v => v.SelectToken("alias").ToString() == "MyPlugin.HeatMap")?.Parent.Parent;
    
    var ctrlData = ctrl.SelectToken("value");
    

    I am sure there must be a more elegant solution but this works for now in order to meet my deadline.

    Thanks, Simon

Please Sign in or register to post replies

Write your reply to:

Draft