jQuery:将按钮过滤器转换为选择菜单选项?

时间:2016-04-19 00:00:30

标签: javascript jquery html

我使用的是Lever的职位列表API,但在目前的形式中,它使用按钮按类别过滤作业。我怎样才能将按钮变成完整的选择菜单?

在小提琴中,选项是"商业开发","客户成功",因此这些将是我想要创建的选择菜单中的选项示例。

Fiddle

HTML:

<section>
  <div class="container" id="jobs-container">
    <h1>Open jobs</h1>
    <div class="jobs-teams">
    </div>
    <div class="jobs-list">
    </div>
  </div>
</section>  

JS:

url = 'https://api.lever.co/v0/postings/leverdemo?group=team&mode=json'

//Functions for checking if the variable is unspecified
function cleanString(string) {
  if (string) {
    var cleanString = string.replace(/\s+/ig, "");
    return cleanString;
  }
  else {
    return "Uncategorized";
  }
}

function nullCheck(string) {
  if (!string) {
    var result = 'Uncategorized'
    return result;
  }
  else { 
    return string;
  }
}

function createJobs(_data) {
  for(i = 0; i < _data.length; i++) {

    var team = nullCheck(_data[i].title)
    var teamCleanString = cleanString(team);
    $('#jobs-container .jobs-teams').append(
        '<a href="#" class="btn '+teamCleanString+'">'+team+'</a>'
      );
  }

  for(i = 0; i < _data.length; i++) {
    for (j = 0; j < _data[i].postings.length; j ++) {
      var posting = _data[i].postings[j] 
      var title = posting.text
      var description = posting.description  
      //Making each job description shorter than 250 characters
      var shortDescription = $.trim(description).substring(0, 250)
      .replace('\n', ' ') + "...";
      var location = nullCheck(posting.categories.location);
      var locationCleanString = cleanString(location);
      var commitment = nullCheck(posting.categories.commitment);
      var commitmentCleanString = cleanString(commitment);
      var team = nullCheck(posting.categories.team);
      var teamCleanString = cleanString(team);
      var link = posting.hostedUrl;

        $('#jobs-container .jobs-list').append(
      '<div class="job '+teamCleanString+' '+locationCleanString+' '+commitmentCleanString+'">' +
        '<a class="job-title" href="'+link+'"">'+title+'</a>' +
        '<p class="tags"><span>'+team+'</span><span>'+location+'</span><span>'+commitment+'</span></p>' +
        '<p class="description">'+shortDescription+'</p>' +
        '<a class="btn" href="'+link+'">Learn more</a>' +
      '</div>'  

      );
    }
  }
}

//Creating filter buttons for sorting your jobs
function activateButtons(_data){
  $('.jobs-teams').on("click", "a", function(e) {
    e.preventDefault();
    for(i = 0; i < _data.length; i++) {
      var teamRaw = _data[i].title;
      var team = cleanString(teamRaw);
      var jobs = $(".jobs-list");if ($(this).hasClass(team)) {
        if ($(this).hasClass("active")) { 
          $(this).removeClass("active");
          jobs.find(".job").fadeIn("fast");
        }
        else {
          $(".jobs-teams").find("a").removeClass("active");
          $(this).addClass("active");
          jobs.find("."+team).fadeIn("fast");
          jobs.find(".job").not("."+team).fadeOut("fast");
        }
      } 
    }
  })
}

//Fetching job postings from Lever's postings API
$.ajax({
  dataType: "json",
  url: url,
  success: function(data){
    createJobs(data);
    activateButtons(data);
  }
});

2 个答案:

答案 0 :(得分:1)

我所做的更新如下。

  • 在jobs-team
  • 上添加了select标记
  • createJob()

    //get select element on the element with jobs-team css class
    $('#jobs-container .jobs-teams select').append(
       //append option.
       '<option value="" class=' + teamCleanString + '>' + team + '</option>'
    );}
    
  • activateButtons()

    //get selected option.
    if($(this).find(":selected").hasClass(team))
    

&#13;
&#13;
// Replace "leverdemo" with your own company name
url = 'https://api.lever.co/v0/postings/leverdemo?group=team&mode=json'

//Functions for checking if the variable is unspecified
function cleanString(string) {
  if (string) {
    var cleanString = string.replace(/\s+/ig, "");
    return cleanString;
  }
  else {
    return "Uncategorized";
  }
}

