MudBlazor's Autocomplete is not working even if the component is filled with data - mudblazor

Whenever I type the string for the MudBlazor's Autocomplete, the component does not give me the result. I can get all the data inside the Autocomplete Component, but cannot search for it.
razor.cs
private PropertyTransactionType _sPropertyTransactionType;
private PropertyTransactionType SPropertyTransactionType
{
get => _sPropertyTransactionType;
set
{
_sPropertyTransactionType = value;
}
}
private async Task<IEnumerable<PropertyTransactionType>> Search(string value)
{
return PropertyTransactionTypes;
}
razor
<MudAutocomplete T="ascor_pmis.Shared.Entities.Properties.Parameters.PropertyTransactionType"
Label="Transaction Type"
#bind-Value="SPropertyTransactionType"
SearchFunc="#Search"
ToStringFunc="#(e=> e==null?null : $"{e.TransactionType} [{e.Debit_Credit}]")" />

Related

MudBlazor dropdown not defaulting to value from database

I'm using Blazor with MudBlazor and I have the following form on an Edit page:
<EditForm Model="BookRequestVM" OnInvalidSubmit="InvalidBookRequest" OnValidSubmit="#ValidBookRequest">
...
<MudItem xs="12" sm="4">
<MudSelect T="BookType" Label="Book Type" #bind-Value="#BookRequestVM.BookType" #bind-SelectedValues="hashBookTypes" Required="true">
#foreach (var selectItem in BookTypes)
{
<MudSelectItem Value="#selectItem">#selectItem.TypeTitle</MudSelectItem>
}
</MudSelect>
</MudItem>
</EditForm>
...
#code {
public class BookType
{
public int BookTypeId { get; set; }
public string TypeTitle { get; set; }
}
public HashSet<BookType> hashBookTypes = new HashSet<BookType>();
...
protected override async Task OnInitializedAsync()
{
BookRequestVM = await _bookService.GetBookRequest(Id); // Fetch info from database
BookTypes = _bookService.GetBookTypes().ToList(); // Get all valid dropdown values
hashBookTypes = new HashSet<BookType>(BookTypes);
}
}
Because I'm pulling in existing data (this Book Type field is required when creating a book request), there will always be a Book Type associated with this Book Request. I see that the BookTypeVM was able to pull the Book Type in from the database in the service call, and on the valid submit method, it's bound and gets saved properly. It's just when it loads in, it doesn't default to the value that was saved to the database--only the first value from the dropdown list. Any ideas on what's going on here?
Is this a multi-select? If not then why are you setting #bind-SelectedValues="hashBookTypes". hashBookTypes comes from BookTypes which is a list of all the book types. I'm no expert on MudBlazor, but it appears your setting the selected values to the full list of values. Without MultiSelection="true" then I'm guessing its setting the current value to the first value in the list.
Your code has more problems than the one MrC found. You need to be very careful with using a POCO class in a select without overriding Equals() and GetHashCode() because the select uses a HashSet internally to find out which item is selected. Also, if you want it to convert the selected BookType to string it should override ToString().
Your BookType class should look like this:
public class BookType
{
public string Title { get; set; }
public override bool Equals(object other) {
return (other as BookType)?.Title == Title;
}
public override int GetHashCode()
{
return this.Title.GetHashCode();
}
public override string ToString() => Title;
}
And here is the Select to go with it:
<MudSelect T="BookType" Label="Book Type" #bind-Value="#RequestedBookType" Required="true">
#foreach (var selectItem in BookTypes)
{
<MudSelectItem Value="#selectItem">#selectItem.Title</MudSelectItem>
}
</MudSelect>
Here is a fiddle that demonstrates your code with above changes to make it work: https://try.mudblazor.com/snippet/mOwvPvbhHYHFBoiV
#bind-SelectedValues="hashBookTypes" was the culprit. This is used for multiselect. Unfortunately, I don't recall adding this code, but removing this resolved this issue.

Xamarin FOrms routing with passing parameters in Shell

In my codeBehind of my Page1 I have:
{
//do not select item
((ListView)sender).SelectedItem = null;
//go to stockDetailsPage
await Shell.Current.GoToAsync("postlogin/stockdetails?tickerSymbol=AAPL.NASDAQ");
}
As you can see I hardcoded the value in order to test it.
Earlier it was without param, and it work, now I need to pass param tickerSymbol.
And in my stockDetailsPage in my ViewModel I added
[QueryProperty("TickerSymbol", "tickerSymbol")] above my class
and in my class I declared properties:
public string TickerSymbol
{
set { SetProperty(ref tickerSymbol, Uri.UnescapeDataString(value)); }
get { return tickerSymbol; }
}
So in my constructor of that vm, I now want to call method with input argument of that param, but Im getting null all the time.
Can you suggest me where Im wrong?
As Xamarin doc said it should be able to pass param to the class for the page's BindingContext, I tried the following and it works:
in code behind, set BindingContext to your ViewModel:
TestParamViewModel testParamViewModel;
public TestPage()
{
InitializeComponent();
testParamViewModel = new TestParamViewModel();
this.BindingContext = testParamViewModel;
}
Add QueryPropertyAttribute to your ViewModel:
[QueryProperty("Name", "name")]
class TestParamViewModel
{
string name;
public string Name
{
set
{
name = Uri.UnescapeDataString(value);
}
}
}
call navigation:
await Shell.Current.GoToAsync("testpage?name=Abyssinian");
Hope it helps.

