JQuery catch an event on Paragraph change - javascript

I would like to make a script that, when the text of a certain paragraph change, start a certain function, I tried the follow but i don't think the method change() works for a paragraph
$("#myParagraph").change(function(){......})

You would wrap that tag or "paragraph" in a container, and bind that container to a event possibly. You could also look into using the length of the "text" property. During this triggered event, check that the state is different. I can write an example if you need one. One place to look at is the
//global variable. Store in hidden field if you would like.
var currentVal = $('element').text();
$('element').bind("DOMSubtreeModified",function(){
var newVal = $(element).text();
if(currentVal != newVal)
{
//call function here.
}
});
This is basic and very simple, but to give you the idea.

Related

Javascript Generating Text into Textbox?

I wrote this little bit of code but I'm not sure why it's not working? It's supposed to take in the persons name and depending on what they selected it will output a website with their name at the end of it.
JSFiddle
http://jsfiddle.net/tQyvp/135/
JavaScript
function generateDynamicSignature() {
var dynSig = "";
var user = document.getElementById("usernameInput");
var e = document.getElementById("scriptListInput");
var strUser = e.options[e.selectedIndex].text;
if (strUser == "example") {
dynSig = "http://example.com/users/";
}
document.getElementById("generateSignature").addEventListener('click', function () {
var text = document.getElementById('dynamicSignatureOutput');
text.text = (dynSig + user);
});
}
HTML
<select class="form-control" id="scriptListInput">
<option value="example">Example 1</option>
</select>
There are a few problems with your code, I'll try to list them all.
First, you never added the username input to your HTML.
Next, you seem mixed up on the way to access/set the text of an HTML input. You do this through the value field. For the username input, you forgot to access any property, so you'll need to change it to:
var user = document.getElementById("usernameInput").value;
You later used the text property of both the select element and the output. These should also both be value.
Another problem is that you've placed a listener inside a listener. Your outer function, generateDynamicSignature, listens for the onclick event of the button. This function only runs after the button is clicked. But inside this function, you attach a new listener. This inner listener will only run if someone clicks the button twice.
I've included these changes in a new fiddle:
https://jsfiddle.net/zdfnk77u/
where is usernameInput in your html?
in the if, use === instead of ==
If and when you add the missing "usernameInput" element in your HTML, all you'll have to do is...
dynSig='http://example.com/users/'+usernameInput.value;
I think part of the problem is that you want to access the value and not the text of input elements. So for text and strUser, you want to do text.value instead of text.text and such.
Also, based on the JSfiddle, you probably want to rewrite how you're using the document listener and the onclick of the html element. Every time the button is clicked it goes through the generateDynamicSignature and creates a listener to change the value, but doesn't necessarily change the value itself. If you move the logic of the generate function inside the click listener, that should fix most of your problems.
You create your generateDynamicSignature inside $(document).ready.
There are two approaches.
define function generateDynamicSignature outside
$(document).ready
or
bind your button.click to a handler inside $(document).ready
Do not mix these two.

Change multiple div contents on another div mouse hover without css/with an xml source file

