data-ajax-update and data-ajax-mode="replace" not working in dotnet core jquery unobtrusive ajax - asp.net-core

I have an anchor which should replace a grid with a partial view .
<a class="btn btn-primary"
data-ajax="true"
data-ajax-method="GET"
data-ajax-mode="replace"
data-ajax-update="content"
data-ajax-url="#Url.Action("add","user")"> Create User </a>
<div class="row table-area">
<div class="col-md-12" id="content">
#Html.AjaxGrid(Url.Action("results", "user"))
</div>
</div>
I see it calls the user action with partial view but it never updates the section with id="content".
Here is my controller method -
[Route("add")]
public IActionResult AddUser()
{
return PartialView("Partials/AddUser",new RegisterViewModel());
}
Ideally it should replace the grid content with the partial view altogether but it is not replacing . The response status is 200 and I can see that the contents are being returned in response . Anybody has any idea what is the issue here ?

Change data-ajax-update="content" to data-ajax-update="#content"

Rather than using data-ajax-url, use the asp-controller and asp-action and the #content should work.
<a class="btn btn-primary" asp-controller="user" asp-action="add"
data-ajax="true"
data-ajax-method="GET"
data-ajax-mode="replace"
data-ajax-update="#content">Create User</a>

Related

Nothing happens when clicking search button on bootsrap and .net core

I am trying to learn .net core and what I want to do is: I have a search bar and a GetDetail function in controller. I want to trigger that function when clicking search button according to text in form. But when I click button, nothing happens. I did not complete the trigger part but even if I simply redirect to another page with href, also nothing happens. Here is my search bar view code which taken from sbadmin2:
<div class="row justify-content-center">
<div class="col-6 p-3">
<div class="input-group">
<input type="text" class="form-control bg-light border-0 small" placeholder="Input" aria-label="Search" aria-describedby="basic-addon2" id="code">
<button class="btn btn-primary" type="button" action="/Books/GetDetail?">
<i class="fas fa-search fa-sm"></i>
</button>
</div>
</div>
</div>
and the function I want to trigger is a get request:
public IActionResult GetDetail(string codes)
{
var request = $"?codes={codes}";
var products = _httpTool.HttpGetAsync<List<Products>>($"{AppSettings.ApiUrl}/GetProducts{request}");
var productList = products.Result.ToList();
return Json(productList);
}
Why nothing is happening and how can I achieve this?
Thanks in advance!
try something like this:-
<form method="post" asp-action="GetDetail">
//clarify code
<input type="submit" value="Search" class="btn btn-outline-primary mt-1"/>
//clarify code
</form>
[HttpPost]
public IActionResult GetDetail(string codes)
{
var request = $"?codes={codes}";
var products = _httpTool.HttpGetAsync<List<Products>>($"{AppSettings.ApiUrl}/GetProducts{request}");
var productList = products.Result.ToList();
return Json(productList);
}
After clicking Searchyou see something will happen.

How to delete from a database in Ajax?

I'm sure there are similar questions, but I searched both here and on Google and found no answer.
I have a list of products in the database. And I have a method that delete the current product by button. And it works great!
The problem starts when I try to make the button not POSTBACK
I know the problem is with the RETURN but if I do not write it, I have an error message because my method is - async Task
For what I need to change the method so that it works without changing the URL / postback?
index.cshtml-
<ul class="list-group list-group-lg list-group-flush list my--4">
#foreach (var prod in Model.ProductList)
{
<li class="list-group-item px-0">
<div class="row align-items-center">
<div class="col-auto">
<span class="avatar avatar-lg">
תמונה
</span>
</div>
<div class="col ml--2">
<h4 class="card-title mb-1">
<a href="#!">
#Html.DisplayFor(modelItem => prod.ProductName)
</a>
</h4>
<p class="card-text small text-muted mb-1">
אימייל
</p>
</div>
<div class="col-auto">
<form method="post">
<input type="submit" asp-page-handler="Delete" value="Delete" asp-route-id="#prod.Id" data-ajax="true" data-ajax-success="deleteItem(this)" />
</form>
</div>
</div>
</li>
}
Index.cshtml.cs-
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
Product currentProduct = new Product();
foreach (var item in _context.Products)
{
if (item.Id==id)
{
currentProduct = item;
break;
}
}
_context.Products.Remove(currentProduct);
_context.SaveChanges();
return RedirectToPage("./Index");
}
Based on your code, we can find that it will return HTTP 302 redirect response status code while you make AJAX request from client side. Please note that AJAX can not automatically redirect to that page, normally we do not return a redirect response to AJAX client.
As #schwartz721 mentioned, if possible, you can try to modify the handler to return JsonResult or OkResult etc rather than RedirectToPage, then you can handle response in success callback.
Besides, if you indeed want to do AJAX submission and redirect user to index page after user delete a product, you may need to do redirection on client side, like below.
window.location.href = url_here;

