browser-sync onchange event not fired on mirrored browsers - onchange

Browser-sync has a feature called "Interaction sync" that allows you to "scroll, click, refresh and form actions are mirrored between browsers while you test.", however it doesn't seem to work for the onchange event.
While React component `onChange` event not being triggered when synced with BrowserSync refers to it not working for React, it doesn't even work in a simple html with js.
A number of the forms we use have conditionally dependent fields, and this prevents you from completing a form of this type. Is there a way around this?
I have included a simplified version of this form below. To test this out:
take a copy of the below snippet and save it as an html file
navigate to the directory containing the html
open a command prompt, navigate to the html file, and run
browser-sync start --server
browser-sync will launch a browser containing the default url (http:localhost:port), append "/test.html" to the url
copy the url to another browser
You'll see that while the selection of the dropdown mirrors, the event and associated javascript don't fire.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<style>
.hide{
display:none !important;
}
</style>
</head>
<body>
<form>
<h1>Conditional Form</h1>
<label>dependee</label>
<select name="radioGroup" id="radioGroup" onchange="displayDependent();">
<option value="-1">--</option>
<option value="radio1">radio1</option>
<option value="radio2">radio2</option>
</select>
<div id="text1Group" class="hide">
<label>text1</label>
<input type="text" name="text1">
</div>
<div id="text2Group" class="hide">
<label>text2</label>
<input type="text" name="text2">
</div>
<div id="text3Group">
<label>text3</label>
<input type="text" name="text3">
</div>
</form>
</body>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<script>
function displayDependent() {
var dropDownSelect = document.getElementById('radioGroup').value;
// hide both
if (dropDownSelect == "-1") {
$("#text1Group").addClass("hide");
$("#text2Group").addClass("hide");
}
// show 1 hide 2
if (dropDownSelect == "radio1") {
$("#text1Group").removeClass("hide");
$("#text2Group").addClass("hide");
}
// show 2 hide 1
if (dropDownSelect == "radio2") {
$("#text2Group").removeClass("hide");
$("#text1Group").addClass("hide");
}
}
</script>
</html>

Doesn't look like it is available at this time.
Stumbled upon this github issue, shortly after:
https://github.com/BrowserSync/browser-sync/issues/22

Related

VueJS: Call function from bootstrap/jQuery script includes in template/layout from a component

