I have not been able to find a working example or a good explanation of how I can achieve the following: (I would appreciate if anyone can point me in the right direction.
I have a query string: **"/api/bla?sources=[1,2]&plans=[1,2]&codes=[1,2,3]"**
I will be updating the query string via either javascript or jquery when certain events occur on my page, doesnt matter which.
For example, there is a multi select dropdown on the page which houses [sources] and [plans] and [codes]... These dropdowns have IDs which i am to update my request url with upons selecting items in teh dropdowns.
When a source with ID "3" is selected from the dropdown (or checkbox, doesnt matter what page controls are being used) the query string parameter sources[1,2] will need a "3" appended. Likewise then if the item with an ID of "2" is unselected, it will likewise be removed from the query string leaving the new string as sources[1,3]
I am somewhat new to javascript/jquery and especially more advanced string manipulation. I have been attempting to recreate something to demonstrate this and have gotten to the following which is not fully working.
Basically my initial if statement works as intended, but the moment the else is hit (when another ID needs to be added to an existing model in the query string - like a second ID for [sources] or [codes]) it returns wonky output - seeng as I couldnt get the right formula to update everything correctly.
//TIMEMTABLE QUERY
function updateCalendar(filter_id, filter_element) {
//Run through the filter checks before making final call to query and update timetable?
//GET THE MODEL/OBJECT NAME
var queryName = filter_element.attr('data-owner');
//GET THE IDs //this is either an array of all selected IDs or a single id which is used in the else statement
var queryId = filter_element.attr('value');
var queryIds = $('#'+filter_id).val();
var modelCheckIndex = requestString.toLowerCase().indexOf(queryName.toLowerCase());
//build a request string
if (modelCheckIndex < 0) {
console.info('ADD MODEL TO QUERY STRING');
requestString = requestString + "&" + (queryName.toLowerCase() + "[" + queryIds + "]");
console.log(requestString);
}
else{
console.info('UPDATE MODEL ON QUERY STRING');
var position = requestString.toLowerCase().indexOf(queryName.toLowerCase());
//requestString = requestString.substr(modelCheckIndex -1, requestString.length -1) + "," + queryId + "]";
requestString = requestString.slice(modelCheckIndex.indexOf("]"), modelCheckIndex) + "," + queryId;
console.log(requestString);
}
//MAKE THE API CALL USING CREATED QUERY STRING
}
If anyone has any examples or fiddles lying around I would also appreciate it.
Fiddle I am trying to get to work
It looks like you are just having trouble parsing and updating a query string. In which case, I have a function I've been using for that (thank you Google)
function getUriParams(string) {
var params = {},
queryString = string.slice(string.lastIndexOf('?')).substring(1),
regex = /([^&=]+)=([^&]*)/g,
m;
while (m = regex.exec(queryString)) {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
return params;
}
The input is your requestString and the output is an object of key value pairs of the query string.
To make the object a string, jQuery makes it easy with $.param().
//get key value pairs
var obj = getUriParams(requestString);
//make query string
var str = $.param(obj);
I suggest to change the logic a bit. I would use some data storage for the wanted parameter and rebuild the request string every time when it's necessary, like the below example.
It is much more better, than rebuild the string each time when some value has changed.
var data = {
sources: [1, 2],
plans: [],
codes: [1, 3, 4]
};
function buildStr() {
function get(key) { return key + '=' + JSON.stringify(data[key]); }
return '/api/bla?' + ['sources', 'plans', 'codes'].map(get).join('&');
}
document.write('<pre>' + buildStr() + '</pre>');
Related
I have a list with a LOOKUP column to another list. The lookup column is called "Employee" and I want to GET the values from the "Employment Type" field. However I keep on getting a request error. What is wrong with my statement below. Before, I was only looking for choice and $ columns.Everything worked fine until I inserted the Employee/Employment_Type&$expand=Employee part
xhr.open('GET', _spPageContextInfo.webAbsoluteUrl + '/_api/web/lists/GetByTitle(\'' + listName +
'\')/items? $Funding$Funding_Type$Vacant&Direct&Employee/Employment_Type$select=ID,Employee/Employment_Type&$expand=Employee&$top=1000');
also, is my Employment_Type = results[i].Employee/Employment_Type syntax correct below?
Note: I am only including a small part of the overall script
for (var i = 0; i < results.length; i++){
if (results[i].Direct == "DCSP" & results[i].Funding == "A-Base") {
dcsp_abaseSal += results[i].SalEnv3
Employment_Type = results[i].Employee/Employment_Type
TypeSal = results[i].SalEnv3
dcsp_vacant_days += results[i].Vacant_Days
dcsp_variance = dcsp_abase_cap - dcsp_abaseSal
}
}
rest api get look up column:
/_api/web/lists/getByTitle('test3')/items(1)?$select=Title,columnTitle/Title&$expand=columnTitle
You could add columns which you want to get after $select like columnTitle/sourceColumnTitle
I have a search form that allows the user to add as many search terms as they like. When the user enters all of the search terms and their search values and clicks search, a text box will be updated with the search terms. I've got this working with a for loop, but I'm trying to improve my dev skills and am looking for a way to do this with map\filter instead.
Here's the code I'm trying to replace:
var searchTerms = $("#search-form").find(".mdc-layout-grid__inner");
var searchString = "";
for(var i = 0; i < searchTerms.length - 1; i ++)
{
var select = $(searchTerms[i]).find(".select2-selection")[0];
var selectText = $(select).select2('data')[0].text + ":";
var textBox = $(searchTerms[i]).find(".mdc-text-field__input")[0];
searchString = searchString += selectText.replace(/\./g,"").replace(/ /g,"") + textBox.value;
if(i < searchTerms.length - 1)
{
searchString = searchString += " ";
}
}
$("#er-search-input").val(searchString);
Here's a codepen of the current solution.
i'm trying the below, but I get the feeling I'm miles away:
const ret = searchTerms.map((u,i) => [
$($(u[i]).find(".select2-selection")[0]).select2('data')[0].text + ":",
$(u[i]).find(".mdc-text-field__input")[0].value,
]);
My question is, is it possible to do this with map?
Firstly you're repeatedly creating a jQuery object, accessing it by index to get an Element object only to then create another jQuery object from that. Instead of doing this, you can use eq() to get a specific element in a jQuery object by its index.
However if you use map() to loop through the jQuery object then you can avoid that entirely by using this to reference the current element in the iteration. From there you can access the required elements. The use of map() also builds the array for you, so all you need to do is join() the results together to build the required string output.
Finally, note that you can combine the regex expressions in the replace() call by using the | operator, and also \s is more robust than using a whitespace character. Try this:
var $searchTerms = $("#search-form").find(".mdc-layout-grid__inner");
var searchString = $searchTerms.map(function() {
var $searchTerm = $(this);
var selectText = $searchTerm.find('.select2-selection').select2('data')[0].text + ':';
var $textBox = $searchTerm.find('.mdc-text-field__input:first');
return selectText.replace(/\.|\s/g, "") + $textBox.val();
}).get().join(' ');
$("#er-search-input").val(searchString);
I have a search results page in a PHP site that returns a list of results using pagination. The URL looks like this:
findProducts.php?action=searchAssets&orderNumber=xxxx&productName=zzz&skip=20
I have a select menu that allows the user to modify/filter the search results which triggers a script like this:
$(document).ready(function() {
$('#productType').change(function() {
window.location.href = window.location.href + '&productType=' + $(this).val();
});
});
This is working well except for one thing - I need to reset the 'skip' parameter to 0 for the new filter search as the pagination values from the previous search won't be valid or applicable. Is there a way I can change:
skip=20
to:
skip=0
as part of this script?
You could do a RegExp replace on the URL:
window.location.href = window.location.href.replace(/((?:\?|&)skip)=\d+/, '$1=0') + '...';
(untested)
Note that you should do the same with the productType because otherwise you'll add it again and again.
Better solution would possibly be to have a base URL and then add all necessary parameters instead of doing search and replace...
You can get the query from the URL by splitting the URL using ?
This will give you the base url in the first index and the query in the second.
You can then get the query parameters by splitting the query using &.
You can loop through all of the parameters checking if it is the skip parameter. If the parameter is the skip parameter push your new value to an output array. Otherwise push the unchanged parameter to an output array.
You can then use join to join all of your output elements using & to reconstruct the query and return your original base url with your new query string.
<script>
function fixQuery(qstr) {
var parts = qstr.split('?');
var query = parts[1];
var a= query.split("&");
var out=[];
for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');
if(decodeURIComponent(b[0])=="skip")
{
out.push("skip=0")
}
else {
out.push(a[i]);
}
}
return parts[0] + '?' + out.join("&");
}
var result= fixQuery("http://example.com/findProducts.php?param1=test+thing¶m2=hello&skip=10");
console.log(result)
//http://example.com/findProducts.php??param1=test+thing¶m2=hello&skip=0
</script>
I'm trying to write one row of data into a Google Cloud SQL database, using a prepared statement as described here:
https://developers.google.com/apps-script/guides/jdbc
I have the data stored in an object called valuesByTitle, which looks like this:
{NAME: 'fun event', LOCATION: '123 Main St.'}
The data is inserted into the SQL table if I write everything out like this:
var conn = getConnection(); // connects to db
var stmt = conn.prepareStatement('INSERT INTO events '
+ '(NAME, LOCATION) values (?, ?)');
stmt.setString(1, valuesByTitle['NAME']);
stmt.setString(2, valuesByTitle['LOCATION']);
stmt.execute();
}
However, I would like to automate the process, so I don't have to change the code each time the variables change.
I have two new variables, one for the column names and one for a set of place holders (e.g. "?") for the insert statement.
var columns = Object.keys(valuesByTitle);
var placeholders = columns.map(function(column) {
return "?";
};
Using these, this prepared statement should automatically insert whatever is in the valuesByTitle object (assuming all the values are string values):
var conn = getConnection();
var stmt = conn.prepareStatement("INSERT INTO events (" + columns.join(",") + ") VALUES (" + placeholders.join(",") + ")");
for (i = 0; i < columns.length; i++) {
stmt.setString(i+1, valuesByTitle[columns[i]]);
}
stmt.execute();
For some reason, it's not inserting the data. Surprised not to find any examples either. Is the logic off or is it just not possible to do?
Thanks.
All your code is OK, you simply forgot to close the map() bracket i.e.
var columns = Object.keys(valuesByTitle);
var placeholders = columns.map(function(column) {
return "?";
};
should be
var columns = Object.keys(valuesByTitle);
var placeholders = columns.map(function(column) {
return "?";
});
(note the ending bracket after return "?";})
I have implemented searchbox using jQuery. Here is the code which sends search term and
after that I receive Json which I use to make list of matched searched items.
The problem is that on each keyup I delete all matched items :
$("#realPlaceForSearchItems").html("");
because if I don't that I get duplications when searching for product if I enter "pro" and then type "d". (I am appending list items to the list) Is it possible to achieve that I somehow just delete elements that do not match "prod" (which previously matched "pro" ofcourse) and that elements that match prod stay untouched after typing "d".
$("#searchInput").keyup(function () {
$this = $(this);
$('#realPlaceForSearchItems').show();
$("#realPlaceForSearchItems").html("");
var seachedTerm=$this.val();
if ($this.val().length> 2)
{
$("#realPlaceForSearchItems").html("");
$('#realPlaceForSearchItems').show();
$.ajax({
type: "POST",
url: ROOT + "Filter/Search/",
data: {term: $this.val()},
success: function (data)
{
var Link = $("#searchTemplate>li>a");
var placeForProductId=$("#searchTemplate>li>a>input");
var placeForPicture = $("#searchTemplate>li>a>div>img");
var placeForProductName = $("#searchTemplate>li>a>div>div");
var placeForPrice= $("#searchTemplate>li>a>div>span");
$.each(data.productsWereSeached, function () {
console.log("sddsd", data.totalrows);
var imagesFolder="/Content/images/";
var pathToProduct="/ProductDetails/Index/"
var slash = "/";
Link.attr("href", pathToProduct + this.Id);
placeForProductId.val(this.Id);
if (this && this.Picture) //for the case there is no any picture there would be error cant read propery or undefined
placeForPicture.attr("src", imagesFolder + this.Id + slash + this.Picture.FileName);
else
placeForPicture.attr("src", "");
placeForProductName.html(this.Name);
placeForPrice.html((parseFloat(this.Price) / 100.0).toString() + " kn");
$listItem = $("#searchTemplate").html();
$("#realPlaceForSearchItems").append($listItem);
});
$("#nOfMatchedProducts").val(data.totalrows);
if (data.totalrows > 2)
{
var searchurl="/Search/ShowMoreSearched?term="
$showMoreItem = $("#showMoreItem").html();
$("#showMoreItem>li>a").attr("href",searchurl+seachedTerm);
$("#realPlaceForSearchItems").append($showMoreItem);
}
},
failure: function ()
{
}
});
}
});
$.each(data.productsWereSeached, function () {
if($('a[href="'+pathToProduct + this.Id+'"]').length == 0) {
console.log("sddsd", data.totalrows);
var imagesFolder="/Content/images/";
var pathToProduct="/ProductDetails/Index/"
var slash = "/";
Link.attr("href", pathToProduct + this.Id);
placeForProductId.val(this.Id);
if (this && this.Picture) //for the case there is no any picture there would be error cant read propery or undefined
placeForPicture.attr("src", imagesFolder + this.Id + slash + this.Picture.FileName);
else
placeForPicture.attr("src", "");
placeForProductName.html(this.Name);
placeForPrice.html((parseFloat(this.Price) / 100.0).toString() + " kn");
$listItem = $("#searchTemplate").html();
$("#realPlaceForSearchItems").append($listItem);
}
});
Psst... I'm assuming you also want to limit calls to the server and that your search result list is not wildly huge!
So! Benefit to your current approach is you don't have to manage/compare any existing data set. This makes things easier when a search for "pro" changes to a search for "cro" or any other change that makes the previous AJAX call irrelevant. But, like you said, it leaves you with this clear then re-add items inefficiency when you search for "prod" after "pro".
Idea:
Store the most recent AJAX call criteria in a global.
If new search value includes the latest AJAX search value, filter/hide items in the existing data set which do not match the new criteria. Do not perform a new search.
If new value does not include the latest AJAX search value: clear current data set, update AJAX search value, execute new AJAX call
Pass the index from $.each (http://api.jquery.com/jQuery.each/) into your function, then use it to select the search result you will replaceWith (http://api.jquery.com/replaceWith/) the element you just built. In using this method, your four LI elements within the search results UL must exist before a search.keyup is executed.
Do this by changing two lines...
$.each(data.productsWereSeached, function (index) {
... all of the existing code in the loop stays the same except ...
$("#realPlaceForSearchItems LI:eq(" + index + ")").replaceWith($listItem);
});