Dynamically add Select2 to Row - javascript

why when i try to add select2 to new row the new select2 failed to initialize (it shown as select html tag).
Here's my code to create the table :
<table id="tbldet" class="table table-bordered table-striped table-hover" style="width:100%;margin:0 auto;">
<thead>
<tr>
<th><p>Nama Barang</p></th>
<th><p>Harga</p></th>
<th><p>Qty</p></th>
<th><p>Total</p></th>
<th style="width:50px"><p>Aksi</p></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select class="select2" name="det_brg" style="width:100%;">
</select>
</td>
<td>10000</td>
<td>4</td>
<td>930000</td>
<td><span class="btn btn-danger"><i class="fa fa-remove"></i></span></td>
</tr>
</tbody>
</table>
javascript function to initializeSelect :
function initializeSelect2(selectElementObj) {
selectElementObj.select2({
width: "80%",
tags: true,
language:"id",
ajax: {
url: "controller/barang_list.php",
dataType: "json",
type:"GET",
delay: 250,
data: function (params) {
return {
search: params.term
}
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
id:item.id,
text:item.text
}
})
};
},
cache: false
},
minimumInputLength: 3,
dropdownParent:$("#form-data")
});
};
$(".select2").each(function() {
initializeSelect2($(this));
});
here's the code to add new row :
//create new row
$("#add_row").click(function(e) {
//new row
$("#tbldet").append(
'<tr>\
<td>\
<select class="select2" name="det_brg" style="width:100%;">\
</select>\
</td>\
<td>10000</td>\
<td>4</td>\
<td>930000</td>\
<td><span class="btn btn-danger"><i class="fa fa-remove"></i></span></td>\
</tr>'
);
var newSelect=$(this).closest("tr").find(".select2");
initializeSelect2(newSelect);
})
i suspect there's problem with finding new 'select2' component on new row, but when i use alert(newSelect) it didn't show NULL / Undefined

Your suspicion is correct, your code will never find the new .select2 element. The reason has to do with the way .closest() works. You can investigate that here:
https://api.jquery.com/closest/
But in the mean time:
Change
var newSelect=$(this).closest("tr").find(".select2");
TO
var newSelect=$("#tbldet").find(".select2").last();

Related

Adding delete button to bootstrapTable in MVC

