Get data attribute inside multiple children - performance

I have this issue: Multiple classes with several span inside of each class and want to extract all data attributes of the first class.
<div class="parent_class">
<span data-year="a_1">Data</span>
<span data-make="b_1">Data</span>
<span data-model="c_1">Data</span>
<span data-motor="d_1">Data</span>
</div>
<div class="parent_class">
<span data-year="a_2">Data 2</span>
<span data-make="b_2">Data 2</span>
<span data-model="c_2">Data 2</span>
<span data-motor="d_2">Data 2</span>
</div>
I have made several tries and just got the first data attribute with not problem.
var year_response = $('.parent_class:first span').data('year');
Response:
year_response = a1;
But when I tried for the make and other data attribute I got undefined
Actual:
var make_response = $('.parent_class:first span').data('make');
**Response:
make_response = undefined;**
Desire:
var make_response = $('.parent_class:first span').data('make');
**Response:
make_response = b_1;**

How about just fetching all data attributes of the spans as objects and mapping them to an array :
var data = $.map($('.parent_class:first span'), function(el) {
return $(el).data();
});
FIDDLE
or an object if all the data attributes are different :
var data = {};
$.each($('.parent_class:first span'), function(i, el) {
$.each($(el).data(), function(k,v) {data[k] = v});
});
FIDDLE

You are telling it to get the first span, but the you want the second span (the one with make). What about getting the first with the make data attribute?
console.log($('.parent_class > span[data-make]:first').data('make'));
You could also select the nth element with the nth-child selector:
console.log($('.parent_class > span:nth-child(2)').data('make'));

Related

Output user first name

I want to get the name of the user to put it on an h1.
What dies this line stand for?
#select="option => selected = option">
I'm using Buefy for the vue components.
<template>
<section>
<div class="field">
<b-switch v-model="keepFirst">
Keep-first <small>(will always have first option pre-selected)</small>
</b-switch>
</div>
<p class="content"><b>Selected:</b> {{ selected }}</p>
<b-field label="Find a name">
<b-autocomplete
v-model="name"
placeholder="e.g. Anne"
:keep-first="keepFirst"
:data="filteredDataObj"
field="user.first_name"
#select="option => selected = option">
</b-autocomplete>
</b-field>
</section>
</template>
<script>
import data from '#/assets/data_test.json'
// Data example
// [{"id":1,"user":{"first_name":"Jesse","last_name":"Simmons"},"date":"2016-10-15 13:43:27","gender":"Male"},
// {"id":2,"user":{"first_name":"John","last_name":"Jacobs"},"date":"2016-12-15 06:00:53","gender":"Male"},
// {"id":3,"user":{"first_name":"Tina","last_name":"Gilbert"},"date":"2016-04-26 06:26:28","gender":"Female"},
// {"id":4,"user":{"first_name":"Clarence","last_name":"Flores"},"date":"2016-04-10 10:28:46","gender":"Male"},
// {"id":5,"user":{"first_name":"Anne","last_name":"Lee"},"date":"2016-12-06 14:38:38","gender":"Female"}]
export default {
data() {
return {
data,
keepFirst: false,
name: '',
selected: null
}
},
computed: {
filteredDataObj() {
return this.data.filter((option) => {
return option.user.first_name
.toString()
.toLowerCase()
.indexOf(this.name.toLowerCase()) >= 0
})
}
}
}
</script>
# is shorthand for v-on:, so it's handling a select event with a function that receives option as a parameter and assigns it to selected.
Since v-model is bound to name, you should be able to do <h1>{{name}}</h1> to have the same value show up in an H1.
The data section has the main variables for your object. name is there. There is also a computed (named filteredDataObj) that should return an array (length of zero or one) with the matching test data. If you want other fields (like id) you would need to look there. Something like
{{filteredDataObj.length ? filteredDataObj.id : ''}}
would give the id if name matched anything in the data set.

Grails: how to pass a array (and not a string!) using remoteFunction (ajax) from controller to view?

I need to load different data in a div when I change a Select option, not only a simple string but I list/array/map of strings. My code:
View:
<div id="contextMenu">
<div id="testeDiv">${result}</div>
<form class="selecionarConta" name="formulario">
<g:select id="selecionaConta"
name="selecionarConta"
class="selectConta"
from="${menuDropDown}"
optionValue="string"
optionKey="value"
onchange="${remoteFunction(controller:'dashboard',action:'teste', update:'testeDiv', params:'\'varteste=\'+this.value')}"/>
</form>
</div>
Controller:
def teste() {
def result = [["Lemon":"${params.varteste}"],["Orange":"5"],["Grapefruit":"10"]]
[result:result]
}
Let's suppose I want to load an array or even an object in this div "testeDiv" and then any content I want, e.g. a list, or even a single element from this list e.g. <div id=testeDiv>${result[1]}</div>

