How to send dynamically generated variables via ajax, using post method - html

I've an html page wich contains a table, some rows and inside any row i checkbox.
When i select a checkbox i will to delete the message BUT only when i click a red-button-of-death.
Example
table
tr(unique_id)
td [checkbox]
td Content
td Other content
[... and so on]
/table
[red-button-of-death]
Now, the delete of multi rows must be without the reload of the page so i set up an ajax function that work like this:
setup ajax object.
set the open method (post/get, url, true)...
wait for the response of the "url" page.... take a coffe, have a break.
got response, using jquery delete the row using the unique id of the rows.
jquery: popup a feedback for the action just done
jquery: update some counter around the page
So, i begin tryin to delete a single record and everything go fine, i has created a link on every rows that call the function to delete "single record" passing the id of the item.
But now i've to develop the multi-delete-of-doom.
the first thing that i've think was "i can envelop the table in a 'form' and send everything with the 'post' method".
That seems to be brilliant and easy....
but doesn't work :-|
Googling around i've found some example that seems to suggest to set a variable that contains the item to send... so, trying to follow this way i need a method to get the name/id/value (it's not important, i can populate an attribute with the correct id) of the selected checkbox.
Here the function that make the ajax call and all the rest
function deleteSelected() {
var params = null;
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("post", "./cv_delete_pm.php?mode=multi", true); //cancella i messaggi e ritorna l'id delle righe da cancellare
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status != 404) {
var local = eval( "(" + xmlhttp.responseText + ")" );
/*
//cancella gli elementi specificati dalla response
var Node = document.getElementById(local.id);
Node.parentNode.removeChild(Node);
loadMessagesCount('{CUR_FOLDER_NAME}'); //aggiorna sidebar e totale messaggi nel body
initTabelleTestate(); //ricrea lo sfondo delle righe
$("#msgsDeleted").attr("style", "left: 600px; top: 425px; display: block;");
$("#msgsDeleted").fadeIn(500);
$("#msgsDeleted").fadeOut(2000);
$("#msgsDeleted").hide(0);
*/
}
}
};
xmlhttp.send(params);
}
Actually the variable 'param' is set to null just because i'm doing some experimentation.
So, the questions
are:
- Is it possible to make an ajax request sending the content of the form? How?
- Is it possible to get the name/value/id (one of these) of all the selected checkbox of an html page? How?
Answer to one of these two question with the solution is enough to win my personal worship :)

Edit: I think you are using JQuery so look here: http://api.jquery.com/category/ajax/
You should be using a javascript frame work such as dojo or jquery to handle Ajax. Writing you own ajax functions from scratch is not recommended.
Some frameworks:
http://www.dojotoolkit.org/
http://www.jquery.com/ (http://api.jquery.com/category/ajax/)
http://mootools.net/
A jquery example (are you already using this framework?):
$.post("test.php", $("#testform").serialize());
A Dojo Example:
Submitting a form using POST and Ajax:
function postForm() {
var kw = {
url: 'mypage.php',
load: function(type, data, evt) {
dojo.byId("someElement").innerHTML=data;
},
formNode: dojo.byId("myForm"),
method: "POST",
error: function(type, data, evt){
//handle error
},
mimetype: "text/html"
};
dojo.io.bind(kw);
}

Update. Solved.
I've used the builtin function of jquery to manage the form sumbit using the $jQuery.post() function and the $(#idform).serialize() function. It's really late now but tomorrow i'll try to remember to paste here the correct code :)
Thanks for the answer anyway :)
Update (code below):
//Send by Post
function deleteSelected() {
$.post("./delete.php?mode=multi",
$("#pmfolder_form").serialize(),
function(data){
var local = eval( "(" + data + ")" );
//this delete the html via dom to update the visual information
for (var i = 0; i < local.length-1; ++i) {
var Node = document.getElementById(local[i]);
Node.parentNode.removeChild(Node);
}
});
}
The structure of the selectbox was something like:
<input type="checkbox" name="check_<? print $progressive_id; ?>" value="<? print $real_id; ?>"/>
That's all. :)

Related

How To Make an INPUT Field As "Required" In HTML5?