function nullCheck(string) {
  if (!string) {
    var result = 'Uncategorized'
    return result;
  }
  else { 
    return string;
  }
}

function createJobs(_data) {
  for(i = 0; i < _data.length; i++) {
    
    var team = nullCheck(_data[i].title)
    var teamCleanString = cleanString(team);
    $('#jobs-container .jobs-teams select').append(
    	'<option value="" class=' + teamCleanString + '>' + team + '</option>'
       );
  }
  //'<a href="#" class="btn '+teamCleanString+'">'++'</a>'

  for(i = 0; i < _data.length; i++) {
    for (j = 0; j < _data[i].postings.length; j ++) {
      var posting = _data[i].postings[j] 
      var title = posting.text
      var description = posting.description  
      //Making each job description shorter than 250 characters
      var shortDescription = $.trim(description).substring(0, 250)
      .replace('\n', ' ') + "...";
      var location = nullCheck(posting.categories.location);
      var locationCleanString = cleanString(location);
      var commitment = nullCheck(posting.categories.commitment);
      var commitmentCleanString = cleanString(commitment);
      var team = nullCheck(posting.categories.team);
      var teamCleanString = cleanString(team);
      var link = posting.hostedUrl;
    
    	$('#jobs-container .jobs-list').append(
      '<div class="job '+teamCleanString+' '+locationCleanString+' '+commitmentCleanString+'">' +
        '<a class="job-title" href="'+link+'"">'+title+'</a>' +
        '<p class="tags"><span>'+team+'</span><span>'+location+'</span><span>'+commitment+'</span></p>' +
        '<p class="description">'+shortDescription+'</p>' +
        '<a class="btn" href="'+link+'">Learn more</a>' +
      '</div>'  
    
      );
    }
  }
}

//Creating filter buttons for sorting your jobs
function activateButtons(_data){
  $('.jobs-teams select').on("change", function(e) {
  	e.preventDefault();
    for(i = 0; i < _data.length; i++) {
    	var teamRaw = _data[i].title;
      var team = cleanString(teamRaw);
      var jobs = $(".jobs-list");
      if ($(this).find(":selected").hasClass(team)) {
      	if ($(this).hasClass("active")) { 
          $(this).removeClass("active");
          jobs.find(".job").fadeIn("fast");
        }
        else {
          $(".jobs-teams").find("a").removeClass("active");
          $(this).addClass("active");
          jobs.find("."+team).fadeIn("fast");
          jobs.find(".job").not("."+team).fadeOut("fast");
        }
      } 
    }
  })
}

//Fetching job postings from Lever's postings API
$.ajax({
  dataType: "json",
  url: url,
  success: function(data){
  	createJobs(data);
    activateButtons(data);
  }
});
&#13;
body {
  font-family: 'Lato', sans-serif;
  overflow-y: scroll;
}
  
p {
  margin: 0 0 1em 0;
  line-height: 1.4em;
}
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
section {
  position: relative;
  padding: 30px;
}
.container {
  max-width: 960px;
  margin: 0 auto;
}
.job {
  display: inline-block;
  vertical-align: top;
  width: 50%;
  padding: 40px 30px;
}
h1 {
  font-size: 48px;
  color: #454545;
  padding: 0 30px;
}
.job-title {
  font-size: 24px;
  text-decoration: none;
  color: #454545;
}

.job-title:hover {
  color: #00A0DF; 
}

.tags span {
  color: #999;
  font-size: 12px;
  color: grayMediumDark;
}
.tags span:after {
  content: ', ';
}
.tags span:last-of-type:after {
  content: '';
}
.description {
  color: #999;
}
.btn {
  display: inline-block;
  padding: 7px 15px;
  text-decoration: none;
  font-weight: normal;
  color: #999;
  border: 2px solid #ebebeb;
  -webkit-border-radius: 4px;
  border-radius: 4px;
  background: #f9f9f9;
}
.btn:hover {
  background: #ebebeb;
  color: #555;
}
.btn.active {
  background: #454545;
  border-color: #454545;
  color: #fff;
}
.jobs-teams {
  margin-bottom: 40px;
  padding: 0 30px
}
.jobs-teams .btn {
  margin: 0 8px 8px 0;
}
.jobs-teams .btn:first-of-type {
  margin-left: 0;
}
.jobs-teams .btn:last-of-type {
  margin-right: 0;
}
&#13;
<section>
  <div class="container" id="jobs-container">
    <h1>Open jobs</h1>
    <div class="jobs-teams">
      <select></select>
    </div>
    <div class="jobs-list">
    </div>
  </div>
