Vaadin with JQuery FileUpload - file-upload

I would like to create FileUploader with Vaadin . But I need to get more features over normal Vaadin Upload.
beautiful and easy to manage (but optional)
fast and never failed while uploading
include progress bar
show preview
multi file upload support
upload file size and type restriction
drag and drop
client-side image resizable (it is main feature for me because all of my uploaded files were images)
There has an addon MultiFileUpload. Yes , it is perfect for most of my requirements but not for client-size image resizing. So I decided to use JQuery FileUpload because it is support for Client side Image Resizing.
I used vaadin Window for upload image. But I got a problem while creating my window , very hard to create each HTML elements respectively (may be I have less exp). So I used CustomLayout with HTML for easy to create and edit design of my image uploader window.
Below is my custom layout HTML file. (two scripts were templates for image preview)
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload">
<td width="100px" align="center">
<span class="preview"></span>
</td>
<td width="400px" align="center">
<p class="name">{%=file.name%}</p>
{% if (!o.files.error) { %}
<div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar" style="width:0%;"></div></div>
{% } %}
{% if (file.error) { %}
<div><span class="label label-important">Error</span> {%=file.error%}</div>
{% } %}
</td>
<td width="100px" align="center">
{% if (!i) { %}
<button style="display: none;" class="start" type="button">
<span>Start</span>
</button>
<div class="v-button v-widget cancel" type = "button">
<span class="v-button-wrap" style="color: red;">
<span class="v-button-caption">Cancel</span>
</span>
</div>
{% } %}
<br>
{%=o.formatFileSize(file.size)%}
</td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download">
<td width="100px" align="center">
<span class="preview">
{% if (file.path) { %}
<img src="../{%=file.path%}" width="100px">
{% } %}
</span>
</td>
<td width="400px" align="center">
<p class="name">
{%=file.name%}
</p>
{% if (file.error) { %}
<div><span class="label label-important">Error</span> {%=file.error%}</div>
{% } %}
</td>
<td width="100px" align="center">
<span class="size">{%=o.formatFileSize(file.size)%}</span>
</td>
</tr>
{% } %}
</script>
<table cellpadding="5" style="width: 100%;">
<colgroup>
<col>
</colgroup>
<tbody>
<tr>
<td width="90px">
<div style="text-align: right; width: 120px;">UploadPhoto :</div>
</td>
<td>
<div id="pnlProgress" aria-valuenow="0" aria-valuemax="100" aria-valuemin="0" style="display: none;" class="progress progressall progress-success progress-striped active">
<div style="width: 0%;" class="allbar" id="pnlProgressBar"> </div>
</div>
</td>
</tr>
<tr>
<td colspan="3">
<div id="imageForm" style="width: 600px;">
<form id="fileupload">
<div style="margin-bottom: 10px; border: 1px solid #DDD; width: 600px; height: 300px; overflow: scroll">
<table cellspacing="0" cellpadding="5">
<tbody class="files"></tbody>
</table>
</div>
<div style="margin-bottom: 10px;" class="fileupload-buttonbar">
<div class="v-button v-widget btnPlus">
<span class="v-button-caption">Add Files</span>
<input type="file" multiple="" name="files[]">
</div>
<div class="v-button v-widget start" type = "submit">
<span class="v-button-wrap">
<span class="v-button-caption">StartUpload</span>
</span>
</div>
<div class="v-button v-widget cancel" type = "reset">
<span class="v-button-wrap">
<span class="v-button-caption">Cancel All</span>
</span>
</div>
</div>
<div style="border: 1px solid #999; width: 600px; height: 100px;" id="dropZone">
<div class="carPhotoDropMsg">
Draft & Drop Photos<br>(jpg, jpeg, png, gif only)
</div>
</div>
</form>
</div>
</td>
</tr>
</tbody>
Below is for ImageUpload window
public final class ImageUploadDialog extends CustomComponent {
private Window window;
public void show() {
UI.getCurrent().addWindow(window);
// 123 is seq for save in database or other use
Page.getCurrent().getJavaScript().execute("initImageuploader(123)");
}
public ImageUploadDialog() {
CustomLayout layout = new CustomLayout("imageUploadLayout");
window = new Window("Uploading Photos");
window.center();
window.setWidth("615px");
window.setModal(true);
window.setResizable(false);
window.setClosable(true);
window.setContent(layout);
}
}
And below is my upload.js file for initialize my image uploader
function initImageuploader(seq) {
$('#fileupload').fileupload({
url : 'photo/upload.html?s=' + seq,
sequentialUploads : true,
disableImageResize : false,
imageMaxWidth : 1024,
imageMaxHeight : 1024,
previewCrop : true,
dropZone : $("#dropZone"),
acceptFileTypes : /(\.|\/)(gif|jpe?g|png)$/i,
progress : function(e, data) {
if (data.context) {
var progress = data.loaded / data.total * 100;
progress = Math.floor(progress);
$('.progress').attr('aria-valuenow', progress);
$('.progress').css('display', 'block');
$('.bar').css('width', progress + '%');
}
},
progressall : function(e, data) {
var progress = data.loaded / data.total * 100;
progress = Math.floor(progress);
$('.progressall').attr('aria-valuenow', progress);
$('.progressall').css('display', 'block');
$('.allbar').css('width', progress + '%');
if (progress > 20) {
$('.allbar').text(progress + '% Completed');
}
},
stop: function (e) {
return;
}
});
}
And you need additional javascripts files for image uploader and I imported them at my UI class as below
#JavaScript({ "vaadin://themes/myproject/js/load-image.min.js",
"vaadin://themes/myproject/js/tmpl.min.js",
"vaadin://themes/myproject/js/jquery/jquery-1.10.1.min.js",
"vaadin://themes/myproject/js/jquery/vendor/jquery.ui.widget.js",
"vaadin://themes/myproject/js/jquery/jquery.iframe-transport.js",
"vaadin://themes/myproject/js/jquery/jquery.fileupload.js",
"vaadin://themes/myproject/js/jquery/jquery.fileupload-ui.js",
"vaadin://themes/myproject/js/jquery/jquery.fileupload-process.js",
"vaadin://themes/myproject/js/jquery/jquery.fileupload-image.js",
"vaadin://themes/myproject/js/jquery/jquery.fileupload-validate.js",
"vaadin://themes/myproject/js/canvas-to-blob.min.js",
"vaadin://themes/myproject/js/upload.js" })
#StyleSheet({ "vaadin://themes/myproject/css/jquery-ui-1.10.3.custom.min.css",
"vaadin://themes/myproject/css/imageUpload.css" })
public class EntryPoint extends UI {
..............
}
Please Notice for JS Files Order !
Below is my Custom CSS file for image upload window (imageUpload.css)
table.upld-status {
display: none;
}
.fileupload-buttonbar .btnPlus {
float: left;
position: relative;
overflow: hidden;
color: blue;
text-align: center;
margin-right : 10px;
}
.fileupload-buttonbar .btnPlus input {
margin: 0px;
position: absolute;
top: 0px;
right: 0px;
line-height: 30px;
font-size: 23px;
direction: ltr;
opacity: 0;
}
.carPhotoDropMsg {
color: #DDD;
font-size: 20pt;
height: 82%;
padding: 9px;
text-align: center;
}
.progress {
background-color: #F7F7F7;
background-image: linear-gradient(to bottom, #F5F5F5, #F9F9F9);
background-repeat: repeat-x;
border-radius: 4px 4px 4px 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset;
height: 17px;
overflow: hidden;
}
.progress-success.progress-striped .bar, .progress-success.progress-striped .allbar, .progress
striped .bar-success {
background-color: #62C462;
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
}
.progress.active .bar, .progress.active .allbar {
animation: 2s linear 0s normal none infinite progress-bar-stripes;
}
.progress-success .bar, .progress-success .allbar, .progress .bar-success {
background-color: #5EB95E;
background-image: linear-gradient(to bottom, #62C462, #57A957);
background-repeat: repeat-x;
}
.progress-striped .bar, .progress-striped .allbar {
background-color: #149BDF;
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-size: 40px 40px;
}
.progress .bar, .progress .allbar {
-moz-box-sizing: border-box;
background-color: #0E90D2;
background-image: linear-gradient(to bottom, #149BDF, #0480BE);
background-repeat: repeat-x;
box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.15) inset;
color: #FFFFFF;
float: left;
font-size: 12px;
height: 100%;
text-align: center;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
transition: width 0.4s ease 0s;
width: 0;
}
I need server-side control for save image . You need two jars apache-common-io and apache-common-fileupload. Below is for maven repository of these two jars.
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Finally , below is codes for server-side control .
#WebServlet(value = "/photo/upload.html")
public class UploadServletController extends HttpServlet {
protected final void doPost(final HttpServletRequest request,
final HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> fields = null;
try {
fields = upload.parseRequest(request);
}
catch (FileUploadException e) {
throw new RuntimeException("Error Parsing File Item " + e.getMessage(), e);
}
if (fields != null) {
String message = uploadPhoto(request, fields);
out.write(message);
}
}
public final synchronized String uploadPhoto(final HttpServletRequest request,
final List<FileItem> sessionFiles) {
List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>();
for (FileItem item : sessionFiles) {
if (!item.isFormField()) {
Long seq = Long.parseLong(request.getParameter("s"));
// get from vm arguments (eg:-DstaticDir=/Applications/springsource/workspace/myproject/src/main/webapp)
String staticDir = System.getProperty("staticDir");
Date today = new Date();
SimpleDateFormat fmtYMD = new SimpleDateFormat("/yyyyMMdd/HH");
SimpleDateFormat fmtHMS = new SimpleDateFormat("HHmmssS");
String saveDir = "data/photo" + fmtYMD.format(today);
String format = ".jpg";
try {
format = item.getName().substring(item.getName().lastIndexOf("."), item.getName().length())
.toLowerCase();
}
catch (Exception e) {
// nothing to do!
}
String fileName = seq + "_" + fmtHMS.format(today) + format;
Map<String, Object> res = new HashMap<String, Object>();
// Save image in specify location
String filePath = staticDir + "/" + saveDir;
saveFile(filePath, fileName, item);
res.put("seq", seq);
res.put("path", saveDir + "/" + fileName);
res.put("ext", format.substring(1));
res.put("name", item.getName());
res.put("size", item.getSize());
ret.add(res);
}
}
Map<String, Object> result = new HashMap<String, Object>();
result.put("files", ret);
JSONObject obj = new JSONObject(result);
return obj.toString();
}
public static String saveFile(final String filePath, final String fileName, final FileItem item) {
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
File imageFile = new File(file, fileName);
try {
item.write(imageFile);
}
catch (Exception e) {
e.printStackTrace();
}
item.setFieldName(filePath + fileName);
return item.toString();
}
}
I know my codes may have risks and some weakpoints . Every suggestions were welcome . But I believe there has some useful for newbie (I am also a newbie). Sorry for too long and bad format.
The last thing is my problem ....
Why preview image (after upload not before upload) automatically include url instead of filepath ? I got image not found error
"NetworkError: 404 Not Found - http://localhost:8080/myproject/VAADIN/themes/myTheme/data/photo/20140723/23/123_235918346.jpg"
Actually this image path should be data/photo/20140723/23/111_235918346.jpg. I have no idea why prefix url http://localhost:8080/myproject/VAADIN/themes/myTheme/ was automatically include (may be due to my CustomLayout HTML file path) ? File paths were got from HTTP response (with JSON). I think it is due to VAADIN because it works on my GWT project or may be I am wrong. Any suggestions ? Thanks for reading my question.

I fixed it by repairing src value of preview template for after upload image as ...
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) {; %}
<tr class="template-download">
<td width="100px" align="center">
<span class="preview">
{% if (file.path) { %}
<img src="/myproject/{%=file.path%}" width="100px">
{% } %}
</span>
</td>
<td width="400px" align="center">
<p class="name">
{%=file.name%}
</p>
{% if (file.error) { %}
<div><span class="label label-important">Error</span> {%=file.error%}</div>
{% } %}
</td>
<td width="100px" align="center">
<span class="size">{%=o.formatFileSize(file.size)%}</span>
</td>
</tr>
{% } %}
</script>
Now everythings were fine. If you didn't see image immidiately , please check your IDE (Eclipse or STS) setting as below
Preference > General > Workspace
and check checkboxes Refresh on access and Refresh using native hooks or polling.

