I have a drop-down in j-table and I want to extract the selected value from it. Is there any way to get the selected option values from j-table.
sections_template_id: {
title: 'Template',
inputTitle: "Template*",
options: web_sections,
create: true,
edit: true,
list: true
}
, sec_hidden: {
type: 'hidden'
, inputTitle: "Template*"
, create: true
, edit: false
, list: false
, defaultValue: web_sections
}
i want to set the value of sections_template_id in sec_hidden
this is my route on which i am calling a function
Route::post('cms-web-section-templates',['as' => 'cms-web-section-templates', 'uses' => 'CmsController#Main_sections']);
and here is my function
public function Main_sections(Request $request)
{
$types = SectionType::getTypes();
$web_section = WebTemplate::all();
//dd($web_section);
$rows[] = array("DisplayText"=>"", "Value"=>"");
foreach ($web_section as $key => $web_sections) {
$rows[] = array(
'DisplayText' => $web_sections->name,
'Value' => $web_sections->id,
);
}
$this->response['Options'] = $rows;
$this->response['Result'] = "OK";
return json_encode($this->response);
}
I used jquery/javascript to grab data from jtable. I cant find in the jtable documentation how to grab the selected value. If you inspect element, once you select the row, a class is added in that row which is "jtable-row-selected".
<script>
var all_rows = [];
$('tr.jtable-row-selected').each(function(){
var len = $(this).children().length;
var row = [];
for(let i = 0;i < len; i+=1){
row.push($(this).children()[i].innerText)
}
all_rows.push(row);
})
//console.log(all_rows);
</script>
Try the jtable selectedRows method to get a jquery object of the selected rows.
The documentation https://jtable.org/ApiReference/Methods#met-selectedRows has short worked example how to get the record and fields for each selected row.
Related
Let's say I have an entity User.
The User can have many Address.
In Address There's 2 fields :
Country
State
What I want :
When the user create his account, he can add as many address as he
wants.
When the user select a Country, it populate the State field based on the country.
What I've done :
UserType :
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', 'collection', array(
'type' => new AddressType(),
'allow_add' => true,
'allow_delete' => true))
//...
}
The Javascript to add address (which is working : based on symfony doc):
<script type="text/javascript">
$(document).ready(function() {
var $container = $('div#mybundle_user_address');
var $addLink = $('Add address');
$container.append($addLink);
$addLink.click(function(e) {
addAddress($container);
e.preventDefault();
return false;
});
var index = $container.find(':input').length;
$container.children('div').each(function() {
addDeleteLink($(this));
});
function addAddress($container) {
var $prototype = $($container.attr('data-prototype').replace(/__name__label__/g, 'Address n°' + (index+1))
.replace(/__name__/g, index));
addDeleteLink($prototype);
$container.append($prototype);
index++;
}
function addDeleteLink($prototype) {
$deleteLink = $('Delete');
$prototype.append($deleteLink);
$deleteLink.click(function(e) {
$prototype.remove();
e.preventDefault();
return false;
});
}
});
</script>
Ok, but now, How do I add I call a .change() on the select created after clicking on "add address" ?
Because if you add many address, divs will have this name :
#mybundle_user_address_0_country
#mybundle_user_address_1_country
#mybundle_user_address_2_country
...
So how do I select the div to have a .change() call of these divs ? And where do I put the javascript ? Inside the first javascript when I add divs ? Or outside ?
I'm currently trying to do a survey system. I have a dynamic dropdown that displays one column 'questiontitle' from my table database. Here's my code of displaying the 'questiontitle' in the dropdown.
<?php
$query=mysqli_query($con, "SELECT * FROM question");
while($row=mysqli_fetch_array($query))
{
?>
echo "<option value='$row[question_id]'>";
echo $row["questiontitle"];
echo "</option>";
<?php
}
?>
echo "</select>";
And here's my database table.
My main question is how do I display the 'Option_1 to Option_10 columns' depending on the 'answer_type' column when a data is clicked from the dropdown in real time without refreshing the page? Like if the 'answer_type' is checkbox, it will display the option1-10 as checkbox and if it's radiobutton, it will display the option1-10 as radiobuttons.
There is a lot work to be done to achieve what you want to do. But I can give you a small snippet which you can use to start.
What you still have to do is
Show a page with all questions in the select box. This is done in PHP
checking how ajax works. Expand the showQuestion() function with ajax functionality so your question & answer data is retrieved from the server. this is a good read. When you got your answer, call the appropriate function to display your question and answers. OR store all your information locally...
add a button so that you can send the answers to the server. Listen to the click event and send data (small modifications are required to what I have wrote though) to the server (read the link that I have shown in point 2)
// question object
var questions = {
json1: {
questiontitle: 'How frequently ...',
answertype: 'radiobutton',
options: ['Heavy user', 'serious user', 'regular user', 'light user']
},
json2: {
questiontitle: 'What part of the day...',
answertype: 'checkbox',
options: ['Morning', 'Afternoon', 'Early evening', 'lat evening']
},
json3: {
questiontitle: 'To what extend does the ...',
answertype: 'radiobutton',
options: ['1-5 times', '6-10 times', '> 10 times']
}
};
// function that adds the "questions" input elements to the container
function insertToQuestionBox(els) {
var box = document.getElementById('questionBox');
// cleanup box
while(box.firstChild) box.removeChild(box.firstChild);
// populate with els
for(var i = 0; i < els.length; ++i) box.appendChild(els[i]);
}
// creates the input element based on args
function createInput(type, name, text) {
var i = document.createElement('input');
i.type = type;
i.name = name;
var l = document.createElement('label');
l.textContent = text;
var s = document.createElement('section');
s.appendChild(l);
s.appendChild(i);
return s;
}
// create element with question in it
function createQuestionEl(question) {
var s = document.createElement('span');
s.textContent = question;
return s;
}
// function that is called if the question is of type radio
function handleRadioButtons(data) {
var inputs = [];
inputs.push(createQuestionEl(data.questiontitle));
for(var i = 0; i < data.options.length; ++i) {
inputs.push(createInput('radio', 'rraaddioo', data.options[i]));
}
insertToQuestionBox(inputs);
}
// create checkboxes
function handleCheckboxes(data) {
var inputs = [];
inputs.push(createQuestionEl(data.questiontitle));
for(var i = 0; i < data.options.length; ++i){
inputs.push(createInput('checkbox', 'nana' + i, data.options[i]));
}
insertToQuestionBox(inputs);
}
// gets called each time the drop down has changed
function showQuestion() {
var data = questions[this.value];
switch(data.answertype) {
case 'radiobutton': handleRadioButtons(data); break;
case 'checkbox': handleCheckboxes(data); break;
// todo when default? error ?
}
}
// listen to select changes
document.getElementById('showQuestion').addEventListener('change', showQuestion);
<select id="showQuestion">
<option>please choose</option>
<option value="json1">show json1</option>
<option value="json2">show json2</option>
<option value="json3">show json3</option>
</select>
<div id="questionBox"></div>
On select box change event pass questionid to server side and query your database for answer_type and options and in that method add a condition
$options = '';
if(anwsertype=='radio') {
$options .= <input type="radio" /> Your option
} else {
$options .= <input type="checkbox" />Your option
}
The above condition should be in a loop for each option.
So what I want to do is to pre-select few filters depending on the parameters of the location.search
Example Url : index.html?Type=Building&Stage=Stage 2
Here is my code
var searchObj = searchToObj(); // {Type: 'Building', Stage: 'Stage 2'};
var presetFilters = [];
for (var filterName in searchObj){
if (filterName != 'search') {
var filterID = oTable.column(filterName+':name').index();
presetFilters.push([filterID, searchObj[filterName]]);
}
}
yadcf.exFilterColumn(oTable, presetFilters);
The table is filtered but the select boxes stay on the default label.
What can I do?
I am trying to populate a sublist in a suitelet with data from a custom saved search that I have already created. My problem is that the sublist is only populating data from fields that correspond to the "type" of saved search I am doing. For example, in this instance the saved search is a "transaction" type search. If, for example, I want to reference a customer field withing the saved search, say "Name" and "Billing Address", this data will not populate the sublist in the suitelet. All other fields that are being referenced in the Transaction record itself populate the sublist fine. I was just wondering if anyone has ever run into the same issue, anyways here's the code I'm trying to implement.
var form,
sublist;
//GET
if (request.getMethod() == 'GET')
{
//create form
form = nlapiCreateForm('Test Custom Suitelet Form', false);
//create sublist to show results
sublist = form.addSubList('custpage_sublist_id', 'list', 'Item List');
//form buttons
form.addSubmitButton('Submit');
form.addResetButton('Reset');
// run existing saved search
var searchResults = nlapiSearchRecord('transaction','customsearchID');
var columns = searchResults[0].getAllColumns();
// Add the search column names to the sublist field
for ( var i=0; i< columns.length; i++ )
{
sublist.addField(columns[i].getName() ,'text', columns[i].getLabel() );
nlapiLogExecution('DEBUG', 'Column Label',columns[i].getLabel());
}
//additional sublist fields
sublist.addMarkAllButtons();
sublist.addField('custfield_selected', 'checkbox', 'Selected');
sublist.setLineItemValues(searchResults)
response.writePage(form);
}
If you review the nlobjSublist docs you'll see that sublist.setLineItemValues can also take an array of hashes. What does work is:
function getJoinedName(col) {
var join = col.getJoin();
return join ? col.getName() + '__' + join : col.getName();
}
searchResults[0].getAllColumns().forEach(function(col) {
sublist.addField(getJoinedName(col), 'text', col.getLabel());
nlapiLogExecution('DEBUG', 'Column Label', col.getLabel());
});
var resolvedJoins = searchResults.map(function(sr) {
var ret = {
id: sr.getId()
};
sr.getAllColumns().forEach(function(col) {
ret[getJoinedName(col)] = sr.getText(col) || sr.getValue(col);
});
return ret;
});
sublist.setLineItemValues(resolvedJoins);
Let's say I have a data like this:
[
{ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true},
{ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false}
]
Kendo Grid is using this data:
columns.Bound(m => m.ID);
columns.ForeignKey(p => p.SomeForeignKeyID, ViewBag.ForeignKeys as IEnumerable<object>, "Value", "Name");
Here's the problem: how to make ForeignKey column editable, but only in rows, where IsFkEnabled == true? Edit mode is InCell.
Notes:
this solution works for in-cell editing only (inline or popup editing
require a different approach)
the first approach can lead to unwanted visual effects (grid
jumping) under certain circumstances; if you experience that, I
recommend approach #2
approach #2 may not work if you want to use the MVC wrappers (although it may be possible to extend Kendo.Mvc.UI.Fluent.GridEventBuilder); in that case, you'll need to bind the edit handler in JS
Approach #1
Use the grid's edit event and then do something like this:
$("#grid").kendoGrid({
dataSource: dataSource,
height: "300px",
columns: columns,
editable: true,
edit: function (e) {
var fieldName = e.container.find("input").attr("name");
// alternative (if you don't have the name attribute in your editable):
// var columnIndex = this.cellIndex(e.container);
// var fieldName = this.thead.find("th").eq(columnIndex).data("field");
if (!isEditable(fieldName, e.model)) {
this.closeCell(); // prevent editing
}
}
});
/**
* #returns {boolean} True if the column with the given field name is editable
*/
function isEditable(fieldName, model) {
if (fieldName === "SomeForeignKeyID") {
// condition for the field "SomeForeignKeyID"
// (default to true if defining property doesn't exist)
return model.hasOwnProperty("IsFkEnabled") && model.IsFkEnabled;
}
// additional checks, e.g. to only allow editing unsaved rows:
// if (!model.isNew()) { return false; }
return true; // default to editable
}
Demo here (updated for Q1 2014)
To use this via the MVC fluent syntax, simply give the anonymous edit function above a name (e.g. onEdit):
function onEdit(e) {
var fieldName = e.container.find("input").attr("name");
// alternative (if you don't have the name attribute in your editable):
// var columnIndex = this.cellIndex(e.container);
// var fieldName = this.thead.find("th").eq(columnIndex).data("field");
if (!isEditable(fieldName, e.model)) {
this.closeCell(); // prevent editing
}
}
and reference it like this:
#(Html.Kendo().Grid()
.Name("Grid")
.Events(events => events.Edit("onEdit"))
)
The disadvantage to this is that the editor gets created first before the edit event is triggered, which can sometimes have undesirable visual effects.
Approach #2
Extend the grid by overriding its editCell method with a variation that triggers a beforeEdit event; for that to work with grid options, you'll also need to override the init method:
var oEditCell = kendo.ui.Grid.fn.editCell;
var oInit = kendo.ui.Grid.fn.init;
kendo.ui.Grid = kendo.ui.Grid.extend({
init: function () {
oInit.apply(this, arguments);
if (typeof this.options.beforeEdit === "function") {
this.bind("beforeEdit", this.options.beforeEdit.bind(this));
}
},
editCell: function (cell) {
var that = this,
cell = $(cell),
column = that.columns[that.cellIndex(cell)],
model = that._modelForContainer(cell),
event = {
container: cell,
model: model,
field: column.field
};
if (model && this.trigger("beforeEdit", event)) {
// don't edit if prevented in beforeEdit
if (event.isDefaultPrevented()) return;
}
oEditCell.call(this, cell);
}
});
kendo.ui.plugin(kendo.ui.Grid);
then use it similar to #1:
$("#grid").kendoGrid({
dataSource: dataSource,
height: "300px",
columns: columns,
editable: true,
beforeEdit: function(e) {
var columnIndex = this.cellIndex(e.container);
var fieldName = this.thead.find("th").eq(columnIndex).data("field");
if (!isEditable(fieldName, e.model)) {
e.preventDefault();
}
}
});
The difference of this approach is that the editor won't get created (and focused) first. The beforeEdit method is using the same isEditable method from #1.
See a demo for this approach here.
If you want to use this approach with MVC wrappers but don't want / can't extend GridEventBuilder, you can still bind your event handler in JavaScript (place below the grid MVC initializer):
$(function() {
var grid = $("#grid").data("kendoGrid");
grid.bind("beforeEdit", onEdit.bind(grid));
});
None of these approaches worked for me. A very simple implentation looks like this
edit: function (e) {
e.container.find("input[name='Name']").each(function () { $(this).attr("disabled", "disabled") });
}
Where edit is part of the kendo grid declaration and Name is the actual name of the field.
Please try with the below code snippet.
VIEW
<script type="text/javascript">
function errorHandler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
function onGridEdit(arg) {
if (arg.container.find("input[name=IsFkEnabled]").length > 0) {
arg.container.find("input[name=IsFkEnabled]").click(function () {
if ($(this).is(":checked") == false) {
}
else {
arg.model.IsFkEnabled = true;
$("#Grid").data("kendoGrid").closeCell(arg.container);
$("#Grid").data("kendoGrid").editCell(arg.container.next());
}
});
}
if (arg.container.find("input[name=FID]").length > 0) {
if (arg.model.IsFkEnabled == false) {
$("#Grid").data("kendoGrid").closeCell(arg.container)
}
}
}
</script>
<div>
#(Html.Kendo().Grid<MvcApplication1.Models.TestModels>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.ID);
columns.Bound(p => p.Name);
columns.Bound(p => p.IsFkEnabled);
columns.ForeignKey(p => p.FID, (System.Collections.IEnumerable)ViewData["TestList"], "Value", "Text");
})
.ToolBar(toolBar => toolBar.Save())
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Events(e => e.Edit("onGridEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Events(events => events.Error("errorHandler"))
.Model(model =>
{
model.Id(p => p.ID);
model.Field(p => p.ID).Editable(false);
})
.Read(read => read.Action("ForeignKeyColumn_Read", "Home"))
.Update(update => update.Action("ForeignKeyColumn_Update", "Home"))
)
)
</div>
MODEL
namespace MvcApplication1.Models
{
public class TestModels
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsFkEnabled { get; set; }
public int FID { get; set; }
}
}
CONTROLLER
public class HomeController : Controller
{
public ActionResult Index()
{
List<SelectListItem> items = new List<SelectListItem>();
for (int i = 1; i < 6; i++)
{
SelectListItem item = new SelectListItem();
item.Text = "text" + i.ToString();
item.Value = i.ToString();
items.Add(item);
}
ViewData["TestList"] = items;
return View();
}
public ActionResult ForeignKeyColumn_Read([DataSourceRequest] DataSourceRequest request)
{
List<TestModels> models = new List<TestModels>();
for (int i = 1; i < 6; i++)
{
TestModels model = new TestModels();
model.ID = i;
model.Name = "Name" + i;
if (i % 2 == 0)
{
model.IsFkEnabled = true;
}
model.FID = i;
models.Add(model);
}
return Json(models.ToDataSourceResult(request));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ForeignKeyColumn_Update([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<TestModels> tests)
{
if (tests != null && ModelState.IsValid)
{
// Save/Update logic comes here
}
return Json(ModelState.ToDataSourceResult());
}
}
If you want to download demo then click here.
The simplest way is to use the dataBound event to conditionally apply one of the special CSS classes to the cells that the grid ignore for editing:
http://dojo.telerik.com/izOka
dataBound: function(e) {
var colIndex = 1;
var rows = this.table.find("tr:not(.k-grouping-row)");
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
var model = this.dataItem(row);
if (!model.Discontinued) {
var cell = $($(row).find("td")[colIndex]);
cell.addClass("k-group-cell");
}
}
},
Another approach is to use your own "editor" function for column definition that provides either an input element or a plain div depending on your condition.
Use Template column instead of Bound column
columns.Template(#<text></text>).ClientTemplate("#=Id#").Title("Id");