</section>  

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

我看到你得到了答案,但我想我会把你的2美分扔进去告诉你如何,不仅要巩固这段代码( ¡很多! )但也可以更好地使用一些你可能不知道的jQuery方法。没有任何批评意图,只是希望向您展示另一种方式,可以帮助您在将来更好地使用jQuery。

/**	debug()
 *	Simply for writing console messages as needed for testing.
 */
function debug() {
	try {
		window['console'] && (console.log(Array(100).join("=")), console.log.apply(console, arguments), console.log(Array(100).join("=")));
	} catch (a) {}
};

/**	ajaxSuccess(data, status, xhr)
 *	Easily seperated, and therefor easy to read/write method to use for success callback
 */
function ajaxSuccess(data, status, xhr) {
	debug("Success:\t", $([data, status, xhr]));
	var sorted = sortData(data);
	debug("Sorted Data:\t", sorted);
	prepHTMLContainers();	//	ensure are HTML space is ready
	$.each(sorted, function(title, postings) {
		debug("Postings for ["+title+"]:\t", postings);
		//	add select option for each category
		$('<option />', { text: postings[0].category, value: title }).appendTo('#jobsTeams select');
		$.each(postings, function(i, post) {
			//	notice here, i do away with all that silly string building
			//	jQuery has a lot of nice options for building HTML,
			//	below is simply one of many ways
			var container = $('<div />').addClass('job').data('desc', { short: post.shortDescription, full: post.description }),
				aTitle = $('<a />', { href: post.url, text: post.title }).addClass('job-title').appendTo(container),
				pLocCom = $('<p />').addClass('tags').appendTo(container),
				pDesc = $('<p />', { text: post.shortDescription }).addClass('description').appendTo(container),
				aMore = $('<a />', { "class": 'btn', href: post.url, text: 'Learn more' }).appendTo(container)
			
			pLocCom
				.append($('<span />', { text: post.location }))
				.append($('<span />', { text: post.commitment }))
			
			container
				.addClass(post.teamClean.toLowerCase())
				.addClass(post.locationClean.toLowerCase())
				.addClass(post.commitmentClean.toLowerCase())
			
			$('#jobsList').append(container);
		});
	});
	$('#jobsTeams select').show();
}

/**	prepHTMLContainers()
 *	As stated, clean and clear HTML containers and ready them for new listings of data.
 */
function prepHTMLContainers() { $('#jobsTeams select, #jobsList').empty(); $('#jobsTeams select').hide().append($('<option />', { text: ' - Select a Category - ', value: '' })); }

/**	sortData(data)
 *	Sort data in a manner that makes creating the HTML easier
 */
function sortData(data) {
	var ret = {};
	$.each(data, function(index, item) {
		var catClass = trimString(item.title, true).toLowerCase();
		if (!ret[catClass]) ret[catClass] = [];
		$.each(item.postings, function(i, post) {
			ret[catClass].push({
					category: trimString(item.title),
					title: trimString(post.text),
					description: $(trimString(post.description)),
					shortDescription: $(trimString(post.description)).text().substring(0, 250).replace('\n', ' ') + '...',
					"location": trimString(post.categories.location),
					locationClean: trimString(post.categories.location, true),
					commitment: trimString(post.categories.commitment),
					commitmentClean: trimString(post.categories.commitment, true),
					team: trimString(post.categories.team),
					teamClean: trimString(post.categories.team, true),
					url: post.hostedUrl
				});
		});
	})
	return ret;
}

/**	trimString(str, cln)
 *	Simple and clean cut way to trim each string. Second param provides way to remove space if desired.
 */
function trimString(str, cln) { return !str ? 'Uncategorized' : !cln ? $.trim(str) : $.trim(str).replace(/\s+/ig, ""); }

//	The first variable, "myAjax", will be used to ensure there's only ever one call to our ajax'd link
//	The second is simply the options we'll use in it
var myAjax, myAjaxOpts = {
		data: "group=team&mode=json",
		dataType: "json",
		url: "https://api.lever.co/v0/postings/leverdemo",
		beforeSend: prepHTMLContainers,
		success: ajaxSuccess
	};