Related

Switching to new window sometimes leading to error page in the new window while the parent window is working fine in the background

enter image description here
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0070)http://ussbyintv8057.acetst.com/Enterprise_CRS/CAT06/NewQuote/ast.aspx -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">
<title>Aboveground Storage Tank</title>
<meta name="vs_snapToGrid" content="False">
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
<link rel="stylesheet" type="text/css" href="./Aboveground Storage Tank_files/ACE.css">
<script language="JavaScript" src="./Aboveground Storage Tank_files/Calendar.js.download"></script>
<script language="javascript" src="./Aboveground Storage Tank_files/CommonFunctions.js.download">
</script>
<script language="javascript">
function Validate_Page() {
var err_msg = ""
if (document.all.txtASTID.value.length < 1) {
err_msg = "AST ID required;"
}
if (document.all.txtDate.value.length < 1) {
err_msg = err_msg + "Installation Date required.;"
} else {
if (!isDate(document.all.txtDate.value)) {
err_msg = err_msg + "Installation Date must contain a valid date.;"
}
}
if (document.getElementById("txtRetroDate").style.visibility != 'hidden') {
if (document.getElementById("txtRetroDate").value == "") {
err_msg = err_msg + "Retroactive Date required.;"
} else if (!isDate(document.getElementById("txtRetroDate").value)) {
err_msg = err_msg + "Retroactive Date must contain a valid date.;"
}
//CHANGE START QC ID 11096 - Release 3.8- DONE BY N9V333
else if (document.all.txtDate.value.length > 1 && isDate(document.all.txtDate.value)) {
if (new Date(document.getElementById("txtRetroDate").value) < new Date(document.getElementById("txtDate").value))
err_msg = err_msg + "Retroactive date cannot be prior to the tank installation date. Please correct;"
}
//CHANGE END QC ID 11096 - Release 3.8- DONE BY N9V333
}
if (!document.all.radlASTSecContainment_0.checked && !document.all.radlASTSecContainment_1.checked && !document.all.radlASTSecContainment_2.checked) {
err_msg = err_msg + "AST's Secondary Containment required.;"
}
if (!document.all.Radio1.checked && !document.all.Radio2.checked) {
err_msg = err_msg + "Please answer question concerning Piping Secondary Containment (Y/N);";
}
if (!document.all.Radio3.checked && !document.all.Radio4.checked) {
err_msg = err_msg + "Please answer question concerning Automatic Overfill / Spill Protection ....: (Y/N);";
}
if (document.all.txtGallons.value.length < 1) {
err_msg = err_msg + "AST Capacity entry required.;"
} else {
if (!isValidNumeric(document.all.txtGallons.value)) {
err_msg = err_msg + "AST Capacity must be numeric.;"
} else {
//Changes made on 2009-05-14 start
if (document.all.txtGallons.value > 49999 && document.getElementById("hdnIsUnderwriter").value != "1")
//Changes made on 2009-05-14 end
{
err_msg = err_msg + "AST Capacity cannot exceed 49,999.;"
}
}
}
if (document.all.selContents.value == -1) {
err_msg = err_msg + "Tank Contents selection required.;"
}
// CHANGE START: RELEASE 3.7.1 TURNING ON FL; QCID:9000 DONE BY: N9V333;
//debugger;
if (('Underwriter' == 'Underwriter')) {
if (('UW' == 'BK')) {
if (document.all.hdnState.value != "FL" && document.all.hdnRenVer.value == 1) {
//debugger;
if (document.all.txtRetroDate.value != "") {
var mindate = new Date(Date.parse("01/01/2010"));
var retro = new Date(Date.parse(document.all.txtRetroDate.value));
if (retro < mindate) {
err_msg = err_msg + "Retroactive Date cannot be prior to 2010."
}
}
}
}
} else {
if (document.all.hdnRenVer.value == 1) {
//debugger;
if (document.all.txtRetroDate.value != "") {
var mindate = new Date(Date.parse("01/01/2010"));
var retro = new Date(Date.parse(document.all.txtRetroDate.value));
if (retro < mindate) {
err_msg = err_msg + "Retroactive Date cannot be prior to 2010."
}
}
}
}
//CHANGE START: RELEASE 3.7.1 TURNING ON FL; QCID:9000 DONE BY: N9V333;
// 2.7b retro start
if ((document.all.hdn_appstate.value == 1 && document.all.hdnState.value != "FL") || (document.all.hdn_appstate.value == 1 && document.all.hdnState.value == "FL" && document.all.hdnRenVer.value != 1)) {
if (document.all.txtRetroDate.value != "") {
//Changes start for CRS-99
if ('Underwriter' == 'Broker') {
//Changes end for CRS-99
var diff_eff = new Date(Date.parse(document.all.hdnRetro.value));
var diff = new Date(Date.parse(document.all.txtRetroDate.value));
var year = (diff_eff.getFullYear()) - (diff.getFullYear());
if (year > 10) {
err_msg = err_msg + "Retroactive Date cannot be more than 10 years;"
}
//Changes start for CRS-99
}
//Changes end for CRS-99
//alert(diff_eff.getFullYear());
//alert(year);
//return false;
}
}
// 2.7b retro end
//hawaii start
if (document.all.hdnState.value == "HI" || document.all.hdnState.value == "KS") {
if (!document.all.Radio5.checked && !document.all.Radio6.checked) {
err_msg = err_msg + "Please answer question concerning AutomaticTankGauging ....: (Y/N);";
}
}
//hawaii end
if (err_msg.length > 0) {
//call the window to display the err_msg
//stop the user from going forward....until errors are corrected
//alert(err_msg)
//ie8
//window.open('../ErrorHandler/ErrorDisplay.aspx?error='+err_msg,'','menubar=no,status=yes,toolbar=no,height=' + (window.screen.availheight * .40) + ',width=' + (window.screen.availwidth * .60) + ',top=' + (window.screen.availheight * .20) + ",left=" + + (window.screen.availwidth * .20) );
window.open('../ErrorHandler/ErrorDisplay.aspx?error=' + err_msg, '', 'menubar=no,status=yes,toolbar=no,height=296,width=818,top=148,left=273');
//ie8
return false;
}
}
</script>
</head>
<body language="javascript" ms_positioning="GridLayout" style="background-color: #f7f3f7">
<form name="ASTF" method="post" action="http://ussbyintv8057.acetst.com/Enterprise_CRS/CAT06/NewQuote/ast.aspx" id="ASTF">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="">
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="">
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="GbJqOk+UZo3hc6eziOSe1TWs1YFJe8diotc3h7bt+nAPjwWT/5CejnvP3/CGLxHf5Nowh+weD3cK8ylbUVK8f+oSrZ8S196kSuvJHdZOmG1X7c/pNJcNEgo2UjVKYw9+jQWXgzXEBBjN1jfJC0ABAq6n4IpAwKaiQLBaXlFd7vsvy1ALlzBvCsWIwYHbYNfdsW0txHFS058RT3fmRjt8jxEC0xzFl+Z4loM2X1wuj7+QTqmfPESdZKgpcR89IYPVcIrOuQghc2v0tFsnniHjIaGu5JdkDr3Dk7cU79UPruFYwA+uh3EHKTc/qQKxw1SjIslHDdjE92hT9BuJto4R1MQGn96kT5NDkeRHMm7/n59W+G2g+V+4qV2gwJtGlF3J60p4uHkgngib7Ss05EyUZ8E8KwWN16FRKhtagYx9s3qVBg0+2ruvMiD6eQxa0NO2+uCRSltNXrZ3kXHoAGRInl0J7Mu9eP2CxPolwu8QHLW6VEyRQ3DB5gRrfrswxmBKfFrAQnW/WAQvJLl5kWdOJd+webpWoPxX0YOUiql/d/mujrHO++J842p//K+Dgx9Ve9LdllBnPSujeMPNflnsQmIH4Tibx8Oj9+nlC6EYCqTS0sW5dSIqlPnjsb7TnEy2kG+Yik1O4S+pkHWdLGf0QQo1xEkXKddQMBJMLWc4nt/71x9bzpxfPOwn7DHRGcLdgW9sXg1Q8iGyP0s/Tzdb0X0ZQfsMVYDvaAqmAKGq3LBjck6Vo/WxCJ+Dw8LBxIUOuHYjOr7qxkBwXpu8G1dsMEKdnx2/D2zHo6gI+Xp/C6SpquAOWBBExbnvRN7INwQWAJAkHLFUE0UMjXNBYBMAWAcHgD3vlbhM1AWYH40CNL6pZsPBvdefrIc+Q1apSFo4S6DzZSWLmO5zKNM5OGB27lL0JwWSPHfjBd/bfQ==">
<script type="text/javascript">
<!--
var theForm = document.forms['ASTF'];
if (!theForm) {
theForm = document.ASTF;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
// -->
</script>
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="431C18A6">
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="L8p4Ezi1hY1zmMsLghx4ZJ0i41/0K2tDT8Pa/1Lp5CGgl+/UgcpG1SQiGlcR4T/nBBKkPzRgWCLAXoFbjhOt5C0ydoSAyideL5w5VBPeR5hDQgxdMA+fG/l1Q+Sm5KLNKAyOKVyoHK/HzvHKW86894W4zruodHI5BJQbp1LWrtpBdgay9znmOa3q0PvT94XnT6jc/lQ1lubpSj0UD19DrlT0dFFoSkggeT8JkOR3fLGLei97UyeuMBG8vdUUvTQLZgZ9Hw5Cdjvipm3LFk56vggCyDMRJQUY8Sle85Sm96mqw70G9bo24MUFPP3ApGzvzQw9fsoZ/Gx/hQCU3gJBLdRFxDJmjHffN2ikkhQ4WEWYo+/JpYCSr/64mX17VwUwZ6TXpagqUadVbMTKM4ff0q8q2XVgB3baBRDqUwhDWzJ/9RJVJ0ckZ2mV4lN4vFmIz4MJ8PoRC65PYD0D9UiGtAikqcI1uO6nYSYhX9lQcCelAd0eZx7wggCfAokusbopVTQ+rp81x/EVwewjh730g7dKh+crGY2SUFVZNlHs4lbDyuWy32VxhTNvNJECFDz2+5McgNXe20nE3VWOzu8qGQnG9Qw/BzRMXHkqptmawZlCZYYQ7NtqaUOozq0FtjBprZbTHP4ydss9WLJX4qwQVt9qF+JWbrer+F1Qr4jEPmDE4z6BcqpRSglVUB8=">
<span id="Label1" class="StyledLabel" style="z-index: 100; position: absolute; top: 60px; left: 15px; bottom: 466px">Select AST:</span>
<a onclick="setDateField(ASTF.txtRetroDate);top.newWin = window.open('../calendar.htm','cal','dependent=yes,width=60,height=220,screenX=100,screenY=150,left=550,top=233,titlebar=yes')" href="javascript:doNothing()">
<img src="./Aboveground Storage Tank_files/calender_icon.png" id="Img3" style="z-index: 133; position: absolute; top: 137px; left: 385px; width: 22px;
height: 20px" border="0" alt="Popup Calendar">
</a>
<span id="Label12" class="StyledLabel" style="z-index: 130; position: absolute; top: 299px; left: 241px">No</span>
<span id="Label11" class="StyledLabel" style="z-index: 129; position: absolute; top: 279px; left: 240px">Yes</span>
<span id="Label10" class="StyledLabel" style="z-index: 126; position: absolute; top: 226px; left: 241px; bottom: 310px;">Yes</span>
<input value="Radio2" name="requirements2" type="radio" id="Radio3" style="z-index: 125; position: absolute; width: 13px; height: 20px; top: 282px;
left: 230px" tabindex="110" checked="checked">
<input value="Radio1" name="requirements2" type="radio" id="Radio4" style="z-index: 122; position: absolute; width: 13px; height: 20px; top: 302px;
left: 230px" tabindex="110">
<span id="Label9" class="StyledLabel" style="width:208px;z-index: 128; position: absolute; top: 277px; left: 16px">Automatic Overfill / Spill Protection and / or Electronic Leak Detection: </span>
<span id="Label8" class="StyledLabel" style="z-index: 127; position: absolute; top: 247px; left: 241px">No</span>
<input value="Radio2" name="requirements1" type="radio" id="Radio2" style="z-index: 124; position: absolute; top: 253px; left: 230px" tabindex="110">
<input value="Radio1" name="requirements1" type="radio" id="Radio1" style="z-index: 123; position: absolute; top: 232px; left: 230px; bottom: 295px;" tabindex="110" checked="checked">
<span id="Label6" class="StyledLabel" style="z-index: 121; position: absolute; top: 229px; left: 16px">Piping Secondary Containment:</span>
<select name="selAST" onchange="javascript:setTimeout('__doPostBack(\'selAST\',\'\')', 0)" language="javascript" id="selAST" tabindex="10" class="StyledDropDown" style="width:177px;z-index: 101; position: absolute; top: 60px; left: 232px">
<option value="-1">New AST</option>
<option selected="selected" value="184253">test 1</option>
</select>
<span id="Label2" class="StyledLabel" style="z-index: 103; position: absolute; top: 108px; left: 15px">Installation Date:</span>
<input name="txtDate" type="text" id="txtDate" style="z-index: 105; position: absolute; top: 110px; left: 232px; width: 145px" class="StyledText" tabindex="30" value="12/03/2018">
<input name="txtRetroDate" type="text" id="txtRetroDate" style="z-index: 132; position: absolute; top: 136px; left: 232px; width: 145px" class="StyledText" tabindex="30" value="12/03/2018">
<a onclick="setDateField(ASTF.txtDate);top.newWin = window.open('../calendar.htm','cal','dependent=yes,width=60,height=220,screenX=100,screenY=150,left=550,top=207,titlebar=yes')" href="javascript:doNothing()">
<img src="./Aboveground Storage Tank_files/calender_icon.png" id="IMG1" style="z-index: 116; position: absolute; top: 110px; left: 385px; bottom: 416px;
width: 22px; height: 20px" border="0" alt="Popup Calendar">
</a>
<span id="Label3" class="StyledLabel" style="z-index: 106; position: absolute; top: 160px; left: 16px">AST's Secondary Containment:</span>
<table id="radlASTSecContainment" class="StyledLabel" border="0" style="width:230px;z-index: 107; position: absolute; top: 160px; left: 220px;
font-weight: bold">
<tbody>
<tr>
<td><input id="radlASTSecContainment_0" type="radio" name="radlASTSecContainment" value="IM" checked="checked" tabindex="40"><label for="radlASTSecContainment_0">Impermeable</label></td>
</tr>
<tr>
<td><input id="radlASTSecContainment_1" type="radio" name="radlASTSecContainment" value="PR" tabindex="40"><label for="radlASTSecContainment_1">Permeable</label></td>
</tr>
<tr>
<td><input id="radlASTSecContainment_2" type="radio" name="radlASTSecContainment" value="NA" tabindex="40"><label for="radlASTSecContainment_2">None</label></td>
</tr>
</tbody>
</table>
<span id="Label4" class="StyledLabel" style="z-index: 108; position: absolute; top: 388px; left: 17px">AST's Capacity Gallons:</span>
<input name="txtGallons" type="text" value="12" maxlength="9" id="txtGallons" tabindex="50" class="StyledText" style="z-index: 109; position: absolute; top: 392px; left: 234px">
<span id="Label5" class="StyledLabel" style="z-index: 110; position: absolute; top: 415px; left: 19px">Tank Contents:</span>
<select name="selContents" id="selContents" tabindex="60" class="StyledDropDown" style="width:177px;z-index: 111; position: absolute; top: 420px; left: 234px">
<option value="-1">Contents</option>
<option value="Unleaded">Unleaded</option>
<option selected="selected" value="Diesel">Diesel</option>
<option value="Waste Oil">Waste Oil</option>
<option value="Fuel Oil">Fuel Oil</option>
<option value="Jet/Aviation">Jet/Aviation</option>
<option value="Ethanol">Ethanol</option>
<option value="Other">Other</option>
</select>
<input type="submit" name="btnAddTank" value="Add Additional AST" id="btnAddTank" tabindex="70" class="UsabilityButton" style="width:150px;z-index: 112; position: absolute; top: 470px; left: 20px; right: 805px;">
<input type="submit" name="btnDeleteTank" value="Delete this AST" id="btnDeleteTank" tabindex="80" class="UsabilityButton" style="width:136px;z-index: 113; position: absolute; top: 470px; left: 272px">
<input type="submit" name="btnSaveTank" value="Save" onclick="return Validate_Page();" language="javascript" id="btnSaveTank" tabindex="90" class="UsabilityButton" style="z-index: 114; position: absolute; top: 502px; left: 60px; width: 60px">
<span id="lblASTID" class="StyledLabel" style="z-index: 118; position: absolute; top: 84px; left: 15px">AST's ID:</span>
<input name="txtASTID" type="text" value="test 1" id="txtASTID" tabindex="20" class="StyledText" style="z-index: 119; position: absolute; top: 86px; left: 232px; bottom: 455px;">
<input type="submit" name="btnDone" value="Done" onclick="return Validate_Page();" language="javascript" id="btnDone" tabindex="100" class="UsabilityButton" style="z-index: 120; position: absolute; top: 502px; left: 311px; width: 60px">
<div style="padding: 0px 0 0 15.5px; width: 700px">
<!--
All .aspx pages using the control will have to set ActiveButton property for this control. The pages will
also have to call setLabelText() function on its body load.
-->
<!-- Start changes for UW Version Rating -- 16/02/2009-->
<!--<table width="80%" cellspacing="0" cellpadding="0">-->
<table width="100%" cellspacing="0" cellpadding="0">
<!-- End changes for UW Version Rating -- 16/02/2009-->
<tbody>
<tr>
<!-- ie8-->
<td height="5px"></td>
</tr>
<tr>
<td height="5" width="100%">
<table id="HeaderText1_TblBorder" cellspacing="0" cellpadding="0" border="1" class="subcontainer" width="773px">
<tbody>
<tr>
<td>
<table cellpadding="0" border="0" width="773px">
<tbody>
<tr>
<td valign="center">
<span id="HeaderText1_lblInsured" class="StyledLabelHeader">Insured's Name: safsdfdsf</span>
</td>
<td align="right" valign="center">
<span id="HeaderText1_lblQuote" class="StyledLabelHeader">Quote Number: Q164692 </span>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</form>
<span id="Label13" class="StyledLabel" style="width:120px;z-index: 131; position: absolute; top: 134px; left: 16px">Retroactive Date:</span>
<input name="hdnIsUnderwriter" type="hidden" id="hdnIsUnderwriter" value="1">
<!-- 2.8 Release -->
<input name="hdn_appstate" type="hidden" id="hdn_appstate" value="1">
<input name="hdn_state_effectivedate" type="hidden" id="hdn_state_effectivedate" value="4/6/2012">
<input name="hdnRetro" type="hidden" id="hdnRetro" value="12/3/2018">
<input name="hdnState" type="hidden" id="hdnState" value="CA">
<input name="hdn_statename" type="hidden" id="hdn_statename" value="CA">
<input name="hdninstalldate" type="hidden" id="hdninstalldate">
<!-- 2.8 Release -->
<!--CHANGE START: RELEASE 3.7.1 TURNING ON FL; QCID:9000 DONE BY: N9V333-->
<input name="hdnRenVer" type="hidden" id="hdnRenVer" value="1">
<!--CHANGE END: RELEASE 3.7.1 TURNING ON FL; QCID:9000 DONE BY: N9V333-->
</body>
</html>
Issue 1: Sometimes New window is openning, but with an Error. Attached the Screenshot for better idea.
Issue 2: Some while after switching back to parent window as per my code, it is unable to locate the element in the parent window. enter image description here
Code used to switch to a new window and handle the element in the window :
String winHandleBefore = driver.getWindowHandle();
driver.findElement(By.id("btnAddRemoveAST")).click();
for(String winHandle : driver.getWindowHandles())
{
driver.switchTo().window(winHandle);
}
driver.findElement(By.xpath("//input[#name='txtASTID']")).sendKeys("Test");
driver.close();
driver.switchTo().window(winHandleBefore);
driver.findElement(By.xpath("//input[#name='btnNext']")).click();
Pass the window title for below function if the window exit you have nothing to do with the driver.
You have to mark that step as failed .
public static void SwitchToPopup (this IWebDriver driver, string windowTitle )
{
driver.Wait(2);
driver.Sync();
string current = driver.CurrentWindowHandle;
foreach (string handle in driver.WindowHandles)
{
driver.SwitchTo().Window(handle);
if (driver.Title.Contains(windowTitle))
{
Reporter.Logtofile("Error window displayed: " + WindowTitle,Status.Info);
break;
}
}
}

How do I convert my vue into a component.vue

I have a fiddle that changes the contrast and brightness of an image.
When I try and add it as a .vue component onto my site the slider no longer effects the image. I know the issue is around my filter function. I just can't understand why my :style attribute isn't applying the change to me element.
What am I doing wrong/not getting?
fiddle that works - https://jsfiddle.net/BBMAN/fxtrtqpj/14/
code for my .vue component that does not work.
<template>
<div class="brightness-slider container">
<h1>{{ msg }}</h1>
<h2>Built using Vue.js</h2>
<div class="row">
<div class="col-md-10">
<img ref="img" class="img img-responsive" :style="filters" />
</div>
<div class="col-md-2">
<strong>Contrast ({{contrast}})</strong>
<input class="slider vertical" type="range" orient="vertical" v-model="contrast" max="1" min="0" step="0.01" />
</div>
</div>
<div class="row">
<div class="col-md-12">
<h4>
<strong>Brightness ({{brightness}})</strong>
</h4>
<input class="slider horizontal" type="range" v-model="brightness" max="3" min="0" step="0.01" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ImageBrightnessSlider',
data() {
return {
//sending data to view.
msg: 'Audience Republic Brightness Modifier',
brightness: 1,
contrast: 1
}
},computed: {
filters() {
const toDash = (str) => str.replace( /([a-z])([A-Z])/g, '$1-$2' ).toLowerCase()
debugger;
return { filter: Object.entries(this._data).filter(item => typeof(item[1]) !== 'object').map(item => `${toDash(item[0])}(${item[1]})`).join(' ') }
}
},
mounted() {
this.$refs.img.src = require('../assets/pleasure-garden-1200-by-768.jpg')
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
input[type=range][orient=vertical]{
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* WebKit */
width: 8px;
height: 100%;
padding: 0 5px;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 3px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
</style>
"fiddle that works" = incorrect
you are trying to shove HTML CSS JavaScript into Javascript!!!
interpreter Javascript does not understand HTML CSS!
you code must be something like this
index.html
<div id="App">
<!-- HTML code -->
</div>
<script>
// js code
</script>
<style scoped>
/* css code */
</style>
you have many mistakes, please see official documentation
also, you can see my vue examples
UPDATED:
SFC example

How to click on close(X) icon in iframe pop-up in selenium

//please check the code below for the close button
<div class="fancybox-wrap fancybox-desktop fancybox-type-iframe fancybox-opened" tabindex="-1" style="width: 557px; height: auto; position: absolute; top: 20px; left: 396px; opacity: 1; overflow: visible; display: block;">
<div class="fancybox-skin" style="padding: 0px; width: auto; height: auto;">
<div class="fancybox-outer">
<div class="fancybox-inner" style="overflow: auto; width: 557px; height: 385px;">
<iframe id="fancybox-frame1455168443258" class="fancybox-iframe" frameborder="0" allowfullscreen="" mozallowfullscreen="" webkitallowfullscreen="" hspace="0" vspace="0" name="fancybox-frame1455168443258" scrolling="auto" src="http://100stohappiness.dev-imaginovation.net/100s-happiness/100s-happiness/login" style="height: 460px;"/>
</div>
</div>
<a class="fancybox-item fancybox-close orange-color-bg" href="javascript:;" title="Close"/>
</div>
</div>
You first need to switch to the iframe
Java syntax, similar in all languages
String parentHandle = driver.getWindowHandle();
// switch to the new window
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parentHandle))
{
driver.switchTo().window(handle);
}
}
// click on close button
driver.findElement(By.className("fancybox-close")).click();
// switch back to the old window
driver.switchTo().window(parentHandle);

