Call javascript function from another js file - javascript

I have a javascript file that reads the input from textbox inputs in MVC/AngularJS. The method looks like the following:
$scope.Clients_CW = {
....
}
function sendForm(data)
{
$scope.Clients_CW = data;
var submitData = registrationService.SaveFormData($scope.Clients_CW);}
I'm using the jQuery wizard with next, previous and finish buttons. This is in a different javascript file to the code above. My finish button looks like the following:
$($this.buttons.finish).click(function() {
if(!$(this).hasClass('buttonDisabled')){
if ($.isFunction($this.options.onFinish))
{
var context = { fromStep: $this.curStepIdx + 1 };
if (!$this.options.onFinish.call(this, $($this.steps), context))
{
return false;
}
}
else {
var frm = $this.target.parents('form');
if (frm && frm.length)
{
alert($scope.Clients_CW);
frm.submit();
}
}
}
return false;
});
My question and problem is... how do I pass through the $scope.Clients_CW data to the finish button method or how do I call the sendForm(data) method and it's parameter in the finish button method?

You can very well use route params to pass data between states. Refer ngRoute. You could also store the data in $rootScope or $localStorage for example to use the data in multiple states. The latter step would also work if both the files are required for the same state.

Related

AngularJS - Handling dynamic search using $http and debounce

I have a text input below, bound to a model req.mod1, with a debounce delay in updating model, that calls a pullData() function.
<input type="text" class="form-control" ng-change="pullData()" ng-model-options="{debounce: 1000}" ng-model="req.mod1">
Inside of pullData() I have a simple $http.get request, that pulls data and updates some other fields in the form.
$scope.pullData = function(){
var pullingData = true;
if (!pullingData){
$http.get('example.com/search/' + $scope.req.mod1 ).then(res)
...
$scope.req.mod2 = res.data.mod2;
$scope.req.mod3 = res.data.mod3;
var pullingData = false;
...
}
}
The problem that arises is that multiple calls stack on top of each other -- I think -- and so if a user happens to input text, wait >1second, and type some more, the call would go out with the first inputted text. Then it would pull the data and update the form with the first res. I'm trying to keep track of the request with a pullingData var.
Any ideas on how to handle a truly dynamic search call? Is there a way to cancel requests if a new one comes in? Or maybe just tell angular to constantly overwrite it?
Thanks in advance.
I think this is what you need
http://odetocode.com/blogs/scott/archive/2014/04/24/canceling-http-requests-in-angularjs.aspx
When you create a request.. it's called Promise, so what you need to cancel is that.
Something like this:
app.factory("movies", function($http, $q){
var getById = function(id){
var canceller = $q.defer();
var cancel = function(reason){
canceller.resolve(reason);
};
var promise = $http.get("/api/movies/slow/" + id, { timeout: canceller.promise})
.then(function(response){
return response.data;
});
return {
promise: promise,
cancel: cancel
};
};
return {
getById: getById
};
});
When the user enters something to search, your app should always search by the user's input. It means that you shouldn't cancel the user's input.
For example, the user want to search something about 'starwar', when he/she enter 'star', and you get some result. If now you cancel the 'war' which is entered after, the result is not good. So just let Angular override the result.
Moreover, some errors in your example of code, when you call pullData, it never passes the if check:
$scope.pullData = function(){
var pullingData = true;
// !pullingData is always false
if (!pullingData){
$http.get('example.com/search/' + $scope.req.mod1 ).then(res)
}
}

ServiceNow Javascript passing variables from GlideAjax functions

