My Implementation of SimpleModal isn't working - simplemodal

I'm a total jQuery noob and I'm trying to use Eric Martin's SimpleModal Confirm Override dialog box in an ASP.Net web page. It's not working - no surprise, I have no idea what I'm doing! Here's a simplified version of my aspx page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Reimbursements.aspx.cs" Inherits="EAS.telecom.Reimbursements" MasterPageFile="~/common/default.master" Title="Reimbursements" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<%# MasterType VirtualPath="~/common/default.master" %>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type='text/javascript' src='~/jquery/confirm/js/jquery.js'></script>
<script type='text/javascript' src='~/jquery/confirm/js/jquery.simplemodal.js'>
$.modal('#confirm');</script>
<script type='text/javascript' src='~/jquery/confirm/js/confirm.js'></script>
<script language="javascript" type="text/javascript">
//some regular javascript here
</script>
<asp:Panel runat="server" ID="pnlEmployeeInfo" Enabled="false">
<div id='content'>
<div id='confirm-dialog'>
<h3>Confirm Override</h3>
<p>A modal dialog override of the JavaScript confirm function. Demonstrates the use of the <code>onShow</code> callback as well as how to display a modal dialog confirmation instead of the default JavaScript confirm dialog.</p>
<input type='button' name='confirm' class='confirm' value='Demo'/> or <a href='#' class='confirm'>Demo</a>
</div>
<!-- modal content -->
<div id='confirm'>
<div class='header'><span>Confirm</span></div>
<div class='message'></div>
<div class='buttons'>
<div class='no simplemodal-close'>No</div><div class='yes'>Yes</div>
</div>
</div>
<!-- preload the images -->
<div style='display:none'>
<img src='~/jquery/confirm/img/confirm/header.gif' alt='' />
<img src='~/jquery/confirm/img/confirm/button.gif' alt='' />
</div>
</div>
//more controls, including an AJAX TabContainer
</asp:Panel></asp:Content>
When I run the page, I see the Demo button and the Demo link, but clicking on them does nothing. What am I missing? Can I use SimpleModal on an ASP.Net page? Within a Content control? Thanks much!

Multiple issues here.
A script tag with a src cannot also contain script body. So, this is invalid.
<script src='~/jquery/confirm/js/jquery.simplemodal.js'>$.modal('#confirm');</script>
If you use an ID, SimpleModal is called like so: $('#content').modal();
That call needs to be within a click event handler.
<script>
$(document).ready(function () {
$('a.confirm').click(function () {
$('#content').modal();
});
});
</script>

Related

Passing value between files in Vue without node/npm

I'm trying to setup basic prototype web pages to test UX design in code. And want to recycle html files such as left navigation. Trying to use Vue to do this so that I can also learn Vue. I do not have access to the artifactory (company policy). So I cannot use things other than this http vue loader package that I found. So far, I was able to add external vue which is comp-nav. But from here, I want to pass title="Service" from index.html to comp-vue. How do I do that? Any help would be great! BTW, using Apache2 that came with mac to run.
index.html
<!DOCTYPE html>
<html lang="en">
<title>App</title>
<!-- Vue2 -->
<!-- from https://github.com/FranckFreiburger/http-vue-loader -->
<head>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
</head>
<body>
<div id="app">
<comp-nav title="Service"></comp-nav>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
components: {
'comp-nav': httpVueLoader('components/comp-nav.vue')
}
});
</script>
</body>
</html>
components/comp-nav.vue
<template>
<div id="nav">
<div class="nav-header">
<div class="header-title"><a>{{ title }}</a></div>
<div class="header-close">U</div>
</div>
<div class="nav-body">
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</div>
</div><!-- #nav -->
</template>
Based on the example from the docs, you could define a component prop in comp-nav.vue:
<template>
<div class="header-title">{{ title }}</div>
</template>
<script>
module.exports = {
props: ['title']
}
</script>

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.

Vuejs input file form

