Is there a way in Angular 2 Material force align (say a chip with very long text) and not mess up with the form element under it?enter image description here
Fixed this by declaring a fixed width upon opening the dialog.
let dialogRef = this.dialog.open(ModalComponent, {
width: '250px'
});
Related
original title: VueJS with Bootstrap, stretched link with hidden button
I am trying to make clickable bootstrap cards in a VueJS project, I want clicking the card to open a collapsible element within the card, right now I have something that works using a button with the "stretched-link" class
<b-card
v-bind:img-src="`https://via.placeholder.com/200`"
img-alt="Image"
img-top
tag="article"
style="max-width: 20rem;"
class="mb-2">
<b-button v-b-toggle="'collapse-' + unique-identifier" variant="primary" class="stretched-link ">Toggle</b-button>
<b-collapse v-bind:id="'collapse-' + unique-identifier" class="mt-2">
<b-card>This is the collapsed content</b-card>
</b-collapse>
</b-card>
I'm trying to make this work without having a visible button in the card, I've tried using the invisibile class and the d-none class (class="stretched-link d-none" and class="stretched-link invisible")
In both cases, the button is made invisible but so is the stretched link. Is there any way to maintain the active stretched link area while hiding the button icon?
ok I figured out a solution for my particular use case with JQuery,
What I was really after was a clickable image with the functionality of a bootstrap button. So this is a solution for that problem, not exactly hidden stretched links.
In my Vue component I define the triggerButton method, which finds a button by its id and clicks it.
<script>
import $ from 'jquery'
export default {
props: //just filling this for structure,
data() {
return {
//stuff
}
},
async mounted() {
//more placeholder structure
},
methods: {
//here is the sauce
triggerButton(id) {
$("#"+id).click();
},
}
}
</script>
Then in the <template> body I have a hidden button. "unique-identifier" is just a unique number that is put in, it's needed in my case because im generating many of these elements in a for loop and they need to have distinct ids.
In this case I'm using the bootstrap button to trigger a unique modal.
<b-button style="display:none" v-bind:id="'button'+ unique-identifier" v-b-modal="'modal' + unique-identifier">Launch centered modal</b-button>
Then finally I have an image displayed in the bootstrap card, and on click i call the triggerButton method that will now display my modal.
<img v-on:click="showModal('button' + unique-identifier)" :src="`https://placekitten.com/g/200/200`"/>
Basically, I'm creating a form component that is contained inside a v-dialog. The form component will have different child components that are rendered based on select input. So I have to set width of v-dialog to "unset", so that the width of the dialog will stretch to match its content.
The transition works when I toggle the value of width, eg: either 450px or 300px. The problem is that I don't know beforehand the width of the form contains in the dialog, so I definitely need to use dynamic width.
So far, I can not find anyways to achieve transition when using dynamic width. I was trying to get the width of the form component using refs, but setting width to unset, prevent the transition. By the way, the transition I'm talking about is the transition of the width, when using fixed width, it shows nice transition but not for dynamic width
<div id="app">
<v-app id="inspire">
<div class="text-center">
<v-dialog v-model="dialog" width="unset">
<template v-slot:activator="{ on }">
<v-btn color="red lighten-2" dark v-on="on">
Click Me
</v-btn>
</template>
<v-card>
<v-select v-model="selectedForm" :items="items">
</v-select>
<div v-if="selectedForm==='form-a'" class='form-a'>FormA</div>
<div v-if="selectedForm==='form-b'" class='form-b'>FormB</div>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" text #click="dialog = false">
I accept
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</v-app>
</div>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
selectedForm: "form-a",
items: ["form-a", "form-b"],
dialog: false
};
}
});
codepen for using fixed width: https://codepen.io/duongthienlee/pen/MWaBLXm
codepen for using dynamic width: https://codepen.io/duongthienlee/pen/GRpBzmL
Noted that in the example i made in codepen, I defined width already, but the real case is that I don't know beforehand the width of form-a and form-b component. form-a and form-b width will be inherited by its parent div which is v-dialog, so that's why I set the width of v-dialog to be unset.
An example of what I mean "dynamic width": form-a has a select input. When user chooses an item, there will be a request to server to get input labels. So form-a will render multiple input fields based on the response body from server. The response body will contain label and default values information. So that makes the width of form-a becomes dynamic.
I think something like this can work for you.
Change v-dialog like so:
<v-dialog v-model="dialog" :width="forms.find(x => x.name===selectedForm).width">
Modify data() to return a forms prop:
data() {
return {
selectedForm: "form-a",
items: ["form-a", "form-b"],
dialog: false,
forms: [
{
name: 'form-a',
width: 200
},
{
name: 'form-b',
width: 1000
}
]
};
}
What you want to do is get the size of the rendered form, and then apply it to the dialog.
This is a common theme when attempting to animate content with dynamic dimensions.
One way to do this is by:
Set the form's visibility as hidden
Wait for it to render
Get the form's width and set it to the dialog
Unset the form's visibility
The tricky/hacky part is that you have to properly await DOM (setTimeout) and Vue ($nextTick) recalculations. I didn't have to await for Vue's $nextTick in this example, but you probably will if you're rendering nested form components:
<div class="form-container">
<div :style="formStyle('form-a')" class='form-a' ref="form-a">FormA</div>
<div :style="formStyle('form-b')" class='form-b' ref="form-b">FormB</div>
</div>
computed:{
formStyle(){
return form => ({
visibility: this.selectedForm == form ? 'inherit' : 'hidden',
position: this.selectedForm == form ? 'inherit' : 'absolute'
})
}
},
methods: {
async onSelectChange(form){
// async request
await new Promise(resolve => setTimeout(resolve, 1000))
this.selectedForm = form
this.recalculate()
},
async recalculate(){
// wait for DOM to recalculate
await new Promise(resolve => setTimeout(resolve))
const formEl = this.$refs[this.selectedForm]
this.dialogWidth = formEl.clientWidth
this.dialogHeight = formEl.clientHeight
},
...
}
Here's the working code to give you an idea:
https://codepen.io/cuzox/pen/yLYwoQo
If I understand you correctly, then this can be done using css. You can try replace all the fix width in the form with
width: fit-content;
For example in you codepen:
.form-a {
width: fit-content;
height: 350px;
background: blue;
}
.form-b {
width: fit-content;
height: 500px;
background: red;
}
The v-dialog renders into a div with class v-dialog:
It seems the animation only works when the the width is of known value, so it cannot be just "unset". The solution would be to get the width of the child element, and set the width of the v-dialog accordingly with a variable.
See VueJS get Width of Div on how to get the width of the child element.
Let me know if it works, I find this is very interesting.
i have like 4 textbox with required and i have a button name ‘add’ and another button for open a new page ..
the problem is where i’ m clicking at the button who open the new page they tell me to fill the text box .. is there any way to make the required working just for the « add » button ?
ps: í’m using content place holde and i already triyed to use but still not working
set the line width to zero...
series: {
5: {
type: 'line',
lineWidth: 0
}
}
How to put header in listview with GridLayout.
When I put header above listview my header take some height and last row in listview is not showed, because of header.
I also found a way to set header in listview directly:
data-win-options="{ header: select('.header') }">
With this my header is positioned on the left side of list, not above the list, like normal header should be.
I did not see any example with listview GridLayout and header section above (for instance I wanna put search box and heading in header).
Any example of this ?
Two solutions are here:
1) This is answer I get from Microsoft:
In the list view the WinJS.UI.GridLayout's viewport is loaded
horizontally.
You need to change the viewport's orientation to vertical. You can do
this by attaching the event onloadingstatechanged event.
args.setPromise(WinJS.UI.processAll().then(function () {
listview.winControl.onloadingstatechanged = function myfunction() {
if (listview.winControl.loadingState == "viewPortLoaded")
{
var viewport = listview.winControl.element.getElementsByClassName('win-viewport')[0];
viewport.className = 'win-viewport win-vertical';
}
}
}));
and change the class win-horizontal to win-vertical.
2) Problem could be also solved adding standard html header and list below header, without data-win-options="{ header: select('.header') }" attribute.
In that case we need to calculate height of the list:
.list {
height: calc(100% - headerHeight);
}
I'm trying to unstyle an input element so that its text looks like plain/inline-text, and I've reset pretty much every css property it can have, but I can't get the input's width to adjust/shrink to its content (input { width:auto; min-width:0; } does not work). It obeys an arbitrary width like input { width: 10px; }, so obviously its width is adjustable.
I see people trying to do it with javascript (the fiddle from the answer doesn't work anymore), so I'm wondering if what I want is even possible.
Here's a fiddle.
Played with this. Couldn't do it. What are you trying to achieve? Are you aware of the contenteditable attribute?
This might get you what you need.
https://developer.mozilla.org/en-US/docs/HTML/Content_Editable
What if you just avoid the whole style snafu and do a little text shuffling? You already have everything you need with jQuery.
http://jsfiddle.net/2fQgY/8/
The date is <span class="dateSpoof"></span><input class="myDate" type="hidden" value="foo" />.
Thanks for coming.
$('.myDate').datepicker({
showOn: 'button',
buttonText: 'select...',
onClose: function () {
var dateText = $(this).val();
$('.dateSpoof').html(dateText);
$('.ui-datepicker-trigger').hide();
},
dateFormat: 'd M yy'
});
Here's an example that's resettable: http://jsfiddle.net/2fQgY/11
And here's one that's all text and nothing but text: http://jsfiddle.net/2fQgY/14