I am using ServiceNow. I need to validate a form onSubmit. I am using GlideAjax with a script include to validate data. How can I pass variables from the Ajax function calendarDate(response) to other functions within the Client Script? When the glide ajax function returns an error message, I want to set the variable "isValid" to false.
I have done this easily with Client Scripts that do not involve GlideAjax. I simply set the variable isValid to the result of the function such as var isValid = checkLnrDates();
However, setting a variable equal to the function call when using GlideAjax does not return any value that I can use. I perhaps am not understanding the way that the GlideAjax functions are called and handled.
Catalog Client Script onSubmit
function onSubmit () {
var isValid = checkLnrDates();
if (isValid == false) {
g_form.submitted = false;
return false;
}
}
function checkLnrDates() {
var start = g_form.getValue('start_date');
//Check calendar date format valid YYYY-MM-DD
//Script include ClientDateTimeUtils checks the input data
var ajaxCalendarDate = new GlideAjax('ClientDateTimeUtils');
ajaxCalendarDate.addParam('sysparm_name', 'validateCalendarDate');
ajaxCalendarDate.addParam('sysparm_userDate', start);
ajaxCalendarDate.getXML(calendarDate);
}
function calendarDate(response){
//This is where we get the response returned from the ClientDateTimeUtils script include ajax function
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer != 'true'){
g_form.showFieldMsg('start_date', answer,'error');
//How can I pass the value of a variable to the function above? I want to set isValid to false
isValid = false;
return false;
}
}
The fact that you need to get a response from the AJAX round-trip before you can proceed means that you're not actually asynchronous. You could probably just call ajaxCalendarDate.getXMLWait() and then call ajaxCalendarDate.getAnswer() to get the response synchronously (see Synchronous GlideAjax)
However, since you're already submitting, and your code relies on a server-side function call to validate some input, you might just consider moving this logic into a Before Insert Business Rule that validates, and aborts using current.setAbortAction(true) if your validation fails.
Wiki example here.
Your business rule would look something like:
function onBefore(current, previous) {
if (!CliendDateTimeUtils.validateCalendarDate(current.start_date)) {
current.setAbortAction(true); // Don't save the record
gs.addErrorMessage("Start date is not valid"); // Add an error message for the user
}
}
try this:
function onSubmit(){
checkLnrDates();
return false;
}
function checkLnrDates() {
var start = g_form.getValue('start_date');
//Check calendar date format valid YYYY-MM-DD
//Script include ClientDateTimeUtils checks the input data
var ajaxCalendarDate = new GlideAjax('ClientDateTimeUtils');
ajaxCalendarDate.addParam('sysparm_name', 'validateCalendarDate');
ajaxCalendarDate.addParam('sysparm_userDate', start);
ajaxCalendarDate.getXML(calendarDate);
}
function calendarDate(response){
//This is where we get the response returned from the ClientDateTimeUtils script include ajax function
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer != 'true'){
g_form.showFieldMsg('start_date', answer,'error');
return false;
}
else
g_form.submit();
}

AngularJS and Restangular, trying to convert update method to API

I'm trying to convert my basic crud operations into an API that multiple components of my application can use.
I have successfully converted all methods, except the update one because it calls for each property on the object to be declared before the put request can be executed.
controller
$scope.update = function(testimonial, id) {
var data = {
name: testimonial.name,
message: testimonial.message
};
dataService.update(uri, data, $scope.id).then(function(response) {
console.log('Successfully updated!');
},
function(error) {
console.log('Error updating.');
});
}
dataService
dataService.update = function(uri, data, id) {
var rest = Restangular.one(uri, id);
angular.forEach(data, function(value, key) {
// needs to be in the format below
// rest.key = data.key
});
// needs to output something like this, depending on what the data is passed
// rest.name = data.name;
// rest.message = data.message;
return rest.put();
}
I tried to describe the problem in the codes comments, but to reiterate I cannot figure out how to generate something like rest.name = data.name; without specifying the name property because the update function shouldn't need to know the object properties.
Here is what the update method looked like before I started trying to make it usable by any of my components (this works)
Testimonial.update = function(testimonial, id) {
var rest = Restangular.one('testimonials', id);
rest.name = testimonial.name;
rest.message = testimonial.message;
return rest.put();
}
How can I recreate this without any specific properties parameters hard-coded in?
Also, my project has included lo-dash, if that helps, I don't know where to start with this problem. Thanks a ton for any advice!
Try like
angular.extend(rest,testimonial)
https://docs.angularjs.org/api/ng/function/angular.extend

