I need business data inside my HTML pages. This data is not directly related to the DOM, but is used to handle javascript (and/or jquery) operations on the DOM. For example I shoud know that an object with id=100 holds objects with ids 1001, 1002 and 1003.
object (id=1000) = {1001,1002,1003}
I've been asking around but I hear different ideas.
Some solutions so far now
A datalist.
<dl id="1000">
<dt>1001</dt>
<dt>1002</dt>
<dt>1003</dt>
</dl>
Classes from tags
<span id="1000" class="o_1001 o_1002 o_1003">
(or any other tag ?)
<dl id="1000" class="o_1001 o_1002 o_1003">
UPDATED : Not in HTML at all? Since it's about data that is needed for javascript I might just as well put it directly in javascript?
<script>
var object = { id : 1000, value : [1000,1001,1002]; }
storeGlobal(object);
</script>
And storeGlobal would be a globar var in a js-script, that now also has the data.
Any ideas?
If the data is in some way related to some element(s) in the DOM, you could use jQuery.data(). It's a very nice and clean way of storing data in a page.
If it's not related to any DOM element, it's probably easiest to handle it completely in JS as an array/object.
If it's just data you will use in your javascript, write it as javascript and be done with it. Don't shove it into the DOM for no particular reason. You can either just have it as javascript literals (possibly generated by something like JSON.stringify on the server) or as a distinct JSON document your javascript retrieves via an ajax request.
Related
I'm just learning how to use the DOM properly and I'm struggling with how to get my javascript to interact with html. I have an array of objects with info about cats (just to help me learn) that I want to display using HTML, and I'm wondering what is best practice.
Should I put my data and js in a separate file to my html, or just write it in script tags in the html doc?
Is there a way I can use template literals in my html to do javascript that way, or does everything have to be a method like getelementbyid ?
Any help is much appreciated. Thanks!
There are a lot of options you have.
You can use jquery templates to bind the data to HTML. The data would be in javascript and you can have placeholders to display that data.
You can use Jquery to manipulate your DOM and place data inside HTML elements.
You can use some of the javascript frameworks like KnockoutJs to bind data from javascript data to HTML dynamically
The choice really depends on your use case. If you just have to display a read-only information, jquery templates should be fine. Using Jquery is probably easiest to start with, but messy and unmaintainable in the long run. If you have to implement a lot of dynamic data-driven behaviour, then use javascript frameworks.
you can simply create html div with cats-info id:
<div id="cats-info"></div>
then in your js file you could find this tag by id
const catsInfo = document.getElementById('cats-info');
then you could create cat list:
const catsData = [
{name: 'puffy', color: 'black'},
{name: 'flipper', color: 'white'}
];
function createCatList(cats) {
return `
<ul>
cats.map(cat => convertToCatItem(cat))
</ul>
`;
}
function convertToCatItem(cat) {
return `<li>${cat.name} - ${cat.color}</li>`;
}
and put your list into you catsInfo block;
catsInfo.innerHTML = createCatList(catsData);
Be free to ask
Let's say i want to open a PHP page and without another request, pass some JSON data directly to the browser, so it will be accessible to my Javascript functions.
I don't know the right way to do it, but what i do currently is something like this :
<textarea id="mydata" style:"display:none">[{code:1,name:'John'},{code:2,name:'Mary'},{code:3,name:'Paul'}]</textarea>
I put the data inside a invisible textarea and now the data inside 'mydata' textarea is accessible by JS doing something like this :
var myData = JSON.parse($('#mydata').val());
Although this works, somehow it does not seem to me the right way to do it... I know i could avoid to 'dirty' the html code by getting the data using Ajax after the page opens, but what i'm trying to do here is avoid more requests, so with only one request, everything will be accessible. Actually in my application i have about 5 textareas like these, so with only 1 request to the server i get all data needed.
Thanks
From PHP's perspective, there is no difference between this:
<textarea id="mydata" style:"display:none">[{code:1,name:'John'},{code:2,name:'Mary'},{code:3,name:'Paul'}]</textarea>
and this:
var myData = [{code:1,name:'John'},{code:2,name:'Mary'},{code:3,name:'Paul'}];
Both of the above take the form of:
[a string][the serialized object][a string]
Whether you're surrounding the values with HTML or with JavaScript, that surrounding decoration is just raw output strings as far as PHP is concerned. So there's no need to add the extra step of outputting the JSON to a form element and then using JavaScript to get the form element's value as a string and parse it back to an object. You can just emit the object itself directly to JavaScript code.
I'm programming in oTree (which is a Django based environment for social experiments) and I have the following problem. I defined some lists in Python and I'd like to import them and use them in an HTML template. If I print them in HTML I manage to see them without any problem, however, once I need to use them in Javascript, the program fails to read them and the single quotes of the elements of the list are converted in '.
The list is imported like this var filtered_elements = {{ array }};.
I think the problem is exactly here, as JS cannot work with them. Do you have any suggestion on how to do that? I considered using JSON, but since I'm quite new to programming, I cannot understand if it's just a waste of time or there is a simpler way out.
Thanks for your answers!
It sounds like your data is already JSON, otherwise you would be getting single quotes and u prefixes. So the only issue is Django autoescaping; you can disable it with the safe filter:
var filtered_elements = {{ array|safe }};
Your data should be JSON, instead of putting the Python list into the contact directly, put "array": json.dumps(array) in the context dictionary.
The JSON string doesn't need HTML escaping inside a tag, but it does need JS escaping! Otherwise some string may include something like </script><script>absolutely anything goes here... to run arbitrary JavaScript, if the JSON contains user data.
So use |escapejs:
var filtered_elements = {{ array|escapejs}};
I have a question about best practices when using jQuery/JavaScript/Ajax. Lets say that I have some tasks and there is a calendar for every task. The User is able to click on a day in a task calendar and book the task at the specific day via AJAX. I have to store the date and the ID of the task somewhere and i am using really bizarre IDs for that such as:
<span class="day_field" id="date_13-02-2013_task_4">13.02.2013</span>
Then i just attach an listener like this:
$('.day_field').on('click',function(){
var date = $(this).id.split('_')[1];
var task_id = $(this).id.split('_')[3];
//place for some validation
$.post('book_task.php',{task_id: task_id, date: date},function(data){
//something cool with the result
});
});
My question is: Is this the right way how to do it? I am not pretty sure, because the IDs can be really long + it contains ID in database which is not probably save at all.
Thanks!
T.
Use HTML5 data attributes:
<span class="day_field" data-date="13-02-2013" data-task="4">13.02.2013</span>
$('.day_field').on('click',function(){
var date = $(this).data("date");
var task_id = $(this).data("task");
//place for some validation
$.post('book_task.php',{task_id: task_id, date: date},function(data){
//something cool with the result
});
});
The right wayA better way to do it would be to store the data in either data attributes, or make the span an anchor tag and store the param string desired in the href attribute.
<span class="day_field" data-date="13-02-2013" data-task="4>13.02.2013</span>
or
<a class="day-field" href="?task_id=4&date=13-02-2013">13.02.2013</a>
with this for the anchor tag:
$('.day_field').on('click',function(e){
e.preventDefault();
$.post("foo.php",this.href,handler);
});
Instead of an ID, you can use custom data attributes, like this:
<span class="day_field" data-date="date_13-02-2013_task_4">13.02.2013</span>
And then you can access the value like this in jQuery:
$(".day_field").data("date");
Exposing the actual ID of something in your database is only as insecure as your database.
Using the id of the element seems fine to me, too, if it uniquely identifies a thing. Using the data attributes is a possibility to save on splitting logic if you like, but you could still use id in tandem.
Conventionally speaking, this is very tame code compared to much of what jQuery is.
One more elegant way to associate data to an element is to use jQuery's data. However, I would consider building a jQuery plugin and using one instance of it for each task. A plugin encapsulates all of the data it needs, so you wouldn't need to store it tied to the element, which is not great.
I will first explain what I'm trying to do then I will explain why just in case you get bored of reading the whole scenario.
Basically I have some HTML markup stored in a variable I now need to a wait to access the different elements within the variable. For example:
var markUp = "<h3>h3 tag</h3><p>paragraph tag</p>";
What I need to know is if there is a way for me to query the variable to retrieve say the h3 tag, in a similar way you would use the query function ? I have seen some other practices where people append the var to a hidden div then query the div. I would prefer to avoid this but if that is the only way I will proceed.
I have come across this problem whilst developing a drag and drop application, on drop i use a custom creator function to change the items structure once it is dropped.
If further explanation is needed please say, thanks advance Jonathan
You can use dojo._toDom to create a DOM fragment from your string.
var markup = "<h3>h3 tag</h3><p>paragraph tag</p><p>another paragraph</p>";
var domFragment = dojo._toDom(markup);
dojo.query("p", domFragment).forEach(function(element,i) {
console.debug(element.innerHTML);
});
The underscore prefix in _toDom means that it's a "private" member method of dojo. Normally, it's bad practice to use these as if they were public (like I do here). However, in the case of _toDom I believe it's generally considered acceptable, and according to this trac entry, it sounds like it'll be made public in the next version.