Retrieving g:select value from within gsp - No form - grails

How does one pass the value of the g:select box in a link action:
<g:select name="sel.n" from="${personList}" value="" />
<g:link action="addValue" params="${[personID: personInstance.id, selectionVal: sel.n.value]}">Add</g:link>
How do I retrieve the value of the selection box sel.n to pass in that action link?
This is NOT a form.

You'll want to use jQuery for something like this. Below is a sample that should get you started down the right path.
var val = "";
$('#sel\\.n').change(function() {
val = $(this).text();
 $("a").attr('href', function(i, h) {
      return h + (h.indexOf('?') != -1 ? "&" : "?") + "selectValue="+val;
});
});
The above code will catch when the select box changes and then alters the query string of the href link. If your unfamiliar with jQuery you'll need to run through some basics it's an essential tool for things like this. Good luck and enjoy!

Related

How to extract the "href" attribute of <a> and paste it in a Google sheet?

I would like to extract an HTML anchor's ( < a href="" >Link here< /a > ) "href" attribute from the following page:
https://tvm.liga.nu/cgi-bin/WebObjects/nuLigaTENDE.woa/wa/teamPortrait?team=2368692&championship=K%C3%B6ln-Leverkusen+Winter+2019%2F2020&group=18
and put it in my google sheet.
I tried several xpath expressions for this page but it is everytime "N/A".
Still the simple xpath doesn't work, e.g.
importxml("https://tvm.liga.nu/cgi-bin/WebObjects/nuLigaTENDE.woa/wa/teamPortrait?team=2368692&championship=K%C3%B6ln-Leverkusen+Winter+2019%2F2020&group=18";"//tr")
What am I doing wrong?
Thanks Tanaike for all of your efforts.
I changed the script a little bit, because the result is based on pure html and needs to be changed so that the link could be clicked.
function getWebsite(url, searchText, baseURL)
{
var html = UrlFetchApp.fetch(url);
var text = html.getContentText();
var re = new RegExp('(?<=<a href=")(.*)(?=">.*' + searchText +')',"g");
var link = text.match(re)[0];
if (link !== null)
{
var link = text.match(re);
link = link.replace(/&/g,"&");
link = link.replace(/"/g,"\"");
return baseURL + link;
}
else { return "not found"; }
}
It depends which information you're looking for, but for example...
A1: https://tvm.liga.nu/cgi-bin/WebObjects/nuLigaTENDE.woa/wa/teamPortrait?team=2368692&championship=K%C3%B6ln-Leverkusen+Winter+2019%2F2020&group=18
A2: //table[2]/tbody/tr/td[6]/a/#href
A3: =IMPORTXML(A1,A2,1)
To find A2 - in Chrome - right-click a link of interest and "Inspect." Right-click on the href of interest to you, and "Copy full XPath."
Delete the part before the table reference, but leave TWO "/"s before the table reference. Then, delete the reference to the specific row following "tr", i.e., the "[x]". This way you'll select the entire column - in this case "[6]"
Fiddle as necessary.

Select2 searches inside the html of the formatted options