If search don't return values from database show an empty form

So i got a page that have a search form, and when the user search for a value if there are no records on database the form returns empty, but if there are records the form is populated with data.
What i was thinking was this
var db = Database.Open("myDataBase");
var selectCommand = "SELECT * FROM exportClient";
var searchTerm = "";
if(!Request.QueryString["searchField"].IsEmpty() ) {
selectCommand = "SELECT * FROM exportClient WHERE clientAccount = #0";
searchTerm = Request.QueryString["searchField"];
}
if(IsPost){
var selectedData = db.Query(selectCommand, searchTerm);
}
And Then:
<body>
<div class="col_12">
<form method="get">
<label>search</label><input type="text" class="col_3" name="searchField" />
<button type="submit" class="button red" value="search">search</button>
</form>
</div>
#if(!Request.QueryString["searchField"].IsEmpty() ){
foreach(var row in db.Query(selectCommand, searchTerm)) {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM POPULATED
</form>
</div>
}
} else {
<div class="col_12 box">
<form method="post">
// HERE IS THE FORM NOT POPULATED
</form>
</div>
}
</body>
But what is happening is that the form that is not populated is always showing up when i enter the page, and i need that the only thing that user see when enter the page is the input field to do the search.
What am i doing wrong ?
I'm not sure of having understood your goal, but in my opinion your main problem is to detect if either exists or not a query string.
I think that your code should be like this
#if(Request.QueryString.HasKeys())
{
if(!Request.QueryString["searchField"].IsEmpty() ){
<p>searchField has value</p>
} else {
<p>searchField hasn't value</p>
}
}
There are a number of potential issues I can see with your code, hopefully you can put these together to achieve what you wanted:
As Selva points out, you are missing the action attribute on your forms.
The selectedData variable you create inside your IsPost() block goes out of scope before you do anything with it. Perhaps you didn't include all your code though, so ignore this if it just isn't relevant to the question.
To answer the main question: if you don't want the empty form to appear when the user hasn't yet performed a search, surely you just need to completely remove the else block - including the empty form - from your HTML?
Hope that helps.

WebGrid form posting in ASP.NET Web Pages Razor v2

OK, typical problem:
I have a table with 7884 of records (for now—but there will be lots...)
I want to offer admins a quick way to monitor this table through the web.
I also need to provide viewers the ability to specify some filtering to further narrow the results, as well as be able to say how many records to pull from the DB.
I'm making my intro to ASP.NET web development and so I chose to use the (more straightforward) ASP.NET WebPages framework.
I'm using the System.Web.Helpers.WebGrid to display the records and I like the fact that it automatically implements paging.
I'm using a <form method="post"> to gather the filtering parameters, so that when the form posted back, I can adjust my querying based on these values. I also assign these values to the form fields so that the user can see the posted parameters in use.
However, I noticed that the page links generated by the WebGrid that are displayed in the page footer all the reference current page URL with a query fragment of the form ?page=n.
So, obviously, when the pages are navigated, I receive a request without my page form data...
What would be your recommended pattern to solved this simple issue and keeping the development of these pages short for the time being?
#{
Layout = "~/_TablePageLayout.cshtml";
Page.Title = "Wala-Wala";
var headlinePattern = Request.Form["headlinePattern"];
var _headlinePattern = headlinePattern;
if (string.IsNullOrWhiteSpace(headlinePattern)) {
_headlinePattern = "%";
headlinePattern = string.Empty;
}
var maxCount = Request.Form["maxCount"];
int? _maxCount = maxCount.TryConvert<int>();
if (_maxCount == null || _maxCount < 0) {
_maxCount = null;
maxCount = string.Empty;
}
var database = Database.Open("Wala-Wala-DB");
var query = _maxCount == null
? #"SELECT * FROM dbo.WalaWala WHERE Headline LIKE #1"
: #"SELECT TOP(#0) * FROM dbo.WalaWala WHERE Headline LIKE #1";
var dataSource = database.Query(query, _maxCount, _headlinePattern);
var grid = new WebGrid(source: dataSource, rowsPerPage: 25, canPage: true);
grid.SortColumn = "Id";
grid.SortDirection = SortDirection.Descending;
var rowStart = grid.PageIndex * #grid.RowsPerPage + 1;
var rowEnd = grid.PageIndex * #grid.RowsPerPage + grid.Rows.Count;
}
<h1>#Page.Title</h1>
<form method="post">
<fieldset>
<legend>Search</legend>
<ol>
<li>
<label for="maxCount">Maximum:</label>
<input type="text" id="maxCount" name="maxCount" value="#maxCount""/>
</li>
<li>
<label for="headlinePattern">Headline Pattern:</label>
<input type="text" id="headlinePattern" name="headlinePattern" value="#headlinePattern""/>
<input type="submit" value="Search" />
</li>
</ol>
</fieldset>
</form>
<p>
<b>#grid.TotalRowCount entries found. Showing results #rowStart to #rowEnd (page #(grid.PageIndex + 1)
of #grid.PageCount).</b>
</p>
<div>
#grid.GetHtml(
tableStyle: "tableStyle",
alternatingRowStyle: "alternatingRowStyle",
mode: WebGridPagerModes.All,
columns: new[] {
grid.Column(columnName: "Id", style: "columnStyle"),
grid.Column(columnName: "Headline", style: "columnStyle"),
grid.Column(columnName: "DTS", style: "columnStyle"),
}
)
</div>
Use jQuery to force the form to be POSTed and prevent the click on the link from initiating a GET request. This article explains how to do that in more detail: http://www.mikesdotnetting.com/Article/180/Displaying-Search-Results-In-A-WebGrid

