Display javascript validation messages on the screen not alert messages? - javascript

I'm using struts1.3.8. I'm using struts ValidatorPlugIn for generating client side and server side validation messages.
Now client side javascript is generated by validator plugin. If there is any validation errors it is displaying in alert messages. But i want to display them besides the text field.
I'm still now working with alert messages only.. But now requirement changed. I tried but no use...
How to do it?
This is the code generated by plugin
`enter code here` function jcv_handleErrors(messages, focusField) {
if (focusField && focusField != null) {
var doFocus = true;
if (focusField.disabled || focusField.type == 'hidden') {
doFocus = false;
}
if (doFocus &&
focusField.style &&
focusField.style.visibility &&
focusField.style.visibility == 'hidden') {
doFocus = false;
}
if (doFocus) {
focusField.focus();
}
}
alert(messages.join('\n'));
}

Without specific information, all I can really suggest is a variation of the following:
window.alert = function(message){
console.log(message);
}
JS Fiddle demo.
Which simply ensures that any messages passed to alert() get passed, instead, to the console.log().
You could, instead, target the messages to a particular element:
window.alert = function(message) {
var output = document.getElementById('output'),
newTextContainer = document.createElement('p'),
text = document.createTextNode(message);
newTextContainer.appendChild(text);
output.appendChild(newTextContainer);
}
JS Fiddle demo.
Using either of these will break any usage of your alert() function in your page, though. So I'd suggest, instead, creating a new function with the latter example (immediately above) and calling that function, rather than over-writing alert().
With regards to creating a custom function to handle your alerts, as well as specify a particular element to which the new 'alerts' should be appended:
function newAlert(message, elem) {
// message is a string containing the message to display.
// elem is the id of the element into which the message should be displayed,
// defaults to an id of 'output' if no element is specified.
var output = elem ? document.getElementById(elem) : document.getElementById('output'),
newTextContainer = document.createElement('p'),
text = document.createTextNode(message);
newTextContainer.appendChild(text);
output.appendChild(newTextContainer);
}
JS Fiddle demo.
Edited in response to question from OP, below:
Next again submit the form I want to overwrite the previous error message. Not twice display the same message.
There are a couple of ways of doing this, assuming you only want to show the last of the error messages, rather than appending those error messages; in the first example I'm using a while loop to remove the firstChild of the output element and, when empty, appending the new error message:
function newAlert(message, elem) {
var output = elem ? document.getElementById(elem) : document.getElementById('output'),
newTextContainer = document.createElement('p'),
text = document.createTextNode(message);
while (output.firstChild){
output.removeChild(output.firstChild);
}
newTextContainer.appendChild(text);
output.appendChild(newTextContainer);
}
JS Fiddle demo.
An alternative is to get a reference to the first paragraph element in the output element (if one exists, otherwise create one) and then simply overwrite the text in that element:
function newAlert(message, elem) {
var output = elem ? document.getElementById(elem) : document.getElementById('output'),
textContainer = output.getElementsByTagName('p')[0] || output.appendChild(document.createElement('p'));
if (textContainer.firstChild){
textContainer
.firstChild
.nodeValue == message;
}
else {
textContainer
.appendChild(document
.createTextNode(message));
}
}

Related

window. onload=function() just works without cached DOM