Dropdown list is not working in the Asp.net Blazor Component

I am trying to learn the new feature in ASP.NET Blazor. I am using Visual Studio 2019. I am trying to create an Ideas Registration form. So the code for dropdownlist i had took from Bootstrap 4. It was not working as expected. Can you please tell me where i am working wrong?
Just a little overwhelmed here, any advice would be much appreciated.
Given Code:
<!-- Card Body -->
<div class="card-body">
<!-- <form -->
<form>
<div class="form-group">
<label for="exampleFormControlInput1">Title</label>
<input type="email" class="form-control" id="exampleFormControlInput1">
</div>
<div class="form-group">
<label for="exampleFormControlSelect1">Description</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="4"></textarea>
</div>
<!-- Basic dropdown -->
<div class="form-group">
<button class="btn btn-primary dropdown-toggle mr-4" type="button" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Basic dropdown
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">.Net</a>
<a class="dropdown-item" href="#">Python</a>
<a class="dropdown-item" href="#">Data Science</a>
<div class="dropdown-divider"></div>
</div>
</div>
<!-- Basic dropdown -->
where i am working wrong
According to the official docs](https://getbootstrap.com/docs/4.0/components/dropdowns/#data-toggledropdown-still-required):
Regardless of whether you call your dropdown via JavaScript or instead use the data-api, data-toggle="dropdown" is always required to be present on the dropdown’s trigger element.
I would suggest you should wrap your Basic dropdown in the following structure
<div class="dropdown">
<button data-toggle="dropdown" class="..." > ...</button>
<div class="dropdown-menu ...>
...
</div>
</div>
You didn't add an event handler for selection. At least you should add a #onclick for the toggle button. When clicking this button, show or hide the dropdown-menu.
Finally, if you want to implement the dropdown component with Blazor(without javascript), you should also replace the text content within the toggle button when someone selects a dropdown list item.
A Demo : How to Create A General Dropdown Component
Rather than simply fixing the issue, I think it's much better to create a general dropdown Component so that we can always invoke them in following way:
#{ var list = new List<string>{ ".NET", "Python","Java" }; }
<Dropdown TItem="string" OnSelected="#OnSelected" >
<InitialTip>This is a dropdown list</InitialTip>
<ChildContent>
<DropdownListItem Item="#list[0]">.NET</DropdownListItem>
<DropdownListItem Item="#list[1]">Python</DropdownListItem>
<div class="dropdown-divider"></div>
<DropdownListItem Item="#list[2]">Java</DropdownListItem>
</ChildContent>
</Dropdown>
#code {
private void OnSelected(string selection)
{
Console.WriteLine(selection);
}
}
Here the TItem is a generic type parameter that is the type of each dropdown list item and can be any .NET type.
Demo
How-To
Add a Shared/Dropdown.razor component:
#using Microsoft.AspNetCore.Components.Web
#typeparam TItem
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle mr-4" data-toggle="dropdown" type="button" #onclick="e => this.show=!this.show "
aria-haspopup="true" aria-expanded="false">
#Tip
</button>
<CascadingValue name="Dropdown" Value="#this">
<div class="dropdown-menu #(show? "show":"")" >
#ChildContent
</div>
</CascadingValue>
</div>
#code {
[Parameter]
public RenderFragment InitialTip{get;set;}
[Parameter]
public RenderFragment ChildContent{get;set;}
[Parameter]
public EventCallback<TItem> OnSelected {get;set;}
private bool show = false;
private RenderFragment Tip ;
protected override void OnInitialized(){ this.Tip = InitialTip; }
public async Task HandleSelect(TItem item, RenderFragment<TItem> contentFragment)
{
this.Tip= contentFragment.Invoke(item);
this.show=false;
StateHasChanged();
await this.OnSelected.InvokeAsync(item);
}
}
Add a Shared/DropdownListItem.razor component:
#using Microsoft.AspNetCore.Components.Web
#typeparam TItem
<a class="dropdown-item" Item="#Item" #onclick="e=> Dropdown.HandleSelect(Item, ChildContent)" >#ChildContent(Item)</a>
#code {
[CascadingParameter(Name="Dropdown")]
public Dropdown<TItem> Dropdown {get;set;}
[Parameter]
public TItem Item{get;set;}
[Parameter]
public RenderFragment<TItem> ChildContent {get;set;}
}
Keep in mind that bootstrap dropdown requires bootstrap javascript to be referenced. And the Blazor template doesn't reference it by default.
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
The accepted answer is great. However, as many have pointed out, the dropdown does not close if an option is not selected. The suggestion to create an #unblur event does not solve the case, as #unclick and #unblur do not seem to work together in .NET 5 (I read somewhere that it does works in the new .NET 6) - #unblur prevents #unclick to be triggered.
I found this solution (#onblur prevents #onclick in blazor server side app), changing the #onclick to #onmousedown and then creating the #onblur event (as suggested) has fixed the issue for me.

Razor Pages - Run a server side method NOT using post

In Razor pages ASP.NET Core, how do I do a basic onclick event for a button which is of type button?
Do I need to wire up an AJAX GET request to get the below "Resend Code" button to work? There is plenty of chatter about OnPost this and that.. but I don't want to post.
Can't be this hard?
<form method="post">
<div asp-validation-summary="All"></div>
<div class="form-group-item">
<label asp-for="Input.TwoFactorCode"></label>
<input asp-for="Input.TwoFactorCode" class="input" />
<span asp-validation-for="Input.TwoFactorCode"></span>
</div>
<div class="form-group-item">
<label class="margin-0" asp-for="Input.RememberMachine">
<input asp-for="Input.RememberMachine" />
#Html.DisplayNameFor(m => m.Input.RememberMachine)
</label>
</div>
<div>
<button type="button" asp-page-handler="ResendCode" class="btn btn-light">Resend Code</button>
<button type="submit" class="btn btn-secondary">Confirm</button>
</div>
</form>
As it stands, the button won't do anything. You can use JavaScript to intercept the button click and then fire a get request using AJAX (jQuery example below):
$('.btn.btn-light').on('click', function(){
$.get('?handler=ResendCode', data, function(){
...
});
});
You can try changing the button to use formmethod="get":
<button type="submit" formmethod="get" asp-page-handler="ResendCode" class="btn btn-light">Resend Code</button>
Note, this will only work for buttons that have type="submit" or type="image" (other type-values don't cause the form to submit). Also it's an HTML5 attribute.
Reference:
https://html.com/attributes/input-formmethod/
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formmethod
maybe try making your own custom handler methods other than OnPost() and OnGet()

use same form for user add and update Angular5

i am learning angular can someone please help me on following :
I have one form which save user (i call api on this submit click). i need to use same form for update user , for that i took two buttons i show "submit" button if user is new (i managethis new and old user from ge api call in OnInit()) and another button is "update" button, i show and hide this buttons depending on Get api call for user in onInit().
form demo code :
<form class="form-area" (ngSubmit)="ngSubmit(applicant)" name="applicantForm" #applicantForm="ngForm" ngNativeValidate>
<div> some fileds</div>
<div class="row" style="content:center">
<div class="col-md-12">
<div class="form-row">
<div class="form-group">
<button *ngIf="submitStatus" type="submit" class="btn btn-info" [disabled]="!applicantForm.form.valid">
<i class="fa fa-send-o"></i> Submit</button>
<button *ngIf="updateStatus" type="submit" class="btn btn-info" [disabled]="!applicantForm.form.valid">
<i class="fa fa-send-o"></i> Update</button>
</div>
</div>
</div>
</div>
</form>
question :
i call (ngSubmit)="ngSubmit(applicant)" method on submit button call to save user, but i confused in how i differentiate this both operation to call ngSubmit(applicant).
i need to perform both operation in single function call from controller.
thanks