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.
Related
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')
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 am developing a front end request/data management system in order to clean up/organize my API calls/refactor how I interface with my backend platform. I am extending the jquery ajax api call to interface with it and I am looking for some advice on where to stick api-specific implementation.
please keep in mind this is a web-application platform and I am trying to make it easier to manage front-end components
The goal is to take defining a request from something like...
var requestObj = new Object();
requestObj.callback = function(responseObj){deleteUserComplete(responseObj); };
requestObj[0] = new Object();
requestObj[0].module = "usermanager";
requestObj[0].context = "#someTable";
requestObj[0].action = "DELETE_USER";
requestObj[0].dataObj = new Object();
requestObj[0].dataObj.userId = $("#ui-tabs-4 .az-switch-panel-off input[name$=userId]").val();
To...
$("button.apiSubmit").apiManager('submitApi');
or
var options = {};
options.callback = someFunction;
options.context = "#someTable";
//etc...
$("button.apiSubmit").apiManager('submitApi', options);
I'm sure you get the idea... but i want to move the ugly request object creation to a factory-type object (mainly just processing forms into objects my backend understands) and moving the api-specific implementation (module, action, context etc) to the markup.
Now for the question(s)...
1) What are the benefits/pitfalls of moving my api-specific request information to the markup?
2) (again, pretty much convinced moving request info to the markup is the right move) class tags or html5 data attributes (x-browser isn't an issue... they are internal apps)?
EX: of class attributes would be... class="apiButton apiButton-module-MODULE_NAME apiButton-action-ACTION_NAME" - obviously a bit ugly... but manageable straightforward way to go about htis.
3) Are there any alternatives to making my api requests more reusable/easier to read? It's the only way I communicate with php so it's very... very important this system is solid.
1) Whereas I somewhat agree with Marcel Korpel on using HTML5 data attributes, I think that using the markup explicitly presents a couple potential problems: first off you are exposing your API/backend internals to the end-user, which is never ideal and secondly its kind of volatile because it could be easily changed (firebug, js) and mess up the behaviour associated with that element.
2) The more elegant (but slightly harder to implement method) would be to use jQuery's .data() method to store related information - this way you keep your markup clean and still have the flexibility of storing as much information as you want related to the element. It is also "hidden" from the end-user (sure firebug/js can access it but it's slightly harder to come by than right in the markup). There are basically 2 ways I can think of how you could implement this: -1 - if you are creating the markup dynamically then wrap the element in a jQuery object and apply the metadata before inserting it into the DOM or -2- if it is being created with PHP you could store it as a serialized string in "rel" or "rev" or someother little-used attribute and then use jQuery to grab it, store in metadata and clear the attribute.
3) However, now that I think about it, whereas using .data() is more elegant, I guess it doesn't make it all the more easier to understand because you are effectively hiding away applications internals. Perhaps you could implement getter/setters to retrieve the metadata or something along those lines.
I recently wrote some javascript code that filled a drop down list based on some XML, pretty simple stuff. The problem was I had to write similar code to do almost the same thing on a different page.
Because the code was almost identical I named most of the functions the same, thinking that they would never be included in the same page. However, naming conflicts arose because both javascript files were eventually included in the same HTML page.
When I had to go back and change the names I simply added first_ or second_ to the method's names. This was a pain and it doesn't seem very elegant to me. I was wondering if there is a better way to resolve name conflicts in javascript?
Try the JavaScript module pattern (or namespaces) used in various libraries.
Try to be DRY (don't repeat yourself) so you can avoid name collisions. If the code is almost the same you better avoid code duplication by creating a function which can handle both cases. The function can take two parameters: which dropdown to populate and with what data. This helps maintainability as well.
update: I assume that you take the XML from an AJAX request. In this case you can create on-the-fly anonymous functions with the appropriate parameters for callback inside a loop.
I would look at how I could merge the two pieces of code (functions?) into a single function. If you need to populate a list box, then pass the list box id into the function, so you are not hard-coded to operate on one single control only...
I did this on my rocket business's web site where I sold rocket motors with different delay values, but in essence, they were the same product, just a different delay value.
Perhaps this might try and explain what I'm trying to say... I use this if an image file happens to be missing, it will display a "no image" image in place of the real image.
function goBlank(image)
{
if(image) {
var imgobj = document[image];
imgobj.src="/images/blank.png";
}
}
In this case, you call it with:
<img src="/images/aerotech.png" name="header" onError="goBlank('header');">
If you need more example with things like list boxes used, let me know. Perhaps even post some sample code of yours.
Another option (if possible) is to carefully tie the code to the element itself.
e.g.
<input type="text" name="foo" id="foo" value="World" onchange="this.stuff('Hello ' + this.value);"/>
<script>
document.getElementById('foo').stuff = function(msg){
//do whatever you want here...
alert('You passed me: ' + msg);
};
</script>
Sorry I couldn't be more descriptive with the title, I will elaborate fully below:
I have a web application that I want to implement some AJAX functionality into. Currently, it is running ASP.NET 3.5 with VB.NET codebehind. My current "problem" is I want to dynamically be able to populate a DIV when a user clicks an item on a list. The list item currently contains a HttpUtility.UrlEncode() (ASP.NET) string of the content that should appear in the DIV.
Example:
<li onclick="setFAQ('The+maximum+number+of+digits+a+patient+account+number+can+contain+is+ten+(10).');">
What is the maximum number of digits a patient account number can contain?</li>
I can decode the string partially with the JavaScript function unescape() but it does not fully decode the string. I would much rather pass the JavaScript function the faq ID then somehow pull the information from the database where it originates.
I am 99% sure it is impossible to call an ASP function from within a JavaScript function, so I am kind of stumped. I am kind of new to AJAX/ASP.NET so this is a learning experience for me.
First of all, if you're pulling the questions from the db on page load you most likely have all the answers too, so just keep going with your current approach by jamming the answers into the page as your code sample is doing. Unless your FAQ list has thousands and thousands of questions, doing it the "AJAX way" by hitting the db on each click of the list item doesn't give you much here IMO. If it does have that many questions then a straight list is the wrong way to go anyway.
Secondly, two things to keep in mind re your approach:
you're placing html inside an html attribute
the attribute is specifying a javascript function to call
So you need to make sure your "answer" escapes both html and is valid js. By valid js I mean it can't have new lines and must escape quotes properly. For example, the following html - although valid html - won't fire the onclick and you'd just get a js syntax error:
<li onclick="setFAQ('This line's
multi line and has a single quote in it!')"
To account for these I would say HttpUtility.HtmlAttributeEncode in tandem with System.Web.Script.Serialization.JavaScriptSerializer is more appropriate to the markup you've shown.
JavaScriptSerializer json = new JavaScriptSerializer();
string answerString = "This line's\nmulti line and has a single quote in it!";
string onClickJS = String.Format("setFAQ({0})", json.Serialize(answerString));
string onClickAttr = HttpUtility.HtmlAttributeEncode(onClickJs);
Even better, use .NET's ListItem object and lose HtmlAttributeEncode altogether:
ListItem faqItem = new ListItem(questionString);
faqItem.Attributes.Add("onclick", String.Format("setFAQ({0})", json.Serialize(answerString)));
The html portion is escaped automatically for you, plus it's a lot cleaner.
As for your javascript, you don't have to decode anything in setFAQ(). Just take its argument and put it in into you "answer" div:
function setFAQ(answer) {
document.getElementById('answer').innerHTML = answer
}
I think just using HttpUtility.HtmlEncode may solve your problem. I'm not sure I follow completely though : \