In my vue-bootstrap application I would like to use hidden input file control. When I use the standard input component it works (Load 1). If i try to do the same with the reactive component form vue-bootstrap library it does not work (Load 2). I would appreciate any hints what I might be doing wrong.
app = new Vue({
el: "#app",
data: {
files: '',
}
})
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" >
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
</head>
<body>
<div id="app">
<div>
<b-button #click="$refs.fileInput1.click()"> Load 1</b-button>
<input type="file" ref="fileInput1" style="display:none;"/>
</div>
<div>
<b-button #click="$refs.fileInput2.click()"> Load 2</b-button>
<b-form-file v-model="files" style="display:none;" ref="fileInput2" />
</div>
</div>
</body>
</html>
The $refs.fileInput2 here is referring to the Vue component, not really the input element, which is actually wrapped inside a div (you could see it if you inspect the rendered element). So one thing you could do (although it's ugly and not recommended, you should at least move this to the methods section):
app = new Vue({
el: "#app",
data: {
files: '',
}
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<div>
<b-button #click="$refs.fileInput1.click()"> Load 1</b-button>
<input type="file" ref="fileInput1" style="display:none;" />
</div>
<div>
<b-button #click="$refs.fileInput2.$el.querySelector('input[type=file]').click()"> Load 2</b-button>
<b-form-file v-model="files" style="display:none;" ref="fileInput2" />
</div>
</div>
Although I would say you should just use the native file input element since you are hiding the <b-form-file/> anyway.
It's working fine.You may check the below fiddle.
https://jsfiddle.net/tyagdvm5/
<b-form-file style="display:none;" v-model="file2" choose-label="Attachment2"></b-form-file>
Or for accurate solution please create a fiddle and upload the link.

button action with jQuery Mobile,

Having trouble constructing a button dynamically with jQuery Mobile. Copy and run. See notes in code.
<!DOCTYPE html>
<html>
<head>
<title>MSC Pre-Close Application</title>
<meta charset="utf-8"/>
<!-- standard Jquery/jQuery Mobile Libraries -->
<script src="jquery.mobile/jquery.js"></script>
<script src="jquery.mobile/jquery.mobile.js"></script>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile.css" />
<BR/>
<div data-role="page" id="mainmenu">
<div data-role="header" data-position="inline">
<h1>Main Menu</h1>
</div>
<div class="ui-body ui-body-c">
<div data-role="content">
<div class="ui-block-a"><button id="click_me" type="submit" data-theme="a" data-icon="home">Click me to change the button to my right</button></div>
<div class="ui-block-a"><button class="cl_pre_phone1" type="submit" rel="external" data-theme="a" data-icon="home">Primary Phone</button></div>
<script>
$(document).ready(function()
{
// this changes the label but not the href action.
$(".cl_pre_phone1").html("<a href='google.com'> Google</a>");
$("#click_me").click(function() {
alert("this should change the text and href of the button!");
// here I would like to change the value as well as the href action, but it does not work.
$(".cl_pre_phone1").html("<a href='yahoo.com'>Yahoo</a>");
//$(".cl_pre_phone1").append("<a href='yahoo.com'>Yahoo</a>");
//$(".cl_pre_phone1").append("<a href='yahoo.com'>Yahoo</a>").reload(true);
});
});
</script>
You're getting messed up by the enhancement which jQM does. Your button is getting rewritten to:
<span class="ui-btn-inner ui-btn-corner-all"><span class="ui-btn-text">Primary Phone</span>
<span class="ui-icon ui-icon-home ui-icon-shadow"></span></span>
<button class="cl_pre_phone1 ui-btn-hidden" type="submit" data-theme="a" data-icon="home" aria-disabled="false">Primary Phone</button>
One way round this would be to change the call inside the callback to:
$(".cl_pre_phone1").attr("href", "http://yahoo.com").parent().find(".ui-btn-text").text("Yahoo");
or you could replace the whole ui-block-a div.

Spring Roo with Dojo/Dijit declative menu bar?

I am trying to use the Dojo/Dijit declarative menu with Spring ROO 1.1.4, but even if I replace the complete roo generated menue.jspx with the example (ligthly addapted) from the Dojo/Dijit hompage, it does not replace the decorated menu divs with the menu.
that is how it look
that is how should look:
My modified menu.jspx
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:menu="urn:jsptagdir:/WEB-INF/tags/menu"
xmlns:sec="http://www.springframework.org/security/tags"
version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<script type="text/javascript">
dojo.require("dijit.MenuBar");
dojo.require("dijit.PopupMenuBarItem");
dojo.require("dijit.Menu");
dojo.require("dijit.MenuItem");
dojo.require("dijit.PopupMenuItem");
</script>
</head>
<div dojoType="dijit.MenuBar" id="navMenu">
<div dojoType="dijit.PopupMenuBarItem">
<span>
File
</span>
<div dojoType="dijit.Menu" id="fileMenu">
<div dojoType="dijit.MenuItem" onClick="alert('file 1')">
File #1
</div>
<div dojoType="dijit.MenuItem" onClick="alert('file 2')">
File #2
</div>
</div>
</div>
<div dojoType="dijit.PopupMenuBarItem">
<span>
Edit
</span>
<div dojoType="dijit.Menu" id="editMenu">
<div dojoType="dijit.MenuItem" onClick="alert('edit 1')">
Edit #1
</div>
<div dojoType="dijit.MenuItem" onClick="alert('edit 2')">
Edit #2
</div>
</div>
</div>
</div>
</jsp:root>
Can anybody give me a hint what I am doing wrong?
(I know the fallback to do the menu programmatic, but I want to do it declarative.)
The html header is looks like that:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=8" />
...
<script type="text/javascript">var djConfig = {parseOnLoad: false, isDebug: false, locale: '${fn:toLowerCase(userLocale)}'};</script>
<script src="${dojo_url}" type="text/javascript"><!-- required for FF3 and Opera --></script>
<script src="${spring_url}" type="text/javascript"><!-- /required for FF3 and Opera --></script>
<script src="${spring_dojo_url}" type="text/javascript"><!-- required for FF3 and Opera --></script>
<script language="JavaScript" type="text/javascript">dojo.require("dojo.parser");</script>
<spring:message code="application_name" var="app_name"/>
<title><spring:message code="welcome_h3" arguments="${app_name}" /></title>
</head>
I don't knows anything about Spring Roo, so maybe I'm saying something very stupid here...
Is that menu.jspx compiling into some static html? If this is the case, you can tell Dojo to parse your initial page simply by setting parseOnLoad to true on your djConfig
var djConfig = {parseOnLoad: true, ...}
(no need to require dojo.parser in this case).
On the other hand, if that template is inserted dinamicaly, you will need to call dojo.parser.parse() on the root 'navMenu' node yourself. You seem to be require-ing it, but I don't see where it is being called.
I had to use:
{
dojo.addOnLoad(function(){
dojo.parser.parse();
});
}
instead of parseOnLoad:true