//	jQuery shorthand for document.ready
$(function() {
	$('#fetchData').on('click', function(e) {
		//	by doing it like this (there's many ways to go about this, 
		//	you don't have to use a button), we ensure that the 
		//	connection is broken before trying to retrieve the same
		//	data over and over
		if (myAjax) myAjax.abort();
		myAjax = $.ajax(myAjaxOpts);
		/**	my general use of this doesn't rely on a global variable, but rather a local one
		 *	i usually just assign it to the element object itself, such as:
		 *	
		 *		if (this.ajx) this.ajx.abort();
		 *		this.ajx = $.ajax(ajaxOpts);
		 *		
		 *	*/
	});
	
	//	see how quick and easy jQuery can make things?!
	//	the following line uses a "static parent" to assign an event to a "child"
	//		by doing it this way, the child can then be "dynamic" (loaded after
	//		page and js has been loaded) and still use the same event without
	//		need to "re-asign"
	$('#jobsTeams').on('change', 'select', function(e) {
		if (!this.value) $(this).children('option:eq(0)').text(' - Select a Category - '), $('#jobsList .job').fadeIn();
		else {
			var val = this.value;
			$(this).children('option:eq(0)').text(' - See All - ');
			$('#jobsList .job').fadeOut().filter(function(i) { return $(this).hasClass(val); }).fadeIn();
		}
	});
	
	//	allows us to now toggle full descript
	//	using .on to a static parent makes this work for all dynamically created children
	$('#jobsList').on('click', '.job', function(e) {
		var descShort = $(this).data('desc').short,
			descFull = $(this).data('desc').full,
			pDesc = $(this).find('.description');
		pDesc.html() == descShort ? pDesc.html(descFull) : pDesc.html(descShort);
	});
	
	//	I moved the initial first call to here, as it appears
	//		the connection to OP's site has slowed up since first
	//		posting this answer.
	//	JS is single threaded, but by using
	//		timers we can "temporarily emulate" multithreading and
	//		keep the browser from locking up on one piece of code
	setTimeout(function() { $('#fetchData').trigger('click'); }, 10);
})

/*	Expected data return
	[
		{
			postings: [
				additional:	String,
				applyUrl:	String,
				categories:	{
					commitment:	Sting,
					location:	Stirng,
					team:		String
				},
				createdAt:	timestamp,
				description:	String(HTML),
				descriptionPlain:	Sting,
				hostedUrl:	String,
				id:			String,
				list:		[
					{
						content:	Sting(HTML),
						text:		String
					}
				],
				text:		String
			],
			title: String
		}
	]
*/
body { font-family: 'Lato', sans-serif; overflow-y: scroll; }
p { margin: 0 0 1em 0; line-height: 1.4em; }
* { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
section { position: relative; padding: 30px; }
.container { max-width: 960px; margin: 0 auto; }
.job { display: inline-block; vertical-align: top; width: 50%; padding: 40px 30px; }
h1 { font-size: 48px; color: #454545; padding: 0 30px; }
.job-title { font-size: 24px; text-decoration: none; color: #454545; }
.job-title:hover { color: #00A0DF; }
.tags span { color: #999; font-size: 12px; color: grayMediumDark; }
.tags span:after { content: ', '; }
.tags span:last-of-type:after { content: ''; }
.description { color: #999; cursor: pointer; }
.btn { display: inline-block; padding: 7px 15px; text-decoration: none; font-weight: normal; color: #999; border: 2px solid #ebebeb; -webkit-border-radius: 4px; border-radius: 4px; background: #f9f9f9; }
.btn:hover { background: #ebebeb; color: #555; }
.btn.active { background: #454545; border-color: #454545; color: #fff; }
.jobs-teams { margin-bottom: 40px; padding: 0 30px; }
.jobs-teams select { display: none; }
.jobs-teams .btn { margin: 0 8px 8px 0; }
.jobs-teams .btn:first-of-type { margin-left: 0; }
.jobs-teams .btn:last-of-type { margin-right: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<button id="fetchData">Fetch Data</button>
<section>
	<div id="jobsContainer" class="container">
		<h1>Open jobs</h1>
		<div id="jobsTeams" class="jobs-teams"><select></select></div>
		<div id="jobsList" class="jobs-list"></div>
	</div>
</section>

享受!