Call JavaScript Function Contained on _Layout.cshtml - javascript

Please help, new web developer alert!
MVC + JavaScript :)
I have a .cshtml page that has a submit button. When I press that button I want to call a JavaScript function contained on my _Layout.cshtml page.
Unfortunately I get a function not found error.
'ReferenceError: validateCheckBoxesInForm is not defined'
Here is the cshtml page...
#model FrontEnd.Web.Areas.PresentationToPolicy.ViewModels.CaseSummary.InsurersReferralViewModel
#{
ViewBag.Title = "Refer To Insurers";
}
<div>
<form asp-area="PresentationToPolicy" asp-controller="CaseSummary" asp-action="ReferToInsurers" method="POST" id="documentDownload">
<div class="panel panel-danger">
<div class="panel-body" style="padding-bottom: 15px">
<div class="row">
<div class="col-md-12">
<input class="btn btn-success btn-lg" type="submit" value="Finish" onclick="validateCheckBoxesInForm(event, 'documentDownload', 'Whooops!', 'You Must Select At Least One Insurer For Referal')" style="max-width: 100%; width: 100%"/>
</div>
</div>
</div>
</div>
</form>
</div>
Here a cut down version of my _Layout.cshtml (the script is loaded just after bootstrap etc, at the start of the body)
#inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body style="background-color: #f6f8fa">
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-ui/jquery-ui.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/dist/manifest.js"></script>
<script src="~/js/dist/vendor.js"></script>
<script src="~/js/dist/scripts.js" asp-append-version="true"></script>
</environment>
<div class="container body-content">
#RenderBody()
<hr style="margin-bottom: 2px; padding-bottom: 2px" />
<footer>
<p style="vertical-align: baseline">© 2017 - ABACUS Portfolio Portal</p>
</footer>
</div>
#RenderSection("Scripts", required: false)
</body>
</html>
Oh and the script that contains the function!
function validateCheckBoxesInForm(event, formId, title, message) {
let validated = false;
let form = $(`#${formId}`);
let elements = form.elements;
event.preventDefault();
for (var i = 0; i < elements.length; i++) {
if (elements[i].type === 'checkbox') {
if (elements[i].checked) {
validated = true;
form.submit();
break;
}
}
}
if (validated === false) {
$('<div></div>')
.appendTo('body')
.html(
`<div id="validateModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content" style="border-color: #f00">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h3 class="modal-title">
${title}
</h3>
</div>
<div class="modal-body">
<h4>${message}</h4>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal" style="width: 150px">Ok</button>
</div>
</div>
</div>
</div>`
);
$('#validateModal').modal('show');
}
}
And finally a cut down version of 'View Source'
<body style="background-color: #f6f8fa">
<script src="/lib/jquery/dist/jquery.js"></script>
<script src="/lib/jquery-ui/jquery-ui.js"></script>
<script src="/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="/js/dist/manifest.js"></script>
<script src="/js/dist/vendor.js"></script>
<script src="/js/dist/scripts.js?v=iHOVZCmLJ7F7ev0DnwzRmkZgp-zu74ZoPGBIra9EaIk"></script>
<div class="container body-content">
<form method="POST" id="documentDownload" action="/PresentationToPolicy/CaseSummary/ReferToInsurers/43cffe87-2d8f-43eb-8ad2-e0b046fc8d20">
<div class="panel panel-danger">
<div class="panel-body" style="padding-bottom: 15px">
<div class="row">
<div class="col-md-12">
<input class="btn btn-success btn-lg" type="submit" value="Finish" onclick="validateCheckBoxesInForm(event, 'documentDownload', 'Whooops!', 'You Must Select At Least One Insurer For Referal')" style="max-width: 100%; width: 100%"/>
</div>
</div>
</div>
</div>
</form>
</body>
</html>
If I press view source and click on the script link I get this...
webpackJsonp([19],{
/***/ 749:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(750);
/***/ }),
/***/ 750:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
//Global Functions that will be run of every page
//Called via _Layout.cshtml
function validateCheckBoxesInForm(event, formId, title, message) {
var validated = false;
var form = $('#' + formId);
var elements = form.elements;
event.preventDefault();
for (var i = 0; i < elements.length; i++) {
if (elements[i].type === 'checkbox') {
if (elements[i].checked) {
validated = true;
form.submit();
break;
}
}
}
if (validated === false) {
$('<div></div>').appendTo('body').html('<div id="validateModal" class="modal fade">\n <div class="modal-dialog">\n <div class="modal-content" style="border-color: #f00">\n <div class="modal-header">\n <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>\n <h3 class="modal-title">\n ' + title + '\n </h3>\n </div>\n <div class="modal-body">\n <h4>' + message + '</h4>\n </div>\n <div class="modal-footer">\n <button type="button" class="btn btn-danger" data-dismiss="modal" style="width: 150px">Ok</button>\n </div>\n </div>\n </div>\n </div>');
$('#validateModal').modal('show');
}
}....
So I guess my question is how to I call the function contained on the _Layout page from the child cshtml page?
I guess I could use a script section on the page, but this function is shared by multiple places. So I kinda need a central location to keep the code dry.

