Multiple AJAX functions - ajax

I am trying to add an ajax function to a script that does 2 things essentially:
Step 1: Determine if it needs to search for users or create a new one
Step 2: Based on selection 1, it will either go to the selected script (that part works) or call a new function (that part doesn't work, yet). Now, I know the 2nd function itself works perfectly as I called it directly in the anchor tag and had no issues, so it has to be in how I am trying to all it witin the function itself. here's what I have so far:
function changecm(){
var txt = 'Select An Option To Continue:<br>
<input type="radio" name="type" id="type" value="search" style="font-size:22px;"><br>
<input type="radio" name="type" id="type" value="create" style="font-size:22px;">';
$.prompt(txt,{
buttons:{Confirm:true, Cancel:false},
submit: function(v,m,f){
var flag = true;
if (v) { }
return flag;
},
callback: function(v,m,f){
if(v){
var type = f.type;
if(type == 'create'){
$.post('changecm',{type:type},
function(data){
$("div#customer").html(data);
}
);
}
else{
function(changecmnow);
}
}
}
});
}
That's function 1. Here's function 2:
function changecmnow(){
var txt = 'Enter the first name, last name, or telephone number of the customer to limit your results:<br>
<input type="text" name="terms" id="terms" style="font-size:22px; width:400px;">';
$.prompt(txt,{
buttons:{Confirm:true, Cancel:false},
submit: function(v,m,f){
var flag = true;
if (v) { }
return flag;
},
callback: function(v,m,f){
if(v){
var terms = f.terms;
$.post('changecm',{terms:terms},
function(data){
$("div#customer").html(data);
}
);
}
}
});
}

if you just want to invoke the function, why not just
else { changecmnow();
}

Related

jquery deferred with async calls

Please find the below code snippet:
HTML:
<div>
<span> First Name : <input type="text" id="firstName" name="First Name"/></span>
</div>
<br/>
<div>
<span>Student Id: <input type="text" id="studentId" name="studentId"/></span>
<span>Teacher Id: <input type="text" id="teacherId" name="teacherId"/></span>
</div>
<br/>
<div>
<span>Student Name : <input type="text" id="stdLastName" name="stdLastName"/></span>
<span>Student Age :<input type="text" id="stdAge" name="stdAge"/></span>
</div>
<br/>
<div>
<span>Teacher Name : <input type="text" id="tchrLastName" name="tchrLastName"/></span>
<span>Teacher Age : <input type="text" id="tchrAge" name="tchrAge"/></span>
</div>
<br/>
<input type="button" value="Submit" id="submit"/>
Javascript:
$('#firstName').focus();
var d1= new $.Deferred();
$('#firstName').blur(populatePage());
//called on blur of first name
function populatePage() {
$.when(populateStdDetails(),populateTchrDetails()).done(function(resp1, resp2){
$('#stdLastName').val(resp1[0].stdName);
$('#stdAge').val(resp1[0].age);
$('#tchrLastName').val(resp2[0].stdName);
$('#tchrAge').val(resp2[0].age);
console.log('All details populated....');
d1.resolve();
});
return d1;
}
//first ajax call
function populateStdDetails() {
if($('#firstName').val() != '' && $('#studentId').val() !='') {
return $.ajax({
url : '/someURL?studentId='+studentId+'&firstName='+firstName,
type :'GET',
contentType:'json'
});
}
}
//second ajax call
function populateTchrDetails() {
if($('#firstName').val() != '' && $('#teacherId').val() !='') {
return $.ajax({
url : '/someURL?teacherId='+teacherId+'&firstName='+firstName,
type :'GET',
contentType:'json'
});
}
}
$('#submit').click(function(e){
//wait for the ajax calls to be completed
$.when(populatePage()).done(function(e){
console.log('All done !!!!');
//Move to next page;
});
});
The First Name text field has an onblur event attached which works fine in usual scenario but when the focus is on "First Name" and "Submit" is clicked, the submit function is called instead of waiting for the onblur event to be completed.
You have placed deferred.resolve in wrong places in your timeout functions. Do it like this way:
function doSomething(deffered) {
$('#log').append('doSomething');
deferred.resolve();
return deferred;
};
function ajaxRequests1(deferred) {
setTimeout(function(){
$('#log').append('......ajaxRequests1');
deferred.resolve();
}, 1000);
return deferred;
};
function ajaxRequests2(deferred) {
setTimeout(function(){
$('#log').append('.....ajaxRequests2');
deferred.resolve();
}, 5000);
return deferred;
};
var func1 = function () {
var promise = new $.Deferred();
ajaxRequests1(promise);
return promise;
}
var func2 = function () {
var promise = new $.Deferred();
ajaxRequests2(promise);
return promise;
}
var stepFinal = function() {
var promise = new $.Deferred();
doSomething(promise);
return promise;
}
$.when(func1().promise(), func2().promise())
.done(function () {
stepFinal().done();
});
OK, if you want populatePage() to be called when focus leaves #firstname, and if the user also clicked on the submit button and you want the submit operation to wait for that blur action to finish, you can do this:
$('#firstName').blur(function(e) {
// call populatePage and set the resulting promise as a data item so
// the submit handler can get access to it
var self = $(this);
var p = populatePage();
self.data("blurPromise", p);
// when this promise is done, clear the blurPromise
p.always(function() {
self.removeData("blurPromise");
});
});
//called on blur of first name
function populatePage() {
return $.when(populateStdDetails(),populateTchrDetails()).done(function(resp1, resp2){
$('#stdLastName').val(resp1[0].stdName);
$('#stdAge').val(resp1[0].age);
$('#tchrLastName').val(resp2[0].stdName);
$('#tchrAge').val(resp2[0].age);
console.log('All details populated....');
});
}
//first ajax call
function populateStdDetails() {
if($('#firstName').val() != '' && $('#studentId').val() !='') {
return $.ajax({
url : '/someURL?studentId='+studentId+'&firstName='+firstName,
type :'GET',
contentType:'json'
});
} else {
// just return already resolved promise
return $.when();
}
}
//second ajax call
function populateTchrDetails() {
if($('#firstName').val() != '' && $('#teacherId').val() !='') {
return $.ajax({
url : '/someURL?teacherId='+teacherId+'&firstName='+firstName,
type :'GET',
contentType:'json'
});
} else {
return $.when();
}
}
$('#submit').click(function(e){
// get blur promise or dummy resolved promise
var p = $("#firstName").data("blurPromise") || $.when();
p.then(function() {
// do your submit logic here
// The onBlur handler is done now
});
});
Things I've updated in your promise handling code:
Use the $.ajax() promises directly without wrapping them in yet another promise.
Use the $.when() promises directly without wrapping them in yet another promise.
When using an if statement to decide whether or not to execute an asynchronous operation, it is usually best to also return a promise in the else arm so your function consistently always returns a promise. If there's nothing else to do in the else clause, then a shortcut for returning an already resolved promise in jQuery is to just return $.when();.
Be warned that .done() is jQuery-specific and not standard promise behavior. If you're already on jQuery 3.x or higher, then you should probably switch to .then() and then your promises will behave like the promise standard.

knockoutjs data bind hidden field value

I'm having a hidden field in a knockout template that its value gets updated with jquery. The problem is when trying to pass this value to the server with ajax, I get null value in the controller. But the html source code shows that the value of the hidden field is updated. If I replaced the hidden field with a textbox, it would work fine only when I enter text manually.
jQuery
function getFileDetail(fileID, fileName) {
$('#hdnFileName' + fileID).val(fileName);
$('#lblFileName' + fileID).text(fileName);
}
Here is the html knockout template:
<script type="text/html" id="fileTemplate">
<div data-role="fieldcontain">
<label data-bind="text: 'File Upload ' + ID, attr: { id: 'lblFileName' + ID }"></label><input type="button" value="Remove" data-bind="click: removeFile" />
</div>
<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID, value: fileName }" />
</script>
ViewModel
function FileViewModel() {
var self = this;
self.ID = ko.observable();
self.fileName = ko.observable();
self.removeFile = function (file) { };
self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);
self.addNewFile = function () {
var newFile = new FileViewModel();
newFile.ID = self.Files().length + 1;
newFile.fileName = "";
newFile.removeFile = function (file) { self.Files.remove(file); };
self.Files.push(newFile);
//$("input[name='hdnFileName'").trigger("change");
}
}
function ViewModel() {
var self = this;
self.fileViewModel = new FileViewModel();
self.submitForm = function () {
$.ajax({
type: "POST",
url: "<%= Url.Action("MeetingPresenter")%>",
data: "{Files:" + ko.utils.stringifyJson(self.fileViewModel.Files) + "}",
contentType: "application/json",
success: function (data) {},
});
};
}
Your model property ID is an observable, so you need to 'unwrap' to get the value from it when you are concatenating, like this:
<input type="hidden" name="hdnFileName" data-bind="attr: { id: 'hdnFileName' + ID(), value: fileName }" />
and this:
<label data-bind="text: 'File Upload ' + ID(), attr: { id: 'lblFileName' + ID() }"></label>
If you are using knockout.js you don't neede to modify the DOM, you can just update the ViewModel and the DOM will be updated according
function getFileDetail(fileID, fileName) {
viewModel.fileViewModel.update(fileID, fileName);
}
Add the update function in FileViewModel
function FileViewModel() {
// rest of the code
self.update = function(fileID, fileName) {
var file = ko.utils.arrayFirst(self.Files(), function(file) {
return file.ID == fileID;
});
file.fileName(fileName); // this will change and the UI will be updated according
};
}
Note: Please notice that you have a default item in Files that will not be changed with update function because properties are not observable
self.Files = ko.observableArray([{ ID: 1, fileName: "", removeFile: function (file) { self.Files.remove(file); }}]);
You can solve this by making them observable (i.e. ID: observable(1)) or you can create a new FileViewModel().
Note: The viewModel must be accesible in the function (i.e. global instance), otherwise will be undefined.
It looks to me that setting a field's value via the DOM does not interact with knockout. If you are setting its value using .value, the observable will not be updated. You should be updating the observable.
I wrote a little Fiddle to demonstrate. Every 2 seconds, it sets the input's value via the DOM, but the bound observable only changes when you type something.
http://jsfiddle.net/qcv01h2e/
var viewModel = (function () {
return {
fv: ko.observable().extend({notify:'always'})
};
}());
ko.applyBindings(viewModel);
setInterval(function () {
console.debug("Set it");
var f = document.getElementById('field');
f.value = "Hi";
console.debug("fv is", viewModel.fv());
}, 2000);
I came across a similar issue where I need to set a value without user input.
Before doing the click update function I do the required model update. If you have mode operations better to introduce a function in the model.
<input data-bind="click: function(){ isEnabled(true); update() }" />
What I actually did was,
<input data-bind="click: function(){ isEnabled(!isEnabled()); update() }" />
Keep in mind that asynchronous nature of javascript.

