Blazor data binding two values to selectlist - asp.net-core

I can easily bind one value to my model, but what if I want to bind two or more?
Sample code, tried to bind to the complex object but it fails.
Component:
<select id="myClassId" #onchange="SelectionChanged" class="form-control">
<option value=""></option>
#foreach (var myObject in myClassList)
{
<option value="#myObject">#myObject.AccountName</option>
}
</select>
Code
void SelectionChanged(ChangeEventArgs e)
{
Console.WriteLine(((MyClass)e.Value).AccountId);
Console.WriteLine(((MyClass)e.Value).AccountName);
}
UPDATE:
Ended up doing this. Probably not the most elegant solution, but I'm not sure if there are other more "supported" ways.
<select id="myClassId" #onchange="SelectionChanged" class="form-control">
<option value=""></option>
#foreach (var myObject in myClassList)
{
<option value="#myObject.AccountId;#myObject.AccountName">#myObject.AccountName</option>
}
</select>
void SelectionChanged(ChangeEventArgs e)
{
var accountId = e.Value.ToString().Split(";")[0];
var accountName = e.Value.ToString().Split(";")[1];
Console.WriteLine(accountId);
Console.WriteLine(accountName);
}

The value of a select is a string. That is a fundamental limitation of the HTML, and has nothing to do with Blazor. You cannot use an object. Your best bet here is to assign an id or some other uniquely identifying value, and then in your onchange handler, look up the actual object you want to assign using that value.

Related

After using <InputSelect> first value in select is empty

I have been working for a while with Blazor Server host model and now i am building forum with it. I have small strange case, maybe someone will help me to find solution.
This is EditForm
<EditForm Model="#Category">
<InputSelect id="category" class="form-select" #bind-Value="#Category.Id">
#foreach (var category in Categories!)
{
<option value="#category.Id">#category.Category</option>
}
</InputSelect>
</EditForm>
This is list of items:
Categories = await _repository!.GetAllCategories();
This is how "GetAllCategories()" looks like:
public async Task<IEnumerable<CategoryEntity>> GetAllCategories()
{
return await _context.Categories.OrderBy(x=>x.Id).ToListAsync();
}
and the thing is:
First item in Select is blank:
How can i make first item as Value of it? Has someone found something similar?
I found solution.
I changed:
<InputSelect id="category" class="form-select" #bind-Value="#Category.Id">
to:
<InputSelect id="category" class="form-select" #bind-Value="#Category.Category">

laravel 8 asort() expects parameter 2 to be int, string given

i want to sort and show products based on the value selected in a dropdown i.e lowest price,highest price and latest products.i have a tired the code above in the controller and in my jquery script but i get the following error asort() expects parameter 2 to be int, string given.i havent understood where i hve gone wrong with my codebase.
the function in the controller
public function merchadise (){
$products=Merchadise::where('merch_isactive',1)->paginate(2);
if(isset($_GET['nice-select'])&&!empty($_GET['nice-select'])){
if(isset($_GET['nice-select'])=="latest_products"){
$products->sortBy('id','Desc');
}elseif(isset($_GET['nice-select'])=="lowest_price"){
$products->sortBy('merch_price','Asc');
}elseif(isset($_GET['nice-select'])=="highest_price"){
$products->sortBy('merch_price','Desc');
}elseif(isset($_GET['nice-select'])=="product_name_a-z"){
$products->sortBy('merch_name','Asc');
}elseif(isset($_GET['nice-select'])=="product_name_z-a"){
$products->sortBy('merch_name','Desc');
}
}else{
$products->sortBy('id','Desc');
}
return view('frontend.product.product',compact('products'));
}
at the blade file
<div class="showing-product-number text-right">
<form name="sortproducts">
<select class="nice-select" id="nice-select">
<option value="">Default sorting</option>
<option value="latest_products">Sort by new arrivals</option>
<option value="lowest_price">Sort by price: low to high</option>
<option value="highest_price">Sort by price: high to low</option>
<option value="product_name_a-z">Product Name A-Z></option>
<option value="product_name_z-a">Product Name Z-A</option>
</select>
</form>
</div>
the script code
$(document).ready(function(){
$("#nice-select").on('change',function(){
this.form.submit();
});
});

How to add dynamically v-model and it's initial values to existed html elements by vuejs

