Validate null value throwing undefined - javascript

I have a select like this:
<select class="form-control" ng-hide="Catalogos.length==0"
ng-change="filtro(selected)" ng-model="selected"
ng-options="item.Nombre for item in Catalogos ">
</select>
From there I get selected value in function like this:
$scope.filtro = function(selected) {
$scope.selectedID = selected.ID;
}
There I get Id for selected value, but now I use it into another function, but that function can get parameter null or not so function is:
$scope.insertar = function () {
if ($scope.catalogoid != null) {
var url = "../../api/Catalogo/UpdateCatalogoRegistro/" + $scope.Codigo + "/" + $scope.Nombre + "/" + $scope.catalogoid + "/" + $scope.Catalogo;
if ($scope.selected.ID != null) {
url = url + "/" + $scope.selected.ID;
}
apiService.post(url....
Problem is when it comes null it just throw $scope.selected is undefined when it pass this validation
if ($scope.selected.ID != null) {
url = url + "/" + $scope.selected.ID;
}
How can I validate it if $scope.selected doesn´t exist in this case?

you stored it in $scope.selectedID but retrieving from $scope.selected.ID.
Use
if ($scope.selectedID != null) {

Related

How to use Angular.js to populate multiple select fields using AJAX calls to different endpoints

I apologize up front for the possible lack of clarity for this question, but I'm new to Angular.js and my knowledge of it is still slightly hazy. I have done the Angular.js tutorial and googled for answers, but I haven't found any.
I have multiple select/option html elements, not inside a form element, and I'm populating them using AJAX. Each form field is populated by values from a different SharePoint list. I'm wondering if there is a way to implement this using Angular.js?
I would like to consider building this using Angular because I like some of it features such as data-binding, routing, and organizing code by components. But I can't quite grasp how I could implement it in this situation while coding using the DRY principle.
Currently, I have a single AJAX.js file and I have a Javascript file that contains an array of the different endpoints I need to connect to along with specific query parameters. When my page loads, I loop through the arrays and for each element, I call the GET method and pass it the end-point details.
The code then goes on to find the corresponding select element on the page and appends the option element returned by the ajax call.
I'm new to Angular, but from what I understand, I could create a custom component for each select element. I would place the component on the page and all the select and options that are associated with that component would appear there. The examples I've seen demonstrated, associate the ajax call with the code for the component. I'm thinking that I could use a service and have each component dependent on that service and the component would pass it's specific query details to the service's ajax call.
My current code - Program flow: main -> data retrieval -> object creation | main -> form build.
Called from index.html - creates the multiple query strings that are passed to ajax calls - ajax calls are once for each query string - the very last function in the file is a call to another function to build the form elements.
var snbApp = window.snbApp || {};
snbApp.main = (function () {
var main = {};
main.loadCount = 0;
main.init = function () {
function buildSelectOptions(){
//***
//Build select options from multiple SharePoint lists
//***
var listsArray = snbApp.splistarray.getArrayOfListsForObjects();
for(var i = 0; i < listsArray.length; i++){
var listItem = listsArray[i];
var qryStrng = listItem.list +
"?$select=" + listItem.codeDigits + "," + listItem.codeDescription + "," + listItem.ItemStatus + "&$orderby=" + listItem.codeDescription + "&$filter="+listItem.ItemStatus+" eq true" + "&$inlinecount=allpages"
var listDetails = {
listName: listItem.list,
listObj: listItem,
url: "http://myEnv/_vti_bin/listdata.svc/" + listItem.list +
"?$select=" + listItem.codeDigits + "," + listItem.codeDescription + "," + listItem.ItemStatus + "&$orderby=" + listItem.codeDescription + "&$filter="+listItem.ItemStatus+" eq true" + "&$inlinecount=allpages"
};
var clientContext = new SP.ClientContext.get_current();
clientContext.executeQueryAsync(snbApp.dataretriever.letsBuild(listDetails), _onQueryFailed);
}
//***
//Build select option from other API endpoint
//***
var listDetails = {
listName:"SNB_SecondaryActivityCodes",
url: "http://myEnv/requests/odata/v1/Sites?$filter=(IsMajor eq true or IsMinor eq true) and IsActive eq true and IsPending eq false and CodePc ne null and IsSpecialPurpose eq false&$orderby=CodePc"
};
snbApp.dataretriever.letsBuild(listDetails);
}
buildSelectOptions();
//***
//Add delay to populate fields to ensure all data retrieved from AJAX calls
//***
var myObj = setTimeout(delayFieldPopulate,5000);
function delayFieldPopulate(){
var optObj = snbApp.optionsobj.getAllOptions();
var osType = $("input[name=os_platform]:checked").val();
snbApp.formmanager.buildForm(osType, optObj);
}
};
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return main
})();
AJAX calls here - called from main/previous file:
var snbApp = window.snbApp || {};
snbApp.dataretriever = (function () {
var listsArray = snbApp.splistarray.getArrayOfListsForObjects();
function getListData(listItem) {
var eventType = event.type;
var baseURL = listItem.url;
$.ajax({
url: baseURL,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
}
})
.done(function(results){
snbApp.objectbuilderutility.buildObjectFields(results, listItem);
})
.fail(function(xhr, status, errorThrown){
//console.log("Error:" + errorThrown + ": " + myListName);
});
}
function _onQueryFailed(sender, args) {
alert('Request failed.\nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
return{
letsBuild:function(item) {
getListData(item);
}
};
})();
Builds a item name object - called from recursive AJAX calls / previous file
var snbApp = window.snbApp || {};
snbApp.objectbuilderutility = (function () {
function formatItemCode(itemCode, eventType){
if(eventType !== 'change'){ //for load event
var pattern = /^CE/;
var result = pattern.test(itemCode);
if(result){
return itemCode.slice(2);
}else{
return itemCode.slice(0,3);
}
}else{ //for change event
var pattern = /^CE/;
var result = pattern.test(itemCode);
if(result){
return itemCode.slice(2);
}else{
return itemCode.slice(3);
}
}
}
return{
buildObjectFields: function(returnedObj, listItem){ //results:returnedObj, prevItem:listItem
//***
//For SharePoint list data
//***
if (listItem.listName !== "SNB_SecondaryActivityCodes") {
var theList = listItem.listName;
var firstQueryParam = listItem.listObj.codeDigits;
var secondQueryParam = listItem.listObj.codeDescription;
var returnedItems = returnedObj.d.results;
var bigStringOptions = "";
//regex to search for SecondaryFunctionCodes in list names
var pattern = /SecondaryFunctionCodes/;
var isSecFunction = pattern.test(theList);
if(isSecFunction){
bigStringOptions = "<option value='0' selected>Not Applicable</option>";
}else{
bigStringOptions = "<option value='0' disabled selected>Select Option</option>";
}
$.each(returnedItems, function (index, item) {
var first = "";
var second = "";
for (var key in item) {
if (item.hasOwnProperty(key)) {
if (key != "__metadata") {
if (key == firstQueryParam) {
first = item[key];
}
if (key == secondQueryParam) {
second = item[key];
}
}
}
}
bigStringOptions += "<option value=" + first + " data-code=" + first + ">" + second + "</option>";
});
var str = theList.toLowerCase();
snbApp.optionsobj.updateFunctionOrActivity(theList.toLowerCase(), bigStringOptions);
//***
//For other API
//***
} else {
var theList = listItem.listName;
var bigStringOptions = "<option value='0' disabled selected>Select Option</option>";
var returnedItems = returnedObj.value;
for(var i = 0; i < returnedItems.length; i++){
var item = returnedItems[i];
//***
//change event type means the user selected a field
//***
if(listItem.eventType === "change"){
var siteCodeChange = item.SiteCodePc;
if (typeof siteCodeChange === "string" & siteCodeChange != "null") {
siteCodeChange = siteCodeChange < 6 ? siteCodeChange : siteCodeChange.slice(3);
}
bigStringOptions += "<option value='" + item.Id + "' data-code='" + siteCodeChange + "' data-isDivSite='" + item.IsDivisionSite + "' data-isDistSite='" + item.IsDistrictSite + "' data-divID='" + item.DivisionSiteId + "' data-distID='" + item.DistrictSiteId + "'>(" + siteCodeChange + ") " + item.Name + "</option>";
snbApp.formmanager.buildSelectSiteLocations(bigStringOptions);
//***
//load event which means this happens when the page is loaded
//***
}else{
var siteCodeLoad = item.SiteCodePc;
if (typeof siteCodeLoad === "string" & siteCodeLoad != "null") {
var siteCodeLoad = siteCodeLoad.length < 4 ? siteCodeLoad : siteCodeLoad.slice(0, 3);
}
bigStringOptions += "<option value='" + item.Id + "' data-code='" + siteCodeLoad + "' data-isDivSite='" + item.IsDivisionSite + "' data-isDistSite='" + item.IsDistrictSite + "' data-divID='" + item.DivisionSiteId + "' data-distID='" + item.DistrictSiteId + "'>(" + siteCodeLoad + ") " + item.Name + "</option>";
snbApp.optionsobj.updateFunctionOrActivity(theList.toLowerCase(), bigStringOptions);
}
}
}
}
};
})();
Form management - called from previous file, gets all select elements on page and appends items from the object in previous file to each select element.
var snbApp = window.snbApp || {};
//Direct interface to the form on the page
snbApp.formmanager = (function(){
var form = {};
form.content_holder = document.getElementById("content_holder");
form.sec_act_codes = document.getElementById("snb_secondary_activity_codes");
form.prim_func_codes = document.getElementById("snb_primary_function_codes");
form.sec_func_codes = document.getElementById("snb_secondary_function_codes");
form.sec_func_nums = document.getElementById("snb_secondary_function_numbers");
form.host_options = document.getElementById("snb_host_options");
form.site_locs_div = document.getElementById("site_locations_div");
form.site_locs = document.getElementById("snb_site_locations");
form.dc_or_off_prem_div = document.getElementById("dc_or_off_premise_div");
form.dc_off_prem_codes = document.getElementById("snb_dc_offpremise_codes");
var snb_secondary_activity_codes = "";
var snb_primary_function_codes = "";
var snb_secondary_function_codes = "";
var snb_secondary_function_numbers = "";
var snb_host_options = "";
var snb_site_locations = "";
var snb_dc_op = "";
//builds the server location hosting options selection
function buildLocationTypeSelector() {
var locationOptionsString = "<option value='0' disabled selected>Select Option</option>";
for (var i = 0; i < locationOptions.length; i++) {
var location = locationOptions[i];
locationOptionsString += "<option value=" + location.hostLocale + " data-code=" + location.code + ">" + location.hostLocale + "</option>";
}
$("#snb_host_options").append(locationOptionsString);
}
function buildSiteLocations(bigString){
if(bigString === undefined){
var siteLocs = document.getElementById("snb_site_locations");
var newOption = document.createElement("option");
newOption.setAttribute("value", 0);
newOption.setAttribute("disabled","disabled");
newOption.setAttribute("checked","checked");
var newText = document.createTextNode("Select Option");
newOption.appendChild(newText);
siteLocs.appendChild(newOption);
} else{
var siteLocs = document.getElementById("snb_site_locations");
siteLocs.innerHTML = bigString;
}
}
return {
form:form,
buildSelectSiteLocations: function(bigString){
buildSiteLocations(bigString);
},
buildForm: function (osType, optObj) {
buildLocationTypeSelector();
buildSecondaryFunctionNumberSelector();
buildSiteLocations();
if(osType === 'windows'){
$("#snb_secondary_activity_codes").append(optObj.windows.secondary_activity);
$("#snb_primary_function_codes").append(optObj.windows.primary_function);
$("#snb_secondary_function_codes").append(optObj.windows.secondary_function);
$("#snb_site_locations").append(optObj.windows.site_location);
$("#snb_dc_offpremise_codes").append(optObj.windows.dc_offpremise);
}else{
$("#snb_secondary_activity_codes").append(optObj.unix.secondary_activity);
$("#snb_primary_function_codes").append(optObj.unix.primary_function);
$("#snb_secondary_function_codes").append(optObj.unix.secondary_function);
$("#snb_site_locations").append(optObj.unix.site_location);
$("#snb_dc_offpremise_codes").append(optObj.unix.dc_offpremise);
}
}
};
})();
Thanks in advance.

Set a default URL parameter if none is specified or is blank

I have this code:
function getURLParameter(name) {
return decodeURI(
(RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1] || ''
);
}
In my HTML, I call out a user's device brand and model using:
<script>document.write(getURLParameter("brand") + (" ") + getURLParameter("name"))</script>
The only problem is that this is only working for certain mobile devices. When it doesn't work, it's simply left blank. Is there a way to add a default value if it's empty?
You can simply compare the values with
if(name === " " || name == null) {
//code
}
or
if(name !== " " || name != null) {
return decodeURI(
(RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1] || ''
);
}

dynamic input and select how to build queryString

I'm trying to build a query parameter for when doing a search, I managed to build it with input field however there's a select dropdown menu to select other values.
<input type="text" class="dd">
<select name="" class="sel">
<option value=""></option>
<option value="Prepare">Prepare</option>
<option value="Ready">Ready</option>
<option value="Cancel">Cancel</option>
</select>
<button onclick="buildQuery()">Build query</button>
jQuery code for query building the query param
function buildQuery(){
var result = "?";
var getVal = $('input.dd').val();
console.log('Input > ', getVal);
var getSelectVal = $('select.sel').val();
if (getVal != null && (getVal != "")) {
let inputValues = getVal
.split("\n")
.filter(function (str) { return str !== "" })
.join("&test=");
// then add it to the overall query string for all searches
result = result + 'test' + "=" + inputValues + "&";
console.log('Results > ', result);
}
Not sure how can I get the value from the select and construct it similar way to my input console.log output Results > ?test=f&
So if you fill in the input and select an option it the queryParam should say something like ?test=inputVal&test=selectVal or individual ?test=inputVal or ?test=selectVal
What I can do is copy the whole if() statement and replace the getVal with getSelectVal but it seems inefficient and duplicating the code.
Actual code --
newSearchParams.properties.forEach(function (inputSearch) {
// first reparse the input values to individual key value pairs
// Checks which field is not null and with empty string (space)
var getVal = $('input.input_' + inputSearch.name).val();
var getSelectVal = $('select.select_' + inputSearch.name).val();
if (getVal != null && (getVal != "")) {
let inputValues = getVal
.split("\n")
.filter(function (str) { return str !== "" })
.join("&" + inputSearch.name + "=");
// then add it to the overall query string for all searches
result = result + inputSearch.name + "=" + inputValues + "&";
}
}, this);
// remove trailing '&'
result = result.slice(0, result.length - 1);
return result;
Sample Fiddle
Edit: -- This is what I'm trying to get out of this question,
if(paramMethod == 'path'){
// build parameter api/id/1
} else if(paramMethod =='query'{
// build queryString api/apiPoint?id=1
} else if(paramMethod == 'none') {
// var result = "";
// return result;
}
If you're not worrying about IE < 9:
function buildQuery() {
return $('.dd, .sel')
.toArray()
.reduce(function(str, el) {
return str + (el.value ? el.name + '=' + el.value + '&' : '')
}, '?')
}
Working fiddle: https://jsfiddle.net/qk3d7bq1/2/
If you care about IE < 9:
function buildQuery() {
var query = '?'
$('.dd, .sel').each(function() {
if (this.value) {
query += this.name + '=' + this.value + '&'
}
})
return query
}
Working fiddle: https://jsfiddle.net/d51f5uyw/2/
Update
If you want to make this generically useful, just pass a selector string to buildQuery to select the exact things you want:
function buildQuery(selector) {
return $(selector)
.toArray()
.reduce(function(str, el) {
return str + (el.value ? el.name + '=' + el.value + '&' : '')
}, '?')
}
Fiddle: https://jsfiddle.net/qsxkz4qu/1/
Alternatively you could specify a container and have buildQuery find all of the form fields inside that container:
Fiddle: https://jsfiddle.net/uar5h3xe/1/
But buildQuery itself should not be defining any selection variables. That's configuration that should be passed to it.
Update
If you want to parameterize the whole thing, you could use something like what's shown at this fiddle: https://jsfiddle.net/uar5h3xe/4/

Recursive Function not working correctly

I have a recusive function that is supposed to loop through a json object and output the expression. However, my recusion seems to be off because it's outputting field1 != '' AND field3 == '' when it should be outputting field1 != '' AND field2 == '' AND field3 == ''
I've tried a couple different things and the only way I can get it to work is by creating a global variable outstring instead of passing it to the function. Where am I off? When I step through it, i see a correct result but once the stack reverses, it start resetting outstring and then stack it back up again but leaves out the middle (field2).
JSFiddle
function buildString(json, outstring) {
var andor = json.condition;
for (var rule in json.rules) {
if (json.rules[rule].hasOwnProperty("condition")) {
buildString(json.rules[rule], outstring);
} else {
var field = json.rules[rule].id;
var operator = json.rules[rule].operator;
var value = json.rules[rule].value == null ? '' : json.rules[rule].value;
outstring += field + ' ' + operator + ' ' + value;
if (rule < json.rules.length - 1) {
outstring += ' ' + andor + ' ';
}
}
}
return outstring;
}
var jsonObj = {"condition":"AND","rules":[{"id":"field1","operator":"!= ''","value":null},{"condition":"AND","rules":[{"id":"field2","operator":"== ''","value":null}]},{"id":"field3","operator":"== ''","value":null}]};
$('#mydiv').text(buildString(jsonObj, ""));
The function has a return of a string.
When you call the function recursively from within itself, you aren't doing anything with the returned string from that instance, just calling the function which has nowhere to return to
Change:
if (json.rules[rule].hasOwnProperty("condition")) {
buildString(json.rules[rule], outstring);
}
To
if (json.rules[rule].hasOwnProperty("condition")) {
// include the returned value in concatenated string
outstring += buildString(json.rules[rule], outstring);
}
DEMO
Why so complicated?
function buildString(obj) {
return "condition" in obj?
obj.rules.map(buildString).join(" " + obj.condition + " "):
obj.id + " " + obj.operator + " " + string(obj.value);
}
//this problem occurs quite often, write a utility-function.
function string(v){ return v == null? "": String(v) }

Add <option> in IE 6 unwards

I've the code below written in JavaScript to add a new option to the select list from the opener window:
function updateSelectList()
{
var field = opener.document.objectdata.ticketPersonId;
if (true && opener && field)
{
var val = document.createElement('option');
var title = document.objectdata.titleId.options[document.objectdata.titleId.selectedIndex].text;
val.text = title + ' ' + document.objectdata.firstName.value + ' ' + document.objectdata.lastName.value + ':' + document.objectdata.username.value;
val.value = null;
val.selected = true;
field.add(val, null);
}
}
works all fine in Firefox, Google Chrome etc but not IE 6 :-(
please advise how I can make this work in IE 6 aswell.
Here's my snippet:
if (oldopt!=null || !horus.brokenDOM)
select.add(newopt, oldopt);
else
newopt=options[options.length]=new Option(newopt.text, newopt.value, false, false);
The definition of horus.brokenDOM is left to the reader :)
IIRC, I had some difficulty with using pre-defined Option objects (generally pulled out of another selectbox) in this context with IE, hence the in-place object creation.
function updateSelectList()
{
var field = opener.<%= updatelist %>;
if (<%= called %> && opener && field)
{
var val = opener.document.createElement('option');
var title = document.objectdata.titleId.options[document.objectdata.titleId.selectedIndex].text;
val.text = title + ' ' + document.objectdata.firstName.value + ' ' + document.objectdata.lastName.value + ':' + document.objectdata.username.value;
val.value = <%= thePerson != null ? thePerson.getId() : null %>;
val.selected = true;
try
{
field.add(val, null);
}
catch(error)
{
field.add(val, 0);
}
}
}
this seams to work. What a mission!

Categories