On my website I have a reservation forum,
and I put that the person cannot submit the forum unless submitting their name and phone number.
<p><label>Phone #:<input type="text" id="phone" name="phone" placeholder="###-###-####" style="margin:10px; width:100px; height:15px" required>
It works perfect on every device besides any mobile device using safari, so I wanted to know what code can I use so it can work on all devices.
Any input/help/advice would be appreciated.
Mobile Safari validation isn't really up to par compared to all the other browsers. You can check out feature support by going to Can I use. What I would do to fix this issue is grab Modernizr.js or use some other feature detection to find out if form validation is supported. If it isn't, then just put it in a little JS snippet saying that the field is required.
Something like this should do if you use Modernizr.js and select "Input Attributes" under HTML5.
var jsRequired;
if (!Modernizr.input.required) {
jsRequired = true;
}
Then on the form submission:
$('#form-submit').on('click', (function(evt) { // this is the form submit button
evt.preventDefault(); // preventing reload of the page
if (jsRequired == true) {
var requiredInputs = $('input[required]');
for (var i = 0; i < requiredInputs.length; i++) {
if (requiredInputs[i].value == '') {
$('#submission-info').text('Whoa whoa whoa, you missed one...');
// highlight the missed one by adding a class
requiredInputs[i].className += " submission-error";
return false; //; stop the rest of the submission
}
}
}
var formData = $('form#contact-form').serialize(); // serialize data
$.ajax({
url: 'mail.php', // rename this to your php file
type: 'POST',
data: formData
}).done(function(response) {
// do stuff to to show the user that the form was submitted
$('#submission-info').text('Success, your information has been sent to us (and the NSA of course) and we will reply to you as soon as possible.');
}).fail(function(response, error) {
// tell the user what happened that caused the form submission to fail
$('#submission-info').text('Oh no, something happened. Maybe try again?');
});
});
Some of the code should be changed around to fit your stuff but otherwise it should be in the general direction of what you are looking to do.

innerHTML call to receive a url

I am trying to make a call so that when a title of a video is clicked on in my playlist, it will call back a particular videos url to be shown in the metadata field box that I have created.
So far I am getting results but the function below that I am using is giving me rmtp url's like this:
(rtmp://brightcove.fcod.llnwd.net/a500/d16/&mp4:media/1978114949001/1978114949001_2073371902001_How-to-Fish-the-Ice-Worm.mp4&1358870400000&7b1c5b2e65a7c051419c7f50bd712b1b
)
Brightcove has said to use (FLVURL&media_delivery=http).
I have tried every way I know of to put a media delivery in my function but always come up with nothing but the rmtp or a blank.
Can you please help with the small amount of code I have shown. If I need to show more that is not a problem. Thanks
function showMetaData(idx) {
$("tr.select").removeClass("select");
$("#tbData>tr:eq("+idx+")").addClass("select");
var v = oCurrentVideoList[idx];
//URL Metadata
document.getElementById('divMeta.FLVURL').innerHTML = v.FLVURL;
Here is my Population call for my list.
//For PlayList by ID
function buildMAinVideoList() {
//Wipe out the old results
$("#tbData").empty();
console.log(oCurrentMainVideoList);
oCurrentVideoList = oCurrentMainVideoList;
// Display video count
document.getElementById('divVideoCount').innerHTML = oCurrentMainVideoList.length + " videos";
document.getElementById('nameCol').innerHTML = "Video Name";
//document.getElementById('headTitle').innerHTML = title;
document.getElementById('search').value = "Search Videos";
document.getElementById('tdMeta').style.display = "block";
document.getElementById('searchDiv').style.display = "inline";
document.getElementById('checkToggle').style.display = "inline";
$("span[name=buttonRow]").show();
$(":button[name=delFromPlstButton]").hide();
//For each retrieved video, add a row to the table
var modDate = new Date();
$.each(oCurrentMainVideoList, function(i,n){
modDate.setTime(n.lastModifiedDate);
$("#tbData").append(
"<tr style=\"cursor:pointer;\" id=\""+(i)+"\"> \
<td>\
<input type=\"checkbox\" value=\""+(i)+"\" id=\""+(i)+"\" onclick=\"checkCheck()\">\
</td><td>"
+n.name +
"</td><td>"
+(modDate.getMonth()+1)+"/"+modDate.getDate()+"/"+modDate.getFullYear()+"\
</td><td>"
+n.id+
"</td><td>"
+((n.referenceId)?n.referenceId:'')+
"</td></tr>"
).children("tr").bind('click', function(){
showMetaData(this.id);
})
});
//Zebra stripe the table
$("#tbData>tr:even").addClass("oddLine");
//And add a hover effect
$("#tbData>tr").hover(function(){
$(this).addClass("hover");
}, function(){
$(this).removeClass("hover");
});
//if there are videos, show the metadata window, else hide it
if(oCurrentMainVideoList.length > 1){showMetaData(0);}
else{closeBox("tdMeta");}
}
If looking for HTTP paths, when the API call to Brightcove is correct you won't see the rtmp:// urls.
Since you're getting the rtmp URLs, this verifies you're using an API token with URL access, which is good. A request like this should return the playlist and the http URLs (insert your token and playlist ID).
http://api.brightcove.com/services/library?command=find_playlist_by_id&token={yourToken}&playlist_id={yourPlaylist}&video_fields=FLVURL&media_delivery=http
This API test tool can help build the queries for you, and show the expected results:
http://opensource.brightcove.com/tool/api-test-tool
I'm not seeing what would be wrong in your code, but in case you haven't tried this already, debugging in the browser can help you confirm the API results being returned, without having to access it via code. This help you root out any issues with the code you're using to access the values, vs problems with the values themselves. This is an overview on step-debugging in Chrome if you haven't used this before:
https://developers.google.com/chrome-developer-tools/docs/scripts-breakpoints

mvc3 entity framework - convert comma separated list of strings into list<string> in viewmodel, allow users to remove items from list

I am struggling to figure out how to do this with MVC,
I have an entity framework object that has a comma separated list from the db, (can't change the fact that its a horrible csl in the db). I can easily display the list and let them edit it manually. This is rather error prone and would like to split them up and display a list of them in the view. Then allow the user to click a link / button and have them removed from the string and db and the page refreshed to reflect this.
My first thought was to use JQuery to do a ajax json post to do a delete for each item the click an #Html.ActionLink for. I could get it to do the async post back and it would delete the item and would send back a string representing the new string list which I could update the UL with. The second time they clicked a link it would give me a 404, the script I used is:
<script type="text/javascript">
$(document).ready(function () {
$('.viewSeasonsLink').click(function () {
var data =
{
item: $(this).parents('li').first().find('.flagName').text(),
deploymentId: #Model.Id
};
$.post(this.href, data, function (result) {
var list = $("#testme");
list.empty();
var items = result.split(",");
$(items).each(function(index) {
// /* var link = '"' + #Html.ActionLink("Remove", "RemoveItemFromList", "Deployment", null, new { #class = "viewSeasonsLink" }) + '"'; */
var link = '<a class="viewSeasonsLink" href="/SAMSite/Deployment/RemoveItemFromList">Remove</a>';
list.append('<li><span class="flagName">' + items[index] + '</span> - ' + link + ' </li>');
/* list.append('<li><span class="flagName">' + items[index] + '</span> - ' + '\'' + #Html.ActionLink("Remove", "RemoveItemFromList", "Deployment", null, new { #class = "viewSeasonsLink" }) + '\'</li>'); */
});
}, "json");
return false;
});
});
</script>
I could not get the action link to work with the jquery script, so tried hard coding it, still not success.
I then thought I would just try and do a simple actionlink back to a method to remove it and return the normal view, again this posts and will update the db, but will not refresh the webpage at all.
<ul id="testme2">
#foreach (string flag in ViewBag.FeatureFlags)
{
<li><span class="flagName">#flag</span> - #Html.ActionLink("Remove", "RemoveItemFromListTest", "Deployment", null, new { #class = "viewSeasonsLink" })</li>
}
</ul>
public ActionResult RemoveItemFromListTest(string item, int deploymentId)
{
Deployment deployment = db.Deployments.Single(d => d.Id == deploymentId);
ViewBag.CustomerId = new SelectList(db.Customers, "Id", "Name", deployment.CustomerId);
List<string> featureFlags = deployment.FeatureFlags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
featureFlags.Remove(item);
deployment.FeatureFlags = ConvertBackToCommaList(featureFlags);
ViewBag.FeatureFlags = featureFlags;
//db.SaveChanges();
return View("Edit", deployment);
}
EDIT
released I was being a bit daft at one point:
The second test to get it to do a full post back and do the update was still getting caught by the jquery, (also was not passing in the values). I changed the line to this:
<li><span class="flagName">#flag</span> - #Html.ActionLink("Remove", "RemoveItemFromListTest", "Deployment", new { item = #flag, deploymentId = Model.Id }, null)</li>
which does work, but is a bit naff, it would mean any changes made to the form before the remove link clicked would be lost.
I think I see two issues. One is the initial .Post on the viewSeasonsList click event. You are posting back to the Action that loaded the page, not the Action that will handle the delete. I doesn't seem to me that they would be the same Action base on the approach you described.
var url = '/SAMSite/Deployment/RemoveItemFromList';
then
$.post(url, data, function (result) {
Second, in the Ajax response, when you are rebuilding the list, you are including an href attribute for the links. Why? you are not navigating with those links, you are initiating an Ajax request, which has already been set up.
var link = '<a class="viewSeasonsLink">Remove</a>';
ultimately I had one main problem with the jquery solution. When I added a new LI element it was not being hooked up to the ajax call as this was just happening at document.ready. I now replaced the simple .click with a delegate that will also hook up all elements that are added after the ready event, credit to this page for help with it:
$('#featureflaglist').delegate('.removeflaglink', 'click', RemoveFlagFromList);

Populating dropdown list with JSON data using 2 views/documents

I'm having some trouble populating a dropdownlist with some JSON data, i suspect that the error occurs because of the way im appending the $.post within the #stuff div, but i've tried this a couple of ways and just wont get the hang of it.
The select id="" tag & the div lies within another view (it's not part of this particular document) , is that a problem for populating the dropdown-list this way?
Ive tried to alert out the "listItems" and i've got the option values etc... dont get it why it wont populate.
Any help would be appreciated.
Json-response from the $.post =
{"childrendata":[{"id":"42","parent":"1","fName":"hej","lName":"nisse","birthdate":"2011-10-21"}]}
The jQuery/js:
$("#stuff").append(function(){
$.post("show_relations", {},
function(data)
{
$("#stuff").empty();
json = eval('('+data+')');
if(data == '{"childrendata":[]}')
{
$("#stuff").append("No relations registered.");
}
else
{
var listItems= "";
for (var i = 0; i < json.childrendata.length; i++)
{
listItems+= "<option value='" + json.childrendata[i].fName + "'>" + json.childrendata[i].lName + "</option>";
}
$("#child_list").html(listItems);
}
});
});
});
Edit: Based on your comment, I'll assume your problem is purely single-page.
The problem with that code would appear to be the fact that you're trying to use .append() with a function (which is valid jQuery), but that the function doesn't return anything that jQuery can append to the 'stuff' node; $.post makes an Ajax call, which returns immediately.
Instead, try something like the following (modifying the URL to the Ajax call as required):
$.post("url/to/post/to", {},
function(data) {
$("#stuff").empty(); //Clear your stuff div
var children = data.childrendata; //jQuery automatically unserializes json
if(children.length == 0) {
$("#stuff").append("No relations registered.");
}
else {
$('#stuff').append('<select id="child_list"></select>');
$.each(children,
function(index, value) {
//Append each option to the selectbox
$("#child_list").append("<option value='" + value.fName + "'>" + value.lName + "</option>");
}
);
}
},
'json'
);
$.each() is the generic jQuery iterator, which helps de-clutter the code.
What this does is make an Ajax post to the provided URL, which responds with the serialized json object. The callback takes that response (which jQuery has already unserialized by itself), adds a new select to the '#stuff' div, and then adds the dynamically-created options to the new select.
Endnote: My apologies for not posting the link to the $.each documentation, StackOverflow only allows me to post 2 hyperlinks in a single post currently.

Lifehacker implemention of url change with Ajax

I see that Lifehacker is able to change the url while using AJAX to update part of the page. I guess that can be implemented using HTML5 or history.js plugin, but I guess lifehacker is using neither.
Does any one has a clue on how they do it?
I am new to AJAX and just managed to update part of the page using Ajax.
Thank you #Robin Anderson for a detailed step by step algo. I tried it and it is working fine. However, before I can test it on production, I would like to run by you the code that I have. Did I do everything right?
<script type="text/javascript">
var httpRequest;
var globalurl;
function makeRequest(url) {
globalurl = url;
/* my custom script that retrieves original page without formatting (just data, no templates) */
finalurl = '/content.php?fname=' + url ;
if(window.XMLHttpRequest){httpRequest=new XMLHttpRequest}else if(window.ActiveXObject){try{httpRequest=new ActiveXObject("Msxml2.XMLHTTP")}catch(e){try{httpRequest=new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}}
/* if no html5 support, just load the page without ajax*/
if (!(httpRequest && window.history && window.history.pushState)) {
document.href = url;
return false;
}
httpRequest.onreadystatechange = alertContents;
alert(finalurl); /* to make sure, content is being retrieved from ajax */
httpRequest.open('GET', finalurl);
httpRequest.send();
}
/* for support to back button and forward button in browser */
window.onpopstate = function(event) {
if (event.state !== null) {
document.getElementById("ajright").innerHTML = event.state.data;
} else {
document.location.href = globalurl;
return false;
};
};
/* display content in div */
function alertContents() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var stateObj = { data: httpRequest.responseText};
history.pushState(stateObj, "", globalurl);
document.getElementById("ajright").innerHTML = httpRequest.responseText;
} else {
alert('There was a problem with the request.');
}
}
}
</script>
PS: I do not know how to paste code in comment, so I added it here.
It is not an requirement to have the markup as HTML5 in order to use the history API in the browser even if it is an HTML5 feature.
One really quick and simple implementation of making all page transistions load with AJAX is:
Hook up all links except where rel="external" exist to the function "ChangePage"
When ChangePage is triggered, check if history API is supported in the browser.
If history API isn't supported, do either push a hashtag or make a normal full page load as fallback.
If history API is supported:
Prevent the normal link behaviour.
Push the new URL to the browser history.
Make a AJAX request to the new URL and fetch its content.
Look for your content div (or similar element) in the response, take the HTML from that and replace the HTML of the corresponding element on the current page with the new one.
This will be easy to implement, easy to manage caches and work well with Google's robots, the downside is that is isn't that "optimized" and it will be some overhead on the responses (compared to a more complex solution) when you change pages.
Will also have backward compatibility, so old browsers or "non javascript visitors" will just get normal page loads.
Interesting links on the subject
History API Compatibility in different browsers
Mozillas documentation of the History API
Edit:
Another thing worth mentioning is that you shouldn't use this together with ASP .Net Web Forms applications, will probably screw up the postback handling.
Code addition:
I have put together a small demo of this functionality which you can find here.
It simply uses HTML, Javascript (jQuery) and a tiny bit of CSS, I would probably recommend you to test it before using it. But I have checked it some in Chrome and it seems to work decent.
Some testing I would recommend is:
Test in the good browsers, Chrome and Firefox.
Test it in a legacy browser such as IE7
Test it without Javascript enabled (just install Noscript or similar to Chrome/Firefox)
Here is the javascript I used to achieve this, you can find the full source in the demo above.
/*
The arguments are:
url: The url to pull new content from
doPushState: If a new state should be pushed to the browser, true on links and false on normal state changes such as forward and back.
*/
function changePage(url, doPushState, defaultEvent)
{
if (!history.pushState) { //Compatability check
return true; //pushState isn't supported, fallback to normal page load
}
if (defaultEvent != null) {
defaultEvent.preventDefault(); //Someone passed in a default event, stop it from executing
}
if (doPushState) { //If we are supposed to push the state or not
var stateObj = { type: "custom" };
history.pushState(stateObj, "Title", url); //Push the new state to the browser
}
//Make a GET request to the url which was passed in
$.get(url, function(response) {
var newContent = $(response).find(".content"); //Find the content section of the response
var contentWrapper = $("#content-wrapper"); //Find the content-wrapper where we are supposed to change the content.
var oldContent = contentWrapper.find(".content"); //Find the old content which we should replace.
oldContent.fadeOut(300, function() { //Make a pretty fade out of the old content
oldContent.remove(); //Remove it once it is done
contentWrapper.append(newContent.hide()); //Add our new content, hidden
newContent.fadeIn(300); //Fade it in!
});
});
}
//We hook up our events in here
$(function() {
$(".generated").html(new Date().getTime()); //This is just to present that it's actually working.
//Bind all links to use our changePage function except rel="external"
$("a[rel!='external']").live("click", function (e) {
changePage($(this).attr("href"), true, e);
});
//Bind "popstate", it is the browsers back and forward
window.onpopstate = function (e) {
if (e.state != null) {
changePage(document.location, false, null);
}
}
});
The DOCTYPE has no effect on which features the page can use.
They probably use the HTML5 History API directly.