0

Using Core 3.1 and Razor Pages

I trying to undertake the simple task of passing a search string into a ViewComponent and invoke the results.

I have encountered two issue I cannot find help with:

  1. How to pass the input search string to the view component?
  2. How to invoke the view component when the search button is clicked?

_Layout Page

<input id="txt" type="text" />
<button type="submit">Search</button>

@await Component.InvokeAsync("Search", new { search = "" }) 
//Should equal input string

I am new to core so any nudges in the right direction would be appreciated.

2 Answers 2

1

View component is populated on server side and then return to your client for rendering, so you can't directly pass client side input value into view component . In your scenario , when clicking search button , you can use Ajax to call server side method to load the view component and pass the input value :


Index.cshtml

<input id="txt" type="text" />
<button onclick="loadcomponents()">Search</button>

<div id="viewcomponent"></div>

@section Scripts{ 
    <script>
        function loadcomponents() {
            $.ajax({
                url: '/?handler=Filter',
                data: {
                    id: $("#txt").val()
                }
            })
                .done(function (result) {
                    $("#viewcomponent").html(result);
                });
        }
    </script>

}

Index.cshtml.cs

public IActionResult OnGetFilter(string id)
{
     return ViewComponent("Users", new { id = id });
}

UsersViewComponent.cs

public class UsersViewComponent : ViewComponent
{
    private IUserService _userService;
    public UsersViewComponent(IUserService userService)
    {
        _userService = userService;
    }
    public async Task<IViewComponentResult> InvokeAsync(string id)
    {
        var users = await _userService.GetUsersAsync();
        return View(users);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This should be the correct marked answer. But only with 1 change, the id should also be passed in the paramter of the service method to get the particular data.
0

Edit: Oh, you edited the razor tag in after I posted my answer. Well, my answer is only valid for ASP.NET Core MVC.


I assume that your controller looks something like this:

[HttpGet]
public IActionResult Index()
{
    var model = new IndexVM();
    return View(model);
}

[HttpPost]
public IActionResult Index(IndexVM model)
{
    // you can do something with the parameters from the models here, or some other stuff
    return View(model);
}

Your ViewModel can look like this:

public class IndexVM
{
    public string SearchTerm {get;set;}
}

Your View where you use your ViewComponent:

@model IndexVM

// <form tag ...
<input asp-for="SearchTerm" />
<button type="submit">Search</button>
@await Component.InvokeAsync(nameof(Search), Model)

ViewComponent:

public class Search : ViewComponent
{
    public IViewComponentResult Invoke(IndexVM indexVM)
    {
        // Do something with indexVM.SearchTerm
    }
}

View of ViewComponent:

@model IndexVM
// ...

1 Comment

Thanks for offering your time. I should have mentioned that I am using Razor Pages for this. My html and ViewComponet are invoked in a _Layout page which has no associated Controller. I am not sure where I can write the necessary code without having an associated code page. If this was on a view page I think I would be ok.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.