I am using the select2 widget, and I need to display the search results formatted as html.
So I am using it like this:
function formatMyItem(myItem) {
return defaultEscapeMarkup(myItem.someDescription) + " <strong>(" + myItem.someOtherValue + ")</strong>";
}
function defaultEscapeMarkup(markup) {
var replace_map = {
'\\': '\',
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/'
};
return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
return replace_map[match];
});
}
var suggestionValues = [];
for (var i = 0; i < myData.length; i++) {
var myItem = myData[i];
suggestionValues.push({
id: myItem.someKey,
text: formatMyItem(myItem)
});
}
$mySelect.select2({
width: 'resolve',
multiple: true,
data: suggestionValues,
escapeMarkup: function(m) {
// Do not escape HTML in the select options text
return m;
}
});
But now when the user searches for something, that term is searched inside the HTML of the option.
For example, if the user searches for "strong" (assumming that some descriptions can contain the word "strong"), then select2 will suggest all the values (because all of them contain "strong").
Also, when the user searches for "<" (assuming that some descriptions contain mathematical symbols), then select2 will return all values (because all of them contain html tags), but will not highlight the actual "less than" symbol in the descriptions, because they have been actually converted to "& lt;".
How can I make select2 not search inside the html tags?
Ok, it seems the solution was actually quite simple :D
I added the following:
$mySelect.select2({
width: 'resolve',
multiple: true,
data: suggestionValues,
escapeMarkup: function(m) {
// Do not escape HTML in the select options text
return m;
},
matcher: function(term, text) {
// Search the term in the formatted text
return $("<div/>").html(text).text().toUpperCase().indexOf(term.toUpperCase())>=0;
}
});
So now when the user searches for "strong" they get only the relevant results.
But now there is another issue:
Now, if the user searches for "<", then select2 will highlight the "<" inside the strong tag.
It seems that I need to also "patch" somehow the search-results highlighter...
EDIT : Coming back to this, it seems that the solution for the highlighting is not so easy...
The default implementation in select2 is like this:
formatResult: function(result, container, query, escapeMarkup) {
var markup=[];
markMatch(result.text, query.term, markup, escapeMarkup);
return markup.join("");
},
.......
function markMatch(text, term, markup, escapeMarkup) {
var match=text.toUpperCase().indexOf(term.toUpperCase()),
tl=term.length;
if (match<0) {
markup.push(escapeMarkup(text));
return;
}
markup.push(escapeMarkup(text.substring(0, match)));
markup.push("<span class='select2-match'>");
markup.push(escapeMarkup(text.substring(match, match + tl)));
markup.push("</span>");
markup.push(escapeMarkup(text.substring(match + tl, text.length)));
}
Somehow I need to replace these two functions, but I cannot find an easy solution for mapping from the range of characters in the formatted HTML (the search-term to highlight) back to the source html (so that I can add the < span class='select2-match' > ) ...
If any of you has better solutions, please feel free to share them...

Convert Select2 input to tokens

Does the Select2 jQuery plug-in have a built-in function for converting strings to tokens?
I want to be able to call this tokenizing function when the user pastes strings into a Select2 field so that the pasted input becomes tokens.
I think I have solved the question myself with the following code:
// force tokenizing of Select2 auto-complete fields after pasting
$('body').on('paste', '.select2-input', function() {
// append a delimiter and trigger an update
$(this).val(this.value + ',').trigger('input');
});
This assumes that commas are set as delimiters in the plug-in's "tokenSeparators" initialization setting.
For 4.0.1 version:
$('#my-select').data('select2').dataAdapter.$search.val("tag1,tag2,").trigger("input");
This will add two tags: tag1 and tag2 (note trailing ,).
Important: you should add data: [] into select2 init parameters.
Use an input type text, and assign the select2 to it. Like
<input type="text" id="makeTokens" />
and then in javascript
$("#makeTokens").select2({
placeholder: "Paste data",
tags: ["red", "green", "blue"],
tokenSeparators: [",", " "]
});
in the tags, you can assign any values that you want it to display as select options and use the tokenSeperators to seperate the text on commas or spaces etc.
Note: The resultant input value will be comma seperated tokens.
For some reason Donald's solution didn't work for me (maybe newer versions of select2 behaves differently). This is what worked for me:
$('body').on('paste', '.select2-input', function (e) {
var pasteData = (e.originalEvent || e).clipboardData.getData('text/plain') || '';
$(this).val(pasteData + ',');
e.preventDefault();
});
Since at the point the event was triggered the value of .select2-input was an empty string, I extractacted the pasted string from the event object. Apparently the default select2 for copying action was still triggering after this, so I had to add e.preventDefault(); to stop it from running and messing up the input.
just run this jQuery which takes the separatoes from options.tokenSeparators directly, and applies for all select2 instances in the page automatically:
$(document).on('paste', 'span.select2', function (e) {
e.preventDefault();
var select = $(e.target).closest('.select2').prev();
var clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
var createOption = function (value, selected) {
selected = typeof selected !== 'undefined' ? selected : true;
return $("<option></option>")
.attr("value", value)
.attr("selected", selected)
.text(value)[0]
};
$.each(
clipboard.split(new RegExp(select.data('select2').options.options.tokenSeparators.map(function (a) {
return (a).replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}).join('|'))),
function (key, value) {
if (value && (!select.val() || (select.val() && select.val().indexOf('' + value) == -1))) {
select.append(createOption(value));
}
});
select.trigger('change');
});

