Best Practice with jQuery and AJAX calls - javascript

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.

Related

Multiple search by ID. Search not knowing full ID. Sapui5

I was wondering if there was any option to search an element by its id but not knowing the full ID, only part of it. So I could find an element without knowing its full ID or find multiple elements with similar IDs.
For example if I knew I had 3 objects with the followings ID:
"objectID1" "objectID2" and "objectID3".
Could I something like:
getElementByID("objectID*")
I have tried it in JavaScript using: input[id*='PART_OF_ID_I_KNOW']
But it returns an HTML object and I need it for SAPUI5.
Could I use something like:
var myControl = sap.ui.getCore().byId('myId');
But not having to match the full ID (myID)? Thanks.
Though I would not recommend this but it's possible in a way as you describe it.You could look for elements with similar ID with jQuery, get the element's ID and pass it to sap.ui.getCore().byId();
var aElements = $("div[id*='PART_OF_ID_YOU_KNOW']");
//Lets say the first element returned is the one belonging to your control
var oControl = sap.ui.getCore().byId(aElements[0].id); //If the element is a SAPUI5 control, you should get it.
Why do you need to do this? Is it because you want to access controls (with prefixed IDs) inside your views and fragments? Did you give an ID of "myControl" to the control, but sap.ui.getCore().byId("myControl") doesn't work as the framework added a prefix to it?
If yes, the only reliable way to get a reference to your control is by using the framework provided methods in MVC views and controllers and in fragments.
If you have a control called "myButton" in your view, do this.byId("myButton") or this.getView().byId("myButton") from the controller to get a reference to your control.
If you have a control called "myButton" in a fragment that you embedded in your view via sap.ui.xmlfragment("", "myFragment.fragment.xml"), then use sap.ui.core.Fragment.byId("<prefix>", "myButton") to access it.
Whatever you do, don't make assumptions on how the framework creates these prefixed IDs. These are not documented and can change.
when you use `var myControl = sap.ui.getCore().byId('myId');`
it won't work.It is because when you try to get control by sap.ui.getCore() sapui5 automatically concat extra string to Your id egsap.ui.getCore().byId('xml0--myId') and if you have provided viewId in manifest then while rendering control it uses that. eg
sap.ui.getCore().byId('yourManifiestId--myId')

Javascript / Jquery - correct practice for linking dynamically added elements to a back-end database

I have a page that has inputs that use HTML 5 websockets to update a back-end mysql database with user input. The inputs are added to the page dynamically, and there could be any number of inputs, each for the same field on different records of a MYSQL table. (I actually have a similar scenario all the time... is that just me? :P)
So, I had to come up with a way to maintain the same functionality, but for different records across all inputs. I came up with a working method, but it seems hackish.
the HTML looks like this:
<div class="button updateRecord" id="updateRecord_{RECORD ID}">Update</div>
Javascript: (using body.on to make sure the binding sticks for all instances of the dynamically added element)
body.on("click", ".updateRecord", function () {
// parse out the record ID from the element ID....
var itemID = this.id.split("_")[1];
// example of some stuff we can do with this value now:
// getting information from related input field:
var value = $("#someInput_"+itemID).val();
// use that info to send a request though a websocket:
sendMessage(itemID, value);
});
My question is: Is there a cleaner / more efficient way to do this? Every time I use this method I get a feeling I'm doing it wrong and there is a better way that makes more sense.

Business data in webpage: where and how to store it?

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.

Adding data to createTableViewRow() in appcelerator

How can i add custom data to a TableViewRow?
I'm using createTableViewRow() to setup a TableRow which I'm then added labels and images to it, then finally putting all these TableRows in a TableView. This works fine, but the rows need to have a "date" attribute attached to them, as I'm sorted these rows by dates before they are shown in the TableView.
How would i add a "date" to these TableRows? All these are unixtimestamps.
var row = Ti.UI.createTableViewRow({height:50, _date_var: date});
it can just be attached as a property and retrieved like this
row._date_var
As an add-on to Aaron's answer, if you want to retrieve the date in a click event on the row, you can access it with
e.row._date_var
as in
tableview.addEventListener('click', function(e) {
Titanium.UI.createAlertDialog({
title:'DB Test',
message:'date: ' + e.row._date_var
}).show();
});
This should probably be a comment to Aaron's answer if someone with reputation wants to change it.
Watch out with adding custom variables to views and other Ti objects. If your variable is going to hold something more complex than a string or a number (e.g. an object, particularly a complex object), then it is possible that iOS will crash at some point.
Check out this thread for more details.
https://developer.appcelerator.com/question/122924/how-to-fix-strange-javascript-behaviour-and-crashes-on-ios

Query HTML stored in Var with Dojo

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.

Categories