In my GOHTML file, I am dynamically creating table rows from the results using range. Further, I want to access each row for operations like edit or delete. For example: Click on a row should open a modal with its values. But, with my current implementation the modal is appearing only on the first row. Click doesn't work on rest of the rows.
Table :
<table>
{{range .Bdata}}
<tr class="buy" id="trx_buy">
<td>{{.Sname}}</td>
<td align="center">{{.Uprice}} </td>
<td align="center">{{.Qty}} </td>
<td align="center">{{.Bfee}}</td>
<td align="center">{{.Tprice}}</td>
<td align="center">{{.Fdate}}</td>
</tr>
{{end}}
</table>
<div class="modal-content">
<span class="close">×</span>
<p>{{.Sname}}, {{.Uprice}} </p>
</div>
</div>
Script to handle onclick :
<script>
// Get the modal
var modal = document.getElementById("myModal");
var tr_buy = document.getElementById("trx_buy");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
tr_buy.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
Your problem is in var tr_buy = document.getElementById("trx_buy");. This will only give you the first matching element. You can use document.getElementsByClassName instead and add the onClick() listener to all the elements.
Related
I have a table with several columns. The first column contains a location name and the last column contains a delete button. When I click any of the delete buttons, it currently displays the confirmation message "Are you sure you want to delete the location:" I want the end of the confirmation message to display the location name.
Here are the relevant bits in my view:
#using (Ajax.BeginForm("FirstAjax", "Configuration", null, new AjaxOptions()
{
Confirm = "Are you sure you want to delete the location:\n",
HttpMethod = "POST",
OnFailure = "deleteFailed",
UpdateTargetId = "CustomLocations"
},
new { #id = "deleteLocation" }
))
{
<div id="reportTblDiv">
<table id="CustomLocations">
<tbody>
#foreach (var location in Model.LocationList)
{
<tr>
<td class="location">#location.LocationName</td>
<td>
<input type="submit" title=#Model.DeleteButton name="#location.LocationId" value="#Model.DeleteButton" />
</td>
</tr>
}
</tbody>
</table>
</div>
}
How can I access the correct element in Model.LocationList from the line beginning with Confirm?
Set the id of the first to be the same as the name as the second . Add a handle to the submit in javascript to update the confirm message:
<td id=#location.LocationId class="location">#location.LocationName</td>
<td>
<input type="submit" title=#Model.DeleteButton name="#location.LocationId" value="#Model.DeleteButton" onclick="return btnDeleteClicked(this);"/>
</td>
<script>
function btnDeleteClicked(btnObject){
var tLocation=$(btnObject).attr('name');
var tCurrentMessage=$("#deleteLocation").data('ajax-confirm');
$("#deleteLocation").data('ajax-confirm',tCurrentMessage + tLocation);
return true;
}
</script>
I have the following KendoUI template bound to an observable. When I push a new item to the observable array, how do I apply the kendoNumericTextBox to only the new item in the template?
If I apply by class, it has a strange effect of doubling the spinners on the existing numeric textboxes.
<div id="slots">
<table class="table table-striped table-condensed" style="width:auto;">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Volunteers Needed</th>
<th>
Reservation Passcode <i class="icon-question-sign" title ="Only people with the reservation passcode can signup."></i>
</th>
</tr>
</thead>
<tbody data-template="row-template" data-bind="source: slots">
</tbody>
</table>
</div>
$(document).ready(function () {
var viewModel = kendo.observable({
slots: [{DateText:'1/8/1969', ShiftLabel: "3:00 to 5:00",Slots:2,ReservationCode:"ABC" }]
});
kendo.bind($("#slots"), viewModel);
$(".numeric").kendoNumericTextBox({
format: "n0"
});
viewModel.slots.push({DateText:'1/8/1969', ShiftLabel: "3:00 to 5:00",Slots:2,ReservationCode:"ABC" });
$(".numeric").kendoNumericTextBox({
format: "n0"
});
});
Thanks for any help!
Try defining your template as:
<script type="text/x-kendo-tmpl" id="row-template">
<tr>
<td>#= DateText #</td>
<td>#= ShiftLabel #</td>
<td class="numeric"><input data-role="numerictextbox" data-format="n0" data-bind="value: Slots"></td>
<td>#= ReservationCode #</td>
</tr>
</script>
and remove the $(".numeric").kendoNumericTextBox(...) initializations. Doing this you should have a NumericTextBox each time the template is run (one per row).
Your JavaScript is like this:
$(document).ready(function () {
var viewModel = kendo.observable({
slots: [
{DateText: '1/8/1969', ShiftLabel: "3:00 to 5:00", Slots: 2, ReservationCode: "ABC" }
]
});
kendo.bind($("#slots"), viewModel);
viewModel.slots.push({DateText: '1/8/1969', ShiftLabel: "3:00 to 5:00", Slots: 3, ReservationCode: "ABC" });
});
See it running here http://jsfiddle.net/OnaBai/BV48W/
Why:
The fact that you use a CSS class (.numeric) causes you end up having a KendoUI Numeric Text Box inside the other.
Example: You have the following HTML:
<label>Number 1: <input id="number1" class="numeric"/></label>
<label>Number 2: <input id="number2" class="numeric"/></label>
And the JavaScript
$(document).ready(function () {
$(".numeric").kendoNumericTextBox({
format: "n0"
});
$(".numeric").kendoNumericTextBox({
format: "n0"
});
});
You will see what you called strange effect of doubling the spinners on the existing numeric textboxes.
Each time that you invoke kendoNumericTextBox using .numeric selector you add one extra spinner to the element. If it does not have a spinner (data just added to viewModel) it gets one but if then you add data and invoke kendoNumericTextBox using .numeric selector, that previous element gets another.
So I have a viewModel that looks like this
self.zones = ko.observableArray(zones);
ko.utils.arrayForEach(self.zones(), function (zone) {
//Get all rooms for the zone
zone.rooms = getChildren("Organization", "Organization", zone.ID);
if (zone.rooms.length > 0) {
zone.buttons = ko.observableArray([]);
//For each Room in Zone find the Buttons and add them to the Zone.buttons ObservableArray
ko.utils.arrayForEach(zone.rooms, function (room) {
room.buttons = getChildren("Organization", "ButtonAssign", room.ID, { scheduleID: self.scheduleID });
ko.utils.arrayForEach(room.buttons, function (button) {
zone.buttons.push(button);
});
});
}
So a you can see a zone has a property called buttons that is an Observable array
In my view I loop through each zone and output the buttons but one of my zones does not contain any buttons and throws this exception:
Error: Unable to parse bindings.
Message: ReferenceError: buttons is not defined;
Bindings value: foreach:buttons
<table>
<tbody>
<tr data-bind="foreach: zones" style="vertical-align: top;">
<div class="zoneDiv">
<span data-bind="text: Name"></span>
<div data-bind="foreach:buttons" class="buttonsList">
<div class="buttonField">
<div data-bind="text: Name" style="float: left; width: 140px;">
</div>
</div>
<input type="hidden" data-bind="value: ID" />
</div>
</div>
</td>
</tr>
</tbody>
</table>
So my question is: How do you check for null values in an observable array before you start looping on it?
Additionally how do you check for a null value on a single property such as button.Name so that if the button has a name Ill write it out in a div and if it does not I wont write out anything (Or a default text).
So basically null checks on viewmodel properties in the view so I wont get this exceptions
Thanks
So my question is: How do you check for null values in an observable
array before you start looping on it?
Use the if binding: http://knockoutjs.com/documentation/if-binding.html
But in the case of your code, why don't you just set an empty observableArray, that way you don't need to introduce any conditionals:
self.zones = ko.observableArray(zones);
ko.utils.arrayForEach(self.zones(), function (zone) {
zone.rooms = getChildren("Organization", "Organization", zone.ID);
zone.buttons = ko.observableArray([]);
if (zone.rooms.length > 0) {
//For each Room in Zone find the Buttons and add them to the Zone.buttons ObservableArray
ko.utils.arrayForEach(zone.rooms, function (room) {
room.buttons = getChildren("Organization", "ButtonAssign", room.ID, { scheduleID: self.scheduleID });
ko.utils.arrayForEach(room.buttons, function (button) {
zone.buttons.push(button);
});
});
}
});
I am loading a partial view in the popup using following code:
<div id="Mydiv" title="Modify" class="ModifyRule" style="overflow: hidden" />
<script type="text/javascript">
$(document).ready(function () {
//define config object
var dialogOpts = {
title: "Modify Rule",
modal: true,
autoOpen: false,
height: 300,
width: 700,
open: function () {
//display correct dialog content
$("#Mydiv").load("Modify", { SelectedRow: $('#MyParam').val() });
}
};
$("#Mydiv").dialog(dialogOpts); //end dialog
$('#Modify').click(
function () {
$("#Mydiv").dialog("open");
return false;
}
);
});
</script>
Here is the code from partial view:
#Code
Using (Html.BeginForm())
#<div id="Master">
<table>
<tr>
<td>
#Html.LabelFor(Function(model) model.InputAuthorityGridDetail.TcmAccount)
</td>
<td>#Html.EditorFor(Function(model) model.InputAuthorityGridDetail.TcmAccount)
</td>
<td>
#Html.LabelFor(Function(model) model.InputAuthorityGridDetail.Amount)
</td>
<td>#Html.EditorFor(Function(model) model.InputAuthorityGridDetail.Amount)
</td>
</tr>
<tr align="right">
<td>
<input name="button" type="submit" value="Save" class="btn" />
</td>
</tr>
</table>
</div>
End Using
End Code
the controller method modify returns a partial view named _Modify, the view is rendered correctly in the popup but I notice that the CSS styles are not applied to the controls in the partial view can someone help me?
When a partial is loaded into a layout page, the layout page contain the reference to the css that is used by the partial view.
However, from what I gather here (my javascript is not that great), you are loading the partial directly into a popup display and not using the layout page? If this is correct then your partial will not know about the css. And to correct this you would need to add a reference to the css at the top of the partial.
My partial views dont start with #Code and dont end with End Code. Try removing them and see if it works then.
I used bootstrap-tabs.js and it has worked perfectly.
But I didn't find information about how to load content through AJAX request.
So, how to use AJAX loading with bootstrap-tabs.js?
In Bootstrap 2.0 and up you have to bind to the 'show' event instead.
Here's an example HTML and JavaScript:
<div class="tabbable">
<ul class="nav nav-tabs" id="myTabs">
<li>Home</li>
<li>Foo</li>
<li><a href="#bar" data-toggle="tab">Bar</li>
</ul>
<div>
<div class="tab-pane active" id="home"></div>
<div class="tab-pane" id="foo"></div>
<div class="tab-pane" id="bar"></div>
</div>
</div>
JavaScript:
$(function() {
var baseURL = 'http://yourdomain.com/ajax/';
//load content for first tab and initialize
$('#home').load(baseURL+'home', function() {
$('#myTab').tab(); //initialize tabs
});
$('#myTab').bind('show', function(e) {
var pattern=/#.+/gi //use regex to get anchor(==selector)
var contentID = e.target.toString().match(pattern)[0]; //get anchor
//load content for selected tab
$(contentID).load(baseURL+contentID.replace('#',''), function(){
$('#myTab').tab(); //reinitialize tabs
});
});
});
I wrote a post about it here: http://www.mightywebdeveloper.com/coding/bootstrap-2-tabs-jquery-ajax-load-content/
You can listen the change event and ajax load content in the event handler
$('.tabs').bind('change', function (e) {
var now_tab = e.target // activated tab
// get the div's id
var divid = $(now_tab).attr('href').substr(1);
$.getJSON('xxx.php').success(function(data){
$("#"+divid).text(data.msg);
});
})
I wanted to load fully dynamic php pages into the tabs through Ajax.
For example, I wanted to have $_GET values in the links, based on which tab it was - this is useful if your tabs are dynamic, based on database data for example.
Couldn't find anything that worked with it but I did manage to write some jQuery that actually works and does what I'm looking for.
I'm a complete jQuery noob but here's how I did it.
I created a new 'data-toggle' option called tabajax (instead of just tab), this allows me to seperate what's ajax and what's static content.
I created a jQuery snippet that runs based on that data-toggle, it doesn't mess with the original code.
I can now load say url.php?value=x into my Bootstrap Tabs.
Feel free to use it if you want to, code is below
jQuery code:
$('[data-toggle="tabajax"]').click(function(e) {
e.preventDefault()
var loadurl = $(this).attr('href')
var targ = $(this).attr('data-target')
$.get(loadurl, function(data) {
$(targ).html(data)
});
$(this).tab('show')
});
HTML:
<li>Val 1</li>
So here you can see that I've changed the way bootstrap loads thing, I use the href for the dynamic ajaxlink and then add a 'data-target' value to the link instead, that should be your target div (tab-content).
So in your tab content section, you should then create an empty div called val1 for this example.
Empty Div (target):
<div class='tab-pane' id='val1'><!-- Ajax content will be loaded here--></div>
Hope this is useful to someone :)
I suggest to put the uri into the tab-pane elements, it allows to take advantage of web frameworks reverse url fonctionnalities. It also allows to depend exclusively on the markup
<ul class="nav nav-tabs" id="ajax_tabs">
<li class="active"><a data-toggle="tab" href="#ajax_login">Login</a></li>
<li><a data-toggle="tab" href="#ajax_registration">Registration</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="ajax_login"
data-target="{% url common.views.ajax_login %}"></div>
<div class="tab-pane" id="ajax_registration"
data-target="{% url common.views.ajax_registration %}"></div>
</div>
And here is the javascript
function show_tab(tab) {
if (!tab.html()) {
tab.load(tab.attr('data-target'));
}
}
function init_tabs() {
show_tab($('.tab-pane.active'));
$('a[data-toggle="tab"]').on('show', function(e) {
tab = $('#' + $(e.target).attr('href').substr(1));
show_tab(tab);
});
}
$(function () {
init_tabs();
});
I loads the active tab, and loads a tab only if it is not already loaded
There is an error in your code user1177811.
It has to be $('[data-toggle="tabajax"]').
Also there is room for improvement. The .load() method, unlike $.get(), allows us to specify a portion of the remote document to be inserted. So i added #content to load the content div of the remote page.
$this.tab('show'); is now only called, when response was a success.
Here is the code
$('[data-toggle="tabajax"]').click(function(e) {
e.preventDefault();
$this = $(this);
var loadurl = $(this).attr('href');
var targ = $(this).attr('data-target');
$(targ).load(loadurl+'?ajax=true #content', function(){
$this.tab('show');
});
});
Here is how I do it. I utilize an attribute data-href which holds the url I want to load on show. This will not reload data that is already loaded unless you set $('#tab').data('loaded'); to 0 or remove it. It also handles relative vs. absolute urls by detecting the location of the first slash. I am not sure of the compatibility with all browsers but it works in our situation and allows for the functionality we are looking for.
Javascript:
//Ajax tabs
$('.nav-tabs a[data-href][data-toggle="tab"]').on('show', function(e) {
var $this = $(this);
if ($this.data('loaded') != 1)
{
var firstSlash = $this.attr('data-href').indexOf('/');
var url = '';
if (firstSlash !== 0)
url = window.location.href + '/' + $this.attr('data-href');
else
url = $this.attr('data-href');
//Load the page
$($this.attr('href')).load(url, function(data) {
$this.data('loaded', 1);
});
}
});
HTML:
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active">
Tab 1
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="js-tab1">
<p>
This content isn't used, but instead replaced with contents of tab1.php.
</p>
<p>
You can put a loader image in here if you want
</p>
</div>
</div>
</div>
Here is a solution I have found - and modified to suit my needs:
$("#tabletabs").tab(); // initialize tabs
$("#tabletabs").bind("show", function(e) {
var contentID = $(e.target).attr("data-target");
var contentURL = $(e.target).attr("href");
if (typeof(contentURL) != 'undefined') { // Check if URL exists
$(contentID).load(contentURL, function(){
$("#tabletabs").tab(); // reinitialize tabs
});
} else {
$(contentID).tab('show');
}
});
$('#tabletabs a:first').tab("show"); // Load and display content for first tab
});
This is an MVC example using Razor. It will interact with two partial views named: _SearchTab.cshtml and _SubmissionTab.cshtml
Notice that I am naming the id of the tabs the same as the partials.
Markup:
<!-- Nav tabs -->
<ul id="tabstrip" class="nav nav-tabs" role="tablist">
<li class="active">Submission</li>
<li>Search</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane fade in active" id="_SubmissionTab">#Html.Partial("_SubmissionTab")</div>
<div class="tab-pane fade" id="_SearchTab"></div>
</div>
The #Html.Partial will request the page on the active tab on page load
Script:
<script>
$('#tabstrip a').click(function (e) {
e.preventDefault()
var tabID = $(this).attr("href").substr(1);
$("#" + tabID).load("/#ViewContext.RouteData.Values["controller"]/" + tabID)
$(this).tab('show')
})
</script>
The load function will perform an ajax request as each tab is clicked. As for what path is requested you will notice a #ViewContext.RouteData.Values["controller"] call. It simply gets the controller of the current view assuming the partial views are located there.
Controller:
public ActionResult _SubmissionTab()
{
return PartialView();
}
public ActionResult _SearchTab()
{
return PartialView();
}
The controller is needed to relay the load request to the proper partial view.
Here is the Bootstrap tab Ajax example, you can use it...
<ul class="nav nav-tabs tabs-up" id="friends">
<li> Contacts </li>
<li> Friends list</li>
<li>Awaiting request</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="contacts">
</div>
<div class="tab-pane" id="friends_list">
</div>
<div class="tab-pane urlbox span8" id="awaiting_request">
</div>
</div>
and here is the AJAX call
$('[data-toggle="tabajax"]').click(function(e) {
var $this = $(this),
loadurl = $this.attr('href'),
targ = $this.attr('data-target');
$.get(loadurl, function(data) {
$(targ).html(data);
});
$this.tab('show');
return false;
});
I use this function and it's really nice because she prevent's you from load ajax again when going back to that tab.
Tip: on tab href, just put the destination. Add this to footer:
$("#templates_tabs").tabs({
beforeLoad: function( event, ui ) {
if (ui.tab.data("loaded")) {
event.preventDefault();
return;
}
ui.ajaxSettings.cache = false,
ui.jqXHR.success(function() {
ui.tab.data( "loaded", true );
}),
ui.jqXHR.error(function () {
ui.panel.html(
"Not possible to load. Are you connected?");
});
}
});