Processing multiple select controls within jquery mobile form

I am trying to process multiple input selects in a form each one has a unique name and id.
here is my first try, this is broken when y = value.val(); executes
var selects = $("#pmWorkOrderProcedureStepsForm").find('select');
$.each(selects,
function(index, value)
{
y = value.val();
});
I can see in chrome debug that value has a reference to something that looks like
HTMLSelectElement#select-choice-400139826
Where select-choice-400139826 is my first select input name.
How do I get just the name and the selected value of the input from here.
New to jquery mobile!
You can use the following code snippet:
var selects = $("#pmWorkOrderProcedureStepsForm").find("select");
$.each(selects,function(){
name = $(this).attr('name');
value = $(this).val();
});
A demo here - http://jsfiddle.net/5xg6F/
Let me know if that helps.

Backbone.js: Change datetime field from Rails

When I print the created_at field of a model using Backbone.js( <i> {{created_at}} </i>
), I'm getting: 2011-08-07T12:03:00Z.
I'm trying to change the date to a readable format for hours and I'm not being able to.
I want the T and Z to be removed before printing.
thanks
Change the variable in your template context, or add a new one. I would add a new one.
If this is in your render function, it may be changed to something like this:
render: function() {
var context = this.model.toJSON();
context['created_at_formatted'] = this.formatDate(context['created_at']);
var html = this.template.to_html(context);
$(this.el).html(html);
}
With a function added to the view like this:
formatDate: function(d) {
var pad = function (n) {
return n < 10 ? '0' + n : n;
};
// in case the date is a string; you can remove this if you know it will be a date
if (typeof date === 'string') {
d = new Date(d);
}
return [
d.getUTCFullYear(), '-',
pad(d.getUTCMonth() + 1), '-',
pad(d.getUTCDate()), ' ',
pad(d.getUTCHours()), ':',
pad(d.getUTCMinutes()), ':',
pad(d.getUTCSeconds())
].join("");
}
Then the template would be like this:
<i> {{created_at_formatted}} </i>
To simplify the date formatting function, you could also use a date formatting library like DateJS. You could also move the date formatting to the model.
Readable? Why not jQuery timeago?
jQuery timeago
In your Backbone model,
toTemplateData: ->
_.extend
created_duration: do => $.timeago #get("created_at") if #get("created_at")
In your Backbone view,
render: ->
#$el.html(#template(#model.toTemplateData() ))
In your template,
<time title="{{created_duration}}"></time>
You can use the strftime on your created_at
<i> {{created_at.strftime('%Y/%m/%d')}} </i>
Ben's answer is correct but the formatting of the date should really be in a model somewhere as it is business logic.
My variation of that would be:
render: function() {
var context = this.model.format().toJSON();
var html = this.template.to_html(context);
$(this.el).html(html);
}
And in your model, something like:
format() {
this.set('created_at_formatted', formatDate(this.get('created_at')));
return this;
}
formatDate: function(d) {
// format date stuff (See Ben`s answer)
return d;
}
And your template would render:
<i> {{created_at}} </i>
This removes some redundancy, promotes reuse and it is easier to read. Perhaps my answer needs a little work but hopefully you get the general idea.

Resources