Related

Razor Communicate Display of Modal from PageModel's OnPost() Method

I want to communicate from my Razor PageModel's OnPost() method to display the modal upon validation errors for it. Which basically means changing the modal's css from display none to block. Is there a way for this to be done?
Currently on return Page() the modal is hidden because thats what its css is initially set to, and is normally displayed on the user clicking the button to show it. I marked in my PageModel code where Id like the communication to occur
#page
#{
ViewData["Folder"] = "CourtUser";
<form asp-action="AddorEditUsersOnHearing" method="post" name="AddorEditUsersOnHearingForm" id="AddorEditUsersOnHearing">
<div class="container">
<div class="row">
<div class="col-md-8 mb-4">
<p>Add/Edit Users on <b style="font-style:italic">#Model.HearingName </b></p>
<div class="modal" tabindex="-1" role="dialog" id="AddUserForm">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add User</h5>
<button type="button" onclick="closeAddUserForm()" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="form-group" style="margin-top:5px;padding-left:45px">
<label asp-for="AddUserInput" style="width:100px"></label>
<input asp-for="AddUserInput" class="form-control col-4" id="EmailInputBox" style="display:inline-block" onchange="ValidateEmail()" />
<span style="display:block" asp-validation-for="AddUserInput" class="text-danger"></span>
</div>
<div class="modal-footer">
<button class="btn btn-primary" style="margin:0 auto" asp-page-handler="AddUser" name="AddUserSubmit" value="Yes">Submit</button>
</div>
</div>
</div>
</div>
<input asp-for="HearingId" type="hidden" />
<input asp-for="HearingName" type="hidden" />
<button type="button" class="btn btn-primary" onclick="ShowAddUserForm()">Add User</button>
<button style="float:right" class="btn btn-primary">Remove User(s)</button>
</div>
</div>
</div>
</form>
}
<script type="text/javascript">
function ShowAddUserForm() {
document.getElementById("AddUserForm").style.display = "block";
}
function closeAddUserForm() {
document.getElementById("AddUserForm").style.display = "none";
}
</script>
public IActionResult OnPostAddUser()
{
if (ModelState.IsValid)
{
if (AddUserInput == null)
{
ModelState.AddModelError("AddUserInput", "Please enter an email");
UsersonHearingList = HttpContext.Session.GetObjectFromJson<List<UsersModel>>("UsersonHearingList");
//*****This is where I want to communicate to the view to display the modal.*******
return Page();
}
}
else
{
return RedirectToPage("/Shared/Error");
}
}
You can try to use TempData.Here is a demo:
js:
#section Scripts
{
<script type="text/javascript">
$(function () {
if ("#TempData["Modal"]" == "Display")
{
ShowAddUserForm();
}
});
function ShowAddUserForm() {
document.getElementById("AddUserForm").style.display = "block";
}
function closeAddUserForm() {
document.getElementById("AddUserForm").style.display = "none";
}
</script>
}
handler:
public IActionResult OnPostAddUser()
{
if (ModelState.IsValid)
{
if (AddUserInput == null)
{
ModelState.AddModelError("AddUserInput", "Please enter an email");
UsersonHearingList = HttpContext.Session.GetObjectFromJson<List<UsersModel>>("UsersonHearingList");
//*****This is where I want to communicate to the view to display the modal.*******
TempData["Modal"] = "Display";
return Page();
}
}
else
{
return RedirectToPage("/Shared/Error");
}
}
result:

