Bootstrap 5 show some toasts on load - bootstrap-5

I have 2 different toasts on my view. One will show via js which works fine. The other is added on the server side html generation given a criteria and I want it to show on page load. The examples I see loop over all toasts on page load and show them which won't work for this as I don't want that because of the other toast I show in a given situation via js. I do specify the data-bs-autohide="false" but it still doesn't show after initialized. I guess I would think that data attribute would cause it to show when initialized?
This is the js initializing
var toasts = [].slice.call($(".toast"));
var toastList = toasts.map(function(t){ return new bootstrap.Toast(t, {});
The html of the toast I want to show on load if it exists (the server side feeding the html has an if condition in it to even add the toast html or not for this one).
<div class="toast align-items-center text-white bg-primary border-0"
role="alert" aria-live="assertive" aria-atomic="true"
data-bs-delay="5000" dat-bs-autohide="false">
<div class="d-flex">
<div class="toast-body">
Sucess
</div>
</div>
</div>

Related

How to find a link that has text nested in a div with Capybara?

I'm trying to find a link in my navbar, nested like so:
<div class="menu logged-out" id="loggedoutmenu">
<a href="/users/auth/twitter?state=navbar_basic" data-no-instant>
<div class="option"> via Twitter</div>
</a>
</div>
I've tried using the following methods and none of them have worked:
find_link("via Twitter")
find_link("via Twitter", {href: "/users/auth/twitter?state=navbar_basic"})
find('div', {class: 'option'})
Not really sure how to grab that element... The main goal is to test the link via click_link.
Edit:
Here's the full HTML structure:
<body>
<div class="top-bar" id="top-bar">
<nav>
<--- other nav elements not listed --->
<div class="navigation-butt desktop" id="navigation-butt">
<div class="menu logged-out" id="loggedoutmenu">
<a href="/users/auth/twitter?state=navbar_basic" data-no-instant>
<div class="option"> via Twitter</div>
</a>
</div>
</div>
</nav>
</div>
</body>
I'm guessing the menu is collapsed and you haven't done anything to open it, so the link isn't actually visible on the page. Assuming you just need to click on the '#loggedoutmenu' item to open the menu you could do something like
find('#loggedoutmenu').click.click_link('via Twitter')
which will click on 'loggedoutmenu' then look for the link inside it, and click the link when found. If clicking on '#loggedoutmenu' isn't how you open the menu then you'll need to provide more info.
Update: You have now indicated that the menu opens on hover - so assuming the user has to hover over an ancestor of the button you want to click you can do
find('<css selector for the visible element the user needs to hover over>').hover.click_link('via Twitter')
Writing my solution as an extension of Thomas Walpole's, which lead me to getting it. Thanks again, Thomas!
find('#navigation-butt').hover.click_link(href:"/users/auth/twitter?state=navbar_basic")
Edit: Updated my answer since the previous explanation was incorrect.

Why is my dynamically-added content not rendering with jQuery Mobile?

I'm using jQuery Mobile + Backbone + RequireJS. After successful login I do the following:
require(['app/view/main'], function(MainView) {
var mainView = new MainView();
$('body').html(mainView.render().el);
});
and render() looks like
render: function() {
this.$el.html(this.template);
return this;
}
Upon doing so, my page is blank. Inspecting the body, I do see the following HTML inside the body:
<div data-role="page" id="main">
<div data-role="header" data-position="inline">
<h1>Accounts</h1>
</div>
<div data-role="content">
hello
</div>
</div>
I've also tried doing this inside render():
this.$el.html(this.template).trigger('create');
as well as
this.$el.html(this.template).page();
but the page is still blank. Any ideas why?
If I simply put the HTML inside the body and load the page, it displays fine, like a normal jQuery Mobile app would.
Are you waiting until after pageinit to trigger / create your page?
$(document).bind('pageinit', function() {
// trigger
});
Also, jQM may be interpreting your markup as a single page template and then by injecting a data-role='page' element, you are marking up a multiple page document (with only a single page). Try leaving the <div data-role='page'> element in your default markup and then dynamically add the header, content and footer. jQM should then correctly interprete the markup and enhance it accordingly.

Dialog close event in jquery mobile

I am using jquery mobile and a dialog to display some multiple select boxes. Some of the content is dynamically created with Ajax based on the selections. I would like to make the Ajax call when the dialog is closed (through the regular x button). The main parts of the html look as follows:
<a href="#queryPage" data-rel="dialog" data-transition="slidedown" >Filter Results</a>
<div data-role="page" id="queryPage" data-theme="a">
<div data-role="header" data-theme="a">
<h1>Select Filters</h1>
</div>
<div data-role="content">
<form action="" method="get" id="filterForm">
<fieldset id ="filterFields"></fieldset>
</form>
</div>
</div>
I am currently making the call by running the code on page hide as follows:
$('#queryPage').live('pagehide', function(event) {
//code for ajax call
});
However, I would like to make the call when the dialog closes because some of the select lists are large and they create a new page that hides the queryPage even though the dialog has not been closed. I have tried:
$('#queryPage').bind('dialogclose', function(event) {
alert('closed');
});
and also tried
$('#queryPage').dialog({close:function(event, ui){
alert("closed");
}});
These I have put in a function called on page load but the alert is not shown when the dialog is closed. Any help will be appreciated.
There are no specific events for dialogs as they are simply pages that are displayed as a dialog. Try the pagehide event.
$("#MyDialog").bind("pagehide",function(){
alert("Dialog closed");
});
Also, the first line of your sample code has a link that is outside of a <div data-role="page"> which should not be done.
Pagehide can be delegated as such:
$(document).delegate("#MyDialog", "pagehide", function() {
alert("Dialog closed");
});
and you will also have access to the screen elements of the calling page.
Andleer shared the appropriate event for closing the dialog using jquery. however, we can also code in this way.
$(document).on("pagehide","#Dialog",function(){
console.log('Dialog has closed.');
});

How to use a template for all jQuery Mobile pages?

Behold: a footer template:
<!-- Templates -->
<script type="text/template" id="templateFooter">
<div data-role="navbar">
<ul>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</script>
In every mobile page I have:
<div data-role="footer" data-position="fixed">footer</div>
The way I'm currently loading the template is:
$(function() {
$('div[data-role=footer]').html($('#templateFooter').html());
$.mobile.activePage.trigger('create');
});
This works, but I don't really like using $(function(), but I need to load it if any page shows, so pageinit or pageshow does not help. I'll be using knockout.js going forward, if that is of any help.
Is there a better way to do this?
function getTemplateFooter() {
//return footer text here
}
$("div:jqmData(role='page')").live("pagebeforecreate",function() {
// get the footer of the page
// if footer doesn't exist on page, insert it where you want it... in this case after role="content"?
var $content =$(this).page().find('div:jqmData(role="content")');
$content.after(getTemplateFooter());
}
there is also a pageshow event, that one fires even if the user navigates to the page, through a back button press etc... it bubbles up to the page div
I use it for pages where lots of dynamic data could change between subsequent visits, or even when the user just presses back

Form checkboxes not being displayed correctly second time shown

I have a weird problem with a simple form with checkboxes..
The first time it's shown it looks fine.. But then after navigating back to the previous page and be to it again - the ui is not updates resulting in plain checkboxes without jQuery mobile style..
I've Googled like crazy and found a couple of hints like .fieldcontain(); but it's doesn't work =(
The data is being retrieved through knockout bindings..
Any good ideas?
Here's the code...
<div id="searchCitiesPage" data-role="page" data-theme="a" class="page searchCities">
<header data-role="header" data-theme="b">
</header>
<div data-role="content" class="content" data-theme="a">
<script id="countyListTemplate" type="x-jquery-tmpl">
<form id="fieldform" action="form.php" method="post">
<fieldset id="fieldsetgroup" data-role="controlgroup">
{{each BoligPortal.AdSearch.postalcodesInSelectedCounty}}
<input type="checkbox" name="checkbox-${zipcode}-${timestamp}" id="checkbox-${zipcode}-${timestamp}" class="zipcodecheckbox"/>
<label for="checkbox-${zipcode}-${timestamp}">${zipcode} ${city}</label>
{{/each}}
</fieldset>
</form>
</script>
<div data-bind="template: 'countyListTemplate'"></div>
<div class="submit">
Næste
</div>
</div>
I was having a problem like this too, but in my case, the checkboxes were being redrawn dynamically before loading the page. I tried refreshing:
$("input[type='checkbox']").checkboxradio("refresh");
But it gave me an error stating that checkboxradio hadn't been initialized. However, when I tried this instead:
$("input[type='checkbox']").checkboxradio();
It made the checkboxes appear correctly every time. I'm still fumbling in the dark with JQuery Mobile and can't say exactly what happens where and why (I think I'm initializing the checkboxes?), but I thought I would share for the next time someone like me googles their way to this thread.
You can add some javascript to re-initialize the jQuery Mobile markup for your checkbox on each page load. Something like this:
<script type="text/javascript">
$(function() {
$('[data-role=page]').live('pageshow',function(){
$('#fieldform').find('input').checkboxradio();
});
});
</script>
I would suspect this code
{{each BoligPortal.AdSearch.postalcodesInSelectedCounty}}
<input type="checkbox" name="checkbox-${zipcode}-${timestamp}" id="checkbox-${zipcode}-${timestamp}" class="zipcodecheckbox"/>
<label for="checkbox-${zipcode}-${timestamp}">${zipcode} ${city}</label>
{{/each}}
is being called again when you transition back to the page. I would suggest pulling the infomation/tags/etc.. before the page displays (on the first load) and display it statically. So when transitioning back it shows the same data.
of you could use one of the live events and restyle it before the page shows, example:
$('.zipcodecheckbox').live('pagebeforeshow',function(event, ui){
$("input[type='checkbox']").checkboxradio("refresh");
// or
$(".zipcodecheckbox").checkboxradio("refresh");
});

Resources