How to set jqGrid "editoption" with Lib.Web.MVC

I have a bool data value (true / false) that I want to display as Yes / No in the jqGrid cell.
How do I annotate the view model property to do this?
I think the code below may work but I do not know how to add edit options to the property annoation.
editoptions: { value: "false:No;true:Yes" }
Lib.Web.Mvc supports two ways of providing values for select edit/search fields:
Remote - requires a controller action which will return the values via AJAX call (sample can be find in demo project).
Dedicated class - requires creating a class with specific method.
The second way might work in your case. First you need a class to provide your values:
public class YesNoEditOptionsProvider
{
private static readonly IDictionary<string, string> _editOptions = new Dictionary<string, string>() {
{ "false", "No" },
{ "true", "Yes" }
};
public IDicitionary<string, string> GetEditOptions()
{
return _editOptions;
}
}
Now you can apply this class to your propery:
[JqGridColumnEditable(true, typeof(YesNoEditOptionsProvider), "GetEditOptions", EditType = JqGridColumnEditTypes.Select)]
public bool YesNoColumn { get; set; }

MVC3 shared-search model confusion

(couldn't think of a better title, sorry)
So I've got my layout page, on this page there is a searchbar + options. Choosing whatever, should take you through to the search page, with the results etc. Fairly standard. What I've done to get this working is to create a MasterModel class, with a SearchDataModel class member on it. This SearchDataModel contains the various parameters for the search (search term, what fields to search on etc).
I've then strongly typed my layout page to the MasterModel class, and using a Html.BeginForm... I've constructed the search form for it. However all the checkboxes relating to the fields aren't checked by default, even though the default value for all the fields is true (via a private getter/setter setup).
Yet when I submit the form to the SearchController, all the checkboxes are set to true. So I'm a bit confused as to why it knows they should be true, yet not set the checkboxes to be checked?
Putting breakpoints in key places seems to show that the model isn't insantiated on the get requests, only the post to the Search controller?
I may be going about this all wrong, so if so, pointers as to the right way always appreciated.
public class MasterModel {
public SearchDataModel SearchModel { get; set; }
}
public class SearchDataModel{
private bool _OnTags = true;
private bool _OnManufacturers = true;
private bool _OnCountries = true;
[Display(Name= "Tags")]
public bool OnTags {
get { return _OnTags; }
set { _OnTags = value; }
}
[Display(Name= "Manufacturers")]
public bool OnManufacturers {
get { return _OnManufacturers; }
set { _OnManufacturers = value; }
}
[Display(Name= "Countries")]
public bool OnCountries {
get { return _OnCountries; }
set { _OnCountries = value; }
}
[Required]
[Display(Name="Search Term:")]
public string SearchTerm { get; set; }
}
Then in the _layout page:
#Html.CheckBoxFor(m => m.SearchModel.OnTags, new { #class="ddlCheckbox", #id="inpCheckboxTag" })
#Html.LabelFor(m =>m.SearchModel.OnTags)
Make sure you return a MasterModel with initialized SearchModel from your views:
public ActionResult Index()
{
var model = new MasterModel
{
SearchModel = new SearchDataModel()
};
return View(model);
}
Another possibility to implement this functionality than strongly typing your master layout to a view model is yo use Html.Action as shown by Phil Haack in his blog post.

Waiting for a text change in WatiN

I am trying to test a web page that has ajax calls to update a price.
An ajax call is fired on page load to update an initially empty div.
This is the extension method I'm using to wait for a change in the inner text of the div.
public static void WaitForTextChange(this IE ie, string id)
{
string old = ie.Element(id).Text;
ie.Element(id).WaitUntil(!Find.ByText(old));
}
However it's not pausing even though when I write out the old value and ie.Element(id).Text after the wait, they are both null. I can't debug as this acts as a pause.
Can the Find.ByText not handle nulls or have I got something wrong.
Has anyone got some code working similar to this?
I found my own solution in the end after delving into WatiN's constraints.
Here's the solution:
public class TextConstraint : Constraint
{
private readonly string _text;
private readonly bool _negate;
public TextConstraint(string text)
{
_text = text;
_negate = false;
}
public TextConstraint(string text, bool negate)
{
_text = text;
_negate = negate;
}
public override void WriteDescriptionTo(TextWriter writer)
{
writer.Write("Find text to{0} match {1}.", _negate ? " not" : "", _text);
}
protected override bool MatchesImpl(IAttributeBag attributeBag, ConstraintContext context)
{
return (attributeBag.GetAdapter<Element>().Text == _text) ^ _negate;
}
}
And the updated extension method:
public static void WaitForTextChange(this IE ie, Element element)
{
string old = element.Text;
element.WaitUntil(new TextConstraint(old, true));
}
It assumes that the old value will be read before the change so there's a slight chance of a race condition if you use it too long after setting off the update but it works for me.

Resources