For SEO purposes I need to render html elements by php. For example I have these elements.
<?php foreach ($elements as $key => $element): ?>
<select name="first" v-model="model[<?= $key; ?>]">
<option value="">Select</option>
<option value="1">Some Text</option>
<option value="2">Some Text</option>
</select>
<select name="second" v-model="model[<?= $key; ?>]>
<option value="">Select</option>
<option value="4">Some Text</option>
<option value="5">Some Text</option>
</select>
...
...
...
<select name="eleven" v-model="model[<?= $key; ?>]>
<option value="">Select</option>
<option value="101">Some Text</option>
<option value="102">Some Text</option>
</select>
<?php endforeach; ?>
And probably I can manipulate these elements like this on vue side.
const count_models = <?= count($elements) ?>; // in the html
const app = new Vue({
el: '#app',
data: {
model:[]
},
mounted(){
console.log(this.model);
for (let $i = 0; $i < count_models; $i++) {
this.model[$i] = "";
}
}
})
I cannot declare the initial values for model[?]. I need an xhr or assign counted items to a javascript variable to get how many select element I have on DOM and to declare initial values as null for each model[]. Even I redeclare the initial values of the models, it doesn't bind. I just put an example on jsFiddle. In Angular1 there was ng-init attribute to declare initial value for the model.
How can I solve this problem ?
https://jsfiddle.net/ks7jmgwv/1/
you just encountered one of the most common gotchas of Vuejs: reactivity (and therefor the lack off)!
The issue here is when the model property is created it's just an empty array/object and any property that you add to that element it's not going to be reactive: that means any kind of change made programmatically won't trigger the Vue's internal whatches, the only reason that the v-model still works is that the changes made by the user and not by the code does actually trigger native HTML events.
You have two possible solutions:
Ignore the reactivy part (but you won't be able to programmatically update the selected value, or at least it won't be visible) and just make sure that the 'Select' option will be selected by default by assigning it the correct value (in that way you can just skip all the default for-loop initialization).
<option :value="undefined" selected="selected" disabled>Select</option>
Follow the offical way suggested by the Vuejs' documentation to add a new property to an object and still having the advantage of reactivity
this.$set(this.model, $i, "");
You can check this plunker in which I'm showing you both the ways of obtaining your goal:
https://jsfiddle.net/8y7eu39z/18/
Also, did you know that for placeholder options in a select you can add the attribute disabled?
Reactivy Reference: https://v2.vuejs.org/v2/guide/reactivity.html
Also: if you want a "null" as a default value but did not manage to find a way to make it being recognized by the "select" options just use :value="null" instead of value="null" and then you should be able to use
this.$set(this.model, $i, null);

How to access data in partialview loaded using Ajax

I'm currently building a website where I have to update two separate targets from a single Ajax.BeginForm. I got it working by using an additional container to container the two separate targets. As in:
Original Form
#model Mod1
#using (Ajax.BeginForm("LoadData", new AjaxOptions{UpdateTargetID = "Div1"}))
{
<select id="sel1" name="sel1" onchange="$(this.form).submit">
// ...
</select>
}
#using (Ajax.BeginForm("ProcessData", new AjaxOptions{UpdateTargetID = "Div2"}))
{
<div id="Div1"></div>
// ...
<input type="submit" value="GO!" />
}
Code File
public ActionResult LoadData(int sel1)
{
// loading data from database
return PartialView(mod1);
}
Partial View
#model Mod2
<select id="sel2" name="sel2">
#foreach (var item in Model.SelectItems)
{
<option value="#item.Value">#item.Text</option>
}
</select>
#foreach (var item in Model.CheckBoxItems)
{
<label>#item.Text<input type="checkbox" id="chk1" name="chk1" value="#item.Value"></label>
}
For the processing method, I have tried:
public ProcessData(Mod1 mod1, string[] chk1, int sel2)
However I am unable to retrieve the values for either chk1 or sel2 upon form submission. examination of chk1 and sel2 in Debug mode, chk1 is null while sel2 is 0 (no such value in the select options). Can anyone please offer some insight into the reason for this and also how I can go about solving it. Thank you in advance.
If I understand you correctly you can do what you want y having two submit buttons on the same form, each calling a separate action method. That way each submit button will have access to all the fields in the form. For a detailed explanation of how you can do that see my answer here:
How to use ajax link instead of submit button for form?
Edit
In response to comment: the action method LoadData should return a partial view that contains the other two controls and have the whole begin form included in it:
#using (Ajax.BeginForm("LoadData", new AjaxOptions{
UpdateTargetID = "Div1",
InsertionMode = InsertionMode.Replace
}))
{
<select id="sel1" name="sel1" onchange="$(this.form).submit">
// ...
</select>
}
<div id="Div1">
</div>
<div id="Div2">
</div>
Move this to another partial view:
#using (Ajax.BeginForm("ProcessData", new AjaxOptions{UpdateTargetID = "Div2"}))
{
// ...
<input type="submit" value="GO!" />
}

flexigrid refresh using javascript

Refresh the flexigrid data on dropdown (select) index changed or rebind the flexigrid on index change in javascript or clear the flexigrid data on select change
If you're just looking to bind the grid's refresh with another element, you can use
$('#flex1').flexReload()
I have done the following. On selection change of the Severity, the flexigrid reloads with the data for the selected severity
<select id='ddlSeverity' onchange="setSeverity($('#ddlSeverity option:selected').attr('value'));">
<option value="1">Severity 1</option>
<option value="2">Severity 2</option>
<option value="3">Severity 3</option>
<option value="4">Severity 4</option>
</select>
$(document).ready(function () {
function setSeverity(severity) {
//Construct the URL to be called.
var urlAction = '#Url.Action("RequestQueueBySeverity", "Home", new { severity = "__BOGUS__" })';
//Replace the bogus parameter with the parameter to be passed
urlAction = urlAction.replace("__BOGUS__", severity);
$('#flex1')
.flexOptions({
url: urlAction,
newp: 1
}).flexReload();
}
}
Please mark as answer if it works for you..
For efficient reloading, you can try this:
$("#flexigrid")[0].grid.populate()