Sorting Div's With PrototypeJS

I am looking for some help in sorting div's with PrototypeJS. Here is what I have so far:
document.observe('dom:loaded',function(){
$$('.sortcol').invoke('observe', 'click', function() {
if (this.hasClassName('desc')) {
var desc = false;
this.removeClassName('desc');
} else {
var desc = true;
this.addClassName('desc');
}
var colname = this.className;
var contentid = this.up(2).id;
sortColumn(contentid,colname,desc);
});
});
function sortColumn(contentid,colname,desc) {
$$('#'+contentid).select('.'+colname).sort(function(a,b){
if (desc) {
return (a.text.toLowerCase() >= b.text.toLowerCase() ) ? -1 : 1;
} else {
return (a.text.toLowerCase() < b.text.toLowerCase() ) ? -1 : 1;
}
});
}
Example data:
<div id="contentbox_Users" class="userList">
<div class="userListHeader">
<div class="userListHeaderCell col1">First Name</div>
<div class="userListHeaderCell col2">Last Name</div>
</div>
<div id="contentbox_People">
<div class="userListRow">
<div class="userListCell col1">John</div>
<div class="userListCell col2">Smith</div>
</div>
<div class="userListRow">
<div class="userListCell col1">Bob</div>
<div class="userListCell col2">Ray</div>
</div>
<div class="userListRow">
<div class="userListCell col1">Fred</div>
<div class="userListCell col2">Jones</div>
</div>
</div>
</div>
Basically anything with a class "sortcol", when it is clicked, I want it to sort by the column name clicked (class). The first issue is I need to be able to get the class name correctly when there is multiple classes. The classes are all like col1, col2, etc. How would I find the correct class?
The second thing is changing sortColumn so that it keeps column data together (each row is wrapped by another div) and output the result, replacing the current data.
This needs to be done in prototypejs and I can't change the code to tables.
Thanks in advance for the help.
For the first part of your question it would be much easier if the column name was it's own attribute like rel or data-*, but you say you cannot change the HTML. It is possible to pick out the likeliest class with regex...
var colname = this.className.match(/\bcol\d+\b/).first()
But this is unnecessary if we assume every row has the same columns in the same order. This would be a safer assumption if a table were used.
var colnumber = this.up().childElements().indexOf(this);
The second part of your question is easy, just sort the rows instead of the cells.
Your draft sortColumn function doesn't actually change the elements - select returns an array of element references, not their container - so you need to do something with the resulting array. Luckily any append or insert action of an element causes it to be removed from it's parent first, so simply append them once more and they'll assume the correct order. No replacing is needed, I've seen libraries that bizarrely convert the elements to HTML, concatenate that then reinsert it!?!
The following has been tested.
document.observe('dom:loaded',function() {
$$('.userListHeaderCell').invoke('observe', 'click', function() {
this.toggleClassName('desc');
var colnumber = this.up().childElements().indexOf(this);
var content = this.up(2); // use the element directly instead of it's ID
sortColumn(content, colnumber, this.hasClassName('desc'));
});
});
function sortColumn(content, colnumber, desc) {
content.select('.userListRow').sort(function(a,b){
var atext = a.down(colnumber).innerHTML.stripTags().toLowerCase();
var btext = b.down(colnumber).innerHTML.stripTags().toLowerCase();
return atext.localeCompare(btext) * (desc ? -1 : 1);
}).each(Element.prototype.appendChild, content);
}
This to me seems like you are creating tabular data. So why not use a table? And once you use a table, there are many sorting scripts out there. A quick google came up with this one.

Resources