JavaScript + Bootstrap Dropdown list not allowing me to select the item

I have this bootstrap layout, which is a container inside an accordion-item. There is a dropdown button, containing messages and there's another button that opens a modal to insert a new message and display it in the dropdown list, using localStorage.
When the page loads or is refreshed, I can select the dropdown item normally, but when I add the item, it actually shows up in the list, but I can't select it nor any other item and the selected item is kept there, until the page is reloaded again.
I can still add more messages using the modal and they will still show up in the list.
There's no error in the console to guide me.
The JavaScript code is located at the bottom of the code.
Demonstrating video: https://www.youtube.com/watch?hd=1&v=fhNfpOaJbGs
HTML:
<div class="container">
<div class="row justify-content-center">
<div class="col-4">
<div class="dropdown">
<button class="btn btn-secondary" type="button" id="ddMensagens" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Selecione Mensagem
</button>
<div class="dropdown-menu scrollable-menu" id="mensagem" aria-labelledby="ddMensagens">
</div>
</div>
</div>
<div class="col-4">
<button type="button" class="btn btn-outline-success btn-sm" data-bs-toggle="modal" data-bs-target="#staticBackdrop" title="Clique para cadastrar uma nova mensagem">
Cadastrar Nova Mensagem
</button>
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="false" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalMensagem">Nova Mensagem</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col">
<div class="form-group">
<label for="txtMensagem">Digite sua mensagem</label>
<input type="text" class="form-control" id="txtMensagem" placeholder="Mensagem" style="width: 400px">
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-bs-dismiss="modal">Fechar</button>
<button type="button" class="btn btn-primary" id="saveMensagem" onclick="addItem();" data-bs-dismiss="modal">Salvar</button>
</div>
</div>
</div>
</div>
</div>
<br />
</div>
</div>
JavaScript:
<script defer>
function updateSelect() {
const select = document.querySelector('#mensagem');
const oldMessage = JSON.parse(localStorage.getItem('mensagem')) || false;
if (oldMessage) {
select.innerHTML = '';
oldMessage.forEach(element => {
select.innerHTML += `<button class='dropdown-item' type='button'>${element}</option>`
});
} else {
localStorage.setItem('mensagem', '[]')
}
}
function addItem() {
const text = document.getElementById('txtMensagem').value;
const database = JSON.parse(localStorage.getItem('mensagem')) || [];
if (database && text.length > 3) {
const repetido = database.find(item => item === text.value);
if (!repetido) {
const novasMensagens = [...database, text];
localStorage.setItem('mensagem', JSON.stringify(novasMensagens))
updateSelect();
text.value = ''
}
}
}
updateSelect()
</script>
LINKS:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" type="text/javascript"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Had to change in order to solve my issue (which I still don't know):
function getMensagem() {
let valueMensagem = document.getElementById('mensagem').value;
if (valueMensagem != 0) {
$('select option:selected').each(function (e) {
$('#ContentPlaceHolder1_ddMensagensCopy').val(valueMensagem);
});
}
else {
$('#ContentPlaceHolder1_ddMensagensCopy').val('');
}
}
function updateSelectMensagem() {
const select = document.querySelector('#mensagem');
const oldMessage = JSON.parse(localStorage.getItem('mensagem')) || false;
if (oldMessage) {
select.innerHTML = "<option value='0'> Selecione uma mensagem </option>";
oldMessage.forEach(element => {
select.innerHTML += `<option class='dropdown-item'>${element}</option>`
});
} else {
localStorage.setItem('mensagem', '[]')
}
}
function addItemMensagem() {
const text = document.getElementById('txtMensagem').value;
const database = JSON.parse(localStorage.getItem('mensagem')) || [];
if (database && text.length > 3) {
const repetido = database.find(item => item === text.value);
if (!repetido) {
const novasMensagens = [...database, text];
localStorage.setItem('mensagem', JSON.stringify(novasMensagens))
updateSelectMensagem();
text.value = ''
}
}
}
updateSelectMensagem()
<div class="col-4">
<div class="dropdown-boleto">
<select id="mensagem" class="btn btn-secondary select">
<option value="0">Selecione uma mensagem</option>
</select>
</div>
</div>
.select option {
background: white;
color: #212529;
}
In fact, everything works as expected
https://codesandbox.io/s/shy-cookies-1xt96?file=/index.html

