Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer - checkbox

I want to get Id of an entity which is an int type value; user will check/uncheck the checkbox, so I've converted that into boolean type. But I'm getting error. Here is the code-
#for (int i = 0; i < Model.Count; i++)
{
<form asp-action="ReturnProduct" asp-route-id="#Model[i].HiddenPKVMId"
onsubmit="return jQueryAjaxPost(this);">
<div class="form-group">
<div class="col-md-6 offset-md-3">
<input type="checkbox" asp-for="#Convert.ToBoolean(Model[i].ProductVMName)" />
</div>
</div>
<input type="hidden" asp-for="#Model[i].HiddenPKVMId" />
</form>
}

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer
Seems that you didn't set property in your class. Try something like this:
Use
public class Product
{
public int HiddenPKVMId{ get; set; }
public string ProductVMName { get; set; }
}
instead of
public class Product
{
public int HiddenPKVMId;
public string ProductVMName;
}

Related

How to save # color in database in ASP.Net core

I want to save # color to Data Base.
but it just 0 for FontAwesomeColor in data base:
My view model:
public long FontAwesomeColor { get; set; }
part of my service:
Service service = new Service()
{
.....
FontAwesomeColor = createServiceViewModel.FontAwesomeColor
};
but after add in data base , all details add to data base , except FontAwesomeColor
controller:
public async Task<IActionResult> CreateService(CreateServiceViewModel createServiceViewModel)
{
_siteService.CreateService(createServiceViewModel);
return View(createServiceViewModel);
this is part of my view: ( I use from farbtastic for color Picker)
<div class="col-12 col-md-6 ">
<div class="">
<label for="color" class=" " asp-for="FontAwesomeColor"></label>
<input asp-for="FontAwesomeColor" type="submit" id="color" name="color" value="#123456" />
<div id="picker"></div>
<span asp-validation-for="FontAwesomeColor"></span>
</div>
</div>
I think you can use string instead of long for FontAwesomeColor. By the way, could you pls try to remove id="color" name="color" in your View and check if it's still null?
I copied your view and add the form so that I can submit it. By the way, I created the ViewModel which contained the model having FontAwesomeColor, then I got the null value as well.
After removing that part, it worked for me, that's because the model binding didn't work when the id is conflict.

angular get selected value in multiple selects inside ng-repeat

<tr ng-repeat="x in my_array">
<td>
<select name='[{{$index}}].Name' >
<option ng-repeat="sr in anotherArray" value="{{sr}}">
{{sr}}
</option>
</select>
</td>
</tr>
i have a table with rows populated by ng-repeat: my_array
there is another array : anotherArray
l want when the rows are repeated in angular for my_array to have its own value for [{{$index}}].Name to be based on the selected value for that particular row.
when l post the data to api [{{$index}}].Name will only have the same value even if l select different item for each rows.
l tried using ng-options as it was said its good for
of is there an easy way to get around it .
am populating the anotherArray and anotherArray
on different on same page but they are just an array with string values in it like as below
$scope.anotherArray= [];
$scope.add = function () {
$scope.errortext = "";
if (!$scope.addMe) { return; }
if ($scope.variants.indexOf($scope.addMe) == -1) {
$scope.anotherArray.push($scope.addMe);
}
}
the desired result is like
in image i_prepopulateOnRow1 ,i_prepopulateOnRow2 ...i_prepopulateOnRow upto Nth are add from anotherArray
when ever a new row from my_array is added it must have a select option for anotherArray thus in each row l can have value for i_prepopulateOnRow
the reason am using name as [{{$index}}].Name its becasue am posting to asp.net api.
the problem am facing is whenever l post all the rows have the same value for
[{{$index}}].Name even if l select different values
Edit two
am not getting answers did l do it the wrong way /please even suggestion would help am two days stack on this. Help guys
If you posting page on server side then HTML element name must be match with server class structure
Ex. Server class
public class otherClass
{
public int id { get; set; }
public string name { get; set; }
}
public class myclass
{
public string name { get; set; }
public List<string> nameList { get; set; }
public List<otherClass> otherList { get; set; }
}
then you HTML elment name should be like
<form method="post" action="http://localhost:56096/api/Values">
<div>
<input type="text" name="name" />
</div>
<div>
<ul>
<li>
<input type="text" name="nameList[0]" />
</li>
<li>
<input type="text" name="nameList[1]" />
</li>
<li>
<input type="text" name="nameList[2]" />
</li>
</ul>
</div>
<div>
<ul>
<li>
<input type="hidden" name="otherList[0].id" value="0" />
<input type="text" name="otherList[0].name" />
</li>
<li>
<input type="hidden" name="otherList[1].id" value="1" />
<input type="text" name="otherList[1].name" />
</li>
<li>
<input type="hidden" name="otherList[2].id" value="2" />
<input type="text" name="otherList[2].name" />
</li>
</ul>
</div>
<input type="submit" value="Submit" />
</form>
I home may you get help from this
Thanks

Accessing json object array and showing in Angular 4

I have object that consists of fields, other objects and arrays and it looks like this
Now, in my html, I access data for aaType, adjust etc.
<div class="flexdirectioncolumn">
<div class="flex50">
<label class="label-prop-a"> Name </label>
<div>
<input #name type="text" value={{entity.name}} (keyup.enter)="changeName(name.value)" />
</div>
</div>
<div class="flex50">
<label> AaType </label>
<div>
<input #aaType type="text" value={{entity.aaType}} (keyup.enter)="changeAaType(aaType.value)" />
</div>
</div>
<div class="flex50">
<label> Adjust </label>
<div>
<input #adjustableInput type="checkbox" value={{entity?.adjust}} (keyup.enter)="changeAdjust(adjustInput.value)" />
</div>
</div>
<div class="flex50">
<label> System </label>
<div>
<input #systemInput type="text" value={{entity?.system}} />
</div>
</div>
<div class="flex50">
<label>{{entity.creat.rule}}</label>
<div *ngFor="let param of entity.creat.parameters">
<label>{{param}}</label>
<input type="text" value={{param.value}} />
</div>
</div>
</div>
I managed to show creationInfo.rule that you can see in my html.
Now there is 2 questions that is bothering me:
For some reason, I can't access parameters array so I can use ngFor to create them all.
How can I show my label and input in ngFor div in a way that label will generate parameters name (like "departure-angle") and value in input to show "13"?
Question 1: For some reason, I can't access parameters array so I can use ngFor to create them all.
Answer 1: parameters is not an array it is an object, you cant iterate object using &ngFor
Question 2: How can I show my label and input in ngFor div in a way that label will generate parameters name (like "departure-angle") and value in input to show "13"?
Answer 2:
Solution 1:
In Component add a new variable:
objectArray = Object.keys; // It gives the array of object keys
In html use *ngFor="let param of objectArray(entity.creationInfo.parameters)",
<div class="flex50">
<label>{{entity.creationInfo.rule}}</label>
<div *ngFor="let param of objectArray(entity.creationInfo.parameters)">
<label>{{param}}</label>
<input type="text" value={{entity.creationInfo.parameters[param]}} />
</div>
</div>
Solution 2: You can add a pipe,
This pipe takes the object and return array of objects
import { PipeTransform, Pipe } from '#angular/core';
#Pipe({name: 'array'})
export class ArrayPipe implements PipeTransform {
transform(value, args:string[]) : any {
let array = [];
for (let key in value) {
array.push({key: key, value: value[key]});
}
return array;
}
}
In html,
<div class="flex50">
<label>{{entity.creationInfo.rule}}</label>
<div *ngFor="let param of entity.creationInfo.parameters | array">
<label>{{param.key}}</label>
<input type="text" value={{param.value}} />
</div>
</div>
1.: Parameters is not an array but an Object. So you cannot use *ngFor to access them.
2.: Map the parameters to a key-value array before displaying them.
Inside your ts file:
public params:Array<{key: string, value: string}>;
// Call this method when the "entity" object has been initialized.
private setParams():void {
this.params = Object.keys(this.entity.creationInfo.parameters)
.map(paramKey => ({
key: paramKey,
value: this.entity.creationInfo.parameters[paramKey]
}));
}
And then, inside your template:
<div *ngFor="let param of params">
<label>{{param.key}}</label>
<input type="text" value={{param.value}} />
</div>
Another way to achieve this, is using the Object.entries() function:
public params:Array<Array<any>>;
// Call this method when the "entity" object has been initialized.
private setParams():void {
this.params = Object.entries(this.entity.creationInfo.parameters);
}
Then, inside your template:
<div *ngFor="let param of params">
<label>{{param[0}}</label>
<input type="text" value={{param[1]}} />
</div>

Vue.js and Laravel update multiple rows with one call

For a better understanding, here are two of my models.
Model for images:
class Image extends Model
{
...
public function item()
{
return $this->belongsTo(Item::class);
}
}
Model an item:
class Item extends Model
{
...
public function images()
{
return $this->hasMany(Image::class);
}
}
In my view I am using a mixture of laravel's blade engine and Vue.js which looks like this:
<div class="form-group">
<label>#lang('app.user.edit.images')</label>
<div v-for="(img, index) in my.images">
<input type="text" name="images[]" class="form-control images" v-model="my.image">
</div>
</div>
This gives my one input for any image of the item. By changing the value of each image I want to update all database. I do not know if it is a good practice to name the input like name="images[]" to get an array.
My database table for images looks like this:
+----+---------+-------+------------+------------+
| id | item_id | image | created_at | updated_at |
+----+---------+-------+------------+------------+
Hopefully, some of you had the same problem in the past and can help me out.
you need to pass an id to the system so that you can grab them on the other side to update the database.
<div class="form-group">
<label>#lang('app.user.edit.images')</label>
<div v-for="img in my.images">
<input
type="text"
v-bind:name="'images[' + img.id + ']'"
class="form-control images"
v-model="img.image"
>
</div>
</div>
this will send an array in the Request object in the format of "id" => "url" which should let you update the images appropriately

Posting A String Array

How can I handle an array of input
For example I have in my view:
<input type="text" name="listStrings[0]" /><br />
<input type="text" name="listStrings[1]" /><br />
<input type="text" name="listStrings[2]" /><br />
In my control I try to get the values like:
[HttpPost]
public ActionResult testMultiple(string[] listStrings)
{
viewModel.listStrings = listStrings;
return View(viewModel);
}
On debugging I can see listStrings is null every time.
Why is it null and how can I get the values of the input array
Posting a Collection of Primitives With ASP.NET MVC
To post a collection of primitives the inputs just have to have the same name. That way when you post the form the request's body will look like
listStrings=a&listStrings=b&listStrings=c
MVC will know that since these parameters have the same name they should be converted to a collection.
So, change your form to look like this
<input type="text" name="listStrings" /><br />
<input type="text" name="listStrings" /><br />
<input type="text" name="listStrings" /><br />
I would also recommend changing the parameter type in your controller method to be an ICollection<string> instead of a string[]. So your controller would look like this:
[HttpPost]
public ActionResult testMultiple(ICollection<string> listStrings)
{
viewModel.listStrings = listStrings;
return View(viewModel);
}
Posting a Collection of More Complex Objects
Now, if you wanted to post a collection of more complex objects, say an ICollection<Person> where your definition of the Person class was
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
then the naming convention you used in your original form would come into play. Since you will need multiple inputs representing different properties to post the whole object now, just naming the inputs with the same name won't make sense. You will have to specify which object and which property an input represents in the name. For this you will use the naming convention collectionName[index].PropertyName.
For instance an input for the Age property of a Person might have a name like people[0].Age.
A form used to submit an ICollection<Person> in this case would look like:
<form method="post" action="/people/CreatePeople">
<input type="text" name="people[0].Name" />
<input type="text" name="people[0].Age" />
<input type="text" name="people[1].Name" />
<input type="text" name="people[1].Age" />
<button type="submit">submit</button>
</form>
The method expecting the request would look something like this:
[HttpPost]
public ActionResult CreatePeople(ICollection<Person> people)
{
//Do something with the people collection
}

Resources