Hello!
In our App, we need to make an xhr call to store the dropped element and getting back his "child" elements. I make it in the onAdd like this:
Vue.component('ha-page', {
template: '#page-template',
props: ['page'],
methods: {
onAdd: function (event) {
var templateId = $(event.clone).data('template_id');
self.$http.post('/groups', {template_id: templateId}).then(
function (xhr) {
// Success
Vue.set(event.item, 'fields', xhr.body.group_fields);
Vue.set(event.item, 'id', xhr.body.group.id);
toastr.error('Group created.');
},
function (xhr) {
//Fail
toastr.error('Group creation fail.');
}
);
}
}
});
But this lines do not update the new element of the list:
Vue.set(event.item, 'fields', xhr.body.group_fields);
Vue.set(event.item, 'id', xhr.body.group.id);
Is there a fancy way to update the new Vue element dropped in the list ?
Thx!
Could you provide the template HTML?
Here is the from:
<h3>Group fields templates</h3>
<ul class="list-group" id="availableGroups">
<draggable @add="onAdd" @sort="onSort" @update="onUpdate" :clone="cloneGroup" :list="groups" :options="{animation: 150, sort: false, group: {name: 'fields', pull: 'clone', put: false}}">
<available-groups v-for="group in groups" :group="group"></available-groups>
</draggable>
</ul>
And here is the to:
<div class="panel-body">
<draggable class="list-group field-list" :id="'field-list-' + page.id" :data-page_id="page.id" element="ul" @add="onAdd" @sort="onSort" @update="onUpdate" :list="page.fields" :options="{animation: 150, draggable: '.draggable',group: {name: 'fields',pull: 'clone'}}">
<ha-field v-for="field in page.fields" :page_id="page.id" v-bind:field="field" v-on:delete-field="deleteField(field)" v-on:delete-group-field="deleteGroupField(field, [group, field])" v-on:delete-group="deleteGroup(field)"></ha-field>
</draggable>
</div>
And here are the field component template:
<li class="list-group-item draggable ignore-elements" :id="'field-' + field.id">
<span v-if="field.is_group"><strong>Group: </strong></span>
<span v-else="field.is_group"><strong>Field: </strong></span>
<span class="field-name">@{{field.name}}
<a v-if='field.is_group' :href="'#field-group-list-' + field.id" role="button" data-toggle="collapse" class="btn btn-xs btn-links">
<i class="fa fa-plus"></i></a>
</span>
<p class="pull-right">
<a v-if='!field.is_group' href="#" class="btn btn-xs btn-primary edit-field" :data-field_id="field.id" @click.prevent="editField"><i class="glyphicon glyphicon-pencil"></i></a>
<a v-if='field.is_group' href="#" class="btn btn-xs btn-warning delete-field" :data-field_id="field.id" @click.prevent="$emit('delete-group')"><i class="glyphicon glyphicon-trash"></i></a>
<a v-else='field.is_group' href="#" class="btn btn-xs btn-warning delete-field" :data-field_id="field.id" @click.prevent="$emit('delete-field')"><i class="glyphicon glyphicon-trash"></i></a>
</p>
<ul v-if='field.is_group' class="list-group grouped-fields collapse" :id="'field-group-list-'+field.id">
<li v-for="_field in field.fields" class="list-group-item" :id="'group_field_' + _field.id">
<strong>Field: </strong> @{{ _field.name }}
<p class="pull-right">
<a href="#" class="btn btn-xs btn-primary edit-field" :data-field_id="_field.id" @click.prevent="editField(_field.id)"><i class="glyphicon glyphicon-pencil"></i></a>
<a href="#" class="btn btn-xs btn-warning delete-field" :data-field_id="_field.id" @click.prevent="deleteGroupField(field, _field)"><i class="glyphicon glyphicon-trash"></i></a>
</p>
</li>
</ul>
</li>
Thx
Hi @SebastienDenooz , could you please simplify and create a jsfiddle? Thanks
There is a Vue function named Vue.$forceUpdate() which forces vDOM to update.
What you need to do is only writethis.$forceUpdate(); at the end of the success part of your XHR.
@SebastienDenooz , Did the fix by @vTrippy work for you?
I am closing this. If needed provided a jsfidle and I will re-open the issue.
Hi all,
So, here is my jsfiddle. I try to simplify a maximum my code : https://jsfiddle.net/jon33s0z/1/
The main question is: How to modify / replace the 'cloned' element in the list where it is droped.
Thank's for your time all!!
Seb
@SebastienDenooz use clone props
Yes i see it, but the clone is fired dirctly on the drag start.
If i have more than one page (more than one target for the drag), the clone is fired on drag start, the xhr is made but i do not know yet what "target" page it is. Assuming the REST ressource is POST /pages/#/fieds/, on the clone i do not known the page_id.
Well, you can use the add event on the target draggable component or watch the underlying list using vue watch methods.
Another posiibility should be create an "transformOnAdd" prop that on target component will transform the copied element. Thougths?
transformOnAdd would be a good idea!
But i can not 'find' the new element in the event passed to the add to pass it to the transformOnAdd.
I can not find the new vue element. How can find it to passing it to transformOnAdd? That's my problem :s
I meant transformOnAdd would by a prop of vue.draggable that would be a function taking copied element as entry and returning the element to insert:
function transformOnAdd(copiedElement){
...
return elementToCopyInTheTarget;
}
@SebastienDenooz what is your feedback on this?
Most helpful comment
I meant transformOnAdd would by a prop of vue.draggable that would be a function taking copied element as entry and returning the element to insert: