How to get gridstack position from JSON and add to querySelector Vue3 - vuejs3

I am trying to get gridstack position using JSON data as shown on gridstack serialization.
<button class="x-btn" #click="saveFullGrid()">Save Full</button>
<button class="x-btn" #click="loadFullGrid()">Load Full</button>
<hr />
<textarea id="saved-data" cols="100" rows="20" readonly="readonly"></textarea>
<section class="grid-stack">
<div v-for="(component, key, index) in components" :key="'component' + index" :gs-id="key"
class="grid-stack-item" :gs-x="component.gridPos.x" :gs-y="component.gridPos.y" :gs-h="component.gridPos.h"
:gs-w="component.gridPos.w" gs-auto-position="true">
<div class="grid-stack-item-content">
<component :is="component.name" v-bind="component.props" />
<button class="edit" #click="remove(index, key, component)">Remove</button>
</div>
</div>
<hr />
</section>
//functions on script
<script>
//works and displays data on text area
function saveFullGrid() {
serializedFull = grid.save(true, true);
serializedData = serializedFull.children;
document.querySelector('#saved-data').value = JSON.stringify(serializedFull, null, ' ');
//use ajax to send json to db for storage - not yet implemented
}
//grid is destroyed but is not built again. What's the problem?
function loadFullGrid() {
if (!serializedFull) return;
grid.destroy(true); // nuke everything
grid = GridStack.addGrid(document.querySelector('#gs-id'), serializedFull)
// console.log(grid)
}
</script>
The data is saved but when I try to clear and load data from JSON using function loadFullGrid, the components do not render again on grid.
What could be the problem with my code?
//myjson data
{
"float": true,
"cellHeight": 70,
"minRow": 1,
"children": [
{
"x": 0,
"y": 0,
"w": 6,
"h": 7,
"id": "yourRandomComponent1",
"content": "<div data-v-bd6d1993=\"\" class=\"chartBox\"><canvas data-v-bd6d1993=\"\" id=\"myChart\" width=\"588\" height=\"400\" style=\"display: block; box-sizing: border-box; height: 400px; width: 588px;\"></canvas><!-- <div v-if=\"!loaded\" class=\"lds-dual-ring\"></div> --></div><!-- The Modal --><div id=\"myModal\" class=\"modal\" data-v-bd6d1993=\"\"><!-- Modal content --><div class=\"modal-content\" data-v-bd6d1993=\"\"><span class=\"close\" data-v-bd6d1993=\"\">×</span><div class=\"modal-header\" data-v-bd6d1993=\"\"><h1 class=\"label\" data-v-bd6d1993=\"\">Heading</h1></div><div class=\"modal-body\" data-v-bd6d1993=\"\"><h1 id=\"myList\" data-v-bd6d1993=\"\"></h1></div></div></div><button data-v-99a023f4=\"\" class=\"edit\" data-ol-has-click-handler=\"\">Remove</button>"
},

Related

trigger slide in swiper.js from extern via vuejs

I tried to address a method from an external button that is in swiper.js 8.1.0. goes to the next slide.
I created a refSwiper with the compositon API, no idea I don't see any function that I can call there, even with #onSwiper I get a reference to Swiper, but it doesn't move.
<swiper class="swiper-container" ref="swiperRef"
:pagination="{clickable: true,type: 'fraction' }"
:navigation="{ nextEl: '.arrow', }"
:modules="modules"
:centeredSlides="true"
:loop="false"
:simulate-touch="true"
:allow-touch-move="true"
:allow-slide-next="true"
:allow-slide-prev="true"
:watch-slides-progress="true"
#swiper="onSwiper"
#slideChange="onSlideChange"
:breakpoints="{
'1200': {
slidesPerView: 3,
spaceBetween: 770,
},
}"
>
<swiper-slide v-for="item, index in array" :key="index" >
<div class="kachel" #click="go(index)" ></div>
</swiper-slide>
</swiper>
<div class="arrows" >
<img src="../assets/svgs/rechtslinks.svg" alt="" #click="onSwipeNext()" >
</div>
ok, but how can i call the right function in my swiperRef
const onSwipeNext = () => {
console.log(swiperRef);
swiperRef.value.nextSlide();
}

VueJs calling :key in method

im new to Vue and trying myself in Vue3 and Vuetify.
Similar to this Post im trying to :key or ref a vue-signature-pad in a for loop.
I initialize an empty Array and push a new element, which adds a new signature.
<template>
<div>
<v-container>
<div class="row" v-for="(input, index) in inputs">
<v-container>
<VueSignaturePad
id="signature"
width="100%"
height="300px"
ref="signaturePad"
/>
</v-container>
<div class="buttons">
<button #click="undo">Undo</button>
<button #click="save">Save</button>
</div>
</div>
<v-row justify="center">
<v-btn #click="addRow"
class="ma-2"
color="blue-grey"
icon="mdi-plus-circle-outline"
></v-btn>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
data: () => ({
inputs: [],
}),
methods: {
addRow() {
this.inputs.push({
name: ''
})
},
undo() {
this.$refs.signaturePad.undoSignature();
},
save() {
const { isEmpty, data } = this.$refs.signaturePad.saveSignature();
alert("Open DevTools see the save data.");
console.log(isEmpty);
console.log(data);
}
}
}
</script>
<style scope>
</style>
In the Post i already mentioned, i tried the Solution from Mathieu Janio.
So if i understand everything right, ref is not working and i have to use :key on the div itself.
So i tried his Solution
<template>
<div
class="row"
v-for="(applicants, index) in applicant_details"
:key="index"
>
<div class="col-sm-4">
<div class="form-group">
<p>Signature for {{ applicants.first_name }}</p>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<VueSignaturePad ref="" />
<button type="button" #click="undo" class="btn btn-warning">
Undo
</button>
</div>
</div>
</div>
</template>
<script setup>
const applicant_details = [
{ first_name: 'john', signature: '' },
];
const undo = () => {
//will undo the signature
};
const save_signature = () => {
//Save the signature
};
</script>
But now im stuck at calling the right "undo"
The signatepad github example uses ref: at the single signaturepad, which is ok.
but not working at the forloop
How do i call now the right function in "undo" for the solution above?
I tried using "this.$.vnode.key" but this gives me an error.
"Uncaught TypeError: Cannot read properties of undefined (reading '$')".
I figured my first way out.
Heres what i have done.
The Signaturepad got an index on the ref.
<VueSignaturePad
:id="'signaturePad' + index"
width="100%"
height="300px"
:ref="'signaturePad' + index"
:options="options"
/>
The "undo" button is giving it "ref" with
<button #click="undo(`signaturePad${index}`)">Undo</button>
And the undo function itself has the first item in its ref array
undo(ref) {
this.$refs[ref][0].undoSignature();
}
Maybe someone has some more efficient way. Feel free :)

JQuery Filer post files on submit

Trying to use jquery.filer to upload images to my controller in asp.net mvc. Everything works as expected if I simply use the HTML file input type but once I enable the plugin it stops populating HttpPostedFileBase property.
After reading the documentation I couldn't find anyway of simply attaching the files to the input and uploading them on submit.
CONTROLLER
[HttpPost]
public ActionResult Create(IEnumerable<HttpPostedFileBase> files, ListingModel model)
{
return View(model);
}
JS
$("#filer_input").filer({
limit: 6,
maxSize: 5,
extensions: null,
changeInput: '<div class="jFiler-input-dragDrop"><div class="jFiler-input-inner"><div class="jFiler-input-icon"><i class="icon-jfi-cloud-up-o"></i></div><div class="jFiler-input-text"><h3>Drag&Drop files here</h3> <span style="display:inline-block; margin: 15px 0">or</span></div><a class="jFiler-input-choose-btn blue">Browse Files</a></div></div>',
showThumbs: true,
theme: "dragdropbox",
templates: {
box: '<ul class="jFiler-items-list jFiler-items-grid"></ul>',
item: '<li class="jFiler-item">\
<div class="jFiler-item-container">\
<div class="jFiler-item-inner">\
<div class="jFiler-item-thumb">\
<div class="jFiler-item-status"></div>\
<div class="jFiler-item-info">\
<span class="jFiler-item-title"><b title="{{fi-name}}">{{fi-name | limitTo: 25}}</b></span>\
<span class="jFiler-item-others">{{fi-size2}}</span>\
</div>\
{{fi-image}}\
</div>\
<div class="jFiler-item-assets jFiler-row">\
<ul class="list-inline pull-left">\
<li>{{fi-progressBar}}</li>\
</ul>\
<ul class="list-inline pull-right">\
<li><a class="icon-jfi-trash jFiler-item-trash-action"></a></li>\
</ul>\
</div>\
</div>\
</div>\
</li>',
itemAppend: '<li class="jFiler-item">\
<div class="jFiler-item-container">\
<div class="jFiler-item-inner">\
<div class="jFiler-item-thumb">\
<div class="jFiler-item-status"></div>\
<div class="jFiler-item-info">\
<span class="jFiler-item-title"><b title="{{fi-name}}">{{fi-name | limitTo: 25}}</b></span>\
<span class="jFiler-item-others">{{fi-size2}}</span>\
</div>\
{{fi-image}}\
</div>\
<div class="jFiler-item-assets jFiler-row">\
<ul class="list-inline pull-left">\
<li><span class="jFiler-item-others">{{fi-icon}}</span></li>\
</ul>\
<ul class="list-inline pull-right">\
<li><a class="icon-jfi-trash jFiler-item-trash-action"></a></li>\
</ul>\
</div>\
</div>\
</div>\
</li>',
progressBar: '<div class="bar"></div>',
itemAppendToEnd: true,
removeConfirmation: true,
_selectors: {
list: '.jFiler-items-list',
item: '.jFiler-item',
progressBar: '.bar',
remove: '.jFiler-item-trash-action'
}
},
dragDrop: {
dragEnter: null,
dragLeave: null,
drop: null
},
//uploadFile: {
// url: "./php/upload.php",
// data: null,
// type: 'POST',
// enctype: 'multipart/form-data',
// beforeSend: function(){},
// success: function(data, el){
// var parent = el.find(".jFiler-jProgressBar").parent();
// el.find(".jFiler-jProgressBar").fadeOut("slow", function(){
// $("<div class=\"jFiler-item-others text-success\"><i class=\"icon-jfi-check-circle\"></i> Success</div>").hide().appendTo(parent).fadeIn("slow");
// });
// },
// error: function(el){
// var parent = el.find(".jFiler-jProgressBar").parent();
// el.find(".jFiler-jProgressBar").fadeOut("slow", function(){
// $("<div class=\"jFiler-item-others text-error\"><i class=\"icon-jfi-minus-circle\"></i> Error</div>").hide().appendTo(parent).fadeIn("slow");
// });
// },
// statusCode: null,
// onProgress: null,
// onComplete: null
//},
addMore: false,
clipBoardPaste: true,
excludeName: null,
beforeRender: null,
afterRender: null,
beforeShow: null,
beforeSelect: null,
onSelect: null,
afterShow: null,
//onRemove: function(itemEl, file, id, listEl, boxEl, newInputEl, inputEl){
// var file = file.name;
// $.post('./php/remove_file.php', {file: file});
//},
onEmpty: null,
options: null,
captions: {
button: "Choose Files",
feedback: "Choose files To Upload",
feedback2: "files were chosen",
drop: "Drop file here to Upload",
removeConfirmation: "Are you sure you want to remove this file?",
errors: {
filesLimit: "Only {{fi-limit}} files are allowed to be uploaded.",
filesType: "Only Images are allowed to be uploaded.",
filesSize: "{{fi-name}} is too large! Please upload file up to {{fi-maxSize}} MB.",
filesSizeAll: "Files you've choosed are too large! Please upload files up to {{fi-maxSize}} MB."
}
}
});
HTML
<div class="form-group clearfix">
<div class="col-sm-12 padding-left-0 padding-right-0">
<input type="file" name="files" id="filer_input2" multiple="multiple">
</div>
</div>
It will not work if you are using drag&drop and uploadFile feature. If you want to get the files from <input type="file"> you will need to disable this 2 options in your jQuery.filer

firebase-collection : input value only updates first keystroke

I have a master-detail scenario. I'm using paper-datatable by David Mulder for my user-list. Data is populated through firebase collection
When tapping a row, a paper-dialog pops up with the details of the selected user.
When trying to edit a field, updating at firebase stops after one keystroke.
What am I missing?
<dom-module id="user-list">
<template>
<style>
:host {
#apply(--layout-vertical);
}
#editDialog {
min-width: 500px;
}
</style>
<firebase-collection location="https://<FIREBASE_APP>.firebaseio.com/users" data="{{users}}"></firebase-collection>
<paper-dialog id="editDialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<div>
<paper-input value="{{selectedUser.name}}" label="Name" class="flex"></paper-input>
<paper-input value="{{selectedUser.username}}" label="Username" class="flex"></paper-input>
</div>
<div class="buttons">
<paper-button dialog-confirm autofocus>Ok</paper-button>
</div>
</paper-dialog>
<paper-datatable id="datatable" selected-item="{{selectedUser}}" selectable on-row-tap="_onDetail" data="{{users}}">
<div no-results>
Loading or no more items...
</div>
<paper-datatable-column header="Name" property="name" type="String" sortable style="min-width: 160px"></paper-datatable-column>
<paper-datatable-column header="Username" property="username" type="String" sortable style="min-width: 40px"></paper-datatable-column>
</paper-datatable>
</template>
<script>
Polymer({
is: 'user-list',
behaviors: [
Polymer.NeonAnimatableBehavior
],
properties: {
type: String,
selectedUser: {
type: Object,
notify: true
},
users: {
type: Array,
notify: true
},
animationConfig: {
value: function() {
return {
'entry': {
name: 'fade-in-animation',
node: this
},
'exit': {
name: 'fade-out-animation',
node: this
}
}
}
}
},
_onDetail: function() {
var dialog = document.getElementById('editDialog');
if (dialog) {
dialog.open();
}
}
})
</script>
</dom-module>
It seems firebase-collection isn't currently meant to be used in this way, it's more of a view into a Firebase location with data that's in an array-like structure. Although with the exception that you can add/delete new items but not update existing ones. See https://elements.polymer-project.org/elements/firebase-element?active=firebase-collection.
That said, each item in the collection has a __firebaseKey__ property that you could use to directly update that item in firebase.

WinJS Two way Binding returning undefined

I am new to window8 development, I am basically trying to implement this link
http://msdn.microsoft.com/en-us/magazine/jj651576.aspx
I am using the view model as in figure8 in the link example, but I am unable to display the data, it shows the undefine, but if I only give one element of array I am able to bind it.
My UI is
<body>
<section aria-label="Main content" role="main">
<!-- display each person -->
<div id="nameLabel">Name</div>
<input id="name" readonly="true" type="text" data-win-bind="value: name" />
<div id="ageLabel">Age</div>
<input id="age" readonly="true" type="text" data-win-bind="value: age" />
<div id="colorLabel">Favorite Color</div>
<div id="color" data-win-bind="style.backgroundColor:favoriteColor"></div>
<div id="buttons">
<button id="previousButton"></button>
<button id="birthdayButton"></button>
<button id="nextButton"></button>
</div>
</section>
</body>
and the JavaScript contains
var people = [
// Notify binding listeners when these objects change
WinJS.Binding.as({ name: "John", age: 18, favoriteColor: "red" }),
WinJS.Binding.as({ name: "Tom", age: 16, favoriteColor: "green" }),
WinJS.Binding.as({ name: "Chris", age: 42, favoriteColor: "blue" }),
];
// Bind the current person to the HTML elements in the section
var section = document.querySelector("section[role=main]");
var current = 0;
var viewModel = WinJS.Binding.as({ person: people[current+1] });
WinJS.Binding.processAll(section, viewModel);
nextButton.onclick = function () {
current = (people.length + current + 1) % people.length;
viewModel.person = people[current];
};
This is the result:
Please help me to bind the UI with data model. Thanks in advance.
The problem happens because you've double wrapped a person with a WinJS.Binding. When you did that, you need to change the property path to:
data-win-bind="value: person.name"
When you created the viewModel property, it created a new property containing the actual person instance:
var viewModel = WinJS.Binding.as({ person: people[current+1] });
Also, note that there isn't two-way binding in WinJs.

Resources