I am using an html <select> (not the server control) on my asp.net webform, which I bound using asp.net ajax via a webservice call. In my webservice I basically do this:
Private Function GetStores() As String
dim stores as DataTable = GetStores()
dim html as new StringBuilder
for each row as DataRow in stores.Rows
html.append("<option>")
html.append(row("store"))
html.append("</option>")
next
return html.tostring()
End Function
From my js, I would then simply use:
$get("myddl").innerHTML = "<select>" + result + "</select>";
The reason why I do this is because the server is faster in creating the required HTML. If I were to fill the ddl from the client-side by just returning the dataTable, then I think it will take a bit longer, depending on the rows.
Also please note that I do this only once when the page is loaded.
What do you think about this? Is this bad? If yes, why?
I think it is bad because I have seen many issues from various browsers arise when you just set the innerHTML of an element.
If you try to create elements by just putting the html markup for them into some controls innerHTML, the html DOM does not always get updated. This can cause your values to not get passed back on form submits, or even make it impossible to refer to the elements using javascript.
You should instead have you WebService return JSON or XML data with just the info you need, (just the store name.) And then use javascript to dynamically create and add the options to the dropdown.
Something like this would work well:
// do your AJAX call and pass back the responseText to this function (For a JSON response)
function FillDDL(text)
{
eval("var data="+text);
var ddl=document.getElementById('ddlID');
for( var i=0; i<data.items.count; i++ )
{
var option = document.createElement("option");
option.text=data.items[i];
option.value=data.items[i]; //IE wont automatically copy the text to the value
ddl.options.add(option,0); //FF will error if you dont tell it where to add the option
}
}
And if you aren't familar with JSON, this is the format to use with the code above:
{items:['name','name2','name3']}
Just return a string like the above from your WebService and you should be all set.
Your server-side method doesn't seem to filter that list of options, so if you are just displaying a select list, why not render it with the initial page, rather than making a subsequent request.
As far as performance in concerned, sending back the data in JSON format is less verbose, so less kilobytes. If we're talking 50 items in the drop down list, you will hardly notice the overhead of creating this using JavaScript vs doing it on the server.
Also, there is a known bug in some versions of Internet Explorer that mean you need to replace the entire select rather than simply updating the options - just in case you run into it!
Related
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 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.
I have a page that requests most of it's content via Ajax. The returned html consists of 2 tables, which I render on the page.
The code I am currently using:
$.post(myUrl, $('form').serialize(), function (data)
{
var $data = $(data);
$('#HeaderIndholdPanel').html($data.find('#GridView1'));
$('#SvarIndholdPanel').html($data.find('#Table1'));
}, 'html');
It does not get any easier, but does it get faster?
The second table is almost 4 MB, so that explains, why it's slow - both tables must be rendered from one request, can't be split.
However I want to optimize it.
I know that Jquery parses the html for scripts and other things. And when the table is replaced it cleans the events assigned to the elements.
Is there any way I can avoid that? It's not neseccary in my case.
I know that my html doesn't have any scripts and I don't assign any avents to it.
Should I return JSON instead and pass that to the native 'innerhtml' method?
Or do you have any better ideas?
I have found that $('#id').replaceWith(data) works much better/faster than $('#id').html(data).
This is because $('#id').html(data) takes the time to trace the object before replacing. When you command a simple replace it seems to ignore any existing value(s) and completes a straight swap.
I found this out when trying to swap out a select list that had thousands or options and using an ajax response to filter it. While watching the code I literally watched it deleted each select option one by one and then re-add it one by one.
Using .replaceWith(data), did a split/quick/1-for-1 replace.
$('#HeaderIndholdPanel').replaceWith($data.find('#GridView1'));
$('#SvarIndholdPanel').replaceWith($data.find('#Table1'));
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.
Here's my issue:
Client(s) give me separate JS files which will run a check of some sort on the user's system (Browser type, are cookies enabled?, etc.) and a list of acceptable values to be returned from this check.
I want to run through each JS file when a user visits the site and compare the results to the list of acceptable values, then alert the user if they pass these requirements or not.
I'm currently using RegisterClientScriptBlock() to add the JS to the client's page, so it's being run, but I'm having issues getting the result value from the JS back to ASP.NET in order to do the comparison.
I've tried using hidden fields that the JS will dump the value to and ASP.NET will read from, but I'm having difficulty generating the hidden fields on demand (since I have no idea how many Js files the client could have) and have them work in the ASP.NET code.
Any help, or suggestions in the right direction would be awesome, thanks!
What I would do is have the results be an array of KeyValuePair objects that you would then serialize to JSON. So you create the javascript object type like so:
function KeyValuePair(key, value){
this.Key = key;
this.Value = value;
}
Then you would build up an array of KeyValuePairs like so:
//This array is declared in the global scope
var ValueArray = new Array();
function someFunction(){
//this assumes that the key and value variables are created earlier in the function
var valueToStore = new KeyValuePair(key, value);
ValueArray[ValueArray.length] = valueToStore;
}
So at the point when you are done with all your checks you would use the json2 serializer to serialize the array to json for storage in your hidden field.
var jsonToSaveToHiddenField = JSON.stringify(ValueArray);
//Logic to store resulting json and trigger the serverside evaluation here
On the server side you would use JavascriptSerializer to deserialize your json to an array of KeyValuePairs. Here is the msdn doc on that: JavaScriptSerializer Class Reference
So with this approach you only need one hidden field. So you don't need to dynamically create it which should simplify the server side retrieval quite a bit.
The above should work with minimal changes however I haven't run this through a compiler so there might be some minor syntax errors preset.