I am working on an experimental project and I was trying playing around with javascript when I encountered this weird thing that I have no explanation for its behavior.I am using bootstrap 4 with CDN. SandboxCode
import React from 'react';
const Button = props => {
const showProps = e => {
e.preventDefault();
console.log(props.day, props.slot);
};
return (
<div>
<div data-toggle="modal" data-target="#myModal">
Click Me!
</div>
<div className="modal fade" id="myModal">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">Add / Edit Slot</h4>
<button type="button" className="close" data-dismiss="modal">
×
</button>
</div>
<div className="modal-body">
<form>
<div className="form-group">
<label>
<h6>Faculty</h6>
</label>
</div>
<div className="form-group">
<label>
<h6>Venue</h6>
</label>
</div>
<div className="form-group">
<label>
<h6>Subject</h6>
</label>
</div>
<button
type="submit"
className="btn btn-success btn-cons btn-block"
onClick={showProps}
>
Save
</button>
</form>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-danger btn-block"
data-dismiss="modal"
>
Close
</button>
</div>
</div>
</div>
</div>
</div>
);
};
export default Button;
this component provides a button which opens a modal when the Save button is clicked inside the modal then it console's two props (day and slot).
Its parent component is the main component which is then used In the App.js file to be rendered.
import React, { Component } from "react";
import Button from "./Button/Button";
export default class Main extends Component {
render() {
return ["Monday", "Tuesday"].map((day, dayIndex) => {
return [0, 1].map((slot, slotIndex) => {
return (
<Button key={dayIndex + "-" + slotIndex} day={day} slot={slotIndex} />
);
});
});
}
}
Excepted Result:- Upon clicking the button and clicking the save button in modal, each button should console different data depending on props.
Output:- All the save button clicks output the same thing.
I have been stuck on this for two days now and I have tried a lot of things.
Its an id issue :). Look at the below code:
<div data-toggle="modal" data-target="#myModal">
Make the id unique for every modal, otherwise no matter which button you click, it will bring up the modal for the first element it finds with the given id.
See the fixed code in this sandbox, basically changed these two lines to ensure a unique modal id:
<div data-toggle="modal" data-target={`#myModal_${props.day}_${props.slot}`}>
And
<div className="modal fade" id={`myModal_${props.day}_${props.slot}`}>
Related
I have a little problem with open one offcanvas from previous canvas. Generally I have canvas like this using bootstrap 5:
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasBottom" aria-controls="offcanvasBottom">Toggle bottom offcanvas</button>
<div class="offcanvas offcanvas-bottom" tabindex="-1" id="offcanvasBottom" aria-labelledby="offcanvasBottomLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasBottomLabel">Offcanvas bottom</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body small">
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#secondoffcanvas" aria-controls="offcanvasBottom" data-bs-dismiss="offcanvas">Open second offcanvas</button>
</div>
</div>
second offcanvas:
<div class="offcanvas offcanvas-bottom" tabindex="-1" id="secondoffcanvas" aria-labelledby="offcanvasBottomLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasBottomLabel">Offcanvas bottom</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body small">
second content
</div>
</div>
My scenario:
Click to open first offcanvas
Click on the button in canvas
Resulst:
first canvas hide
second canvas open
Read "how it works"...
"Similar to modals, only one offcanvas can be shown at a time."
However, you can open one from the other. Programmatically show the 2nd when the 1st is hidden...
var offcanvasBottom = document.getElementById('offcanvasBottom')
var secondoffcanvas = document.getElementById('secondoffcanvas')
offcanvasBottom.addEventListener('hidden.bs.offcanvas', function () {
var bsOffcanvas2 = new bootstrap.Offcanvas(secondoffcanvas)
bsOffcanvas2.show()
})
Demo
Thanks You #Zim. This resolve my issue. I have one question jet. What You think about identify if event was triggered from button on the offcanvas and no triggered from other place? Because now if You click in othe place second canvas is open too
try this
function toggle() {
document.getElementById('offcanvas').classList.toggle('show');
}
I'm new to Vue.js and I struggle with modals. I want to first load the modal window as a user navigates to a certain component. I tried to create some example modal and it opens if I click a button and trigger $('#modalId').modal('show'). But when I try to execute the same command from Vue's created () {...} It does not open a modal window. I don't want to open a modal window with a button click, I want to open as page/component loads.
<!-- This works fine -->
<button class="btn btn-dark" #click="openModal" data-target="#loginModal">Open modal</button>
<!-- MODAL -->
<div class="modal" ref="modal" id="loginModal" data-keyboard="false" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Insert required data</h5>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control">
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" data-dismiss="modal">Submit</button>
<a href="#" #click="logout" data-dismiss="modal">
<span>{{ $t('pages.userIconInHeader.signOut') }}</span>
</a>
</div>
</div>
</div>
</div>
...
export default {
name: 'test',
data () {
return {}
},
created () {
// HERE I WOULD LIKE TO OPEN MODAL. If it's even possible?
$(document).ready(function () {
this.openModal()
})
},
methods: {
openModal () {
$('#loginModal').modal('show')
},
...
Use in mounted without $(document).ready(function(){}):
mounted() {
this.openModal();
},
Don't mix jQuery and Vue. Vue works with Virtual DOM and you should update, show, hide elements according to Vue documentation, no work around with jQuery. This is article about creating modal in Vue, I hope it helps
https://alligator.io/vuejs/vue-modal-component/
mounted() {
this.showModal()
},
methods: {
showModal() {
this.$modal.show("model-name")
},
}
this can be used for opening model in vuejs
I have two Bootstrap Modal's in my Template.PageName.helper Meteor.callPromise() that I would like to fire-up in a specific order. The order being: modal.hide('loadingPageAnimation') followed by modal.show('c2bNotifications').
By default, modal.hide('loadingPageAnimation') is activated in the page Router.route('/page') by modal.show('loadingPageAnimation')
This successfully displays the modal.show(loadingPageAnimation) while (in my helper) my Meteor.CallPromise() is awaiting results:
../client/main
Meteor.callPromise('c2b').then(
function(results) {
//### When results comes through, Modal.hide('loadingPageAnimation')
Modal.hide('loadingPageAnimation');
//### then Modal.show('c2bNotifications' along with results message)
Modal.show('c2bNotifications', {msg: results};
}).catch( function(error) {
alert("Error!");
}
);
The problem here is that, when the Meteor.callPromise('c2b') returns results, the Modal.hide('newLoadingModal'); is successfully hidden, but the Modal.show('c2bNotifications', {msg: results}); only shows sometimes and sometimes it does not show. I would like some consistency in Modal.show('c2bNotifications', {msg: results}); always showing/working. Can anyone explain why this happens and perhaps give a better coding solution whereby Modal.show('c2bNotifications', {msg: results}); is forced to show?
Find below my template file.
../client/main.html
<template name="c2bNotifications">
<div class="modal fade makeAnOffer">
<div class="modal-dialog modal-sm">
<div class="modal-content modal_MakeAnOffer">
<div class="modal-header">
<h4 class="modal-title">Notification </h4>
</div>
<div class="modal-body">
<div id = approvedMsg > {{msg}} </div>
</div>
<div class="modal-footer c2bNotifications">
<button type="button" class="btn btn-primary btn-lg" id="paymentNotificationClose" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</template>
Looking forward to your help
First solution: What you can do is to add a little timeout to let the first modal the time to be hidden. Then call the Modal.show().
{
Modal.hide('loadingPageAnimation');
setTimeout(function(){
Modal.show('c2bNotifications');
}, 1000);
}
The problem is that you need to wait for the first modal to hide because there is no parameter to add a callback to the Modal.hide() function with the peppelg:bootstrap-3-modal package. If the code above really doesn't work, you can add this code
Modal.allowMultiple = true;
Second solution: I see you that you are using the first modal to show a loading sign, maybe you could add this sign into the c2bNotifications, and showing it with an helper like that :
<template name="c2bNotifications">
<div class="modal fade makeAnOffer">
<div class="modal-dialog modal-sm">
<div class="modal-content modal_MakeAnOffer">
<div class="modal-header">
<h4 class="modal-title">Notification </h4>
</div>
{{#if isLoaded}}
<div class="modal-body">
<div id = approvedMsg > {{msg}} </div>
</div>
<div class="modal-footer c2bNotifications">
<button type="button" class="btn btn-primary btn-lg" id="paymentNotificationClose" data-dismiss="modal">Close</button>
</div>
{{else}}
<!-- insert loading page animation -->
{{/if}}
</div>
</div>
</div>
</template>
And your helper code should look like that:
Template.c2bNotifications.helpers({
isLoaded(){
// return true if your Meteor.callPromise succeed, otherwise false
},
});
Third solution:
You could try to create a homemade callback, maybe by checking if the modal exist in the DOM.
I'm working on a reactjs project in which i have nav menus, and i'm using jquery modal pop up, one of my menus is "Import" which contains two sub menus "CCAWB & GAWB" i'm using react component to render these two submenus under "Import"
<li className="has-submenu">
<a href="#">
<span>Import</span>
</a>
<ul className="submenu">
<li>
<ul>
<RenderCCAWB_GAWBPopUp submenu ="CCAWB"/>
<RenderCCAWB_GAWBPopUp submenu ="GAWB"/>
</ul>
</li>
</ul>
</li>
RenderCCAWB_GAWBPopUp Component returns the following
render(){
return(<li onClick={this.handleShowModal}>
{this.props.submenu}
{this.state.view.showModal ? <UpdateQualityHeaderDummy
handleHideModal={this.handleHideModal} menuName={this.props.submenu} />:null}
</li>);}
on click of any of the sub menus "CCAWB/GAWB" i want to show the modal pop up
which's returned by another component
UpdateQualityHeaderDummy returns the modal itself
return (
<div className="modal" data-backdrop='static' id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog" >
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">{title}</h5>
<button onClick={this.closePop} type="button" className="close"
data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<div className="row">
<div className=" col-lg-12 col-xl-12
qcUpdateStatus">
</div>
<FileUpload menuTitle={this.props.menuName}/>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-dismiss="modal" onClick ={this.closePop}>Close</button>
<button type="button" className="btn btn-danger" data-dismiss="modal" onClick ={this.downloadFeed}>Download Feed</button>
<button type="button" className="btn btn-primary" onClick={this.validateForm}> Upload </button>
</div>
</div>
</div>
</div>);
} });
till here everything works fine and the modal shows up as attached bellow
[Screen 1 for the scenario ][1]
*= > the problem is here, whenever the mouse pointer leaves the browser (i.e goes to the url bar) the modal and the sub menus disappear but the modal opacity stays there (attached bellow)
Screen 2 when the pointer is outside the page
*= >but they show up immediately as soon as the pointer is back to the page (any where)
attached bellow screen 3
Screen 3 when the pointer is inside the page
*=> my trials: i have tried the event mouseleave(when mouse leaves the browser) and set the visibility of the sub menus as visible but they keep disappearing i even set the modal show property as true in the same event but also doesn't work.
$(document).mouseleave(function () {
$('.modal').css('visibility','visible');
$('#navigation > div > ul > li:nth-child(5) >
ul').css('visibility','visible');
$('#myModal > div').css('visibility','visible');
$('#myModal > div > div').css('visibility','visible');});
any suggestions please ?
I am using the bootstrap drop down for a div that contains buttons. The div appears and all, and I see in the dropdown class that a class of "open" is added and the drop down menu has an attribute of "aria-expanded" set to "true". I am pretty sure the bootstrap is working, but I am missing something.
Here is my cshtml template:
#using entryIconContent = Lifegunk.Engine.Resources.Components.EntryIcon
<div class="entry-icon-wrapper">
<div class="entry-type"></div>
<div class="dropdown actions-dropdown">
<div class="dropdown-menu entry-icon-actions">
<button class='change-btn btn btn-default'>
<div class="entry-type"></div>
<span>#entryIconContent.ChangeText</span>
</button>
<button class="move-btn btn btn-default">
<div class="icon-move"></div>
<span>#entryIconContent.MoveText</span>
</button>
<button class='go-btn btn btn-default'>
<div class="icon-arrow-right"></div>
<span>#entryIconContent.GoText</span>
</button>
</div>
</div>
<div class="dropdown entry-types-dropdown">
<ul class='dropdown-menu'></ul>
</div>
</div>
And here is my snippet of javascript code where I call the .dropdown() func:
$entryTypeIcon.click(function () {
if (isEditMode) {
$entryTypesDropMenu.dropdown("toggle");
renderEntryTypes();
} else {
$entryActionsDropdown.dropdown("toggle");
}
if ($entryTypesDropMenu.is(":visible")) {
$entryTypesDropMenu.hide();
$entryActionsDropdown.hide();
}
});//end $entryTypeIcon click handler