I have found the #Olegs answer for FORM based select2 integration to jQgid, but I need help to get it to work in inline mode,, this jsfiddle is my attempt to get my problem online somehow I'm new with fiddle so please be patient :)
http://jsfiddle.net/mkdizajn/Qaa7L/58/
function(){ ... } // empty fn, take a look on jsfiddle
On this fiddle I can't make it to work to simulate the issue I have in my local network but the problem with this select2 component is that when I update some record(via local or ajax), the grid does not pick up my change and it sends null for values where select2 fields are!
I'm sorry that I can't make jsfiddle to work like on my PC :(
Thanks for any help you can think off that may be the issue here..
P.S. one veeeery strange thing is that when I console.log( select2-fields ), before, and after the value is picked up correctly but I suspect that the grid loose that value somewhere in between .. and send null values to server..
I'm posting this in a good will that I think will help anyone if come to close incounter with similar problem like me..
I'll try to bullet this problem out step by step..
first, on my server side I generate one html tag somewhere near grid table that holds info what columns, fields are lookup type.. like this:
<div id="hold_lookup_<?=$unique_id?>" style="display: none"><?php echo $lokki; ?></div>
that gives me output like this:
<div id="hold_lookup_table1" style="display: none">col1+++col2+++col3</div>
define onselectrow event somewhere
$onSelectRow = "function(){
f = $(this).attr('id'); // grid name
try{
n = $('#hold_lookup_' + f).text().split('+++');
}catch(e){
console.log(e)
}
rez = ''; // results
temp = 'textarea[name='; // template
$.each(n, function(index, item){
rez += temp + item + '],'
});
rez = rez.slice(0,-1); // rezemo zadnji zarez
$( rez ).select2({ .. define my ajax, my init etc.. });
}";
$dg->add_event("jqGridInlineEditRow", $onSelectRow);
last but very tricky part is here.. I destroy select2 columns before sending to database in jqgrid.src file where function for SAVE inline method is.. like this
if (o.save) {
$($t).jqGrid('navButtonAdd', elem, {
caption: o.savetext || '',
title: o.savetitle || 'Save row',
buttonicon: o.saveicon,
position: "first",
id: $t.p.id + "_ilsave",
onClickButton: function() {
var sr = $t.p.savedRow[0].id;
rez = rez.split(',');
rez1 = '';
$.each(rez, function(index, item) {
rez1 += item + ','
})
rez1 = rez1.slice(0, -1);
rez1 = rez1.split(',');
$.each(rez1, function(index, item) {
$(item).select2('destroy');
});
you can see that I inserted the code onclickbutton event via same 'rez' variable that was defined in my php file where I created grid..
That's it, I hope that helped someone, event if not in this particular problem, but with methods that was used here :)
cheers, kreso
Related
I have a blade template with a search bar, which has no submit button and is used for filtering. However, I can't seem to get it to filter appropriately, as the page was originally using angular (which has been removed completely).
My page displays all of my products using foreach loops and displays the info from variables in my page controller (pulling everything from the database and storing as variables). Anyway, everything displays fine but I need help getting this to filter properly.
Basically, if a term entered in the search bar is anywhere in the JSON object gathered by the controller, then I want it to only display those objects. I may even need another foreach loop.
Here's the html/blade code:
<!--Search bar div-->
<div class="uk-width-5-10">
<div class="md-input-wrapper search-form">
<form id="searchProducts">
<input type="text" class="md-input label-fixed" name="srch-term" id="srch-term" autofocus placeholder="Search Products"/>
<span class="md-input-bar"></span>
</form>
</div>
<!--foreach loops around the wrapper that shows products, for reference-->
#foreach ($orderFormData->pgroups as $pgroup)
#foreach ($pgroup->image_names as $image_name)
#foreach ($pgroup->pskus as $psku)
Javascript for the search (see the variable for the JSON object, that's what I need to search within)
<script>
var orderFormData = <?php echo json_encode ($tempdata);?>;
</script>
<script>
var orderData = orderFormData // default value
var search = function (e) {
var term = e.currentTarget.value
orderData = Object.entries(orderFormData).reduce(function (data, entry) {
if (entry[0].match(term) || entry[1].match(term)) {
data[entry[0]] = entry[1]
}
return data
}, {})
console.log(orderData)
}
document.querySelector('#srch-term').addEventListener('keyup', search)
</script>
Is there a better way I should be doing this? I may even need to do a foreach loop around the search bar
It kind of sounds like you're looking for an auto complete. Have you looked at the jquery-ui-autocomplete library? It's pretty easy to implement, and might add more functionality more easily than writing loops yourself.
https://jqueryui.com/autocomplete/
I'll get into why I named the function below, but here's my implementation:
monkeyPatchAutocomplete();
$("#your_searchbox_selector").autocomplete({
source: // http://Your_Search_URL_endpoint_here,
delay: 500, // prevents search from running on *every* keystroke
minLength: 1, // default is 2, change or remove as you like
// open page after selecting (with enter key).
select: function( event, ui )
{
var qval = ui.item.id // this pulls whatever field you're looking for in your JSON that you want to use to direct your user to the new page, in my case "id";
var url = 'http://whereever_you_want_your_user_to_go?';
window.location = url + qval;
}
});
For my implementation, I wanted to color code the results in my autocomplete list with active and inactive entries, so my search controller JSON result includes 3 fields:
'value' => $searchable_values, 'id' => $id_mapping_of_whatever, 'class' => $css_classes_to_use
My search controller plugs in emails, names, and phone numbers to the value field, which is searchable, then maps an id, and plugs in css classes that I use to change the text color of the results through a monkeypatch on jQuery's autocomplete:
function monkeyPatchAutocomplete()
{
$.ui.autocomplete.prototype._renderItem = function( ul, item)
{
var re = new RegExp(this.term, 'i');
var t = item.label.replace(re,"<span class='autocomplete-span'>" + this.term + "</span>");
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a class='text-" + item.class + "'>" + t + "</a>" )
.appendTo( ul )
};
};
If you're interested in formatting your results, check out dev.e.loper's answer to: How can I custom-format the Autocomplete plug-in results?.
I'm actually trying to get some data from a website in CasperJs. The datas are stocked in a table.
I'm trying to get a proper JSON file after the scrap. A json with :
- name of the company,
- mail,
- website
- description of activity.
Until now I've been able to open the page and get the data but not precisely (mail and website are on the same ). So I've found how to select precisely each element I want.
But in this case I don't get all table information's, only first row...
I would know if somebody could help me, telling me where to look or how to make loop in my case ? Assume I'm not a professional developper, I'm training myself.
Here my code :
var casper = require('casper').create();
var url = 'http://www.rent2016.fr/pages/exposants';
var fs = require('fs');
var length;
casper.start(url);
casper.then(function() {
this.waitForSelector('table#myTable');
});
casper.then(function(){
var info = this.evaluate(function(){
var table_rows = document.querySelectorAll("tr"); //or better selector
return Array.prototype.map.call(table_rows, function(tr){
return {
nom : document.querySelector(".td-width h3").textContent,
description: document.querySelector(".td-width p").textContent,
mail : document.querySelector("td span a").textContent,
site : document.querySelector('td span a[href^="http"]').textContent,
};
});
});
fs.write('test_rent_stringify.json', JSON.stringify(info), 'w');
this.echo(JSON.stringify(info, undefined, 4));
});
casper.run(function() {
});
Here, we don't have loop : JSON repeat the first row information's. To get every rows informations you have to replace
nom : document.querySelector(".td-width h3").textContent,
by
nom : tr.children[1].textContent,
but in this case you can't precisely target the H3, the links... you get all the information. So actually I can :
loop through the rows and get informations, but they unusable
have only the first row informations but with good presentation
Thanks in advance !
In order to take information inside every element, you have to use tr.querySelector rather than document.querySelector.
The following loop works fine with the page:
var table_rows = document.querySelectorAll("tbody tr"); //or better selector
return Array.prototype.map.call(table_rows, function(tr) {
return {
nom: tr.querySelector(".td-width h3").textContent,
description: tr.querySelector(".td-width p").textContent,
mail: tr.querySelector('td span a[href^="mailto"]').textContent,
site: tr.querySelector('td span a:not([href^="mailto"])').textContent
};
});
Sorry for the noobish question but, I am trying to build a form summary that will populate a div (immediately) with all of the fields being used. Here is a small sample of the field: Fiddle
For some reason the JS is not working as I would expect it to, can anyone point out what I am doing wrong?
For example, I would like it to output: "AND name: john EXCEPT number 222".
I would also like to be able click on a result to remove it, and clear the field. Thank you
$(".allS").change(function () {
if ($(this).next('.textArea').not(':empty'))
// varible to hold string
var str = "";
$("select option:selected").each(function () {
str += $(this).text() + " ";
});
$("#text_here").text(str);
}).change();
$('.textArea').change(function(){
var $inputs = $('form#form :input[type="text"]'),
result = "";
$inputs.each(function(){
// access the individual input as jQuery object via $(this)
result += $(this).val()+"<br>";
});
// store result in some div
$('div#text_here').text(result);
}).change();
There were many mistakes in your code. I simplified it to a very short code that only does what's needed to get the output you requested. Here's the working fiddle.
$(".allS, .textArea").change(function () {
var str = '';
if ($('#name').val().length > 0 && $('#number').val().length > 0)
var str = $('#nameMod>option:selected').text() + ' name:' + $('#name').val() + ' ' + $('#numberMod>option:selected').text() + ' number ' + $('#number').val();
$("#text_here").html(str);
});
Basically, what this does is attach a change event handler to both classes (.alls, .textArea), and when the event is triggered, both input fields are tested for any content. If this test passes, a string is composed out of all the relevant values, and the div content is set. If the test failed (no content), the str variable contains an empty string and the div is cleared.
Just glancing at the code, the selector 'form#form :input[type="text"]' looks wrong. For starters, input is not a pseudoclass. Also, attribute matching shouldn't have the quotes.
This may or may not be what you want (I think it is, from looking at your html):
'form#form input[type=text]'
Also your <br>'s are not working because you called text(). call html() instead.
I'm currently working on Ajax and jQuery live search which finds a results in a JSON file. Script is working fine, but the is only one problem - it's duplicating the result data.
EXAMPLE:
MARKUP:
<div class="row">
<h3>Live Search Results</h3>
<div id="update-results">
<p>event_name | club_name | memberid</p>
<ul id="update">
<!-- <li></li> -->
</ul>
</div>
</div>
SCRIPT:
$('#search').keyup(function() {
var searchField = $('#search').val();
var $update = $('#update');
$update.empty();
$.get("getEventsWithVideos.php?text=" + searchField, function(data) {
var vals = jQuery.parseJSON(data);
if($.isArray(vals['Event'])) {
$.each(vals['Event'], function(k,v){
$update.append("<li value='"+v['id']+"'><a href='#'>" + v['event_name'] + "</a></li>");
});
} else {
$update.append("<li value='"+vals['Event']['id']+"'><a href='#'>" + vals['Event']['event_name'] + "</a></li>");
}
});
});
I've tried to debug and stop the error, but it was unsuccessful. Can anyone help me please with that?
Put the empty() inside the response handler:
$.get("getEventsWithVideos.php?text=" + searchField, function(data) {
$update.empty();
basically you are clearing the list on every keystroke (rapid), then requesting the data, then (sometime later) appending the results that come back (which could be multiple results depending on the timing).
I didn't reproduce your error but I suspect that you have problem with multiple request to server and adding them all instead of last one. Probably adding below code will fix your problem
$update.empty();
Anyway I suggest you to use 2 more functions: throtlle and debounce from underscore to prevent too much request on every keyup.
Also you could try Rx.js witch give following example (https://github.com/Reactive-Extensions/RxJS):
var $input = $('#input'),
$results = $('#results');
/* Only get the value from each key up */
var keyups = Rx.Observable.fromEvent($input, 'keyup')
.map(function (e) {
return e.target.value;
})
.filter(function (text) {
return text.length > 2;
});
/* Now debounce the input for 500ms */
var debounced = keyups
.debounce(500 /* ms */);
/* Now get only distinct values, so we eliminate the arrows and other control characters */
var distinct = debounced
.distinctUntilChanged();
Try changing this line $update.empty(); of your code to $update.find('li').remove(); and put it inside the response handler.
This removes all the previous data before you append the new values. Hopefully it might work.
I'm learning CasperJS and want to try a simple, somewhat useful task. I'd like to make a pdf copy of my gas bill, but I can't even log into the website.
I'm a customer of CT Natural Gas. The URL is:
https://www.cngcorp.com/wps/portal/cng/home/mycng/customerWebAccess/
Logging in should be simple. It should just be my account number and last name.
My code is:
var start_url = "https://www.cngcorp.com/wps/portal/cng/home/mycng/customerWebAccess/"
var casper = require('casper').create()
casper.start(start_url, function() {
this.fill('formid', {
'input1id': '000000000000',
'input2id': 'LastName'
}, true);
this.capture('cng.png');
})
casper.run()
My "real" code uses the full ID shown in the site's HTML, not "formid" or "input1ID". I did not include the full ID in the sample code above because I was unsure what those ID's really were. They look something like: viewns_7_LOIGMC7IA21234QWERASDF1234_:custWebLogin. So much for a "simple" ID. Maybe this is something generated from a WebSphere product?
Anyway, the form is not found. I get:
CasperError: Errors encountered while filling form: form not found
I've also hacked it a bit and put this in my start to see what the form "looks like":
listItems = this.evaluate(function () {
var nodes = document.querySelectorAll('form');
return [].map.call(nodes, function(node) {
return node.id;
})
})
this.echo(listItems);
That returns:
,viewns_7_LOIGMC7IA21234QWERASDF1234_:custWebLogin
I think the form id is messing this up. Can anyone offer any suggestions?
Wait for the form to be loaded to fill the form using the selectors.Use have waitForSelector(),waitFor(),wait() etc other than waitForResource()
casper.start('your_url_here',function(){
this.echo(this.getTitle());
});
casper.waitForResource("your_url_here",function() {
this.fillSelectors('#loginform', {
'input[name="Email"]' : 'your_email',
'input[name="Passwd"]': 'your_password'
}, true);
});
I think the DOM/CSS3 Selectores doesn't work with this ID but it works with xpath :
// Create a function for selectXPath :
var x = require('casper').selectXPath
var start_url = "https://www.cngcorp.com/wps/portal/cng/home/mycng/customerWebAccess/"
var casper = require('casper').create()
casper.start(start_url, function() {
// Query xpath with fillSelectors
this.fill(x('//*[#id="viewns_7_LOIGMC7IA26I00I9TQ9SLI1B12_:custWebLogin"]'), {
'input1id': '000000000000',
'input2id': 'LastName'
}, true);
this.capture('cng.png');
})
casper.run()
Do you need the full ID? Because maybe something like that could work :
this.fill("form[id^='viewns_7_LOIGMC7IA21234QWERASDF1234']", {
'input1id': '000000000000',
'input2id': 'LastName'
Or
this.fill("form[id*='LOIGMC7IA21234QWERASDF1234']", {
'input1id': '000000000000',
'input2id': 'LastName'