how to alert user when there are changes inside an object field - javascript

how can i alert the user if there are any changes inside the object field
i''m trying to detect the changes on this div inside the object
if it's normal the code would be this:
<div id="HeaderNewMessageIcon" class="BrosixContactNewMessage" style="display:none;">
</div>
but if there are changes it will look like this:
<div id="HeaderNewMessageIcon" class="BrosixContactNewMessage" style="display: block; ">
</div>
i want to alert the user if there are changes inside the object, either via alert or using an image.
is there any way for me to achieve this?
and another thing, i have no access to the code inside the object, i can only view it but not edit it.

I believe there must be some JavaScript code which changing your html you can call your method from there. Other way you can use setInterval.
You can use jQuery plugin Mutation Events plugin for jQuery . see thread
var a = document.getElementsByClassName('HeaderNewMessageIcon')[0];
var oldTitle = a.title;
setInterval(function(){
if(a.title !== oldTitle){
alert("Title change");
oldTitle = a.title;
}
},100);
jsfiddle

You have to detect the changes when throught user interaction such as click, mouseover, mousedown, etc... then you can attach a function to see if its attributes or anything inside it changes.
//detect inputs change
$('#HeaderNewMessageIcon').find(':input').change(function(){ alert(...)});
//detect attributes change
$('#HeaderNewMessageIcon').click(function(){
detectChange(this);
});
As for detectChange to work, you must save the attributes when page just loaded
var attrs = $('#HeaderNewMessageIcon').get(0).attributes;
function detectChange(obj){
//pseudo-code, you need to find a function on the web to commpare 2 objetcs
if (obj.attributes === attrs){
alert(...);
}
//the same comparison for the children elements $(obj).children()
}

Related

Access a JQuery object in multiple event handlers

I am new to JQuery and web development in general and hence facing a troubling issue during development. My website interface looks like below:
When a user clicks on any checkbox (for referral purposes, I have selected the box above 'chk2') and then clicks on the 'Show Evidence' button (box 2 in the image), I want the user to be able to highlight portions of the article displayed in the adjacent iframe. I am using a text highlighter Jquery plugin I found on the web. The code for the click event of the 'Show Evidence' button looks like:
$('.show_evidence').click(function(event){
var iframe = document.getElementById('myiFrame');
var hltr = new TextHighlighter(iframe.contentDocument.body);
hltr.setColor("yellow");
});
The above code works fine.
Now, I want to set the highlight color (i.e. hltr.setColor("blue")) to blue when the user clicks on the checkbox 'Unselect' (box 3 in the image). For that I need to be able to access the 'hltr' object I have defined above (i.e. inside the 'click' event handler for '.show_evidence'). Also I want to set the highlight color back to 'yellow' when the user unchecks the 'Unselect' checkbox.
$(".unselect").change(function() {
if(this.checked) {
//Something like - hltr.setColor("blue");
}
else {
// Something like - hltr.setColor("yellow");
}
});
Finally, I also want to unset or undefine the object 'hltr' when the user clicks on the link 'Hide Datums' (box 1 in the image).
So my question is how do I access the hltr object inside the event handlers for .Unselect and the 'Hide Datums' link.
After a lot of stackoverflow surfing, I found that I could use external variables but I am not sure whether that will work for objects. Also, is there a universally recommended design that I should use or follow? What is the best way to achieve what I want?
Looking forward to your suggestions. Please help!
Regards,
Saswati
One way you can go about is extract the lines of code which does the element selection to a separate method.
var hltr;
function getBodyElementOfIframe() {
var iframe = document.getElementById('myiFrame');
if(!hltr) {
hltr = new TextHighlighter(iframe.contentDocument.body);
}
return hltr;
}
Call that method where you want to access the element and then set the color.
$(".unselect").change(function() {
var hltr = getBodyElementOfIframe();
if(this.checked) {
hltr.setColor("blue");
}
else {
hltr.setColor("yellow");
}
});
There are a number of ways to solve it, but one simple way to do it would be to move the variable outside the scope of the method so that it is accessible through out.
I would put it inside on ready.
$(document).ready(function () {
var hltr = {};
$('.show_evidence').click(function(event){
var iframe = document.getElementById('myiFrame');
hltr = new TextHighlighter(iframe.contentDocument.body);
hltr.setColor("yellow");
});
$(".unselect").change(function() {
if(this.checked) {
//Something like - hltr.setColor("blue");
}
else {
// Something like - hltr.setColor("yellow");
}
});
})();
If you need the variable inside several functions, declare it outside of all of them.
$(function(){
var iframe = document.getElementById('myiFrame');
var hltr = new TextHighlighter(iframe.contentDocument.body);
$('.show_evidence').click(function(event){
hltr.setColor("yellow");
});
});
When your event handlers fire, they'll be updating this var and it will be accessible to the next handler called.