Live Search Filter with Checkbox PHP

I have issue about the live search with check box. My problem is when i search one the name list the check box is automatically check. only the showed data check.
example i search world "vin"
all have word vin must be checked.
this is my [sample][1]
[1]: http://jsfiddle.net/v921/TxYqv/3/
UPDATED answer:
Here is how your js should look like:
function filter(element) {
var $trs = $('.AvailableGroupLab tr').hide();
var regexp = new RegExp($(element).val(), 'i');
var $numberOfShownRows = 0;
var $rows = $trs.filter(function () {
if($(element).val() != "")
{
$(this).children(':nth-child(1)').html("<input type='checkbox' checked />");
}
else
{
$(this).children(':nth-child(1)').html("<input type='checkbox' />");
}
return regexp.test($(this).children(':nth-child(2)').text());
});
$rows.show();
if($rows.length == 0)
{
$('#message').show();
}
else
{
$('#message').hide();
}
}
$('input:text').on('keyup change', function () {
filter(this);
})
And put this div whereever you want to put your text:
<div id="message" style="display:none"> No record! </div>

How to use star rating plugin in MVC 4 application?

I want to use this star rating plugin in my MVC 4 application.
I have Rating table like this:
public class Rating
{
public int FromUserId { get; set; }
public int ToProductId { get; set; }
public int RateValue { get; set; }
}
I have an action like this:
public ActionResult SubmitRating(int fromUserId, int toProductId , int rateValue )
{
return View();
}
FromUserId is #WebSecurity.CurrentUserId and
ToProductId is Model.Id
I have problem with ajax. I need to send RateValue to action.
How can I send selected value to SubmitRating action in controller and reverse, to send back an answer from controller to view (to show selected value, to show any message to user etc.) ?
This does not work. How to write ajax code here?
$(function(){
$('#star-rating').rating(function(vote, event){
$.ajax({
url: "#Url.Action("SubmitRating", "MyController")",
type: "GET",
data: {rateValue : vote},
});
});
});
Let's assume some things:
your HTML has the product id:
<div id="star-rating" data-pid="#Model.Id">
<input type="radio" name="example" class="rating" value="1" />
<input type="radio" name="example" class="rating" value="2" />
<input type="radio" name="example" class="rating" value="3" />
<input type="radio" name="example" class="rating" value="4" />
<input type="radio" name="example" class="rating" value="5" />
</div>
so you can have a list of products instead only one product per page.
It's not a security practice to pass the user id if that's the same as the current logged in one, you could simple fetch the userid from the current session., so we would have in our controller:
public class ServicesController : Controller
{
public ActionResult RateProduct(int id, int rate)
{
int userId = WebSecurity.CurrentUserId;
bool success = false;
string error = "";
try
{
success = db.RegisterProductVote(userId, id, rate);
}
catch (System.Exception ex)
{
// get last error
if (ex.InnerException != null)
while (ex.InnerException != null)
ex = ex.InnerException;
error = ex.Message;
}
return Json(new { error = error, success = success }, JsonRequestBehavior.AllowGet);
}
}
this way you can easily call your rate like:
<script>
$(function () {
$('#star-rating').rating(function (vote, event) {
var anchor = $(event.currentTarget),
pid = anchor.closest(".ratting-item").data("pid"),
url = '#Url.Action("RateProduct", "Services")';
// show a loading div that would have a animated gif
$(".loading").show();
$.ajax({
url: url,
type: "GET",
data: { rate: vote, id: pid },
success: function (data) {
if (data.success) {
// all went well, here you can say Thank you
}
else {
// There must be an Exception error, let's show it
}
},
error: function (err) {
// the call thrown an error
},
complete: function () {
$(".loading").hide();
}
});
});
});
</script>
updated
$(this) does not return the correct element, so we need to use the event property that is passed along the call:
So we need to change to this:
var anchor = $(event.currentTarget),
pid = anchor.closest(".ratting-item").data("pid"),
url = '#Url.Action("RateProduct", "Services")';
a simple console.log($(this)) and then console.log(event); would tell you that, plus, if you fire Fiddler, you will see what's missing as well seeing the error on the returned call.
Project example on GIT
Here's the source code of this project working: https://github.com/balexandre/Stackoverflow-Question-14014091

