I am working on a application which can save user-created HTML templates. Here, the user will have some HTML components at his disposal and would be able to create static HTML pages using those components.
I am auto saving the content of the page using a javascript function.
function saveContent(){
//var getContent=$('#mainWrap').children().removeAttr('id');
var $getContent=$('#mainWrap');
var $finalContent=$getContent.children().removeAttr('id');
var auto="auto";
var pageId = <?php echo $pageId;?>;
var webId = <?php echo $webId;?>;
var userId = <?php echo $userId;?>;
$.ajax({
url:"auto_save.php",
type:"POST",
dataType:"text",
data:"txtComp="+$('#mainWrap').html()+"&auto="+auto+"&pageId="+pageId+"&webId="+webId+"&userId="+userId
});
}
var interval = 1000 * 60 * 0.30; // where X is your every X minutes
setInterval(saveContent,interval);
Issue: I want to to remove the IDs from the HTML components that the user saves, because the IDs are auto generated and not needed when the user publishes the template (on his domain after creation). I have a main wrapper that wraps the entire page called id=mainWrap. If I try to remove the IDs like this $('#mainWrap').children().removeAttr('id'); they are also removed from the current context of the DOM, i.e they are removed from the page where the user is editing his template.
Question: How can I remove the IDs from the HTML elements without affecting the current context of the mainWrap object?
I tried assigning it to another object like this
var $getContent=$('#mainWrap');
var $finalContent=$getContent.children().removeAttr('id');
but still it failed.
Any comments or corrections on whether this is possible? Or am I going about this the wrong way?
Update : The issue is solved to some extent.
Next I want to add the id's back when the user comes back to the edit page.
I get the above saved content using this code
<?php
$sqlEdit = "select revisionContent from tbl_revision where revisionId='".$_SESSION['contentId']."'"; //The query to get the record
$rsEdit = $dbObj->tep_db_query($sqlEdit);//The database object to execute the query
$resEdit = $dbObj->getRecord($rsEdit);
$IdLessContent = $resEdit['revisionContent'];//Variable with the record
?>
Now,I want to use this PHP variable in javascript,so I did this.
<script language="javascript">
var getSavedContent = '<?php echo json_encode($IdLessContent); ?>';
var trimmedCont=($.trim(getSavedContent).slice(1));
//console.log(trimmedCont);
var lengthCont= trimmedCont.length;
var trimmedCont=$.trim(trimmedCont.slice(0,lengthCont-1));
var pageContent=$('<div class="addId">').append(trimmedCont); //Here I tried creating a div dynamically and appending the content to the div.But now I am not able to manipulate or work on this dyamic div and get NULL when I alert saying $('.addId').html();
$('.addId').children().attr('id', 'test'); //I tried doing this but does not work
This is not working.Can you throw some light on it
You can just cycle through the elements in your #mainWrap and remove the id like:
var getContent = $('#mainWrap');
var finalContent = getContent.parent().clone().find('*').removeAttr('id');
Example: http://jsfiddle.net/7m8g4/6/
Security wise you should realize this is a client-side script that is removing the id attributes from the html. There are ways though to manipulate the JavaScript or to bypass it by (for instance) calling the URL in your Ajax request directly with false data.
So you should never rely on your JavaScript only. Make sure your code will not cause problems if for any reason the JavaScript doesn't act as expected. You can do this for instance by searching for id attributes (use a regex) and generate an error message in case there are still some id attributes found. Another way would be to remove them server-side (in PHP) as well if any are found. To achieve this you could do a regex search and replace the matches with empty strings or by making use of substrings. Up to you!
Hope it all makes sense!
EDIT
If you want to add new id attributes back later on you can do something like:
var newContent = $(finalContent).first().wrap('<div class="addId" />');
newContent = $(newContent).parent().find('*').each(function(index, value) {
$(this).attr('id', index);
});
See that in work here.
Related
I'm struggling with conceptually how to implement this (what events to bind to etc).
I'm using CakePHP and have a view with the following:
An array of products to display and an associated price ($products['Product']['price'])
Each product has a base currency set ($product['Currency]['currency'])
I have money.js, accounting.js and another JS that sets JSON data for fx.rates and fx.base
I know the currency that the user wants to see and will likely differ from the product base currency (SessionComponent::read('User.Preferences.Currency')
A div to display the currency shortname (USD) and converted value, each div with unique id
My simple test works fine - using inline-php I've put a bit of JS on the page between two script tags.
<script>
var value = accounting.unformat(<? echo $product['Product']['price'] ?>); // clean up number (eg. user input)
var target = "<? echo SessionComponent::read('User.Preference.currency'); ?>"; // or some user input
var convertedValue = fx(value).from("<? echo $product['Currency']['currency'] >").to(target);
accounting.formatMoney(convertedValue, {
symbol: target,
format: "%v %s"
}); // eg. "53,180.08 GBP"
alert(convertedValue);
</script>
Fine. Works great. But what I can't work out is how to implement this on a page with N number of products.
I'm assuming I create a JS function, something like:
fx_convert(divid, price, fromcurrency, tocurrency)
And in my Cake view, I use inline php to echo the function parameters.
What is the clean way to use jQuery for this function, and have the price 'divs' call fx_convert and update their content with the converted value?
Or is my thinking totally backwards on this? All help is greatly appreciated.
After some decent sleep, figured it out. :)
Using inline PHP, I pass the to/from currencies via the div attributes and set a uniform class name. e.g.
<div class="fx" fx-from="<?php echo $product['Currency']['currency']; ?>" fx-to="<?php echo SessionComponent::read('User.Preference.currency') ?>" fx-value="<?php echo $product['Product']['price']; ?>"></div>
And then use the following jQuery snippet to loop over all elements of class "fx" and do the required calculation (using the excellent money.js and accounting.js)
$(document).ready(function() {
$(".fx").each( function( index, element ){
var value = accounting.unformat($(this).attr("fx-value")); // clean up number (eg. user input)
var target = $(this).attr("fx-to"); // or some user input
var convertedValue = fx(value).from($(this).attr("fx-from")).to(target);
$(this).html(accounting.formatMoney(convertedValue, {
symbol: target,
format: "%v %s"
}));
});
});
Still need to refactor and tidy up, but the solution is there.
I'm trying to keep only certain elements that has been added to a text area using jQuery. I'm using MutationObserver to find any new items added to a div and copy that to the form.
// passes content to the string, new items are also found
// and added using the MutationObserver
//
var stringContent = $("#OriginalOutput").html()
But, in this case I'm looking to get all the new 'li' found in the html.
I tried some methods like this for example:
var stringContent = $("#OriginalOutput").clone().find('.container')
.insertAfter().end().html();
this works but only give me the first 'li' element inside. I also tried other ways replacing insertAfter with something else that left me with the same result, but not giving all the 'li' elements it finds.
I already have the ul element being called somewhere else, and i just need to pass all the 'li' elements found into the string. This way I can use it on here:
//edited from #OriginalOutput to #output
$("#output").val("<ul class=\"mylist\">\n" + stringContent + "</ul>");
Another method i tried was removing the elements i didn't needed just to keep all the 'li' that's been added, but the problem I was having was i didn't know how to remove each class and if i remove the parent div that's holding all the elements, it would just take everything inside it including the 'li' elements, so I'm sure I can't do that. Although I did try to get it out using PHP with str_replace on the final output, but was able to get only certain elements out since most of the elements i need to remove outputs unique ids.
Use the .each() function. If you're only getting one element delivered, this may help. Change your jQuery to look like this:
var stringContent = '';
$("#OriginalOutput").clone().find('li').each(function(){
var t = $(this);
stringContent += t[0].outerHTML;
}
UPDATE
Per asker's comments:
My guess is then that your problem isn't to do with pulling the items, but rather with putting them in. I'd change the way you're inserting them to this:
$("#OriginalOutput").clone().find('li').each(function(){
var t = $(this);
$("#OriginalOutput").append(t);
});
I'm not sure why you'd chosen val() in the original answer, I just assumed that $('#OriginalOutput') was a hidden element. If it is a hidden element, you might want to construct a clone from scratch in your function, like this:
var myCloneElement = $(document.createElement('ul'));
myCloneElement = $('#myTargetList').clone();
$("#OriginalOutput").clone().find('li').each(function(){
var t = $(this);
myCloneElement.append(t);
});
$('#myTargetList').html(myCloneElement.html());
Give this a try:
var stringContent = $("#OriginalOutput .container").clone().find(':not(li)')
.remove().end().html();
Hi all got a small problem accessing a looped php variable. My script loops through and uses x and y from a mysql database. It also loops the id out which I cannot get access to, it comes up as undefined. I am using a mouse out function to detect each separate div that has been looped and get specific id.
Help very much appreciated!
Javascript to get attributes ready for database manipulation:
$(this).mouseout(function() {
var stickytext_id = $(this).attr('textstickyid');//alerted out returns undefined.
});
Looped PHP to get attr form:
$get_textsticky_result=mysql_query($get_textsticky_query);
while($row=mysql_fetch_assoc($get_textsticky_result)){
$x = $row['textsticky_x'];
$y = $row['textsticky_y'];
echo '<div class="textsticky" style="position: absolute; left:'.$x.'px; top:'.$y.'px;" textstickyid="'.$row['textsticky_id'].'">
<div class="textstickyvalueholder"contentEditable="true">'. $row['textsticky_text'] .'
</div><button>Like</button></div>';
}
?>
Can get other looped vars e.g. $row['textsticky_text']; and x and y for position without issue, Is there a better way to do this? I have a feeling the inline style is affecting it but not sure....
Okay, I am just going to go out on a limb here and assume your initial selector is incorrect. $(this) is the window in typical code flow.
$(this).mouseout(function() {
var stickytext_id = $(this).attr('textstickyid');//alerted out returns undefined.
});
Should be:
$('div.textsticky').mouseout(function() {
var stickytext_id = $(this).attr('textstickyid');//alerted out returns undefined.
});
Also, as Kris mentioned in comments, instead of inventing tags use the data attribute which is a part of html5.
<div class="textsticky" data-textstickyid="blah" />
It can then be accessed via jQuery's data method.
http://jsfiddle.net/kQeaf/
And as long as we are offering advice, if you are in jQuery 1.7+ you should be using prop instead of attr for accessing properties (unless of course you decide to use the data method) just recommended.
Your selector on the mouseout event may be wrong: (depending on the context)
$(".textsticky").mouseout(function() {
var stickytext_id = $(this).attr('textstickyid');
});
I want to show a page of my website within iframe in another page.
I mean you can see helper.html while you are navigation main.php.
but I want to change some links in helper.html regarding to some conditions set in main.php.
The regular solution is to get content of helper.html and process it in main.php, then echo it.
But it is server side, I want this process to be client side.
Is that possible with JavaScript?
If your files are located at the same domain, you can use the top.frames property, ro refer to the window object of named frames:
Assume the top HTML to has such a structure:
<iframe name="main" /><iframe name="helper" />
Inside main:
top.frames["helper"].document.getElementById("linkID").href = "http://newlink.com";
If you're using AJAX, you can add the previously shown code in the callback handler. If main.php reloads on change, at the code within <script> tags.
If those files are on different domains but you have a full control of them, then use the following solution:
In the main page call an iframe with GET parameters. For instance:
<iframe src="foo.html?parameter=value" width="400" height="500"></iframe>
In an iframe parse GET parameters using Javascript and show an appropriate content:
// get the current URL
var url = window.location.toString();
//get the parameters
url.match(/\?(.+)$/);
var params = RegExp.$1;
// split up the query string and store in an
// associative array
var params = params.split("&");
var queryStringList = {};
for(var i=0;i<params.length;i++)
{
var tmp = params[i].split("=");
queryStringList[tmp[0]] = unescape(tmp[1]);
}
// print all querystring in key value pairs
for(var i in queryStringList)
document.write(i+" = "+queryStringList[i]+"<br/>");
Source: http://www.go4expert.com/forums/showthread.php?t=2163
Try this...
var myIframe = document.getElementById('SomeIFrame');
myIframe.src = 'www.joobworld.com';
Yes it is possible if both frames are in same domain.
See sample function: in the help frame the id of link is assumed to be "link"
function ChangeLink()
{
var Helpframe = document.getElementById("Helpframe");
var innerDoc = Helpframe.contentDocument || Helpframe.contentWindow.document;
var link = innerDoc.getElementById("link");
link.href="http://www.google.com";
}
This solution is inspired from Javascript - Get element from within an iFrame
What is that called and how do you do it? My page refreshes every 10 seconds using jquery querying a database.
I get new tables casually and I want to be able to update the field to display how many new tables were gathered. I want this because instead of viewing the page to see if any updates happened I can just look at the title of the page inside a tab instead of switching over every 10 seconds you know?
How can this be done? Thanks.
Also the data I am gathering is text in a small table and data is just failed admincp user credentials.
You can change the title of a HTML document using JavaScript:
var title = "This is my new title, can be anything";
document.title = title;
I don't know how you are storing the number of new fields, but you could use a function like this:
function updateTitleBar (newTables)
{
document.title = newTables;
}
... Or you can just use document.title = newTables where you define the newTables somewhere else (and change that value every time you refresh the page in jQuery).
Maybe something like this?
<body onload="runTicker()">
function runTicker(){
setTimeout("document.title = new Date();runTicker()", 5000);
}
But instead of doing document.title = new Date(), replace that with a call to a function that would make an AJAX call to your PHP script. Perhaps using jquery if you're accustomed to that already?