i am very new to VueJS and want to build an Admin Dashboard for an existing bootstrap template (SB Admin Pro). I know there is a BootstrapVUE but we want to use the specified template that we purchased before. So this is not an option for me/us.
My Goal:
In our vue component we make an axios call to our backend to retrieve and show some data. If the call fails we want to call in the catch block a bootstrap function for toast to show some notification to the user (like: Error while fetching data from backend...). We included the bootstrap and jquery libraries from the template in the default index.html.
The Problem:
I don't know how to call the toasts (or other) functions from the vue component. In the template the call looks like this:
$("#toastBasic").toast("show");
Our index.html looks
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="svote UG (haftungsbeschränkt)" />
<script data-search-pseudo-elements defer src="js/font-awesome-5.11.2.min.js" crossorigin="anonymous"></script>
<script src="./js/feather.min.js" crossorigin="anonymous"></script>
</head>
<body class="nav-fixed">
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
</div>
<!-- built files will be auto injected -->
<script defer src="js/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script defer src="js/bootstrap.min.js" crossorigin="anonymous"></script>
<script defer src="js/script.js"></script>
</body>
</html>
Our vue component:
<template>
<main>
<div style="position: absolute; top: 1rem; right: 1rem;">
<!-- Toast container -->
<div style="position: absolute; bottom: 1rem; right: 1rem;">
<!-- Toast -->
<div class="toast" id="toastBasic" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
<div class="toast-header">
<i data-feather="bell"></i>
<strong class="mr-auto">Toast with Autohide</strong>
<small class="text-muted ml-2">just now</small>
<button class="ml-2 mb-1 close" type="button" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="toast-body">This is an example toast alert, it will dismiss automatically, or you can dismiss it manually.</div>
</div>
</div>
</div>
<ContentHeader title="Blank" icon="fas fa-file" subtitle="A blank page to get you started!" />
<div class="container-fluid mt-n10">
<div v-if="error" class="alert alert-danger" role="alert">
{{ error }}
</div>
<div class="row">
<Card cHeader="Eine Karte" class="col-md-12"> {{ contacts }}</Card>
</div>
</div>
</main>
</template>
<script>
import ContentHeader from '../../components/ContentHeader'
import Card from '../../components/Card'
import axios from 'axios';
export default {
name: "Contact",
components: {
ContentHeader,
Card,
},
data() {
return {
contacts: null,
error: null
}
},
mounted() {
const url = 'http://localhost:3000/v1/';
axios.get(url + 'contsact')
.then(response => {
this.contacts = response.data
console.log(response)}
)
.catch(error => {
console.log(error.response)
$("#toastBasic").toast("show");
});
}
}
</script>
In vue.config.js, specify jquery as external (this tells webpack where to provide jquery from when it's imported in any component):
configureWebpack: {
externals: {
jquery: 'window.jQuery'
}
}
Place all the <script>s you want loaded by the time Vue inits in your public/index.html page, in the <head> tag and remove their defer attribute. This includes any jquery plugin (or anything requiring/extending jquery) you might want to use in your Vue app (in your case, bootstrap.min.js).
The above will make it work when developing (in serve). You'll need to do the same for prod: Load jquery and any dependency before initing the Vue app.
Now you can safely use
import * as $ from 'jquery'
in any component.
Webpack will place in $ whatever window.jQuery is at the moment the component inits.
The above approach makes sure all required scripts are loaded before Vue inits (which is a bit extreme, but it makes sure there's no way you can call the jquery method before its dependencies are loaded).
If you don't want to wait for jquery and bootstrap.min.js to load before you init your Vue app, a trick you could use is to assign jquery from window object just before you need it:
yourAlertMethod() {
const $ = window.jQuery;
$.toast()...
}
Obviously, you no longer have to move all the scripts in <head> and to remove their defer. This second method doesn't guarantee they would have already loaded before your method is first used. But your app inits faster.
Here's a basic example.
I used the second method, codesandbox.io doesn't have support for #vue/cli v3 hence vue.config.js doesn't work as in a Vue project created with vue create. Therefore, I had to use the second method.
The full list of dependecies you need to load before you call the $(el).toast() method:
bootstrap.min.css
jquery.js
popper.js
bootstrap.min.js
(see them in public/index.html). You can copy/paste them from Bootstrap.
You can get ref of the element and pass it to jQuery
<div ref="toast" class="toast" id="toastBasic" role="alert" aria-live="assertive" aria-atomic="true" data-delay="5000">
import $ from 'jQuery';
$(this.$refs.toast).toast("show");
I don't recommend that though.

I'm trying to change the text of my div dynamically but it is not working

I'm trying to do something as simple as changing the text in my <p> tag from "hello" to "goodbye: but I can't get it to work.
Here is my html
<body>
<div id="passwordBox">
<!-- <div id="title">
<span>PASSWORD GENERATOR</span>
</div> -->
<p id="password">Hello</p>
</div>
</body>
here is my js
document.getElementById('password').innerHTML = "goodbye";
My js is linked correctly in my head. Other functions that I had in there were working correctly. So I'm wondering what the issue is. I'm sure it's something simple that I am just not seeing but I can't figure it out.
HTML execution happens top-down. HTML calls each script it finds while parsing the HTML document. Since you placed your script in "head" the script gets called immediately. When the script is called, your DOM is not yet ready and your script accesses your DOM element returning a null. So load the script after your DOM is loaded completely ie., after body or just before ""
So the ideal code should look like:
<html>
<body>
<div>
<p id="password">Hello</p>
</div>
</body>
<script>
document.getElementByID("password").innerHTML="goodbye";
</script>
</html>
Or you can still load your script from the head, but just add a button along with event listener (onClick) which calls the JavaScript function when the button is clicked.
<!DOCTYPE html>
<html>
<head>
<script>
function changeContent() {
document.getElementById("demo").innerHTML="goodbye";
}
</script>
</head>
<body>
<p id="password">Hello</p>
<button onclick="changeContent()">Try it</button>
</body>
</html>

HubSpot dropdown in form bug

On our website we use a HubSpot registration form with custom styling that loads in a fancybox popup.
This is how it should look
Our problem is that we need to add an 'on click trigger' (see HTML and JS below) to load the dropdown with the right styling We want to form to work properly without the trigger. Without the click trigger it looks like below:
Also the dropdown isn't working when this form appears.
Our code looks like:
<div class="popup-mask">
<div class="popup sm" id="popup-gartner-get-in-touch">
<h4 class="section-title blue">Get in touch</h4>
<div class="download-form">
<div class="hubpop">
<div class="download-form">
<!--[if lte IE 8]>
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2-legacy.js"></script>
<![endif]-->
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2.js"></script>
<script>
$('a[href="#popup-gartner-get-in-touch"]').click(function() {
hbspt.forms.create({
portalId: "538005",
formId: "190bdb23-c363-4d93-8189-9c7d28782017",
target:'.hubpop',
});
});
</script>
</div>
</div>
</div>
</div><!-- end popup -->
</div><!-- end popup-mask -->
My guess is that you are using some kind of jQuery plugin to style the dropdown. The problem is, your code for that is trying to style something that doesn't exist in the DOM until that trigger is clicked. What you should do is put that jQuery plugin code into the forms onReady function.
hbspt.forms.create({
portalId: '',
formId: '',
onFormReady: function($form) {
// YOUR CODE TO MODIFY THE SELECT DROPDOWN SHOULD GO HERE
console.log($form.find('select'));
}
});
If you're just looking to style the form selects without using a jQuery plugin, you can use this tool to get the css needed to do that.

Materialize - dropdown doesn't work

I am using materialize framework for ui design. If you look at my code , the dropdown doesn't show. Please help.
<div class="input-field col s3">
<select>
<option value="" disabled selected>Choose your option</option>
<option value="1">USD</option>
<option value="2">CAD</option>
<option value="3">HDK</option>
</select>
<label>Select Currency</label>
</div>
You must initialize the select in your JavaScript. Put the following code just before closing your bodytag and it should work fine.
<script>
$(document).ready(function() {
$('select').material_select();
});
</script>
First you must include file jquery in your html before your file materialize.js, then you must initialize the select element. In addition, you will need a separate call for any dynamically generated select elements your page generates.
Modify your code, see: Select Materialize
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="script.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.1/js/materialize.min.js"></script>
<script>
$(document).ready(function(){
$('select').material_select();
});
</script>
I have added complete code for materialize select in one html file. I have added JavaScript code bottom of the body which should be your problem for not working the code. When you create separate flies, you should add JavaScript and css files' paths to your html code relevant order.
<!DOCTYPE html>
<html>
<head>
<title>Select</title>
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body class="row">
<!-- your code start -->
<div class="input-field col s11 m11 l11">
<select>
<option value="" disabled selected>Choose your option</option>
<option value="1">USD</option>
<option value="2">CAD</option>
<option value="3">HDK</option>
</select>
<label>Select Currency</label>
</div>
<!-- your code end -->
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/js/materialize.min.js"></script>
<script>
$(document).ready(function() {
$('select').material_select();
});
</script>
</body>
</html>
When you add external libraries or files to your html file the order is important.
You must be sure that you initialize the select with jquery or JS.
Copy paste this line in your code in the document ready:
$('select').material_select();

Add Dynamically Links to jQuery Mobile

I read a lot about how to add stuff dynamically in jquery mobile, but I couldn't figure out how to add links.
Currently my solution looks like this:
Add a new Page - with id (id="list-1")
Creating a Link for it (href="#list-1")
This solution works perfectly in static pages, but I want to do it dynamically. I have tried a lot with page() and stuff like that but nothing helped me.
My questions are:
How do I add dynamic links & pages?
Did I choose the right way to use ids & anchors (#list-1) as links or is there another solution for jquery mobile?
Let me know if you need more information
To add dynamic links, I have found the easiest way is to just have an event listener waiting for a click on those links. This event listener then saves any parameters you want to pass into the next page you are visiting. You pass the parameters from the list element to the event listener by just specifying parameters within each "li" element.
(create the HTML for a list dynamically & store it into list-1-html)
$("div#my-page div[data-role=content]").html(list-1-html);
$("div.list-1 ul").listview();
$("div.list-1 ul").listview('refresh');
Then your event listener would look something like:
$('#my-page').delegate('li', 'click', function() {
passedParameter = $(this).get(0).getAttribute('passed-parameter');
});
When jQuery Mobile loads your next page, you'll probably want to load this page dynamically and you'll have this passedParameter variable available to you. To load the page dynamically, just add a listener that waits for JQM to try to load the page:
$('[data-role=page]').live('pageshow',function(e, ui){
page_name = e.target.id;
if (page_name == 'my-page-2'){
(do something with passedParameter)
}
});
This is the workflow I use with jQuery Mobile and it has been working just fine. I'm guessing in future releases, though, that they'll build in some kind of support for passing dynamic parameters to pages.
Any new enhancement to the DOM should be done before the page initializes. But by default JQM automatically initializes the page once the page is load in browser.
Hence first you need to set autoInitializePage property to false and then call initializePage() method after the new page and links are add to the document. Hope this helps.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script>
$(document).bind("mobileinit", function(){
$.mobile.autoInitializePage = false;
});
</script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script>
$(document).ready(function() {
//add a link.
$("#page1 div[data-role='content']").append('Next Page');
//add a page.
$('body').append(' <div data-role="page" id="page2" data-title="next page"><header data-role="header" class="header"> <h5>Page 2</h5></header><div data-role="content"><h3>Good Morning...</h3>Back</div><footer data-role="footer" data-position="fixed"><h5>© All rights reserved</h5></footer></div>');
});
window.onload = function() {
$.mobile.initializePage();
};
</script>
</head>
<body>
<div data-role="page" id="page1">
<header data-role="header" class="header">
<h5>jQuery Mobile</h5>
</header>
<div data-role="content">
<form method="get" action="" data-transition="slideup">
<label for="email">Email:</label>
<input type="email" name="email" id="email" value=""/>
</form>
</div>
<footer data-role="footer" data-position="fixed"><h5>© All rights reserved</h5></footer>
</div>
</body>
</html>