The product image is displayed as inline SVG and receives a new color for specific paths, depending on the dropdown selection.
"use strict";
window.onload=function(){
var dropdownColor = document.getElementById('Color');
// When a new <option> is selected
dropdownColor.addEventListener('change', function() {
var selectPathSvg = document.getElementById('pathNumber');
//get value text
var colorValue= selectElemFerse.options[selectElemFerse.selectedIndex].text;
//Clear all Classes from SVGPath
selectPathSvg .classList = '';
// Add that class to the <p>
selectPathSvg.classList.add(colorValue);
})
}
But this Javascript code works only, if the page was read in the DOM for the first time. If you reload this page with F5, this will not lead to any errors in the console, but not to the desired result.
EDIT: Nothing here worked for me. But I noticed that if I delete the `woocommerce_recently_viewed``cookie, that the systems works fine. But how to fix such a thing?
It's generally bad practice to use onload = ... You should instead try using addEventListner("load", ...)
The reason your script does not run, is because it gets compiled after the page has been fully loaded, so you should also check if the load event has already been fired.
"use strict";
if(document.readyState === "complete") onLoad();
else addEventListener("load", onLoad);
function onLoad(){
console.log("Doing on load stuff here...");
}
Try this instead and see if it works:
window.addEventListener('DOMContentLoaded', (event) => {
var dropdownColor = document.getElementById('Color');
// When a new <option> is selected
dropdownColor.addEventListener('change', function() {
var selectPathSvg = document.getElementById('pathNumber');
//get value text
var colorValue= selectElemFerse.options[selectElemFerse.selectedIndex].text;
//Clear all Classes from SVGPath
selectPathSvg .classList = '';
// Add that class to the <p>
selectPathSvg.classList.add(colorValue);
})
});

Disable "Changes you made may not be saved" pop-up window

I use the following frontend code to export a .csv document.
HTML
<form id="tool-export" method="post" action="export/">{% csrf_token %}
<a id="export-link" class="btn btn-sm btn-primary" href="#">DOWNLOAD</a>
</form>
JS
$('#export-link').click(function(e) {
e.preventDefault();
var link = $(this);
var form = link.closest('form');
var project_id = proj_id.find(":selected").val();
var input = $('<input>').attr('type', 'hidden').attr('name', 'project_id').val(project_id);
form.append($(input));
var project_type = proj_type.val();
input = $('<input>').attr('type', 'hidden').attr('name', 'project_type').val(project_type);
form.append($(input));
form.submit();
});
Export works well and I get the correct document. But also I receive the Changes you made may not be saved message after clicking on the export link. How to disable this message? I don't want to see it.
#Dekel helped me to get it.
The message is the beforeunload event.
And I can disable it with window.onbeforeunload = null;.
JS
$('#export-link').click(function(e) {
window.onbeforeunload = null;
e.preventDefault();
var link = $(this);
var form = link.closest('form');
var project_id = proj_id.find(":selected").val();
var input = $('<input>').attr('type', 'hidden').attr('name', 'project_id').val(project_id);
form.append($(input));
var project_type = proj_type.val();
input = $('<input>').attr('type', 'hidden').attr('name', 'project_type').val(project_type);
form.append($(input));
form.submit();
});
In jQuery simply use :
$(window).off('beforeunload');
I had the same problem.
window.onbeforeunload = function () {
// Your Code here
return null; // return null to avoid pop up
}
I've had the same error with embedding Google-Form in Chrome,
I can verify that none of the found solutions helped me. Here is the screenshot of my pop-up:
The only solution I've managed to implement was hiding the element and then unhiding/creating the new iframe with the current embed. Here's the part of my code:
if (oldvalue !== value) { // checks the id of the form (value) is not the same
// set value of the id
$('#info').text(value);
// check the element exists
let exists = value;
if($("#" + value).length == 0) {
//it doesn't exist
exists = false;
}
// hide all child elements of the div for forms
parent.children().hide();
// create new node if needed
if (!exists)
{
// create new form element and embed the form
$("#google-form").clone().attr("id",value).attr('src', record.url).appendTo(parent);
}
// unhide error element
$("#" + value).show();
}
The full code of my solution is here.

Pasting text with the mouse doesn't trigger search

For selectize.js with ajax search inserting text by mouse not cause search
It's can be simle reproduced on http://brianreavis.github.io/selectize.js page.
On Remote Source — Github example:
focus on field
delete selected
insert text any text by mouse (not
by ctrl+v)
no result
How to fix it?
Update
For catching event by jquery bind method. Selectize on method can't catch it (bug?).
$('.selectize').bind('input', function(){
// force selectize to make ajax call and show result
});
// following code catch nothing
$('.selectize')[0].selectize.on('input', function(){
// force selectize to make ajax call
});
But can't find solution for forcing selectize ajax call
You can find fix on the issue page https://github.com/selectize/selectize.js/issues/882
the code
onPaste: function(e) {
var self = this;
if (self.isFull() || self.isInputHidden || self.isLocked) {
e.preventDefault();
} else {
// If a regex or string is included, this will split the pasted
// input and create Items for each separate value
setTimeout(function() {
if (self.settings.splitOn) {
var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn);
for (var i = 0, n = splitInput.length; i < n; i++) {
self.createItem(splitInput[i]);
}
}
self.onKeyUp(e);
}, 0);
}
},

redips.drag get row id when row is dropped and send to server

I am building a django site and have implemented the redips.drag library in one of my pages to allow dragging of table rows. I want a very simple functionality in my code- add a listener, so when the row is dropped, it send the row data to the server. jQuery-speaking, something like this:
$(function() {
$(someDomElement).on('DropEvent', function() {
// send data to server
};
});
The problem though, is that redips.drag is not a jQuery plugin but a javascript one, so my knowledge is a little (more than a little) lacking. I can probably find some other library, but it's performing really well and I prefer understanding how to work with it than look for a different one.
I can probably handle the "sending the data to the server" part by myself, what I can't understand at all is how to "catch" the drop event, what part of the dom do I listen to? I tried adding monitorEvents to different selectors but failed completely.
I also tried to manipulate the script.js file (the one that initializes the row handling), but also failed. here's the one I'm using (example 20 in the redips package):
"use strict";
// define redips object container
var redips = {};
redips.init = function () {
// reference to the REDIPS.drag library and message line
var rd = REDIPS.drag,
msg = document.getElementById('msg');
// initialization
rd.init();
//
// ... more irrelevent code ...
//
// row event handlers
//
// row clicked (display message and set hover color for "row" mode)
rd.event.rowClicked = function () {
msg.innerHTML = 'Clicked';
};
// row row_dropped
rd.event.rowDropped = function () {
msg.innerHTML = 'Dropped';
};
// and so on...
};
// function sets drop_option parameter defined at the top
redips.setRowMode = function (radioButton) {
REDIPS.drag.rowDropMode = radioButton.value;
};
// add onload event listener
if (window.addEventListener) {
window.addEventListener('load', redips.init, false);
}
else if (window.attachEvent) {
window.attachEvent('onload', redips.init);
}
Now I tried adding a console.log('hello') to the rd.event.rowDropped function (right above the msg.innerHTML line), but that doesn't work, I drop the row and nothing shows in the log. Doing a console.log outside the init function works so I know the script can pass stuff to the console.
Please, can anyone help me? I'm at a complete loss...
I know this may be a little lateto answer your question but I found the answer. You need to use the event dropped and the attribute rd.obj (REDIPS.drag.obj) to get the id use it with simple javascript like getAttribute('id')
redips.init = function () {
// reference to the REDIPS.drag library and message line
var rd = REDIPS.drag,
msg = document.getElementById('msg');
// initialization
rd.init();
// row clicked (display message and set hover color for "row" mode)
rd.event.clicked = function () {
msg.innerHTML = 'Clicked' + rd.obj.getAttribute('id');
};
// row row_dropped
rd.event.dropped = function () {
msg.innerHTML = 'Dropped' + rd.obj.getAttribute('id');
};
};

GetElementById of ASP.NET Control keeps returning 'null'

I'm desperate having spent well over an hour trying to troubleshoot this. I am trying to access a node in the DOM which is created from an ASP.NET control. I'm using exactly the same id and I can see that they match up when looking at the HTML source code after the page has rendered. Here's my [MODIFIED according to suggestions, but still not working] code:
ASP.NET Header
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script type="text/javascript">
$(document).ready(
var el = document.getElementById('<%= txtBox.ClientID %>');
el.onchange = alert('test!!');
)
</script>
</asp:Content>
ASP.NET Body
<asp:TextBox ID="txtBox" runat="server"></asp:TextBox>
Resulting Javascript & HTML from above
<script type="text/javascript">
$(document).ready(
var el = document.getElementById('MainContent_txtBox');
el.onchange = alert('test!!');
)
</script>
...
<textarea name="ctl00$MainContent$txtBox" id="MainContent_txtBox"></textarea>
I can only assume that the script is loading before the control id has been resolved, yet when I look at the timeline with Chrome's "Inspect Element" feature, it appears that is not the case. When I created a regular textarea box to test and implement the identical code (different id of course), the alert box fires.
What on earth am I missing here? This is driving me crazy >.<
EDIT: Wierd code that works, but only on the initial page load; firing onload rather than onchange. Even jQuery says that .ready doesn't work properly apparently. Ugh!!
$(document).ready(function() {
document.getElementById('<%= txtBox.ClientID %>').onchange = alert('WORKING!');
})
Assuming the rendered markup does appear in that order, the problem is that the element doesn't yet exist at the time your JavaScript is attempting to locate it.
Either move that JS below the element (preferably right at the end of the body) or wrap it in something like jQuery's document ready event handler.
Update:
In response to your edits, you're almost there but (as others have mentioned) you need to assign a function to the onchange event, not the return result of alert(). Something like this:
$(document).ready(function() {
// Might as well use jQuery to attach the event since you're already using
// it for the document ready event.
$('#<%= txtBox.ClientID %>').change(function() {
alert('Working!');
});
});
By writing onchange = alert('Working');, you were asking JavaScript to assign the result of the alert() method to the onchange property. That's why it was executing it immediately on page load, but never actually in response to the onchange event (because you hadn't assigned that a function to run onchange).
Pick up jQuery.
Then you can
$(function()
{
var el = document.getElementById('<%= txtBox.ClientID %>');
el.onclick() { alert('test!!'); }
});
Other answers have pointed out the error (attempting to access DOM nodes before they are in the document), I'll just point out alternative solutions.
Simple method
Add the script element in the HTML below the closing tag of the element you wish to access. In its easiest form, put it just before the closing body tag. This strategy can also make the page appear faster as the browser doesn't pause loading HTML for script. Overall load time is the same however, scripts still have to be loaded an executed, it's just that this order makes it seem faseter to the user.
Use window.onload or <body onload="..." ...>
This method is supported by every browser, but it fires after all content is loaded so the page may appear inactive for a short time (or perhaps a long time if loading is dealyed). It is very robust though.
Use a DOM ready function
Others have suggested jQuery, but you may not want 4,000 lines and 90kb of code just for a DOM ready function. jQuery's is quite convoluted so hard to remove from the library. David Mark's MyLibrary however is very modular and quite easy to extract just the bits you want. The code quality is also excellent, at least the equal of any other library.
Here is an example of a DOM ready function extracted from MyLibrary:
var API = API || {};
(function(global) {
var doc = (typeof global.document == 'object')? global.document : null;
var attachDocumentReadyListener, bReady, documentReady,
documentReadyListener, readyListeners = [];
var canAddDocumentReadyListener, canAddWindowLoadListener,
canAttachWindowLoadListener;
if (doc) {
canAddDocumentReadyListener = !!doc.addEventListener;
canAddWindowLoadListener = !!global.addEventListener;
canAttachWindowLoadListener = !!global.attachEvent;
bReady = false;
documentReady = function() { return bReady; };
documentReadyListener = function(e) {
if (!bReady) {
bReady = true;
var i = readyListeners.length;
var m = i - 1;
// NOTE: e may be undefined (not always called by event handler)
while (i--) { readyListeners[m - i](e); }
}
};
attachDocumentReadyListener = function(fn, docNode) {
docNode = docNode || global.document;
if (docNode == global.document) {
if (!readyListeners.length) {
if (canAddDocumentReadyListener) {
docNode.addEventListener('DOMContentLoaded',
documentReadyListener, false);
}
if (canAddWindowLoadListener) {
global.addEventListener('load', documentReadyListener, false);
}
else if (canAttachWindowLoadListener) {
global.attachEvent('onload', documentReadyListener);
} else {
var oldOnLoad = global.onload;
global.onload = function(e) {
if (oldOnLoad) {
oldOnLoad(e);
}
documentReadyListener();
};
}
}
readyListeners[readyListeners.length] = fn;
return true;
}
// NOTE: no special handling for other documents
// It might be useful to add additional queues for frames/objects
else {
if (canAddDocumentReadyListener) {
docNode.addEventListener('DOMContentLoaded', fn, false);
return true;
}
return false;
}
};
API.documentReady = documentReady;
API.documentReadyListener = documentReadyListener;
API.attachDocumentReadyListener = attachDocumentReadyListener;
}
}(this));
Using it for your case:
function someFn() {
var el = document.getElementById('MainContent_txtBox');
el.onclick = function() { alert('test!!');
}
API.attachDocumentReadyListener(someFn);
or an anonymous function can be supplied:
API.attachDocumentReadyListener(function(){
var el = document.getElementById('MainContent_txtBox');
el.onclick = function() { alert('test!!');
};
Very simple DOM ready functions can be done in 10 lines of code if you just want one for a specific case, but of course they are less robust and not as reusable.

Categories

Resources