I have a .Net MVC project that fills a table with data using a bootstrapTable from bootstrap v3. I want to add a delete button to each row.
The bootstrapTable takes json data and loads it. The json is built like this:
public virtual JsonResult Search(FormCollection searchArgument)
{
IEnumerable<MyData> myListData = GetMyListData(searchArgument);
var jsonResult = Json(myListData, JsonRequestBehavior.AllowGet);
return jsonResult;
}
So the jsonResult is just a list of all of my MyData. My view that shows the result looks like this:
#model MyNamespace.Web.Models.MyListViewModel
<div class="col-md-12">
#{
ViewBag.Title = "Index";
Layout = MVC.Shared.Views._Layout;
<div class="row">
<div class="col-md-12">
<form role="form" id="formsearch">
<input id="fromsearch" name="fromsearch" type="hidden" value="true" />
<div class="form-group">
#Html.LabelFor(m => m.Status, "Status:")<br />
#Html.DropDownList("status", new SelectList(Model.Status, "Value", "Key", Model.SelectedStatus), new { #class = "selectButton" })
</div>
<input type="button" id="btnsearch" value="Search" />
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
</tr>
</thead>
</table>
</div>
</div>
}
</div>
<script>
$("#btnsearch").click(function () {
$('#table').bootstrapTable('showLoading');
$.ajax({
type: "POST",
url: "#Url.Action(MVC.MyController.ActionNames.Search, MVC.MyController.Name)",
data: $('#formsearch').serialize(),
dataType: "json",
success: function (data) {
$('#table').bootstrapTable('hideLoading');
$('#table').bootstrapTable({
data: data,
striped: true,
pagination: true,
pageSize: 25,
pageList: [10, 25, 50, 100, 200],
search: false
});
$('#table').bootstrapTable('load', data).on('click-row.bs.table', function (e, row, $element) {
Showdetail(JSON.stringify(row));
});
},
error: function (err) {
console.log(err)
}
});
});
function Showdetail(jsonrow) {
var obj = JSON.parse(jsonrow);
window.location = "#Url.Action(MVC.MyController.ActionNames.ShowMyData, MVC.MyData.Name)?myDataId=" + obj.Id;
}
</script>
#section AddToHead
{
#Styles.Render("~/bundles/bootstrap-table/css")
}
#section scripts
{
#Scripts.Render("~/bundles/bootstrap-table")
}
So the javascript function ("#btnsearch").click gets the json data from public virtual JsonResult Search and sends that to bootstrapTable which loads the data in the table. What I want to do is to add a new header in my table, like this:
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
<th></th>
</tr>
</thead>
</table>
And then in the last column add a delete button that has the id of that row (#Model.Id for instance) so that I can call the controller to delete the row from the database and then reload the table so that the row also disappears from the GUI.
I could easily do it with an ActionLink but since I don't loop through all objects and then draw them out on the page, I can't just add an ActionLink to the page. All the rendering of the rows is done in the bootstrapTable.
I looked at this question and answer and it seemed promising but it's not quite what I'm doing and I can't get my head around what I would need to do to get it working for me: Bootstrap table - dynamic button in row.
According to documantation and examples here:
https://live.bootstrap-table.com/example/column-options/events.html
Add to your scripts:
<script>
var $table = $('#table')
function operateFormatter(value, row, index) {
return [
'<a class="remove" href="javascript:void(0)" title="Remove">',
'<i class="fa fa-trash"></i> Delete',
'</a>'
].join('')
}
window.operateEvents = {
'click .remove': function (e, value, row, index) {
//edit here for ajax request to delete row.id record
$.ajax({
type: "POST",
url: "#Url.Action(MVC.MyController.ActionNames.Delete,MVC.MyController.Name)",
data: {id:row.id},
dataType: "json",
success: function (data) {
//when success remove row
$table.bootstrapTable('remove', {
field: 'id',
values: [row.id]
})
},
error: function (err) {
console.log(err)
}
});
}
}
</script>
and edit your html table:
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
<th data-field="operate" data-formatter="operateFormatter" data-events="operateEvents">Actions</th> <!--add this col-->
</tr>
</thead>
</table>

Adding to List<Model> using JQuery

I have a ViewModel with a parameter List. In the View, the user should be able to add or remove from that list such that the added or removed users are reflected in the POST for that parameter. In JQuery, after clicking an "Add" button, an ajax call returns a UserModel variable, but a simple .append doesn't add to the list.
The other questions I've seen on this issue deal with Partial Views, but this situation updates the table of UserModel without needing a Partial View. It seems like there should be an easy way to do this. Does anyone know how to add the returned UserModel to the List in JQuery so that the List will be returned to the Post with the added models?
<script>
$("#bUser").on('click', function () {
var $addedRecipient = $("#AddedRecipient");
if ($addedRecipient.val() != null && $addedRecipient.val() != "") {
$.ajax({
type: "GET",
url: '#Url.Action("GetFullRecipient", "Message")',
data: { CompanyID: $("#CompanyID").val(), Employee: $addedRecipient.val() },
success: function (data) {
$("#Recipients").append(data);//Not adding to Recipients (Model.List<UserModel>) - is there a simple solution like this?
var bRow = $('<tr></tr>'),
bCell = $('<td style="display:none"></td>').append(data.UserID);
bRow.append(bCell);
bCell = $('<td align="center"></td>').append(data.UserFirstName);
bRow.append(bCell);
bCell = $('<td align="center"></td>').append(data.UserEmail);
bRow.append(bCell);
bCell = $('<td align="center"><input type="button" class="btn btn-info removeRecipient" value="Remove"></td>');
bRow.append(bCell);
$("#bTable tbody").append(bRow);//Works with returned data
$addedRecipient.val("");
},
error: function () {
alert("Recipient could not be added.");
}
});
}
});
</script>
this code worked perfect for me, you just have to go through this list, obviously you have to put the #model directive and a type list Recipient.
#model List<...Models.Recipient>
<input type="button" id="btnAdd" class="btn btn-primary" value="Add"
onclick="myfunction()"/>
<script>
function myfunction() {
$.ajax({
type: 'GET',
contentType:"application/json; charset=utf-8",
url: '#Url.Action("GetFullRecipient","Message")',
data: { CompanyID: $("#CompanyID").val(), Employee:
$addedRecipient.val()},
success: function (response) {
$("#containerData").html(response);
},
error: function (result) {
alert(result);
}
});
}
</script>
<div id="containerData">
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Desc_Prod</th>
<th>Cantidad</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
foreach (var item in Model)
{
<tr>
<td>#item.UserID</td>
<td>#item.UserFirstName</td>
<td>#item.UserEmail</td>
<td><a class="btn btn-danger" href="#Url.Action("DeleteRow","Message", new {item.UserID})">Delete</a></td>
</tr>
}
}
</tbody>
</table>
</div>
The answer here followed the link in freedomn-m's comment. Iterate through the Razor table using a for loop, then use a HiddenFor with the model parameter's ID and a CheckBoxFor as the model parameter's selecting field, and have a submit button with a unique name and value. When a button input is clicked and the value fits a given string, loop through the model and add a user that's not there or subtract a user that is there and return to the View.
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered" id="bTable">
<thead>
<tr>
<th style="display:none"></th>
<th style="display:none"></th>
<th class="text-center">Recipient</th>
<th class="text-center">E-mail</th>
<th class="text-center">Select</th>
</tr>
</thead>
<tbody>
#if (Model.Recipients.Any())
{
for (var i = 0; i < Model.Recipients.Count; i++)
{
<tr>
<td style="display:none">#Html.HiddenFor(m => m.Recipients[i].RecipientUserID)</td>
<td style="display:none">#Html.HiddenFor(m => m.Recipients[i].RecipientCorporateID)</td>
<td align="center">#Model.Recipients[i].RecipientName</td>
<td align="center">#Model.Recipients[i].RecipientEmail</td>
<td align="center">#Html.CheckBoxFor(m => m.Recipients[i].RemoveRecipient)</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>

How to set className for selected child component in ReactJS

New to ReactJs - I have had a look at the documentation here and here but I am a bit confused.
So I have a component that creates several table rows according to the JSON data.
I am trying to make it so once a radio button is selected, the class of the parent <td> is set to 'success'. But at the moment all the rows with that column get the same class name.
var SearchResult = React.createClass({
getInitialState: function () {
return {
site: '',
address: '',
data: [],
checked: ''
};
},
onSiteChanged: function (e) {
this.setState({
site: e.currentTarget.value,
checked: 'success'
});
},
render: function () {
var resultRows = this.props.data.map(function (result) {
return (
<tr>
<td className={this.state.checked}>
<input type="radio" name="site_name"
value={result.SITE_NAME}
onChange={this.onSiteChanged}
key={result.id}/>{result.SITE_NAME}</td>
<td>
<input type="radio" name="address"
value={result.ADDRESS}
onChange={this.onAddressChanged} />{result.ADDRESS}</td>
</tr>
);
}, this);
return (
<table className="table table-hover table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{resultRows}
</tbody>
<tfoot>
<tr>
<td></td>
<td>{this.state.site}</td>
<td>{this.state.address}</td>
</tr>
</tfoot>
</table>
);
}
});
What is the best ReactJS way to proceed to make sure the selected result get the selected class name?
Thank you.
To modify values passed to classSet property React has special addon: React.addons.classSet. It is very handy when you are changing multiple different classes but in your case it can be usefull, too:
var SearchResult = React.createClass({
getInitialState: function () {
return {
site: '',
address: '',
checked: false,
data: [],
};
},
onSiteChanged: function (selected) {
this.setState({
site: selected.SITE_NAME,
checked: selected.id,
});
},
render: function () {
var resultRows = this.props.data.map(function (result) {
var cx = React.addons.classSet({
success: (this.state.checked === result.id)
});
return (
<tr key={result.id}>
<td className={cx}>
<input type="radio" name="site_name"
value={result.SITE_NAME}
onChange={this.onSiteChanged.bind(this, result)}
/>{result.SITE_NAME}</td>
<td>
<input type="radio" name="address"
value={result.ADDRESS}
onChange={this.onAddressChanged} />{result.ADDRESS}</td>
</tr>
);
}, this);
return (
<table className="table table-hover table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{resultRows}
</tbody>
<tfoot>
<tr>
<td></td>
<td>{this.state.site}</td>
<td>{this.state.address}</td>
</tr>
</tfoot>
</table>
);
}
});

Multiple auto-refresh data bindings in one page using knockout

One data binding works well and display automatic data but when I add another copying the same pattern of first, second gives error and do not work. So in below example if I do comment anyone, another do not work.
HTML CODE:
<table>
<thead>
<tr><th>Item Name</th><th>Price</th></tr>
</thead>
<tbody data-bind="foreach: itemsdisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
</tr>
</tbody>
</table>
<table>
<thead>
<tr><th colspan="3" style="color:#06C">Stock Market Metal Rates</th></tr>
</thead>
<tbody data-bind="foreach: MetalDisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
<td data-bind="text: Dated" />
</tr>
</tbody>
</table>
This is my JS code:
function GetProducts(handleData) {
$.ajax({
url: 'form.php',
type: "post",
data: '',
dataType: 'json',
success: function(data){
handleData(data);
},
error:function(data){
alert('Failed');
}
});
}
function GetMetals(handleData) {
$.ajax({
url: 'form2.php',
type: "post",
data: '',
dataType: 'json',
success: function(data){
handleData(data);
},
error:function(data){
alert('Failed');
}
});
}
$(function () {
var ItemDisplayViewModel = function() {
var self = this;
self.itemsdisplay = ko.observableArray();
self.update = function() {
GetProducts(function(output){
self.itemsdisplay.removeAll();
$.each(output, function (i) {
self.itemsdisplay.push(new product(output[i]));
});
});
}
};
var MetalViewModel = function() {
var self = this;
self.MetalDisplay = ko.observableArray();
self.update = function() {
GetMetals(function(output){
self.MetalDisplay.removeAll();
$.each(output, function (i) {
self.MetalDisplay.push(new metals(output[i]));
});
});
}
};
var ItemDisplayViewModel = new ItemDisplayViewModel();
window.setInterval(ItemDisplayViewModel.update,1000);
ko.applyBindings(ItemDisplayViewModel);
var MetalViewModel = new MetalViewModel();
window.setInterval(MetalViewModel.update,1000);
ko.applyBindings(MetalViewModel);
});
var product = function (data) {
return {
Name: ko.observable(data.Name),
Price: ko.observable(data.Price)
};
};
var metals = function (data) {
return {
Name: ko.observable(data.Name),
Price: ko.observable(data.Price),
Dated: ko.observable(data.Dated)
};
};
Can anyone help please!
You can do the following.
Provide id for both the tables
<table id="item">
<thead>
<tr><th>Item Name</th><th>Price</th></tr>
</thead>
<tbody data-bind="foreach: itemsdisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
</tr>
</tbody>
</table>
<table id="metal">
<thead>
<tr><th colspan="3" style="color:#06C">Stock Market Metal Rates</th></tr>
</thead>
<tbody data-bind="foreach: MetalDisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
<td data-bind="text: Dated" />
</tr>
</tbody>
</table>
The modify your script to pass the table element to ko.applyBindings method as below.
var itemDisplayViewModel = new ItemDisplayViewModel();
var x = window.setInterval(itemDisplayViewModel.update,1000);
ko.applyBindings(itemDisplayViewModel,document.getElementById("item"));
var metalViewModel = new MetalViewModel();
var y = window.setInterval(metalViewModel.update,1000);
ko.applyBindings(metalViewModel, document.getElementById("metal"));
Please refer 'Activating knockout' section in http://knockoutjs.com/documentation/observables.html - The part of text from the link given below.
For example, ko.applyBindings(myViewModel, document.getElementById('someElementId')). This restricts the activation to the element with ID someElementId and its descendants, which is useful if you want to have multiple view models and associate each with a different region of the page.
What you are doing does not work. you need to do it like this.
ko.applyBindings(ItemDisplayViewModel,document.getElementById('first_div_id'));
ko.applyBindings(MetalViewModel,document.getElementById('second_div_id'));
Or here is another method
var viewModel = function(){
var self = this
self.Item = ko.observable(new ItemDisplayViewModel())
self.Metal = ko.observable(new MetalViewModel())
}
ko.applyBindings(viewModel)
And now
<table data-bind="with:Item">
.
.
.
</table>
<table data-bind="with:Metal">
.
.
.
</table>
And finally
window.setInterval(viewModel.Item().update, 1000);
window.setInterval(viewModel.Metal().update, 1000);
You can take a look at this post for better understanding.

I'm using jquery's $.Ajax method to pull json data but it won't render it to the page

I can get part of the data to render to the page (specifically: request, ack, and return_info) however it will not render my user data (user_id, name, session_token, photo_url). I need all user data stored to render in a table.
$(document).ready(function () {
$.ajax({
url: "http://url/getaccount",
type: 'GET',
dataType: "json",
data: {
'account': 'all'
},
}).then(function (data) {
$('.request').append(data.request);
$('.ack').append(data.ack);
$('.return_info').append(data.return_info);
$('user_id').append(data.user_id);
$('.name').append(data.name);
$('.session_token').append(data.session_token);
$('.photo_url').append(data.photo_url);
});
console.log();
});
Html
<table class="table table-striped">
<tr>
<td><b>User</b>
</td>
<td><b>Turbo User ID</b>
</td>
<td><b>Name</b>
</td>
<td><b>Session Token<b></td>
<td><b>Request</b>
</td>
<td><b>Ack</b>
</td>
<td><b>Return Info<b></td>
</tr>
<tr>
<td class="photo_url"></td>
<td class="user_id"></td>
<td class="name"></td>
<td class="session_token"></td>
<td class="request"></td>
<td class="ack"></td>
<td class="return_info"></td>
</tr>
</table>
I will be using this for several hundred users. I am not sure if I will need a for loop of not. Thank you!
<table id="myTable" class="table table-striped">
<thead>
<tr>
<th><b>User</b></th>
<th><b>Turbo User ID</b>
</th>
<th><b>Name</b>
</th>
<th><b>Session Token<b></th>
<th><b>Request</b>
</th>
<th><b>Ack</b> </th>
<th><b>Return Info<b></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
$(document).ready(function () {
$.ajax({
url: "http://url/getaccount",
type: 'GET',
dataType: "json",
data: {
'account': 'all'
},
}).then(function (data) {
for(var i = 0; i < data.accounts.length; i++){
$('#myTable tbody').append("<tr>");
$('#myTable tbody').append("<td class=\"photo_url\">" + data.accounts[i].photo_url + "</td>");
$('#myTable tbody').append("<td class=\"user_id\">" + data.accounts[i].user_id + "</td>");
//etc...
$('#myTable tbody').append("</tr>");
}
});
console.log();
});

Categories