I'm working on this site, and I need to change the contents of image_preview, title_preview, description_preview, link_preview according to what I'm hovering over (ex: mouse hover "button_a" = image1.png, iliketitle, ulikedesc, welikelink).
I've tried using css solutions like this and this, but I wasn't able to make them work like I needed.
Since the page will have many button_#'s (50-100 buttons), I think css isn't a proper choice.
So what I'm looking for is a way to do this without css, better if with an xml source file, so it'd be easier to manage the content to display for each button. I only found this talking about the xml I'd need, but I'm not sure that's exactly what I need.
Your buttons have a class (e.g. .btn) and the associated data to each button is store somewhere, let's say each button has a data-* attribute which points to the right data.
$('.btn').hover(function() {
var data = $(this).data('something');
if(data == "b1") {
//assign the values related to b1
}
else if(data == "b2") {
//assign the values related to b2
}
//and so on
}
If you have a lot of buttons like that, then the data can be a reference to an array containing the proper info.
Here's a jsfiddle DEMO.
And here's updated DEMO.
EDIT:
.hover() can take two handler which the second will handle when mouse is out of the element.
yourElement.hover(
function() {
//mouse is on the element, do stuff
},
function() {
//mouse is out, do other stuff
}
);
You can have a function to set the default values and call that in hover's second function.
jsfiddle DEMO

jQuery setting input.value = input.title (or other input attribute)

I'm trying to figure out how to set the input value of a text field to the value of it's title when the page loads, as a way to show placeholder text. I'm using an HTML4 Strict doctype. I don't want to store the placeholder text in the input value, because I don't want people without javascript to have to delete the text before typing. I want it to be added with javascript, and then removed when the input gains focus. I have the focus() and blur() methods working, but I can't figure out how to write the initial pageload function to pass the input's title to the val() function.
I currently have this code:
// This doesn't work, it grabs the page title:
$('#item-search').val(this.title);
// Works:
$('#item-search').focus(function() {
if (this.value == this.title) {
this.value = '';
}
});
// Works:
$('#item-search').blur(function() {
if (this.value == '') {
this.value = this.title;
}
});
Just to add another variation, .val() can accept a function as its parameter, fixing your this issues:
$('#item-search').val(function () {
return this.title;
});
this refers to the current scope. In your first example, its referring to document.
You may want.
$('#item-search').val($('#item-search').attr('title'));
Even better:
var $itemSearch = $('#item-search');
$itemSearch.val($itemSearch.attr('title'));
$('#item-search').val(this.title);
In this line this refer the document(html) and set the <title>. To accomplish you job do this:
$('#item-search').val($('#item-search').attr('title'));
Try this:
$('#item-search').val($('#item-search').attr('title'));
Please try this.
$('#item-search').val($("#item-search").attr("title"));

How do you 'replace' numbers with 'x's' in jQuery with one button?

Does anyone know how to do replace multiple text by clicking a button with jQuery?
I've built a website that displays some text/data eg; "£100.00", but I what I need is to be able to 'replace' those monetary values with "£XXX.XX" with a 'Hide' button like you get on some banking websites. For example one web page has:
£100.00, £200.00, £130.00 etc etc..
...so when a user presses the Hide button, all of the numbers on the page turn to £XXX.XX. Ideally, the button should then display "Show" instead of "Hide" and switch back when toggled.
This is for a static dummy site, so no data base.
I suspect this is best handled with jQuery?
Thanks for your time,
D.
Case 1: Controlled Input
Assuming you can at least wrap all monetary values with something like this:
<span class="money-value">£200.00</span>
<span class="money-value">£300.50</span>
And that you can add button declared with:
<button id="secret-button">hide</button>
Then you could have some jQuery code doing this:
/**
* Simple search and replace version.
*/
$(function() {
$("#secret-button").click(function() {
$(".money-value").html($(".money-value").html().replace(/[0-9]/g,"X"));
});
});​
or a more advanced one with:
/**
* Complet version.
*
* 1) on button click, if asking to hide:
* 1.1) iterate over all entries, save their text, and replace it with markers
* 1.2) toggle the button's text to "show"
* 2) on button click, if asking to show:
* 2.1) iterate over all entries, restore previous text
* 2.2) clear the hidden store
* 2.3) toggle the button's text to "hide"
*/
$(function() {
var hiddenStore = [];
$("#secret-button").click(function() {
if ($(this).html() == "hide") {
$(".money-value").each(function () {
var text = $(this).html();
hiddenStore.push(text);
$(this).html(text.replace(/[0-9]/g,"X"));
});
$(this).html("show");
} else {
$(".money-value").each(function (i) {
var text = hiddenStore[i];
$(this).html(text);
});
hiddenStore = [];
$(this).html("hide");
}
});
});​
Complete solution is here: See here: http://jsfiddle.net/u79FV/
Notes:
this won't work for input field values
this assumes your text entries have been marked as shown above
Does what you want with the button's changing state.
Saves the values and puts them back.
Meant to work even if new fields are added dynamically.
Shankar Sangoli's answer uses a different way of saving the stored data, which you could as well consider (using the jQuery .data() method).
you may want to switch the button to an <input type="button" /> tag, in which case you'd use .val() instead of .html() to toggle its text.
Case 2: Uncontrolled Input
Assuming you don't have control over where the values may show up, then you need to do something a bit more complicated, which is to look in the whole page for something that would look like a currency format. I'd advise against it.
But, the jQuery Highlight plugin could be something to look at, as its code does something similar (in that it searches for pieces of code to modify), and you could then reuse some of solution 1 to make it fit your purpose.
That would be harder to design in a fool-proof fashion though.
You could use a regular expression:
var expression = /\d{1}/g;
var newString = myString.replace(expression,"X");
Then just dump newString into whatever control you need it to appear in.
Edit:
A jQuery idea for something like this would be to give all of the controls that have these numbers a common class identifier to make them easy to grab with the selector:
$(".numbers").each(function() {
$(this).text($(this).text().replace(/\d{1}/g, "X"));
}
... more readable ...
$(".numbers").each(function() {
var text = $(this).text();
var newText = text.replace(/\d{1}/g, "X");
$(this).text(newText);
}
If your markup is something like this you can try this.
<span>£1000.00</span><span class="showhide">Hide</span>
JS
$('.showhide').click(function(){
var $this = $(this);
var $prev = $this.prev();
if(!$prev.data('originalvalue')){
$prev.data('originalvalue', $prev.text());
}
if($this.text() == 'Hide'){
$this.prev().text($prev.data('originalvalue').replace(/\d{1}/g,"X"));
$this.text('Show');
}
else{
$prev.text($prev.data('originalvalue'));
$this.text('Hide');
}
});
In the above code I am basically storing the original value using jQuery data method within the span element itself which is used to display the actual value.
Once you click on Hide, get the previous span using prev() method and set its text with original value replacing all the numbers in it by X. Then change the link text from Hide to Show.
Next when you click on Show get the previous span using prev() method and set its text with the original value and change the link text from Show to Hide.
References: .prev(), .data()
$('#yourButton').click(function(){
var saveText = $('body').text();
$(this).data('oldText', saveText);
if ($(this).text() == "Hide"){
$('body').text($('body').text().replace(/\d{1}/, "X"));
$(this).text('Show');
}
else{
$('body').text($(this).data('oldText'));
$(this).text('Hide');
}
});
This is kind of a complicated problem actually. You will need to be able to save the state of the text when its in number form so you will be able to toggle back and forth. The above code is untested but hopefully it will give you an idea what you need to do.
function toggleMoney() {
$('.money').each(function() {
var $$ = $(this), t = $$.text();
$$.text($$.data('t') || t.replace(/\d/g, 'X')).data('t', t);
});
$('#toggleButton').text($('.money').text().match(/\d/) ? 'hide' : 'show');
}
http://jsfiddle.net/DF88B/2/

Tracking changes in web application

I have an application in which the user needs to see the changes that have been made during the latest edit.
By changes I mean, the changes made in all inputs like a textarea, dropdowns.
I am trying to implement this by showing a background image on the right top and then when the user clicks this background image, a popup is shown which shows the difference.
I am using prototype 1.7.0.
My First question would be:-
1. What would be the best approach to implement this functionality?
2. Can I put a onClick on the background image?
There some functions in the jQuery library that I believe would be helpful to you. If you are using prototype, I would guess that there is some similar functionality you may utilize.
I would suggest writing some code like this:
var $input = $('input').add('textarea').add('select');
$input.each(function() {
var id = $(this).attr('id');
var value = $(this).val();
var hiddenId = 'hidden' + id;
var newHiddenInput = $("<input type='hidden'").val(value).attr('id',hiddenId);
$(this).after(newHiddenInput);
});
The above code will create a new hidden input for each input, textarea, and select on your page. It will have the same value as the input it duplicates. It will have an id equivalent to prepending the id with the word 'hidden'.
I don't know if you can attach a click handler to a background image. If your inputs are enclosed inside a <div>, you may be able to get the result you want by attaching the click handler to your div.
In any case, you should now have the old values where you can easily compare them to the user's input so that you can prepare a summary of the difference.
Prototype gives us the Hash class which is almost perfect for this but lacks a way of calculating the difference with another hash, so let's add that...
Hash.prototype.difference = function(hash)
{
var result = this.clone();
hash.each(function(pair) {
if (result.get(pair.key) === undefined)
// exists in hash but not in this
result.set(pair.key, pair.value);
else if (result.get(pair.key) == pair.value)
// no difference so remove from result
result.unset(pair.key);
// else exists in this but not in hash
});
return result;
};
This is no way to tell if an element was clicked on just it's background image - you can find out the coordinates where it was clicked but that is not foolproof, especially since CSS3 adds complications like multiple backgrounds and transitions. It is better to have an absolutely positioned element to act as a button.
$('button-element').observe('click', function() {
var form_values = $H($('form-id').serialize(true));
if (old_values) {
var differences = old_values.difference(form_values);
if (differences.size()) {
showDiffPopup(differences);
}
}
window.old_values = form_values;
});
// preset current values in advance
window.old_values = $H($('form-id').serialize(true));
All that remains is to implement showDiffPopup to show the calculated differences.

Categories