[CLOSED] ComboBox with Templates and AJAX

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] ComboBox with Templates and AJAX

    Hi!
    Could you please create an example corresponding to this one?
    ComboBox with Templates and AJAX

    I'm trying with Razor POST, but Paging<T> is missing.
    I cannot find an Ajax Proxy sample, so I have problems with URL property as well.

    here is my non-working code - I'm trying to set all in codebehind.

    public ComboBox GetCombo()
            {
                var cbo = new ComboBox()
                {
                    DisplayField = "Common",
                    ValueField = "Botanical",
                    Width = 200,
                    PageSize = 10,
                    TypeAhead = false,
                    HideTrigger = true,
                    MinChars = 2,
                    TriggerAction = "Query"
                };
    
                // Store
                var s = new Store
                {
                    PageSize = 15,
                    ModelValue = new Model()
                    {
                        Fields = new List<DataField>
                        {
                            new DataField() { Name = "Common", Type = DataFieldType.String },
                            new DataField() { Name = "Botanical", Type = DataFieldType.String }
                        }
                    }
                };
    
                s.Proxy = new AjaxProxy()
                {
                    ActionMethods = new CRUDModel() { Read = "POST" },
                    Url = "?handler=GetPlants"
                };
    
                cbo.Store = s;
    
                return cbo;
    
            }
    Even in page I'm missing the ListConfig tag helper and I don't know how to set it (but I prefer to work in .cshtml.cs files).

    I tried to use a standard combobox with a local store without any success, but sad consolation, neither yours is working in this example https://examples.ext.net/#/kitchen_sink/forms/register

    If you want to update Example Explorer Project I can download it from github.

    Thank you very much, any hint is much appreciated.
    Last edited by fabricio.murta; Feb 01, 2021 at 11:04 PM.
  2. #2
    Just about a standard ComboBox
    ...for autocomplete I create a new post down here...

    QueryMode needs to be local instead of Local

    Here is the working code :)

    .cshtml

    <ext-section target="Main">
        <ext-container region="Center" scrollable="true" paddingAsString="30 20 30 50">
            <items>
                <ext-combobox model="Model.comboBox" />
            </items>
        </ext-container>
    </ext-section>
    .cshtml.cs

       public ComboBox comboBox { get; set; }
    
            public void OnGet()
            {
                comboBox = GetCombo();
            }
    
            public ComboBox GetCombo()
            {
                var cbo = new ComboBox()
                {
                    Id = "SampleId",
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "local",
                    EmptyText = "Select here..."
                };
    
                // Store
                var s = new Store
                {
                    PageSize = 15,
                    ModelValue = new Model()
                    {
                        Fields = new List<DataField>
                        {
                            new DataField() { Name = "id", Type = DataFieldType.Int },
                            new DataField() { Name = "text", Type = DataFieldType.String }
                        }
                    },
                    Data = new List<object>()
                    {
                        new Sample() { id = 1, text = "Pippo"},
                        new Sample() { id = 2, text = "Pluto"},
                        new Sample() { id = 3, text = "Paperino"}
                    }
                };
    
                cbo.Store = s;
    
                return cbo;
    
            }
    
            public class Sample
            {
                public int id { get; set; }
                public string text { get; set; }
            }
        }
    }
    Last edited by bbros; Jan 28, 2021 at 9:21 AM.
  3. #3
    Autocomplete ComboBox
    ...Still missing the html template...

    I have been able to have a working Autocomplete feature, I just need to know if this is the best practice.

    I used a API REST Controller with the GetData method.

    GetDataController.cs

    using Ext.Net.Core;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace BBros.Oggun.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class GetDataController : ControllerBase
        {
            // POST api/<GetDataController>
            [HttpPost]
            public IEnumerable<object> Post(int start, int limit, int page, string query)
            {
                return new List<object>()
                    {
                        new SampleData() { id = 1, text = "Pippo"},
                        new SampleData() { id = 2, text = "Pluto"},
                        new SampleData() { id = 3, text = "Paperino"}
                    };
            }
            public class SampleData
            {
                public int id { get; set; }
                public string text { get; set; }
            }
        }
    }
    Control generator class

          public static ComboBox GetAutocompleteCombo()
            {
                var cbo = new ComboBox()
                {
                    Id = "SampleAutoId",
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "remote",
                    EmptyText = "Select here...",
                    TriggerAction = "Query"
                };
    
                // Store
                var s = new Store
                {
                    ModelValue = new Model()
                    {
                        Fields = new List<DataField>
                        {
                            new DataField() { Name = "id", Type = DataFieldType.Int },
                            new DataField() { Name = "text", Type = DataFieldType.String }
                        }
                    }             
                };
    
                s.Proxy = new AjaxProxy()
                {
                    ActionMethods = new CRUDModel() { Read = "POST" },
                    Url = "/api/GetData"                
                };
    
                cbo.Store = s;
    
                return cbo;
    
            }
    .cshtml

    <ext-section target="Main">
        <ext-container id="myContainer" region="Center" scrollable="true" paddingAsString="30 20 30 50" model="Model.MyContainer">
        </ext-container>
    </ext-section>
    .cshtml.cs

    namespace BBros.Oggun.Pages
    {
        public class DirectEventsModel : Extreme.DirectEventsPageModel
        {
    
            public Container MyContainer { get; set; }
    
            public void OnGet()
            {
                MyContainer = new Container();
                var acc = Samples.GetAutocompleteCombo();
                MyContainer.Items.Add(acc);
            }
    
        }
    }
    Is it possible for an AjaxProxy to POST the data request to the same PageModel to which the ComboBox is added?
  4. #4
    Hello @BBros!

    Quote Originally Posted by bbros
    Is it possible for an AjaxProxy to POST the data request to the same PageModel to which the ComboBox is added?
    Yes, it definitely is. All you need is to have something like OnPostMyRequestHandler() method in the model class and then call the page/MyRequestHandler.

    I think this is a bit cryptic so maybe this practical example clears it out.

    Check this example containing direct events: Window > Toast > Overview

    In this example, if you click the Toast 2 button, you'll be presented by a server-provided toast command. Look at its source code:

    Markup
    <ext-button onDirectClick="Button2_Click" text="Toast 2" />
    In code behind, there will be a corresponding method:
    public IActionResult OnPostButton2_Click()
    {
        this.X().Toast("Toast 2");
        return this.Direct();
    }
    And if you fiddle with the request (let's put the transmitted payload aside for now), you'll notice it accessed https://examples.ext.net/samples/window/toast/overview/Button2_Click. So it just appended a slash and the action name, removing the heading OnPost word which is but a shorthand for the [HttpPost] attribute.

    With that, you can have as many POST (and other HTTP methods for what it's worth) as you want in a single page / same model.

    For an actual ajax call that is not wrapped in Ext.NET's direct request code, it works pretty much the same, except it is going to return the data you want and not an Ext.NET script to be executed.

    I may have not answered your question, but if the answer above looks like what you wanted, then take a look again in an example we made for you in this post (you may need to follow the link to the github project): Post #2 in GridPanel Editing thread.

    I will give another read to your inquiries so far and respond in next threads what's left unanswered. We should post a follow-up here soon.
    Fabrício Murta
    Developer & Support Expert
  5. #5
    Quote Originally Posted by bbros
    I tried to use a standard combobox with a local store without any success, but sad consolation, neither yours is working in this example https://examples.ext.net/#/kitchen_sink/forms/register
    For this one, I'll tell you how we fixed it.

    This example is based off its v5 equivalent one.

    1. Open v5 examples explorer, click its top-left settings cog and check Debug Mode. The page will refresh.
    2. Browse the Kitchen Sink > Forms > Register example, and click top-right Open (direct) example (makes simple to view the page itself). Click the dialog's Open (direct) button to open it in a dedicated tab.
    3. Open browser debugging tools (F12) and refresh the page
    4. In Sources tab, locate the resource which address reads /extnet-init-js/ in its path
    5. Within the source view, lower left corner, click the { } button to pretty-print the page script source
    6. Navigate down to the combo box definition, you'll see a block like this:

    proxy: {
        type: 'memory',
        reader: {
            type: "array"
        }
    }
    You'll be looking for reader after all, as we want to find out how it is generated by Ext.NET. And usually this result reflects and resembles how Ext.NET 7 should look, as it is more "resembling" the Ext JS raw syntax structure.

    7. Translate this into Ext.NET 7 terms, that is:

    <proxy>
        <ext-memoryProxy>
            <reader>
                <ext-arrayReader />
            </reader>
        </ext-memoryProxy>
    </proxy>
    Voila, the page works!

    A similar hierarchy will be used when you declare it from code behind or Html Helpers. In this case, no CustomConfig needed at all! We have updated the example in the Examples Explorer github project (dev branch).

    In your case, you want an ajax proxy. I believe our last post gives you the right directions into making a proxy "local" to the current page's model (defined within the page's model code).

    -----------------------

    Quote Originally Posted by bbros
    Could you please create an example corresponding to this one? (link)ComboBox with Templates and AJAX
    We can, if you still require it. But maybe you already have all elements to make your page work now?

    -----------------------

    Quote Originally Posted by bbros
    QueryMode needs to be local instead of Local
    Here is the working code :)
    This means you already got it working the way you needed?

    -----------------------

    With this I believe we have at least handled all the points in this thread. Let us know otherwise. We're looking forward to your follow-up!
    Fabrício Murta
    Developer & Support Expert
  6. #6
    Hi, almost all is solved, but there are some changes which make me spend more than 2 days on a ComboBox...
    We really need some more sample, I guess that it's simple for you to complete my code.

    1. I don't know how to set a new Store to the combo during the POST call line 142
    2. MinChars does not work with Change DirectEvent line 102
    3. XTemplate does not have HTML, I guess I did right setting the string value as html since it is nice line 55
    4. AjaxProxy ExtraParams is not a DirectEventParameterCollection, how can I send to the Proxy the primaryBox value? line 85


    I took time for create a complete sample which you can copy and paste into a RazorPage.

    Autocomplete.cshtml
    @page "{handler?}"
    @model ExtCookbook.Pages.AutocompleteModel
    @{
    }
    
    <ext-section target="Main">
        <ext-container region="Center" scrollable="true" paddingAsString="30 20 30 50">
            <content>
                <h1>Autocomplete</h1>
                Type here:
                <ext-comboBox model="Model.primaryBox" />
                Then here:
                <ext-comboBox model="Model.secondaryBox" />
                Combo with template:
                <ext-comboBox model="Model.localStoreBox" />
                Combo with Ajax Proxy:
                <ext-comboBox model="Model.ajaxProxyStoreBox" />
            </content>
        </ext-container>
    </ext-section>
    Autocomplete.cshtml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Threading.Tasks;
    using Ext.Net;
    using Ext.Net.Core;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using MojeeIO;
    
    namespace ExtCookbook.Pages
    {
        public class AutocompleteModel : PageModel
        {
            public ComboBox primaryBox { get; set; }
            public ComboBox secondaryBox { get; set; }
            public ComboBox localStoreBox { get; set; }
            public ComboBox ajaxProxyStoreBox { get; set; }
    
            public void OnGet()
            {
                primaryBox = GetBox();
                secondaryBox = GetBox();
    
                primaryBox.Id = "primaryBox";
                secondaryBox.Id = "secondaryBox";
    
                SetEvent(primaryBox);
                SetEvent(secondaryBox);
    
                //localStoreBox
                localStoreBox = new ComboBox
                {
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "local",
                    EmptyText = "Select here...",
                    Store = new Store()
                    {
                        ModelValue = new Model()
                        {
                            Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String },
                                new DataField() { Name = "sub", Type = DataFieldType.String }
                            }
                        },
                        Data = GetData()
                    },
                    ListConfig = new BoundList
                    {
                        ItemTpl = @"
                                <div>
                                    <b>{text}</b><br />
                                    <font size=-1><i>{sub}</i></font>
                                </div>"
                    }
                };
    
                //Ajax proxy            
                ajaxProxyStoreBox = new ComboBox
                {
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "local",
                    EmptyText = "Select here...",
                    Store = new Store()
                    {
                        ModelValue = new Model()
                        {
                            Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String },
                                new DataField() { Name = "sub", Type = DataFieldType.String }
                            }
                        },
                        Proxy = new AjaxProxy()
                        {
                            ActionMethods = new CRUDModel() { Read = "POST" },
                            Url = "myAjaxProxyUrl"
                        }
                    }
                };
            }
    
            private ComboBox GetBox()
            {
                return new ComboBox
                {
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "remote",
                    EmptyText = "Select here...",
                    TriggerAction = "Query",
                    TypeAhead = true,
                    MinChars = 3,
                    Store = GetNewStore()
                };
            }
    
            private void SetEvent(ComboBox C)
            {
                C.DirectEvents.Change.Url = "/Autocomplete/Combo_Change";
                C.DirectEvents.Change.Method = Ext.Net.Core.HttpMethod.POST;
                C.DirectEvents.Change.ExtraParams.Add(new DirectEventParameter() { Key = "senderId", Value = C.Id, Mode = ParameterMode.Value });
                C.DirectEvents.Change.ExtraParams.Add(new DirectEventParameter() { Key = "query", Value = $"App.{C.Id}.value", Mode = ParameterMode.Raw });
                if (C.Id == secondaryBox.Id) C.DirectEvents.Change.ExtraParams.Add(new DirectEventParameter() { Key = "primary", Value = $"App.{primaryBox.Id}.value", Mode = ParameterMode.Raw });
            }
    
            private Store GetNewStore()
            {
                return new Store()
                {
                    ModelValue = new Model()
                    {
                        Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String }
                            }
                    },
                    Proxy = new MemoryProxy()
                };
            }
    
            private List<object> GetData()
            {
                return new List<object>()
                    {
                        new { id = 1, text = "Pippo", sub = "Dog"},
                        new { id = 2, text = "Pluto", sub = "Dog"},
                        new { id = 3, text = "Paperino", sub = "Duck"}
                    };
            }
    
            public IActionResult OnPostCombo_Change(JsObject jObj)
            {
    
                string senderId = jObj.GetValueOrDefault("senderId").Value.ToString();
                var cbo = this.GetCmp<ComboBox>(senderId);
    
                var query = jObj.GetValueOrDefault("query").Value.ToString();
                if (query.Length >= 3)
                {
                    var s = GetNewStore();
                    s.Data = GetData();
                    cbo.Store = s;
                }
                else
                {
                    var msg = $"You typed less than 3 chars :sleepy:";
                    this.X().Toast(Mojee.Replace(msg));
                }
                return this.Direct();
            }
    
        }
    }
    Thank you again!
    Last edited by bbros; Jan 29, 2021 at 2:06 PM.
  7. #7
    Hello again, @bbros!

    Quote Originally Posted by bbros
    1. I don't know how to set a new Store to the combo during the POST call line 142
    Yes, we have issue #1845 preventing us from nicely dealing with stores from ongoing pages (after initial load). But that's not the end of the world.

    Go ahead and give your store an Id with StoreId = "MyStore" + somethingToMakeIdUnique around your model line 120.

    Then replace lines 151-153 with:

    var dataJson = new StringBuilder();
    using(var writer = new StringWriter(dataJson))
    {
        _serializer.Serialize(new JsObject(GetData()), writer);
    }
    
    this.X().AddScript("App." + recallTheDesiredStoreIdHere + ".setData(" + dataJson + ");");
    You may need to pass the store ID or its unique identifier bit (could be an integer for just MyStore1, MyStore2, or just pass the whole combo's store id in).

    Oh, and the magic to enable this _serializer is to "inject" it in the page. Code-wise, just add this constructor and local variable:

    private ISerializationService _serializer;
    public AutoCompleteModel(ISerializationService serializer)
    {
        _serializer = serializer;
    }
    ASP.NET Core should handle the task of passing this value in.

    You may not really need to wrap GetData() in new JsObject(). Try without it and, if you have issues, adding it may help.




    Quote Originally Posted by bbros
    2. MinChars does not work with Change DirectEvent line 102
    It actually is meant not to affect change event triggering. The MinChars config is related to combo box type ahead and autocomplete queries, not combo box value changes. In that case, I advise you to add a Before= check to avoid costly server round-trips.

    This in your SetEvent() method should perfectly bind the direct method execution with whatever MinChars you set to your combo box:

    C.DirectEvents.Change.Before = "return extraParams.query.length >= this.minChars";



    Quote Originally Posted by bbros
    3. XTemplate does not have HTML, I guess I did right setting the string value as html since it is nice line 55
    This takes me to the issue #1749. It is something we have on sight to fix and I will mention your thread there.

    Your approach looks totally fine and I don't see how it could improve if we are drawing HTML markup from code behind (can't take advantage of syntax highlighting, etc from .cs). The issue would basically improve markup/razor syntax in that regards.




    Quote Originally Posted by bbros
    4. AjaxProxy ExtraParams is not a DirectEventParameterCollection, how can I send to the Proxy the primaryBox value? line 85
    It is indeed not a DirectEventParameterCollection as this is not even a direct event nor a direct method. It is simply a parameter collection. You can pass any list of key-value pair to this, even a (maybe misleading) DirectEventParameterCollection!

    Like (around your line 85):

    ExtraParams = new JsObject(new DirectEventParameterCollection()
    {
        { "ComboName", "primaryBox" }
    })
    or simply an anonymous

    ExtraParams = new JsObject(new []
    {
        new { ComboName = "primaryBox" }
    })
    Notice, though, the casing in the latter block will be converted to lowerCamelCase whereas the former would be maintained:
    - "ComboName", "PrimaryBox" would be output as ComboName: "PrimaryBox" in the first approach
    - ComboName = "PrimaryBox" would be output as comboName: "PrimaryBox" in the first approach

    That is, the string itself won't be touched where object property names would be converted.

    bottomline

    I believe this answers all your inquiries so far? If not, let us know!

    If you think we should have been logging an issue in any of the alternatives provided, let us know as well. I believe all points already have a corresponding issue logged for.
    Fabrício Murta
    Developer & Support Expert
  8. #8
    Thankyou very much for your great support, now I think I can achieve my goals.

    I mis explained myself forgetting a "'s"...
    I would like to send the primaryBox's value App.primaryBox.value via ajax proxy and I don't know how to do.


         //Ajax proxy            
                ajaxProxyStoreBox = new ComboBox
                {
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "remote",
                    EmptyText = "Select here...",
                    TriggerAction = "Query",
                    TypeAhead = true,
                    MinChars = 3,
                    Store = new Store()
                    {
                        ModelValue = new Model()
                        {
                            Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String },
                                new DataField() { Name = "sub", Type = DataFieldType.String }
                            }
                        },
                        Proxy = new AjaxProxy()
                        {
                            ActionMethods = new CRUDModel() { Read = "POST" },
                            Url = "/api/GetData",
                            ExtraParams = new JsObject(new[]
                            {
                                new { PrimaryValue = primaryBox.Value }
                            })
                        }
                    }
    I think https://examples5.ext.net/#/Form/Com...Linked_Combos/ could help me, but I'm missing something.

    GetDataController.cs

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace ExtCookbook.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class GetDataController : ControllerBase
        {
            // POST api/<GetDataController>
            [HttpPost]
            public IEnumerable<object> Post()
            {
                var page = Request.Form["page"];
                var start = Request.Form["start"];
                var limit = Request.Form["limit"];
                var primaryValue = Request.Form["primaryValue"]; // <<---
                string query = Request.Form["query"];
    
                return new List<object>()
                    {
                        new { id = 1, text = "Pippo", sub = "Dog"},
                        new { id = 2, text = "Pluto", sub = "Dog"},
                        new { id = 3, text = "Paperino", sub = "Duck"}
                    };
            }
        }
    }


    I promise, this is the last question! ;)

    Thank you much!
  9. #9
    Hello again, @bbros!

    This really is something that can't be made with just ExtraParams the way we are used to with other submissions' ExtraParams. I believe we may be barking at the wrong tree here, wanting to use extra params with AjaxProxy.

    What do you have in mind that will actually trigger the server data load? I understand you have /api/GetData that should be a generic API that should lie outside the page and return just the json data requested, right?

    I mean just having an AjaxProxy without AutoLoad = true won't make it actually trigger the request. And the way you want the combo to load seems to be very relevant as to how we will want to feed it the information it passes. Is server paging also intended?

    Worst case, we still use AjaxProxy and feed ExtraParams with current value of the combo box as soon as whatever triggers the ajax combo store's load event. But maybe there's something better than an AjaxProxy we may use here. Or maybe the "extra param" should be instead a filter.

    Take a look at Ext.data.proxy.Ajax class docs and it may enlighten you a bit on what direction you should go to attain your objective.
    Fabrício Murta
    Developer & Support Expert
  10. #10
    Go ahead and give your store an Id with StoreId = "MyStore" + somethingToMakeIdUnique around your model line 120.
    Great! This is somewhat the correct way.
    I think the issue #1845 is caused by the store.id which is not "reported" on the page.
    Doing as you say my store.id instead of being primaryBoxStore is ext-data-store-2.

    Anyway it is not preventing me to act on the comboBox.store object in this way:

            public IActionResult OnPostCombo_Change(JsObject jObj)
            {
                string senderId = jObj.GetValueOrDefault("senderId").Value.ToString();
                var cbo = this.GetCmp<ComboBox>(senderId);
    
                var query = jObj.GetValueOrDefault("query").Value.ToString();
                if (query.Length >= 3)
                {
                    var dataJson = new StringBuilder();
                    using (var writer = new StringWriter(dataJson))
                    {
                        _serializer.Serialize(new JsObject(GetData()), writer);
                    }
    
                    this.X().AddScript("App." + senderId + ".store.setData(" + dataJson + ");");
                }
                else
                {
                    var msg = $"You typed less than 3 chars :sleepy:";
                    this.X().Toast(Mojee.Replace(msg));
                }
                return this.Direct();
            }
    The complete code, for anyone who needs the solution or if you need to test the missing store.id, is the following

    Autocomplete.cshtml.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Ext.Net;
    using Ext.Net.Core;
    using Ext.Net.Core.Services;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    using MojeeIO;
    
    namespace ExtCookbook.Pages
    {
        public class AutocompleteModel : PageModel
        {
            public ComboBox primaryBox { get; set; }
            public ComboBox secondaryBox { get; set; }
            public ComboBox localStoreBox { get; set; }
            public ComboBox ajaxProxyStoreBox { get; set; }
    
            private ISerializationService _serializer;
            public AutocompleteModel(ISerializationService serializer)
            {
                _serializer = serializer;
            }
    
            public void OnGet()
            {
                primaryBox = GetBox("primaryBox");
                secondaryBox = GetBox("secondaryBox");
    
                SetEvent(primaryBox);
                SetEvent(secondaryBox);
    
                //localStoreBox
                localStoreBox = new ComboBox
                {
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "local",
                    EmptyText = "Select here...",
                    Store = new Store()
                    {
                        ModelValue = new Model()
                        {
                            Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String },
                                new DataField() { Name = "sub", Type = DataFieldType.String }
                            }
                        },
                        Data = GetData()
                    },
                    ListConfig = new BoundList
                    {
                        ItemTpl = @"
                                <div>
                                    <b>{text}</b><br />
                                    <font size=-1><i>{sub}</i></font>
                                </div>"
                    }
                };
    
                //Ajax proxy            
                ajaxProxyStoreBox = new ComboBox
                {
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "remote",
                    EmptyText = "Select here...",
                    TriggerAction = "Query",
                    TypeAhead = true,
                    MinChars = 3,
                    Store = new Store()
                    {
                        ModelValue = new Model()
                        {
                            Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String },
                                new DataField() { Name = "sub", Type = DataFieldType.String }
                            }
                        },
                        Proxy = new AjaxProxy()
                        {
                            ActionMethods = new CRUDModel() { Read = "POST" },
                            Url = "/api/GetData",
                            ExtraParams = new JsObject(new[]
                            {
                                new { PrimaryValue = primaryBox.Value }
                            })
                        }
                    }
                };
            }
    
            private ComboBox GetBox(string id)
            {
                return new ComboBox
                {
                    Id = id,
                    DisplayField = "text",
                    ValueField = "id",
                    Width = 200,
                    QueryMode = "remote",
                    EmptyText = "Select here...",
                    TriggerAction = "Query",
                    TypeAhead = true,
                    MinChars = 3,
                    Store = GetNewStore(id)
                };
            }
    
            private void SetEvent(ComboBox C)
            {
                C.DirectEvents.Change.Url = "/Autocomplete/Combo_Change";
                C.DirectEvents.Change.Method = Ext.Net.Core.HttpMethod.POST;
                C.DirectEvents.Change.Before = "return extraParams.query.length >= this.minChars";
                C.DirectEvents.Change.ExtraParams.Add(new DirectEventParameter() { Key = "senderId", Value = C.Id, Mode = ParameterMode.Value });
                C.DirectEvents.Change.ExtraParams.Add(new DirectEventParameter() { Key = "query", Value = $"App.{C.Id}.value", Mode = ParameterMode.Raw });
                if (C.Id == secondaryBox.Id) C.DirectEvents.Change.ExtraParams.Add(new DirectEventParameter() { Key = "primary", Value = $"App.{primaryBox.Id}.value", Mode = ParameterMode.Raw });
            }
    
            private Store GetNewStore(string comboId)
            {
                return new Store()
                {
                    Id = comboId + "Store",
                    ModelValue = new Model()
                    {
                        Fields = new List<DataField>
                            {
                                new DataField() { Name = "id", Type = DataFieldType.Int },
                                new DataField() { Name = "text", Type = DataFieldType.String }
                            }
                    },
                    Proxy = new MemoryProxy()
                };
            }
    
            private List<object> GetData()
            {
                return new List<object>()
                    {
                        new { id = 1, text = "Pippo", sub = "Dog"},
                        new { id = 2, text = "Pluto", sub = "Dog"},
                        new { id = 3, text = "Paperino", sub = "Duck"}
                    };
            }
    
            public IActionResult OnPostCombo_Change(JsObject jObj)
            {
                string senderId = jObj.GetValueOrDefault("senderId").Value.ToString();
                var cbo = this.GetCmp<ComboBox>(senderId);
    
                var query = jObj.GetValueOrDefault("query").Value.ToString();
                if (query.Length >= 3)
                {
                    var dataJson = new StringBuilder();
                    using (var writer = new StringWriter(dataJson))
                    {
                        _serializer.Serialize(new JsObject(GetData()), writer);
                    }
    
                    this.X().AddScript("App." + senderId + ".store.setData(" + dataJson + ");");
                }
                else
                {
                    var msg = $"You typed less than 3 chars :sleepy:";
                    this.X().Toast(Mojee.Replace(msg));
                }
                return this.Direct();
            }
    
        }
    }
    After that, I think you can consider this thread closed.
    Thank you!!
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] ComboBox with Templates and AJAX
    By kevinhwang in forum 2.x Legacy Premium Help
    Replies: 4
    Last Post: Jun 21, 2013, 3:22 PM
  2. Replies: 9
    Last Post: Jan 17, 2013, 5:47 PM
  3. [CLOSED] MVC Templates
    By adelaney in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: Aug 16, 2012, 5:04 PM
  4. [CLOSED] Combo with Templates and Ajax
    By deejayns in forum 1.x Legacy Premium Help
    Replies: 4
    Last Post: Dec 02, 2011, 1:22 PM
  5. Templates column in gridpanel
    By hernanjls in forum 1.x Help
    Replies: 0
    Last Post: Aug 13, 2009, 4:47 PM

Posting Permissions