Linking a modal to an entry field and validating using JavaScript

With the following code I'm trying to validate an entry field in JavaScript. The validation requires only 10 characters. When you authenticate, it is supposed to display a modal with a confirmation message:
function myFunction() {
var con_code, text;
//getting the field
con_code = document.getElementById("con_code").value;
if ($.trim($('con_code').val()).length == 0) {
text = "Authentication code is not valid";
}
//trigger to the modal if it meets the condition
$(document).ready(function() {
$("#con_code").click(function() {
$("#myModal").modal();
});
});
document.getElementById("error_con_code").innerHTML = text;
}
<div class="container">
<h2>Activate Modal with JavaScript</h2>
<!-- Trigger the modal with a button -->
<div class="form-group">
<label>Confirmation Code.</label>
<input type="text" name="con_code" id="con_code" class="form-control" required="required" placeholder="Enter your Confirmation Code" />
<br> //the error code display
<span id="error_con_code" class="text-danger"></span>
<br> //the authenticate button
<button type="button" class="btn btn-success btn-sm" id="con_code" onclick="myFunction()">Authenticate</button>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button> //the modal
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
However, it is not authenticating the confirm code. How can I fix it?
You have an error at:
if($.trim($('con_code').val()).length ==0){...}.
It should be $('#con_code')
Also you have 2 elements with the same id="con_code".
Please check with the following codes.
I am assuming you want to show the modal when there is 10 chars in the input field. If the rule changes, then please edit at: 'if ($.trim(con_code.val()).length != 10) {}' in the below codes.
$(document).ready(function() {
myFunction();
});
function myFunction() {
$("#con_code_btn").click(function() {
var con_code = $('#con_code');
var error_con_code = $('#error_con_code');
error_con_code.html('');// Remove Previous Error Message(if any);
if ($.trim(con_code.val()).length != 10) {
error_con_code.html("entication code is not valid");
}
else {
$("#myModal").modal();
}
});
}
Also please change the id of the button to "con_code_btn" in the form:
<button type="button" class="btn btn-success btn-sm" id="con_code_btn" onclick="myFunction()">Authenticate</button>

AngularJS Single Page App: Reference Error, ____ is not defined

In my Single Page App, specifically in the javascript file I am getting an error for uncaught reference for the reroll function. I do not understand what is causing this issue. Is my js file setup the wrong way?
The specific error stated is, Reference Error, reroll is not defined.
HTML:
<body ng-app="app">
<!-- == Main Controller for SPA == -->
<div class="container-fluid bg-dark text-white" style="height:700px" ng-controller="mainCtrl">
<!-- == App Title == -->
<h2 class="display-2 title-container text-center">{{main.title}}</h2>
<div class="row">
<div class="container-fluid word-container text-center">
<!-- == User Phrase Input == -->
<input type="text" ng-model="word" placeholder="Please enter word">
<br>
<br>
</div>
</div>
<div class="row">
<div class="container-fluid anagram-container text-center">
<!-- == Final anagram == -->
Anagram: {{anagram}}
</div>
</div>
<div class="row">
<div class="container-fluid button-container text-center">
<!-- Anagram "Reroll" Button -->
<button type="button" ng-click="reroll(word)" class="btn btn-primary btn-large">Reroll</button>
<!-- Anagram "Clear" Button -->
<button type="button" class="btn btn-primary btn-large" ng-click="word=''">Clear</button>
</div>
</div>
</div>
</body>
Javascript:
var app = angular.module("app", []);
app.controller('mainCtrl', function($scope) {
$scope.main = {};
$scope.main.title = "AnagramJS";
$scope.reroll = function reroll(value) {
// set anagram to randomize
$scope.anagram = value.split('').sort(function() {
return 0.5 - Math.random()
}).join('');
};
$scope.$watch('word', (newVal, oldVal) => {
if (newVal) {
reroll(newVal);
} else {
// empty anagram if word is empty
$scope.anagram = "";
}
});
angular.extend($scope, {
reroll
});
});
reroll(newVal) should be $scope.reroll(newVal);
Also remove the
angular.extend($scope, {
reroll
});

