I'm new at jQuery, so I expect there is an easy answer.
I have a JSON file with different text strings for different dates. I also have an html range slider that I uses the <datalist> tag to define specific dates on the slider. I have written a $.getJSON function that nests a $.each() function to pull the strings from the JSON file.
I need to write in the functionality to display different strings based on the slider position.
This is my jQuery:
var location = $('#state-dates')[0];
$(document).on('input', '#state-dates', function() {
if (location === 1911) {
$.getJSON('Arizona.json', function(inputOne){
$.each(inputOne.first, function(i, field){
$("#leg-control").html(field.legControl);
});
});
}
else if (location === 1943) {
$.getJSON('Arizona.json', function(inputTwo){
$.each(inputTwo.second, function(i, field){
$("#leg-control").html(field.legControl);
});
});
}
});
And my HTML:
<input type="range" min="1911" max="2013" class="bar" step=".1" list="date-list" value="1911" id="state-dates">
Is there a different jQuery method that I should be using to detect the change in the slider, and so display the new string? I also realize that I should probably use < or > instead of = since I want the same text to only change when it reaches a new defined position. Thank you!
EDIT
To help clarify, I'm adding in the relevant JSON and HTML.
JSON:
{
"first": [
{
"legControl": "Not recorded",
}],
"second": [
{
"leg-control": "Democratic",
}]
}
And the HTML for entering the text:
<div class="json-text">
<p class="fill-in" id="leg-control"></p>
</div>
I was able to work out a solution with a web developer friend of mine, so in case anyone else stumbles across this question, the solution I used:
//call the JSON file and store it as a variable called jdata
$.getJSON('Arizona.json', function(json) {
jdata = json;
});
var slider = $('#sliderValue')[0];
slider.oninput = function() {
var position = this.value;
var jrows = $(jdata).filter(function (i, n) {
return n.sYear <= position && n.eYear > position;
});
$("#year-start").html(jrows[0].jsonLineOne);
$("#year-end").html(jrows[0].jsonLineTwo);
};
Essentially this takes the slider input, and runs a return command to check the position. If it is within the bounds of one subsection of the JSON file, then that section is pulled. Hopefully this helps anyone else who comes across it in the future.
Related
I am using this function below to find the data value inside of 3 possible DIVs. The data attribute dynamically changes each time that a slide changes position. I am trying to get the correct returned value of false, but it incorrectly returns true for each slide. What might be the problem?
$('.slidelink').on('click', function(e) {
var parent = $(this).parent().parent().parent().parent();
var parent_name = parent[0].nodeName.toLowerCase();
var parent_tagname = $(parent_name);
if (parent_tagname.attr('data-isactiveslide') == 'true') {
alert('working!');
}
});
And the HTML, which represent individual slides in Revolution Slider Wordpress plugin:
<rs-slides>
<rs-slide data-isactiveslide="false">
<rs-layer-wrap>
<rs-loop-wrap>
<rs-mask-wrap>
<rs-layer class="slidelink"></rs-layer>
</rs-mask-wrap>
</rs-loop-wrap>
</rs-layer-wrap>
</rs-slide>
</rs-slides>
You are walking up the tree referencing the element name. Using that to find all the elements in the page with that tag, and looking at the first one.
$('.slidelink').on('click', function(e) {
var parent = $(this).closest("[data-isactiveslide]");
console.log(parent.data('isactiveslide'))
});
I have a script on my website that translates the text contained within a span when the user mouses over an anchor, and it works just fine. However, browsers that do auto-translation seem to be grabbing the titles that get generated onmouseover and translating them as well, which defeats the purpose of the script. I have tried adding the property translate="no" to the generated text using JS (as seen below in Line 10) but I must be missing something, because it doesn't seem to be having an effect.
Please help?
JS:
$.each($("li"), function(i, elements) {
var links = elements.getElementsByTagName("a");
var article_title = elements.getElementsByClassName("article-title")[0];
$.each(links, function(j, link) {
var previous_title = article_title.innerHTML;
if (!$(link).is('.newspaper, .doi')) {
link.addEventListener("mouseover", function() {
$(article_title).fadeTo(150, 0.5, function() {
article_title.innerHTML = link.title;
$(article_title).prop('translate', 'no');
$(article_title).fadeTo(150, 1, function() {});
});
});
link.addEventListener("mouseout", function() {
$(article_title).fadeTo(150, 0.5, function() {
article_title.innerHTML = previous_title;
$(article_title).fadeTo(150, 1, function() {});
});
});
}
});
});
});
HTML:
<li>
[EN]
[ES]
<span class="article-title">This is an example</span>
</li>
First, are you sure that the script interprets
translate="no"
Property correctly? As in, it figures that this should not be translated? Maybe the code logic appears to be the culprit.
Second, try using .attr instead of .prop?
I'm attempting to make a menu bar that can have <li> elements added and removed. So far so good, but when I try and remove them I'm running into issues. I've toyed with this for a couple hours and now I'm wondering if this whole process could just be made easier (maybe an object?).
Anyways, here's the full code (80 lines), with comments to follow along.
var tabs = $('.accountSelectNav');
var titles = [];
var listItems = [];
// when the page loads check if tabs need to be added to the ul (menu bar)
$(document).ready(function(e) {
if ($.cookie('listItems') != null) {
console.log('not null');
//return "listItems" to it's array form.
listItems = JSON.parse($.cookie('listItems'));
$('.accountSelectNav').append(listItems);
}
});
$('.selectTable td:first-child').on('click', function(e) {
$('#home_select').removeClass('navHighlight');
//grab the text value of this cell
title = $(this).text();
$.ajax({
url:'core/functions/getAccountId.php',
type: 'post',
data: {'title' : title}
}).fail (function() {
alert('error');
}).done(function(data) {
accountId = $.trim(data);
// store values in the cookie
$.cookie('account_id', accountId, {expires : 7});
$.cookie('title', title, {expires : 7});
window.location = ('home_table.php');
});
// make sure the value is NOT currently in the array. Then add it
var found = jQuery.inArray(title, titles);
if (found == -1) {
titles.push(title);
addTab();
}
// make sure the value is NOT currently in the array. Then add it
found = jQuery.inArray(title, listItems);
if (found == -1) {
addListItem();
//place <li>'s in cookie so they may be used on multiple pages
$.cookie('listItems', JSON.stringify(listItems));
};
});
$("body").on("click", ".deleteImage", function (e) {
var removeTitle = $(this).closest('li').find('a').text();
var removeItem = $(this).closest('li')[0].outerHTML;
//remove title from "titles" array
titles = jQuery.grep(titles, function (value) {
return value != removeTitle;
});
//remove <li> from "listItems" array
listItems = jQuery.grep(listItems, function (value) {
return value != removeItem;
});
// this shows the <li> is still in the listItemsarray
console.log(listItems);
// put the array back in the cookie
$.cookie('listItems', JSON.stringify(listItems));
removeTab(this);
});
$("body").on("mouseover", ".accountSelectNav li", function(e) {
$(this).find('.deleteImage').show();
});
$("body").on("mouseleave", ".accountSelectNav li", function(e) {
$(this).find('.deleteImage').hide();
});
function addTab() {
tabs.append('<li class="navHighlight">' + '' + title + '' + '' + '<img src="images/delete.png" class="deleteImage"/>' + '' + '</li>');
};
function removeTab(del) {
$(del).closest('li').remove();
}
function addListItem() {
var s = ('<li class="navHighlight">' + '' + title + '' + '' + '<img src="images/delete.png" class="deleteImage"/>' + '' + '</li>');
listItems.push(s);
}
So you see I have two arrays of equal length that should always be the same length. One stores the title to be displayed in the tab, the other holds the html for the <li> which will be appended to the <ul>. I have no problem removing the title from its array. However removing the <li> from it's array is becoming a rather big hassle. You see when I get the <li> element after its been inflated the html inside does not exactly match what was put in, the browser adds style elements.
Example, the variable "removeItem" represents the html value of the selected <li> I wish to remove. It looks like this:
<li class="navHighlight">Test1<img src="images/delete.png" class="deleteImage" style="display: inline;"></li>
yet the value in my array "listItems" looks like this:
<li class="navHighlight">Test1<img src="images/delete.png" class="deleteImage"/></li>
So my attempt at removing it from my array always fails because they aren't a perfect match.
Now my question is how do I remove this <li> item? Also is there an easier way to do this whole process and I'm just not seeing it?
Thanks for your time.
EDIT
Fiddle by request here
Easiest way I can explain it.
Click the link to the fiddle.
Click any cell in the "App Name" column
This will add a <li> to the <ul> (menu) above of the table
When you hover over the <li> a picture appears
Click the picture
This should remove the <li>, both from the <ul> and from the array listItems
right now it does not
In the process of making this easier to check, I've taken your JSFiddle and did the following:
removed extra console.log and comments
removed interaction with cookies (since I did not have them in the first place, I figured they wouldn't just the first scenario)
After doing so I reached a point (you can see it here) where the desired functionality just works.
I even went ahead and removed the ajax stuff because that alert was driving me crazy. (here)
Since this works fine, my guess is that your issue lies between the lines that I removed.
Your usage of cookies is as follows:
To load existing tabs and add them back again
To save account_id and title, which is not used back again
To persist the listItems after a new item has been added
I then opened up the console with your version of the fiddle and the execution of javascript stops at $.cookie() with the error undefined is not a function.
This clearly indicates that the issue present in the Fiddle is that jQuery.cookie is not present and so those calls are halting the execution of the rest of your script. This also explains why it just started working when I took them out.
I posted the whole process of how I got there to indicate how I trimmed down the problem to specific parts, which is useful to reduce the problem space. When you're out of options and reach a place when you're lost, it's easier to post a question with less code and the specific part of the problem that you've identified. This will help you in finding the issues that you're facing and StackOverflow to provide proper answers to your questions.
Hope it helps!
Here is the solution I came up with. It should be much easier for people to understand than my original post. Although it's a long read it may be worth it, especially for new developers.
The point of this code is to make a menu bar out of an un-ordered list or <ul>. The menu bar needs to be used on multiple pages. So I'll be using cookies.
I start with this code to get a text value from my table.:
$('.selectTable td:first-child').on('click', function(e) {
// This value will be used later for the name of the tab or `<li>` inside our menu bar or `<ul>`
title = $(this).text();
});
Then I place the value in an array. I do this only if the array does not already have this string inside it. I do not want duplicates:
var found = jQuery.inArray(title, titles);
var titles = [];
if (found == -1) {
titles.push(title);
}
Then I store the array into a cookie, using a library like this:
$.cookie('titles', JSON.stringify(titles));
Now when any page loads that needs this menu bar I run this code to check if there are any values:
$(document).ready(function() {
if ($.cookie('titles') != null) {
titles = JSON.parse($.cookie('titles'));
}
});
Now I need to loop through the array. When I loop through the array I have to do 3 things:
1) Grab the string value.
2) Add the html to my new string so it becomes a list item or <li>.
3) Append the newly created <li> to our <ul>.
Like so:
for(var i = 0; i < titles.length; i++) {
var str = titles[i];
var listItem = '<li class="navHighlight">'
+ '<a href="#">'
+ str
+ '</a>'
+ '<a href="#">'
+ '<img src="images/delete.png" class="deleteImage"/>'
+ '</a>'
+ '</li>';
$('.accountSelectNav').append(listItem);
}
Now, if I want to remove this <li> I click the delete image found inside our <li>. What delete image you say? Look at the html I added again. You will see I add an <img> tag in there.
Now delete like so:
$("body").on("click", ".deleteImage", function (e) {
// grabs the text value of my li, which I want to remove
var removeTitle = $(this).closest('li').find('a').text();
// runs through my titles array and returns an array without the value above
titles = jQuery.grep(titles, function (value) {
return value != removeTitle;
});
});
Then I simply place the new array inside my cookie once again. Like this:
$.cookie('titles', JSON.stringify(titles));
And finally I remove the tab like this:
removeTab(this);
function removeTab(del) {
$(del).closest('li').remove();
}
Yay, I'm done. So now, if anyone has a more elegant way of accomplishing this I'm listening. I have no doubt there's a better way, javascript/jQuery isn't even close to my strong point.
The full code can be found here.
I'm looking for tutorial or example on how to implement a simple input text for searching
in the grid.
My attempt (but ng-keyup require angularjs > 1.1.3 and I've got
1.0.7)
<input type="text" ng-keyup="mySearch()" ng-model="searchText">
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('largeLoad.json?q='+encodeURIComponent(ft)).success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
} else {
$http.get('largeLoad.json').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.mySearch = function(){
console.log($scope.searchText);
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage,$scope.searchText);
}
Bye
NB its a fake request against a json file just to make the example.
Update: I'm using ng-grid-1.3.2
Basically to solve this problem I think you can use a solution similar to what I've done below where I'm just watching the property of the model for changes and firing a function to do the filtering on the data set at that point.
The HTML for the text input
<input type="text" placeholder="Type to filter" ng-model="gardenModel.externalFilterText"/>
The JavaScript that filters the data set (also included the part I had a watch on a service to update the data in the first place too or if the data is refreshed to reapply the filter).
//This function is called every time the data is updated from the service or the filter text changes
$scope.filterGardens = function(filterText) {
//Basically everything in this function is custom filtering specific
//to the data set I was looking at if you want something closer to the
//real implementation you'll probably have to dig through the source (I believe they separated the search filter code into it's own file in the original project)
//Creating a temporary array so changes don't cause a bunch of firing of watchers
var tempToShow = [];
//doing case insensitive search so lower case the filter text
filterText = filterText.toLowerCase();
//If the filter text is blank just use the whole data set
if(!filterText || filterText == "")
{
$scope.gardenModel.shownGardens = $scope.gardenModel.gardens;
return;
}
//step through each entry in the main list and add any gardens that match
for (var i = 0; i < $scope.gardenModel.gardens.length; i++) {
var curEntry = $scope.gardenModel.gardens[i];
var curGarden = curEntry.curGarden;
if(curGarden["Garden Name"] && curGarden["Garden Name"].answer.toString().toLowerCase().indexOf(filterText)!=-1)
tempToShow.push(curEntry);
else if(curGarden["Address"] && curGarden["Address"].answer.toString().toLowerCase().indexOf(filterText)!=-1)
tempToShow.push(curEntry);
else if(curGarden["Ownership"] && curGarden["Ownership"].answer.toString().toLowerCase().indexOf(filterText)!=-1)
tempToShow.push(curEntry);
else if(curGarden.gardenId && curGarden.gardenId == filterText)
tempToShow.push(curEntry);
};
$scope.gardenModel.shownGardens = tempToShow;
}
//Watch for any changes to the filter text (this is bound to the input in the HTML)
$scope.$watch('gardenModel.externalFilterText', function(value) {
$scope.filterGardens(value);
});
//Watch for any changes on the service (this way if addition/edit are made and
//refresh happens in the service things stay up to date in this view, and the filter stays)
$scope.$watch( function () { return gardenService.gardens; }, function ( gardens ) {
$scope.gardenModel.gardens = gardens;
$scope.filterGardens($scope.gardenModel.externalFilterText);
});
Edit Cleaned up the code formatting a bit and added some comments.
My approach is not working here. I am on a Welcome Page of a SharePoint 2010 document set and have placed my script in a Content Editor Web Part CEWP. I've got a block of jquery/javascript using the following code. I can get one or the other set of values from two different blocks of code but not both. So it seems like my duplicating some of the lines of code in the tow queries causes things to clash but I am not sure what i can change to make both sets unique or what is clashing between the two. Any guidance greatly appreciated. I'm just going in circles right now. thanks -dave
I am using two blocks that look like this but differ at listName. Maybe the page can only support one of these?
$(document).ready(function () {
$().SPServices({
operation: "GetListItems",
async: false,
CAMLRowLimit: 2000,
listName: "Personnel Management",
completefunc: fnCallBack
});
});
function fnCallBack(xData, Status) {
var index = 0;
$documentListtable = $("#documentListtable");
//Navigate through the XML
$(xData.responseXML).find("z\\:row, row").each(function () {
//Get the values to a local variable
var _url = $(this).attr("ows_FileRef").split(";#")[1];
var _name = $(this).attr("ows_LinkFilename");
;
var _author = $(this).attr("ows_Editor").split(";#")[1];
var modifiedOn = $(this).attr("ows_Modified");
var _TrainingStatus = $(this).attr("ows_Training_x0020_Certificates");
//Create clone of the table row
var $row = $("#templates").find(".row-template").clone();
//Add values to the column based on the css class
$row.find(".DocumentName").html(_pdfLink);
$row.find(".Author").html(_author);
$row.find(".LastModifiedOn").html(modifiedOn);
$row.find(".TrainingStatus").html(_TrainingStatus);
//Change the style for even rows
if (index % 2 == 0) {
$row.addClass("jtable-row-even")
}
if (_TrainingStatus.indexOf("1001") !=-1)
{
index = index + 1;
//add the row to table
$documentListtable.append($row);
}
-
You can try adding both the SPServices calls inside one $(document).ready instead of having two $(document).ready blocks. There can be multiple $(document).ready in a page but your issue sounds like only one SPService call is triggered on page load.