Javascript onclick event firing for id but not for class

I'm fairly new to Javascript, and am trying to get an 'on click enlarge' kind of effect, where clicking on the enlarged image reduces it again. The enlarging happens by replacing the thumbnail by the original image. I also want to get a slideshow using images from my database later on.
In order to do that, I made a test where I replace the id which indicates enlarging is possible by a class and I also use a global variable so that I can keep a track of the url I'm using. Not sure this is the best practice but I haven't found a better solution.
The first part works fine, my image gets changed no problem, values are also updated according to the 'alert' statement. However, the second part, the one with the class never triggers.
What am I doing wrong (apart from the very likely numerous bad practices) ?
If instead of changing the class I change the id directly (replacing .image_enlarged by #image_enlarged, etc.), it seems to call the first function, the one with the id, yet outputs the updated id, which is rather confusing.
var old_url = "";
$(function(){
$('#imageid').on('click', function ()
{
if($(this).attr('class')!='image_enlarged'){
old_url = $(this).attr('src');
var new_url = removeURLPart($(this).attr('src'));
$(this).attr('src',new_url); //image does enlarge
$(this).attr('class',"image_enlarged");
$(this).attr('id',"");
alert($(this).attr('class')); //returns updated class
}
});
$('.image_enlarged').on('click', function (){
alert(1); //never triggered
$(this).attr('src',old_url);
$(this).attr('class',"");
$(this).attr('id',"imageid");
});
});
function removeURLPart(e){
var tmp = e;
var tmp1 = tmp.replace('thumbnails/thumbnails_small/','');
var tmp2 = tmp1.replace('thumbnails/thumbnails_medium/','');
var tmp3 = tmp2.replace('thumbnails/thumbnails_large/','');
return tmp3;
}
As for the html, it's really simple :
<figure>
<img src = "http://localhost/Project/test/thumbnails/thumbnails_small/image.jpg" id="imageid" />
<figcaption>Test + Price thing</figcaption>
</figure>
<script>
document.write('<script src="js/jquery-1.11.1.min.js"><\/script>');
</script>
<script type="text/javascript" src="http://localhost/Project/js/onclickenlarge.js"></script>
From the API: http://api.jquery.com/on/
The .on() method attaches event handlers to the currently selected
set of elements in the jQuery object.
When you do $('.image_enlarged').on(...) there is no element with that class. Therefore, the function is not registered in any element.
If you want to do so, then you have to register the event after changing the class.
Here's an example based on your code: http://jsfiddle.net/8401mLf4/
But this registers the event multiple times (every time you click) and it would be wrong. So I would do something like:
$('#imageid').on('click', function () {
if (!$(this).hasClass('image_enlarged')) {
/* enlarge */
} else {
/* restore */
}
}
JSfiddle: http://jsfiddle.net/8401mLf4/2/
Try using:
addClass('image-enlarged')
instead of:
.attr('class',"image_enlarged");
the best way to do this would be to have a small-image class and a large image class that would contain the desired css for both and then use addClass() and removeClass depending on which you wanted to show.

multiple instanced dynamic javascript popup link

I realize that this posting is possibly a repeat of this one:
Using Javascript to dynamically create links that trigger popup windows
But I'm not good enough at JavaScript to understand how to apply it to the context in which I'm trying to do it.
I'm creating a javascript snippet that could possibly be called multiple times from within a CMS (Umbraco ) that generates webpages.
An id (variable name: mediaid) is passed into this context and I want to dynamically create a link that has an onclick event to launch a popup. I take the ID passed into the context I'm working in (Umbraco calls them "macros") and append the id as a query string to a different URL (same domain) so that the resultant page can do some stuff with the id.
What I have works, but only for one instance on a page. I need a user to be able to insert multiple dynamic links on a page. Right now, the last link generated uses the onclick event for all instances on the page.
<script>
var linkWithQueryParam = 'http://www.mydomain.org/test2?yourkey=<xsl:value-of select="$mediaid" />';
var element = document.createElement("a");
element.id = '<xsl:value-of select="$mediaid" />';
element.href = '#';
element.onclick = function() {
setLink(linkWithQueryParam);
}
function setLink(value) {
window.open(value, 'player', 'width=775,height=520,location=0,directories=0,status=0,menubar=0');
}
document.body.appendChild(element);
element.appendChild(document.createTextNode('Listen To This Audio'));
</script>
So, for example, I have a template elsewhere, that calls this macro I created, twice:
<umbraco:Macro mediaid="4107" Alias="audioPlayerPopUp" runat="server"></umbraco:Macro>
<umbraco:Macro mediaid="26502" Alias="audioPlayerPopUp" runat="server"></umbraco:Macro>
The links are generated, but when I click on them, the link generated above in "linkWithQueryParam" is always whatever the last one was, for all links.
I thought maybe if I set the "id" attribute of the link to make it unique, it would work. But that doesn't work. How can I make the dynamically generated onclick event unique?
I ended up changing my approach and using an event delegate per unclenorton's response in this s.o. post
http://davidwalsh.name/event-delegate
I used a variation on the example to only disable the default link behavior, first checking to see that the link class is matched. This script relies on a named div that is available sitewide and is placed at the bottom of a master template so it is available:
<script>
document.getElementById("main").addEventListener("click", function(e) {
if(e.target)
{
if(e.target.nodeName == "A")
{
if(e.target.className == "miniplayer")
{
if(e.preventDefault) {
e.preventDefault();
}
else
{
e.returnValue = false;
}
var target = e.target;
var popupWindows = window.open(target.href, 'player', 'width=775,height=520,location=0,directories=0,status=0,menubar=0');
}
}
}
});
</script>
I then edited my user macro to simply place the class "miniplayer" on each link it creates and include the media id as a query parameter to another url which provides the media player. That other url resource then pulls the query param id out of the url and looks up the link to the media item. But the .js above launches the pop-up the way that I want.
One challenge I had was on how to dynamically assign the resultant media resource to the player (in this case, jPlayer). I found that if I write the media url to a hidden div, I can then just tell the jPlayer to read the value from it.
So I have a second macro which gets the query param and writes it to a hidden div:
<div style="display:none" id="audioUrl"><xsl:copy-of select="$mediaNode/audioUrl" /></div>
Finally, I adjust the jPlayer jQuery to read the url from the hidden div:
$(this).jPlayer('setMedia', {mp3: $("#audioUrl").text() }).jPlayer("play");
It doesn't seem like the best solution. I don't like passing the mediaid through the url, but it fulfills all my other requirements
The issue here is with globals and closures. The linkWithQueryParam variable is a global that is updated each time that script is added. When you click on the link it goes and fetches the url from the variable which is of course the last one.
You can fix this a few ways,
Wrap this code in an immediate anonymous function. This will reduce the scope of the variables to within the anonymous function.
Set the URL when the script is run instead of when the link is clicked.

Return value from custom alert [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to create TRULY modal alerts/confirms in Javascript?
TL;DR: I've overridden the default alert() function with a custom HTML based one. I want the new dialogue to still block execution, and get the buttons within my dialogue to return true or false from the call to alert() to use in logic (and continue execution).
I'm trying to implement a custom alert box, which replaces the default browser alert with a nicely themed box with the same (or similar) functionality.
I've read this question, and I'm using the solution given in this answer (to the same question). What I want to do now is get my overridden alert to return a true or false value for use in if() statements, depending on whether OK or Cancel was clicked:
if(alert('Confirm?') {
// Do stuff
}
However, due to having custom HTML instead of a normal alert I can't do this for two reasons:
I can't return a value from the buttons in the replacement dialogue (click events bound with $.on()) because I have no idea how to.
I can't block program flow with this alert, as far as I know.
I've bound $.on() events to the Cancel and OK buttons in the replacement dialogue which hide the box. These work fine, but the problem I have now is returning a value when a button is clicked, so that execution will halt until an action is taken by the user.
HTML:
<div class="alert background"></div>
<div class="alert box">
<div class="message"></div>
<hr>
<div class="buttons">
<input type="button" name="cancel" value="Cancel">
<input type="button" name="confirm" value="OK">
</div>
</div>
Current JavaScript: (pretty much a carbon copy of the answer in my linked question)
(function () {
nalert = window.alert;
Type = {
native: 'native',
custom: 'custom'
};
})();
(function (proxy) {
proxy.alert = function () {
var message = (!arguments[0]) ? 'null' : arguments[0];
var type = (!arguments[1]) ? '' : arguments[1];
if (type && type == 'native') {
nalert(message);
} else {
// Custom alert box code
console.log(message);
}
};
})(this);
Ideally, I want to be able to put something like this in the // Custom alert box code part:
$('.alert.box input[name="confirm"]').on('click', function() {
// Hide dialogue box - I can do this already
// *** Return `true` or other truthy value from
// alert for use in `if()` statements
});
So that when the OK or Cancel button is clicked, it removes the custom alert box and returns a true or false value from the call to alert(). I can already remove the alert with $.fadeOut() and $.remove(), that's easy. What isn't is knowing how to get the button click events to get alert() (overridden) to return something.
I've tried to be as clear as I can, but I may have missed something out. Please let me know if I have.
The example below shows an approach to creating a custom alert and handling the outcome of the user selection
/*
message = String describing the alert
successCallBack = callback function for when the user selects yes
*/
function exampleAlert(message, successCallback)
{
/*Alert box object*/
var alertBox = document.createElement("div");
/*Alert message*/
var msg = document.createElement("div");
msg.innerHTML = message;
/*Yes and no buttons
The buttons in this example have been defined as div containers to accentuate the customisability expected by the thread starter*/
var btnYes = document.createElement("div");
btnYes.innerHTML= "Yes";
/*Both yes and no buttons should destroy the alert box by default, however the yes button will additionally call the successCallback function*/
btnYes.onclick = function(){ $(this.parentNode).remove();successCallback();}
var btnNo = document.createElement("div");
btnNo.innerHTML= "No"
btnNo.onclick = function(){ $(this.parentNode).remove();}
/*Append alert box to the current document body*/
$(alertBox).append(msg, btnYes, btnNo).appendTo("body");
}
function test()
{
alert("Example alert is working, don't use this test as a replacement test - horrible recursion!")
}
exampleAlert("shoe", test)
This is fairly basic and doesn't allow for additional data to be supplied to the callback function and for that reason is not ideal for production however jQuery's .bind() and similar methods allow for data to be associated with the callback method
It's worth commenting that while the above demonstrates a full implementation of the problem, there are in fact only two lines that actually matter.
btnYes.onclick...
btnNo.onclick...
Since we're achieving the desired result by binding onclick events for true and false respectively, everything else is there to paint the picture.
With that in mind it is possible to effectively turn any container object with at least one sibling into an alert box for eaxmple:
<!-- Example html -->
<div id='a'>
<ul>
<ul>
<li>Something</li>
<li>Something Else</li>
<li id='yesIdentifier'>Something not necessarily suggesting a trigger?</li>
</ul>
</ul>
</div>
As long as your yes / no (if no exists) options destroy the appropriate container a converting a container into an alert box can be handled in a couple of lines of code.
$('#yesIdentifier', '#a').click(
function(){ someCallback(); $(this).closest('#a').remove()});
Neither of the above are exemplary models for implementation but should provide some ideas on how to go about the task.
Finally... do you really need to replace the native alert method? That is, either you're writing the alert calls, in which case you'd know to use your custom method, or you're overwriting default behaviour that you can't guarantee the other developers will be aware of.
Overall recommendation:
I feel the best approach to this would be to create a jQuery plugin which creates the custom alerts on the fly and track callbacks, results and what not within the plugin.
SOliver.
Why don't you just use a confirm box like so.
var c = confirm('Confirm?');
if(c)
{
// Yes clicked
}
else
{
// No clicked
}
Or you could use jQuery UI's dialog confirmation box.
http://jqueryui.com/demos/dialog/#modal-confirmation

Load Html Content if not exist JQuery AJAX

I have a page with 3 buttons. >Logos >Banners >Footer
When any of these 3 buttons clicked it does jquery post to a page which returns HTML content in response and I set innerhtml of a div from that returned content . I want to do this so that If I clicked Logo and than went to Banner and come back on Logo it should not request for content again as its already loaded when clicked 1st time.
Thanks .
Sounds like to be the perfect candidate for .one()
$(".someItem").one("click", function(){
//do your post and load the html
});
Using one will allow for the event handler to trigger once per element.
In the logic of the click handler, look for the content having been loaded. One way would be to see if you can find a particular element that comes in with the content.
Another would be to set a data- attribute on the elements with the click handler and look for the value of that attribute.
For example:
$(".myElements").click(function() {
if ($(this).attr("data-loaded") == false {
// TODO: Do ajax load
// Flag the elements so we don't load again
$(".myElements").attr("data-loaded", true);
}
});
The benefit of storing the state in the data- attribute is that you don't have to use global variables and the data is stored within the DOM, rather than only in javascript. You can also use this to control script behavior with the HTML output by the server if you have a dynamic page.
try this:
HTML:
logos<br />
banner<br />
footer<br />
<div id="container"></div>
JS:
$(".menu").bind("click", function(event) {
event.stopPropagation();
var
data = $(this).attr("data");
type = $(this).attr("type");
if ($("#container").find(".logos").length > 0 && data == "logos") {
$("#container").find(".logos").show();
return false;
}
var htmlappend = $("<div></div>")
.addClass(type)
.addClass(data);
$("#container").find(".remover-class").remove();
$("#container").find(".hidde-class").hide();
$("#container").append(htmlappend);
$("#container").find("." + data).load("file_" + data + "_.html");
return false;
});
I would unbind the click event when clicked to prevent further load requests
$('#button').click(function(e) {
e.preventDefault();
$('#button').unbind('click');
$('#result').load('ajax/test.html ' + 'someid', function() {
//load callback
});
});
or use one.click which is a better answer than this :)
You could dump the returned html into a variable and then check if the variable is null before doing another ajax call
var logos = null;
var banners = null;
var footer = null;
$(".logos").click(function(){
if (logos == null) // do ajax and save to logos variable
else $("div").html(logos)
});
Mark nailed it .one() will save extra line of codes and many checks hassle. I used it in a similar case. An optimized way to call that if they are wrapped in a parent container which I highly suggest will be:
$('#id_of_parent_container').find('button').one("click", function () {
//get the id of the button that was clicked and do the ajax load accordingly
});

Categories

Resources