Bootstrap Modal and Badges

I have the following lines of code in my webpage - example/demo.
HTML:
<p data-toggle="modal" data-target="#messagesModal">Messages <span class="badge">2</span>
</p>
<!-- Modal -->
<div class="modal fade" id="messagesModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Messages</h4>
</div>
<div class="modal-body">
<div class="alert fade in">
×
<strong>Message 01</strong>:
<p>Lipsum Ipsum
</p>
</div>
<div class="alert fade in">
×
<strong>Message 02</strong>:
<p>Ipsum Lipsum</p>
</div>
</div>
<div class="modal-footer">
<div class="col-md-8 pull-left">
</div>
<div class="col-md-4">
<button type="button" class="btn btn-default pull-right" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
How can I update the badge to represent the correct amount of messages in the modal?
For example, when the user closes or removes a message in the modal, the badge will go from displaying the number 2 to 1?
Also, is it possible to display the text "There are no more messages." when all of the messages have been removed?
Try this:
//Find message number initially, before editing
$(".badge").text($(".alert").length);
//when the modal is closed
$('#messagesModal').on('hidden.bs.modal', function () {
//Set .badge text equal to the length of the .alert array, i.e the number of messages
$(".badge").text($(".alert").length);
//If there are no '.alert' divs, i.e. no messages
if ($(".alert").length == 0) {
$(".badge").text("No messages");
}
});
This takes all the .alert elements (messages) into an array, and sees how long that array is (i.e. how many messages there are).
Then, it updates .badge to reflect that number.
Working JSFiddle: http://jsfiddle.net/joe_young/62hbqmtp/
Well... I've spend some time, but all that you should do for now:
populate message array with your actual data;
add some actual AJAX for removing messages.
So...
$(function() {
var informer = $("#messageInformer a");
var refreshBadge = function(messageCount) {
var badge = informer.find(".badge");
if (messageCount > 0) {
if (!badge.length) {
informer.text("Messages ");
informer.append("<span class=\"badge\">" + messageCount + "</span>");
} else {
badge.text(messageCount);
}
} else {
informer.text("No messages");
}
};
var buildMessage = function(message) {
var htmlMessage = "<div class=\"alert fade in\">";
htmlMessage += "×";
htmlMessage += "<strong>" + message.title + "</strong>:";
htmlMessage += "<p>" + message.text + "</p>";
return htmlMessage;
}
// There should be real data
var messages = [
{ id: "1", title: "Message 01", text: "Lipsum Ipsum" },
{ id: "2", title: "Message 02", text: "Ipsum Lipsum" }];
refreshBadge(messages.length);
informer.on("click", function(e) {
e.preventDefault();
var modalBody = $(".modal-body");
modalBody.empty();
for (var i = 0; i < messages.length; i++) {
modalBody.append(buildMessage(messages[i]));
}
});
$("body").delegate(".alert .close", "click", function() {
var messageId = $(this).data("id");
// There should be some AJAX possibly
messages = messages.filter(function(el) {
return el.id != messageId;
});
if (messages.length == 0) {
$("#messagesModal").modal("hide");
}
refreshBadge(messages.length);
});
});
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<p data-toggle="modal" data-target="#messagesModal" id="messageInformer">Messages <span class="badge"></span>
</p>
<!-- Modal -->
<div class="modal fade" id="messagesModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Messages</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<div class="col-md-8 pull-left">
</div>
<div class="col-md-4">
<button type="button" class="btn btn-default pull-right" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>

Categories