Rails: How do I autocomplete using the Google Places DB?

My application has an address field, which I want an autocomplete (updates as user types, displays below the entry field) for using the Google Places Autocomplete API. Now, I've seen gems which autocomplete words based on fields in a model, which wont work for me, since I can't store all the addresses on google places locally.
I've also tried a google_places_autocomplete gem which returns a list of suggestions when given an input string to autocomplete, but I don't know how to dynamically update the list as the input changes and present it in a nice format.
Can someone please give me an overview of which gems I should use and how I should go about doing this? I can display autocomplete suggestions using predefined addresses with the google_places_autcomplete gem which should mean I don't need to manually parse JSON.
you can do it directly on the view via Google Places javascript library.
Check out this example:
<!DOCTYPE html>
<html>
<head>
<title>Place Autocomplete Address Form</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script>
// This example displays an address form, using the autocomplete feature
// of the Google Places API to help users fill in the information.
var placeSearch, autocomplete;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
function initialize() {
// Create the autocomplete object, restricting the search
// to geographical location types.
autocomplete = new google.maps.places.Autocomplete(
/** #type {HTMLInputElement} */(document.getElementById('autocomplete')),
{ types: ['geocode'] });
// When the user selects an address from the dropdown,
// populate the address fields in the form.
google.maps.event.addListener(autocomplete, 'place_changed', function() {
fillInAddress();
});
}
// [START region_fillform]
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
// [END region_fillform]
// [START region_geolocation]
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = new google.maps.LatLng(
position.coords.latitude, position.coords.longitude);
autocomplete.setBounds(new google.maps.LatLngBounds(geolocation,
geolocation));
});
}
}
// [END region_geolocation]
</script>
<style>
#locationField, #controls {
position: relative;
width: 480px;
}
#autocomplete {
position: absolute;
top: 0px;
left: 0px;
width: 99%;
}
.label {
text-align: right;
font-weight: bold;
width: 100px;
color: #303030;
}
#address {
border: 1px solid #000090;
background-color: #f0f0ff;
width: 480px;
padding-right: 2px;
}
#address td {
font-size: 10pt;
}
.field {
width: 99%;
}
.slimField {
width: 80px;
}
.wideField {
width: 200px;
}
#locationField {
height: 20px;
margin-bottom: 2px;
}
</style>
</head>
<body onload="initialize()">
<div id="locationField">
<input id="autocomplete" placeholder="Enter your address"
onFocus="geolocate()" type="text"></input>
</div>
<table id="address">
<tr>
<td class="label">Street address</td>
<td class="slimField"><input class="field" id="street_number"
disabled="true"></input></td>
<td class="wideField" colspan="2"><input class="field" id="route"
disabled="true"></input></td>
</tr>
<tr>
<td class="label">City</td>
<td class="wideField" colspan="3"><input class="field" id="locality"
disabled="true"></input></td>
</tr>
<tr>
<td class="label">State</td>
<td class="slimField"><input class="field"
id="administrative_area_level_1" disabled="true"></input></td>
<td class="label">Zip code</td>
<td class="wideField"><input class="field" id="postal_code"
disabled="true"></input></td>
</tr>
<tr>
<td class="label">Country</td>
<td class="wideField" colspan="3"><input class="field"
id="country" disabled="true"></input></td>
</tr>
</table>
</body>
</html>
Source, with other examples:
https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform

Absolute position relative which parent in tables? (IE6 vs Firefox/Chrome)

I have a piece of code that do as I want in IE6 but not in Chrome/Firefox:
In IE6, the img is displayed with absolute position relative the td, as I wanted/expected. In Firefix/Chrome the img is displayed relative the outer div.
<div>
<table>
<tr>
<td class="rel cell">
<img src="style/easypos_mobile/icons/pencil.png" class="icon" onclick="_onclick.newArticle_andraNr();"/>
</td>
</tr>
</table>
</div>
.rel
{
position: relative;
}
.icon
{
position: absolute;
top: 3px;
right: -23px;
}
.cell
{
width: 186px;
}
Found this stuff:
The specs leave it open to the
User-Agent to decide if a table-cell
can act as a container for absolute
positioned objects.
http://www.w3.org/TR/CSS21/visuren.html#propdef-position
(note the 'effect of
'position:relative' on
table-row-group, table- header-group,
table-footer-group, table-row,
table-column-group, table-column,
table-cell, and table-caption elements
is undefined').
This fixed it:
<table><tr>
<td style="position: relative; width: 180px;">
<div style="position:relative;width:100%;height:100%;">
<img src="imageA.gif" class="status">
<img src="imageB.gif" class="status">
</div>
</td>
</tr></table>