passing variable to mongodb query in meteor app

So I'm trying to get started with a simple meteor app to search a database. I've got a single input box from which I get the search query with the following code:
Template.search.events = {
'keydown input#search' : function (event) {
if (event.which == 13) {
var item = document.getElementById('search');
Template.results.results(item.value)
//console.log(item);
item.value = '';
}
}
}
I pass the search query to another function which is supposed to query the mongodb and print the result in the template:
Template.results.results = function (item) {
return Products.find({sku: item});
}
However, it never finds the item! If I run the same query in Chrome's console it works. If I replace {sku: item} in the code with (for example) {sku: "A2277"} (which is in my db) then it works! If i create a new variable inside the Template.results.results function such as var item = "A2277" that works too. What's going on here?!
Template helpers were designed to be called by your template, not directly by your event handlers. Your code just asks a query to happen and return a value, but it isn't tied to your template in any way. Instead, you should use a session variable like so:
Template.results.results = function() {
return Products.find({sku: Session.get('itemSku')});
};
Then in your event handler you can do something like:
Template.search.events({
'keydown input#search': function(event) {
if (event.which === 13) {
var $item = $('#search');
Session.set('itemSku', $item.val());
$item.val('');
}
}
});
Note I used jQuery here to set/get the item values. Anyway, that should set the session variable and reactively redraw the results.

WinJS: Loading data

I'm trying to develop my first Windows 8 Store app (HTML/JS). I am using the Grid App Template which suites my Needs I think the best.
This is my model:
I have three entities: 1. GalleryCategory 2. Gallery 3. GalleryItem.
A Gallery is linked to exactly one Category. A GalleryItem is linked to exactly one Gallery...so nothing fancy here...
I'm using the out of the box data.js file to load all categories and all galleries on the Startup of the app. But when I open the galleryDetail.html (which is supposed to Show all the Images of the particular Gallery) I want to load all Images of the Gallery then. (to avoid to much loading on the beginning).
And now I'm finally coming to the Point that I do not understand:
How can I manage this?? I mean
WinJS.UI.Pages.define("/pages/galleryDetail/galleryDetail.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
var item = options && options.item ? Data.resolveItemReference(options.item) : Data.items.getAt(0);
element.querySelector(".titlearea .pagetitle").textContent = item.group.title;
element.querySelector("article .item-title").textContent = item.title;
element.querySelector("article .item-subtitle").textContent = item.subtitle;
element.querySelector("article .item-image").src = item.backgroundImage;
element.querySelector("article .item-image").alt = item.subtitle;
element.querySelector("article .item-content").innerHTML = item.content;
element.querySelector(".content").focus();
var galleryId = item.key;
WinJS.xhr({ url: "http://someUrlToAnAspNetWebsite/Handlers/GalleryItemsHandler.ashx?galleryId=" + galleryId }).done(
// Complete function
function (response) {
var items = JSON.parse(response.responseText);
items.forEach(function (item) {
galleryItemsList.push(item);
});
dataList = new WinJS.Binding.List(galleryItemsList);
var galleryItemsListView = document.getElementById('galleryItemsListView').winControl;
galleryItemsList.itemDataSource = dataList.dataSource;
},
// Error function
function (response) {
// handle error here...
},
// Progress function
function (response) {
// progress implementation goes here...
}
);
},
my Problem is obivous...the ready function continues / Ends before the data is retrieved...as the async call takes a while.
But I thought using the promise (.done()) will do this for me (synchronising the threads)?? Or do I need to use the join() function. If so, where and how?? Sorry for my issues with this...
Thanks for any help...
The ready function itself is an async function, so you only have to return a promise to tell its caller that its not done until some promise is resolved. So you can fix your issue with 7 key strokes. Just add return before the WinJS.xhr call.

Categories

Resources