Jquery Impromptu 4

I'm having a hard time with impromptu(jquery plugin) where I keep getting an undefined value. Here is an example:
<img id=dispatch title='Click to dispatch(COMING SOON)' onclick=Dispatch(0) src='../images/icons/truck_green.png' width=16 height=16/>
<img id=dispatch title='Click to dispatch(COMING SOON)' onclick=Dispatch(1) src='../images/icons/truck_green.png' width=16 height=16/>
<img id=dispatch title='Click to dispatch(COMING SOON)' onclick=Dispatch(2) src='../images/icons/truck_green.png' width=16 height=16/>
<img id=dispatch title='Click to dispatch(COMING SOON)' onclick=Dispatch(3) src='../images/icons/truck_green.png' width=16 height=16/>
function Dispatch(id){
var driver = 'Enter the drivers name:<br><input type="text" id="alertName" name=myname value="" />';
$.prompt(driver,{
submit: myfunc,
buttons: { Ok:true }
});
}
function myfunc(e,v,m,f){
var an = m.children('#alertName');
if(f.alertName == ""){
an.css("border","solid #ff0000 1px");
return false;
}
return true;
}
Eventually I want to take the id and the name typed and do some AJAX. But I cant get the css change. I alerted f.alertName and got undefined and I don't know why. Thank for your help.
I believe you want f.myName. Learn to step through with debugger and examine objects. The answer quickly became obvious.
http://jsfiddle.net/ULeQz/1/
var driver = 'Enter the drivers name:<br><input type="text" id="alertName" name="myname" value="" />';
$.prompt(driver, {
submit: myfunc,
buttons: {
Ok: true
}
});
function myfunc(e, v, m, f) {
debugger;
var an = m.children('#alertName');
if (f.myname == "") {
an.css("border", "solid #ff0000 1px");
return false;
}
return true;
}​

Resources