I am using vue-slicksort on Vue.js, and I am trying to change order_no with the index value after sorting is complete. But I don't even access the method. And the second thing is that I am trying to list all elements after order_no (ex. 1,4 5, 7) = order_nr value.
<SortableList lockAxis="y" v-model="table">
<SortableItem
v-for="(item, index) in table"
:index="index"
:key="index"
:item="item"
#sort-end="changeOrderElement(index)"/>
</SortableList>
changeOrderElement(index){
console.log('Order:', this.table.order_no);
this.table.order_no = index;
console.log('New Order:', this.table.order_no);
}
Related
I have an object with key:val I want to filter the object by value like "ג6"
how i do that? I dont have alias name for search
this is the object
specialityTest={
"4969": "ג6",
"4973": "ג19",
"5163": "ה",
"5165": "ה1",
"5200": "ה2",
"5486": "גן1"
}
I want to do
this.nurseListSpeciality2 = this.specialityTest.filter((el) => {
return el.value == "fffff";
});
I get an error:
this.specialityTest.filter is not a function
how can I filter this object?
You can use Object.keys for filtering your keys where the values match.
this.nurseListSpeciality2 = Object.keys(this.specialityTest).filter((val) => this.specialityTest[val] === "ג6");
Finally, when rendering you can loop over the array of keys that will be returned and the render values associated with those keys
<ul>
<li v-for="val in nurseListSpeciality2" :key="val">
{{ specialityTest[val] }}
</li>
</ul>
I have a list make with vuetify as below.
<v-list dense>
<v-list-item-group mandatory color="blue" v-model="selectedIndex">
<v-list-item
v-for="item in items"
:key="item.id"
#click="listClick"
>
<v-list-item-content>
<v-list-item-title v-text="item.description"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
I am doing a watch on items which is a prop for data on the list
watch: {
items(newItems) {
this.selectFirstItem(newItems);
},
},
In method selectFirstItem, I try to select first item by setting data selectedIndex to 0, which bind to v-model of v-list-item-group like this <v-list-item-group v-model="selectedIndex">
selectFirstItem(items) {
.
.
.
this.selectedIndex = 0;
.
.
.
},
for item filter, I am doing it with computed like below, getTrmLevel1 is a vuex getter.
items() {
if (this.layerIndex === -999) {
return this.getTrmLevel1;
}
return this.getTrmLevel1.filter((item) => item.layer === this.layerIndex);
},
It is working when data change from all to filtered (i.e. add a filter), but it is not working when change from filtered to all (i.e. clear the filter), it keep highlight the item I selected before remove the filter instead of the first one.
I am new to vue so I am not sure if I am doing the right thing to select first item, any pointer are welcome.
Latest finding
After long browsing with the Vue plugin, I find out what caused this behavior.
1) When show all data
**Index \ Item**
0 \ a-1
1 \ a-2
2 \ b-1
3 \ b-2
4 \ c-1
2) When show item contain b only, it is working because the index cannot be reuse as max index is 1, so for example b-1 will need to change the index as the original index 2 is larger then 1 and invalid
**Index \ Item**
0 \ b-1
1 \ b-2
3) When show all items again, it is another story, because index can be reused, so b-1 and b-2 keep their index (0 and 1), so the problem is index 0 actually not the first item, but not Vue/Vueify did not response to this.selectedIndex = 0;
**Index \ Item**
2 \ a-1
3 \ a-2
0 \ b-1
1 \ b-2
4 \ c-1
So my latest question is how to Find out index of first item? or Are there other valid method to select the first item?
Workaround
Although not heavily tested, I find a workaround for this issue, the center of this reuse behavior is about :key as I am doing :key="item.id" it will reuse based on my item key
<v-list-item
v-for="item in items"
:key="item.id"
#click="listClick"
>
so I am now working around this issue by binding the v-for loop index like this :key="index", this way vue reuse the list item base on the position in the list, although it may cause more updating, but I can keep selectedIndex = 0 for my first item
<v-list-item
v-for="(item, index) in items"
:key="index"
#click="listClick"
>
Any recommendation still welcome
I'm learning Vue.js and found this fiddle that does exactly what I want to do.
Here is the fiddle: https://jsfiddle.net/os7hp1cy/48/
I integrated this and am getting this error:
invalid expression: v-for="user in users | filterBy searchKey | paginate"
So I've done some digging and I see it has changed from version 1 to 2. However, I don't know how to fix this.
<li v-for="user in users | filterBy searchKey | paginate">{{ user.name }}</li>
I would like to replace this with something that Vue 2 will support and will work the same way.
As of Vue version 2, filters can only be used inside text interpolations ({{ }} tags). See the documentation for migrating from Vue version 1.
You can use a computed property to filter the users and use that computed property in the v-for directive instead:
computed: {
filteredUsers: function() {
let key = this.searchKey.toUpperCase();
return this.users.filter((user) => {
return user.name.toUpperCase().indexOf(key) !== -1
})
},
paginatedUsers: function() {
var list = this.filteredUsers;
this.resultCount = list.length
if (this.currentPage >= this.totalPages) {
this.currentPage = this.totalPages
}
var index = this.currentPage * this.itemsPerPage
return list.slice(index - 1, index - 1 + this.itemsPerPage)
}
}
<li v-for="user in paginatedUsers">{{ user.name }}</li>
Also, when using v-for to generate a range of numbers like you do for your page numbers, Vue version to starts the index at 1 instead of 0. So, you'll need to update the logic depending on a starting index of 0 as well.
Here's a working fiddle.
I have code like this (JSFiddle)
<li v-for="(itemObjKey, catalog) in catalogs">this index : {{itemObjKey}}</li>
Output:
this index: 0
this index: 1
My question is:
How can I get value index first begin: 1 for example I want
output like this: this index: 1 this index: 2
How can I get count from index, i.e. output like this: this index: 1 this index: 2 this count: 2 field
you can just add 1
<li v-for="(catalog, itemObjKey) in catalogs">this index : {{itemObjKey + 1}}</li>
to get the length of an array/objects
{{ catalogs.length }}
In case, your data is in the following structure, you get string as an index
items = {
am:"Amharic",
ar:"Arabic",
az:"Azerbaijani",
ba:"Bashkir",
be:"Belarusian"
}
In this case, you can use extra variable to get the index in number:
<ul>
<li v-for="(item, key, index) in items">
{{ item }} - {{ key }} - {{ index }}
</li>
</ul>
Source: https://alligator.io/vuejs/iterating-v-for/
Alternatively, you can just use,
<li v-for="catalog, key in catalogs">this is index {{++key}}</li>
This is working just fine.
The optional SECOND argument is the index, starting at 0. So to output the index and total length of an array called 'some_list':
<div>Total Length: {{some_list.length}}</div>
<div v-for="(each, i) in some_list">
{{i + 1}} : {{each}}
</div>
If instead of a list, you were looping through an object, then the second argument is key of the key/value pair. So for the object 'my_object':
var an_id = new Vue({
el: '#an_id',
data: {
my_object: {
one: 'valueA',
two: 'valueB'
}
}
})
The following would print out the key : value pairs. (you can name 'each' and 'i' whatever you want)
<div id="an_id">
<span v-for="(each, i) in my_object">
{{i}} : {{each}}<br/>
</span>
</div>
For more info on Vue list rendering: https://v2.vuejs.org/v2/guide/list.html
Using Vue 1.x, use the special variable $index like so:
<li v-for="catalog in catalogs">this index : {{$index + 1}}</li>
alternatively, you can specify an alias as a first argument for v-for directive like so:
<li v-for="(itemObjKey, catalog) in catalogs">
this index : {{itemObjKey + 1}}
</li>
See : Vue 1.x guide
Using Vue 2.x, v-for provides a second optional argument referencing the index of the current item, you can add 1 to it in your mustache template as seen before:
<li v-for="(catalog, itemObjKey) in catalogs">
this index : {{itemObjKey + 1}}
</li>
See: Vue 2.x guide
Eliminating the parentheses in the v-for syntax also works fine hence:
<li v-for="catalog, itemObjKey in catalogs">
this index : {{itemObjKey + 1}}
</li>
Hope that helps.
Why its printing 0,1,2...?
Because those are indexes of the items in array, and index always starts from 0 to array.length-1.
To print the item count instead of index, use index+1. Like this:
<li v-for="(catalog, index) in catalogs">this index : {{index + 1}}</li>
And to show the total count use array.length, Like this:
<p>Total Count: {{ catalogs.length }}</p>
As per DOC:
v-for also supports an optional second argument (not first) for
the index of the current item.
this might be a dirty code but i think it can suffice
<div v-for="(counter in counters">
{{ counter }}) {{ userlist[counter-1].name }}
</div>
on your script add this one
data(){return {userlist: [],user_id: '',counters: 0,edit: false,}},
I just moved to the laravel framework and am starting to migrate some legacy sites and I have hit a problem with SQL or blade - dunno which.
I have to display a load of rows 'sports classes' which are grouped by year and then month. each needs to show attendance etc.
I am unsure which way to proceed.
I am able to display all rows and sort by date - easy squeezy
I am able to groupBy year AND month - fiddly but sorted it.
These are all displayed in an accordian.
Click the month - the individual rows drop down - you get the idea
I can get a number of rows per month/year
What I am unable to figure out is how to actually display the rows.
The groupBy is this:
$LinkClasses = DB::table('classes_lists')
->select('id, class, teacher, size')
->select(DB::raw('YEAR(date) AS year, MONTH(date) AS month, MONTHNAME(date) AS month_name, COUNT(*) post_count'))
->groupBy('year')
->groupBy('month')
->orderBy('year', 'desc')
->orderBy('month', 'desc')
->orderBy('id', 'desc')
If the code you provided is within your controller, then you can append ->get() after your last ->orderBy(). This will return a Collection. You can then do whatever you want with the Collection (http://laravel.com/api/master/Illuminate/Support/Collection.html), including conversion to an array using ->toArray(), but I think it would be best to utilize the Eloquent ORM if possible.
Anyway, once you have it in the format you want, just pass it to the view like so:
return view('your.view', compact('LinkClasses'));
Then, inside the your.view blade template, you can access this by using the following:
#foreach ($LinkClasses as $currentRow)
<tr>
<td>{{ $currentRow['id'] }}</td>
<td>{{ $currentRow['class'] }}</td>
<td> ... </td>
</tr>
#endforeach
Best guess I can offer without seeing the blade template to get a better idea of what you're doing. Hope that helps!
UPDATE BASED ON OP FEEDBACK:
Since you are only receiving a single record, it seems as though the issue lies in your query. I suggest you simplify your query to fetch all records and then do your sorting within an array. Something like this in your controller:
$allClasses = DB::table('classes_lists')->all();
foreach ($allClasses as $currentClass) {
$yearMonth = date('Y-m', $currentClass['date']);
$classesByYearMonth[$yearMonth][] = $currentClass;
}
ksort($classesByYearMonth);
/* now you have an array of all classes sorted by year-month like this:
// $classesByYearMonth[2014-01] = array(
// [0] => array(1, 'class name', 'teacher name', 23),
// [1] => array(2, 'another class', 'different teacher', 25),
// ...
// );
//
// $classesByYearMonth[2014-02] = ...
*/
return view('your.view', compact('classesByYearMonth'));
Then, inside your blade template:
#foreach ($classesByYearMonth as $yearMonth => $classListArray)
Found {{ sizeof($classListArray) }} classes for {{ $yearMonth }}
#foreach ($classListArray as $currentClass)
<div>
<div>ID: {{ $currentClass['id'] }}</div>
<div>Class: {{ $currentClass['class'] }}</div>
<div>Teacher: {{ $currentClass['teacher'] }}</div>
<div>Size: {{ $currentClass['size'] }}</div>
</div>
#endforeach
#endforeach
I will leave it to you to fix the formatting to make your accordion work. But hopefully that will get you on the right path.
DNoe - thank you so much.
Your reply put me on exactly the right track.
I had to mod some bits due to laravel ambiguities and add the strtotime but the logic was all there.
foreach ($allClasses as $currentClass) {
$ym = $currentClass['date'];
$yearMonth = date("Y-m",strtotime($ym));
$classesByYearMonth[$yearMonth][] = $currentClass;
}
krsort($classesByYearMonth);
return View::make('classes.index', compact('classesByYearMonth'));
The css is simple from here.
I owe you some beers. And thanks for helping me take my head from my butt!
Send me a pm and i would be very very happy to forward beer donation :o
Great work and thank you again. :)
Also, part of the problem was that the results were throwing an stdObject rather than an array.
Being able to compare your code with my own has enabled me to create a dbquery with multiple joins from which meaningfull data is selected and then converted to an array.
$classes = DB::table('table2')
->join('table1', 'table2.id', '=', 'table1.id2' )
->join('table3', 'table1.id3', '=', 'table3.id' )
->orderBy('classes_lists.date','DESC')
->get(array('table1.id', 'teacher', 'date', 'size', 'students', 'fname', 'classname', 'table1.notes'));
$cfr = count($classes);
foreach($classes as $object)
{
$arrays[] = (array) $object;
}
foreach ($arrays as $currentClass){
$ym = $currentClass['date'];
$yearMonth = date("Y-m",strtotime($ym));
$clazByYearMonth[$yearMonth][] = $currentClass;
}
krsort($clazByYearMonth);
This was the output into blade:
Not formatted :
#foreach ($clazByYearMonth as $yearMonth => $classListArray)
Found {{ sizeof($classListArray) }} classes for {{ $yearMonth }}
#foreach ($classListArray as $currentClass)
<div>
date: {{ $currentClass['date'] }} | class: {{ $currentClass['classname'] }} | Size: {{ $currentClass['size'] }} Teacher: {{ $currentClass['fname'] }} |
</div>
#endforeach
#endforeach