My problem is larger than this example but I've composed an example test which exhibits the same behaviour.
The problem, how to attach/reattach the resizable event after dynamically adding an element to the page. I realise that this can be done with click events using something like $('.table1').on('click', 'tr', function() {alert("clicked!");}); which will show the alert when a new tr is added to the table and it is clicked, this uses event delegation. However the examples for using jQuery Resizable do not appear to cater for this, so how can it be done?
Heres my test case (for simplicity this is in a single test file):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Event Delegation Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<style>
#resizable { width: 150px; height: 150px; padding: 0.5em; }
#resizable h3 { text-align: center; margin: 0; }
</style>
<script src="//code.jquery.com/jquery-3.6.0.js"></script>
<script src="//code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script>
jQuery(document).ready( function($) {
$( function() {
$( ".resizable" ).resizable();// <--- How to add a delegated event on this?
} );
$( "button" ).click( function () {
$( "#size-region" ).append('<div id="2" style="width:150px; height: 100px;" class="ui-widget-content resizable"><h3 class="ui-widget-header">Not Resizable</h3></div>');
} );
} );
</script>
</head>
<body>
<div id="size-region" class="height: 90%; width: 100%;">
<div id="1" style="width:150px; height: 100px;" class="ui-widget-content resizable">
<h3 class="ui-widget-header">Resizable</h3>
</div>
</div>
<button>Click me</button>
</body>
</html>
Docs for jQuery Resizable are at https://jqueryui.com/resizable/
Info on event delegation is found at https://learn.jquery.com/events/event-delegation/
I mention the problem being larger, I believe i could just add the element with javascript for it but what if i have 10 other events to add? I'm specifically looking for a method where I can add a single js file and use this whatever is added to the size-region (if this is in fact possible)
Consider the following.
jQuery(function($) {
function makeResize(target) {
return $(target).resizable();
}
makeResize(".resizable");
$("button").click(function() {
var c = ($(".resizable").length + 1)
var newBox = $("<div>", {
id: "resize-" + c,
class: "ui-widget-content resizable"
}).css({
width: "150px",
height: "100px"
}).appendTo("#size-region");
$("<h3>", {
class: "ui-widget-header"
}).html("Resize " + c).appendTo(newBox);
makeResize(newBox);
});
});
#resizable {
width: 150px;
height: 150px;
padding: 0.5em;
}
#resizable h3 {
text-align: center;
margin: 0;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="//code.jquery.com/jquery-3.6.0.js"></script>
<script src="//code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<div id="size-region" class="height: 90%; width: 100%;">
<div id="resize-1" style="width:150px; height: 100px;" class="ui-widget-content resizable">
<h3 class="ui-widget-header">Resize 1</h3>
</div>
</div>
<button>Click me</button>
The initialization of a jQuery UI Widget cannot be delegated in the same way an Event can be. If you want to make a large number of elements be initialized with the same parameters, you can do this with a Function.
Looking at the makeResize() function, I pass in a variable, target that I then wrap so it is a jQuery Object and then initialize Resizable. This technique is very versatile as I can pass in a String, a element, or an object and it will work.
Examples:
$("button").click(function(){
makeResize(this);
});
Makes the button that was clicked upon resizable.
$(document).on("click", "button", function(){
makeResize(this);
});
Delegate the click event to any button that might be created and make it resizable.
I used more pure jQuery and this was my choice and it does not mean that your code, appending an HTML string, is wrong in any way. Two different approaches. I prefer my method as it is easier to read down the line, easier to manipulate or make small changes/fixes, and is easier to make more dynamic.
Your original code could work in a similar way:
$("button").click(function() {
$("#size-region").append('<div id="2" style="width:150px; height: 100px;" class="ui-widget-content resizable"><h3 class="ui-widget-header">Not Resizable</h3></div>');
makeResize("#2");
});
As the new HTML String has been added to the DOM, and is Rendered, we can call it by a selector, "#2".
The pitfall here is that if you click the button a 2nd or 3rd time, you now have multiple elements with the same ID when they need to be unique.
Last note, you do not need to wrap the jQuery in more than one Ready or Anonymous function. You do want to let all the HTML Load and be Ready before you execute your jQuery. This is what $(document).ready(function(){}); and $(function(){}); do for you.
Related
As the developer of the GAS code, the initial HTML dialog appears and functions properly. The html source for EnhancementsDialog.html is:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function onFailure(error) {
var div = document.getElementById('output');
div.innerHTML = "ERROR: " + error.message;
}
</script>
</head>
<body>
<style>
.button {
background-color: blue;
color: white;
padding: 10px;
border: none;
border-radius: 5px;
}
p.Lato{font-size: 20px; font-family: Lato,Arial,serif;}
</style>
<p class="Lato">
Please click the appropriate button for the type of Customization to be added.
</p>
<pre>
<input type="button" class="button" value="EVENT"
onclick="google.script.run.Add_Custom_Action('EVENT');
google.script.host.close);"
>
<input type="button" class="button" value="ENHANCEMENT"
onclick="google.script.run.Add_Custom_Action('ENHANCEMENT');
google.script.host.close;"
>
</pre>
</html>
The html is invoked from a pull down menu on a spreadsheet which calls this function:
function Add_Custom() {
var widget = HtmlService.createHtmlOutputFromFile("EnhancementsDialog.html");
//widget.setWidth(600);
widget.setHeight(175);
SpreadsheetApp.getUi().showModalDialog(widget,"dineDK");
} //end function Add_Custom
The buttons "EVENT" and "ENHANCEMENT" work for me and others except for one user on any browser he uses. Is there any specific system setting that would prevent the 'onClick' from working? The execution log shows me no information.
I am at a loss as to how to investigate this further. Help!
I'm learning how to code and I wanted to link a loading page to my HTML but it doesn't seem to be working. I got my code from here but it seems like it's not working at all. If you guys could identify the problem, that'd be great.
This is the code as of now:
<html>
<head>
<meta charset="UTF-8">
<title>Loading</title>
<link href="demo.css" rel="stylesheet" type="text/css">
<link href="normalize.css" rel="stylesheet" type="text/css">
</head>
<body>
</body>
</html>
I did not find your code.
So Here is a sample approach.
While the page is loading, image will be displayed at the middle of the page and the entire page is in transparent background. So Whenever your page gets loaded, then add hidden class to that image div.
Create 2 Classes one is to make div hidden.
.hidden{
display:none;
}
Second one to show image.
.show_image{
position:fixed;top:0;right:0;bottom:0;left:0;
background: rgba(0,0,0,0.5) url(/img/spinner.gif) no-repeat 50% 50%;
z-index:100;
background-size: 5ex;
}
And your HTML code would be
<div class="show_image"></div>
<div class="hidden box"> Your actual content </div>
Initially your content will be hidden state and loading image will be displayed.
After completion of page loading just toggle the hidden class.
$('.box').removeClass("hidden");
$('.show_image').addClass("hidden");
You can use load function to know that page is fully rendered.
$(window).load(function() {
//everything is loaded
});
So that your content will become visible and loading image will be hidden.
Let me know if you need to any help regarding Page Load.
you can try this one:
function onReady(callback) {
var intervalID = window.setInterval(checkReady, 1000);
function checkReady() {
if (document.getElementsByTagName('body')[0] !== undefined) {
window.clearInterval(intervalID);
callback.call(this);
}
}
}
function show(id, value) {
document.getElementById(id).style.display = value ? 'block' : 'none';
}
onReady(function () {
show('page', true);
show('loading', false);
});
DEMO HERE
I am building an Ionic app and I want to click on the image and change it with a different image. It is a toggle functionality.
I have the following class:
img{
&.default {
background-image: url("img/726-star.png");
&.activated{
background-image: url("img/726-star-selected.png");
}
}
And I apply the class as shown below:
<img class="default" style="width:38px;height:38px;margin-top:30px;"/>
But when I see in the Chrome Debugger tools I don't see the default class being applied. What am I doing wrong?
UPDATE: So, I am using DIV now instead of an image but I don't see the image displayed in the div:
#favImage {
&.default {
background-image: url("img/726-star.png");
}
&.activated {
background-image: url("img/726-star-selected.png");
}
}
<div id="favImage" class="default" style="width:38px;height:38px;margin-top:30px;"></div>
first of all i recommened you to sparate your style in the html to a css file.
second if you are using img tag don't forget to insert src attribute to the img tag other wise the img won't show.
to change the image by clicking on it i use JavaScript function that activated by write an attribute on the img tag "onclick" and call the JavaScript function.
the function take image id into a variable and with the use of a match method check if the image src contains string "726-star-not" if its not the image src changes to "726-star-selected" and vice versa.
to learn more about the match method
function myFunction() {
var image = document.getElementById('favImage');
if (image.src.match("726-star-not")) {
image.src = "img/726-star-selected.png";
} else {
image.src = "img/726-star-not.png";
}
}
#favImage{
width:38px;
height:38px;
margin-top:30px;
}
<html>
<head>
<link rel="stylesheet" href="css/style.css"/>
<script src="js/javascript.js"></script>
</head>
<body>
<img id="favImage" src="img/726-star-not.png" onclick="myFunction()">
</body>
</html>
I have a text field and an explaining div. Can I make this explaining div have opacity = 0 ONLY when I type something in the text field?
Thanks in advance for any help.
Here is the HTML code:
<input type='text' name='input' id="searchdevice" class="search-field" placeholder="" autofocus/>
<div id="explain">
Search your device in the text field
</div>
You can do it with just CSS if you set the input as required:
<input type='text' name='input' id='searchdevice' class='search-field' required='required' autofocus />
<div id='explain'>
Search your device in the text field
</div>
CSS:
/* Show by default */
#explain {
opacity: 1;
}
/* Hide it when input field has content */
#searchdevice:valid + #explain {
opacity: 0;
}
/* Remove "invalid" styling when input field is empty.
E.g. in Firefox, the input has a red box-shadow by default. */
#searchdevice:invalid {
box-shadow: none;
}
When you type something in the input field, it's "valid" and the #explain will have opacity of 0.
Browser support for the :valid selector: http://caniuse.com/#feat=form-validation
Demo: https://jsfiddle.net/2ozh40vp/1/
This will require JavaScript to listen to text input and hide the DIV.
Example using jQuery:
$('#searchdevice').on('input', function(){
$('#explain').addClass('hidden');
});
css:
.hidden {
opacity: 0;
}
Working fiddle: http://jsfiddle.net/spanndemic/kphgg2d0/
You can try:
$('#searchdevice').on('input', function(){
$('#explain').css('opacity', 0);
});
You only need this css line:
input:focus + #explain{opacity:0}
http://jsfiddle.net/kLLkyvyh/
Yes, javascript is good here though, functionality is kept where it belongs, responding to events in css is questionable practice. You'll want the keypress event for typing. The functions defined separately makes them easier to re-use.
var hideExplain = function() {
document.getElementById('explain').style.opacity='0';
}
document.getElementById('searchdevice').addEventListener("keypress", hideExplain);
see keypress example here
You might be better doing this though, as focus and blur will allow you to undo the effect when the user moves on. There's a show function included here too.
var showExplain = function() {
document.getElementById('explain').style.opacity='1';
}
document.getElementById('searchdevice').addEventListener("focus", hideExplain);
document.getElementById('searchdevice').addEventListener("blur", showExplain);
see the example here
You could use keypress to remove the tip and blur to reshow it, that way the tip would hang around for as long as possible for the user. See anothe example
Also, you would find it better to add and remove classes - here's an example with JQuery. Now your style classes are re-usable too.
CSS
.is-transparent {
opacity: 0;
}
.is-opaque {
opacity: 1;
}
JQuery
$('#explain').removeClass('is-opaque').addClass('is-transparent');
You can use this code:
<html>
<head>
<title>Some title</title>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type='text/javascript'>
$(document).ready(function(){
$('#searchdevice').blur(function(){
$('#explain').fadeTo(1000, 0);
});
});
</script>
</head>
<body>
<input type='text' name='input' id="searchdevice" class="search-field" placeholder="" autofocus/>
<div id="explain">Search your device in the text field</div>
</body>
</html>
Here you can try various effects through fadeto from the link - http://api.jquery.com/fadeTo/
I'm following this tutorial (Removed link as YouTube videos are not allowed on SO).
I can't understand why the banner wont flick through as it should, I have 4 images I intend it to flick through.
Also if anyone does solve this how can I make the images link to another page, e.g is it as simple as adding <a href=.......> in the HTML code?
HTML:
<script type="text/javascript" src:"jquery.js"></script>
<div id="banner">
<img src="images/banner1.jpg" class="active" />
<img src="images/banner4.jpg" />
<img src="images/banner2.jpg" />
<img src="images/banner3.jpg" />
</div>
javascript/jQuery
$(document).ready(function () {
setInterval(function () {
//Get current active image
var active = $('#banner .active');
// If there is another image(object) left then make that image next
// If not, go back to the first image of the banner div
if (active.next().length > 0) var next = active.next();
else var next = $('#banner img:first');
//Get the next image ready by modifying the z-index
next.css('z-index', '2');
//Fade out the active image, then
active.fadeOut(1000, function () {
});
//Move the active image to the back of the pile, show it and remove the active class
active.css('z-index', '1').show().removeClass('active');
//Make the next image the active one
next.css('z-index', '3').addClass('active');
});
}, 3000);
});
CSS
#banner {
position: relative;
margin-left: auto;
margin-right: auto;
height: 350px;
width: 950px;
margin-top: 10px;
}
#banner img {
position:absolute;
z-index:1;
}
#banner img.active {
z-index:3;
}
Right so to start with you don't have your script linked up.
You have:
<script type="text/javascript" src:"jquery.js"></script>
It should be:
<script type="text/javascript" src="jquery.js"></script>
As you have just put jquery.js that means if you homepage (whatever page is using it) is in C:\Users\Me\Documents\Website then jquery.js also needs to be in that same folder.
Then we move to the jQuery, its all ok untill the end of it. You close it with }, 3000);
but then try to close it again using });. The indentation also gives it away.
So when we fix that we get this DEMO HERE