Sorry to ask such a basic question on JQuery mobile, but I am not so clear.
With a single page model (split an app into multiple pages), all scripts are loaded at the landing page. However, UI elements (e.g. buttons) may not appear until several pages deep into the clicks. Where and how do I bind event that are not yet loaded? Or how do I bind event as the pages are loaded? $(document).bind("pagecreate", function(){}) is just going to run on landing page, but I suppose I need to bind after the widgets have appeared.
I bind it like this:
$(document).bind("pagecreate", function(event, data) {
$('#btn_newuser2').on('vclick', function(event) {
// do something here.
});
});
You are safe binding event handlers for all DOM elements in the pagecreate event, if you use delegation:
$(document).on("click", "#my_button", function()
{
// handler
});
In this example the click event is binded to the whole document, but the second parameter is a selector for a child element. As stated in the docs:
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future
Related
I'm using ui.bootstrap.modal with a templateUrl. Within my template HTML, I have a "div" element that serves as a container for a third-party component (SlickGrid). When initializing my third-party component, I specify it's containing element using a jQuery selector expression. However, the selector can't seem to find my container element when executed from either within the modal's controller or within my 'opened' promise logic as resolved by modal. I believe the problem is that my dialog HTML hasn't yet been added to the DOM and thus isn't visible to the controller or 'opened' promise. I should add that the dialog itself renders just fine; it's just that I can't reference its container element from ... any context? Perhaps modal doesn't support this use-case? Any thoughts/suggestions would be appreciated!
Thanks, Garry
If i'm not mistaken your question.
You can use bs.modal.shown in your modal shown event
$(your-modal).on("bs.modal.shown",function(){});
I had this problem while using bootstrap-table inside a ui.boostrap.modal - when I initialize my modal, the selector wasn't able to find the <table> element & so couldn't be initialized itself.
The answer was to use the rendered promise, rather than opened. rendered resolves once the template has been added to the DOM, allowing you to select elements defined in the template as you would normally.
Below is a sample of how my implementation was done:
My View
<div ng-controller="MyAngularController" ng-init="init()">
<!-- The actual page content goes here - irrelevant to the example -->
<script type="text/ng-template" id="myngtemplate.html">
<table id="mygrid">
<!-- My bootstrap-table column definitions here -->
</tabie>
</script>
</div>
My JavaScript
// the below was implemented in my page's AngularJS controller,
// left out the controller implementation to make the example more consise
var modal = $uibModal.open({
animation: true,
size: 'lg',
templateUrl: 'myngtemplate.html'
});
modal.rendered.then(function () {
// $('#mygrid') could not find the table element before this
$('#mygrid').bootstrapTable({
data: getModalData()
});
});
Following is my view which contains a div in which partial views are rendered based on actions performed in the view.
//Boiler Plate HTML
<div id="PartialViewHolder">
#Html.Partial(Model.PartialView, Model)
</div>
//Boiler Plate HTML
The partial views are rendered via an ajax call which is as follows
//The url is supplied based on some actions in the main view
function AjaxCall(url){
$.ajax({
url: url,
cache: false,
success: function (html) {
$("#PartialViewHolder").empty();
$("#PartialViewHolder").html(html);
},
error: function (result) {
alert("Error: " + result.status + ": " + result.statusText);
}
});
}
The main page also loads a few other scripts which are common to the partial views. These scripts work when the page is first rendered, i.e when the default partial view is rendered. However these scripts stop working for partial views which are loaded by the ajax call. I believe that these scripts need to be reloaded when the DOM elements change. I am looking for a clean way to reload those scripts when the partial view div is reloaded.
You need to do a bit of reading about Event binding. http://api.jquery.com/on/
Tricky to understand at first but worth it once you do.
Assuming you've got some code like this.
<div class="container">
<div class="partial">
Click here to do stuff
</div>
</div>
JS Code like the example below will only work for objects present when you do the binding (usually document.ready()) It seems like this is the situation you are describing.
$(".magic-link").click(function(){
alert("Magic link clicked");
return false;
})
If you want the event to fire on objects that haven't yet been loaded onto the page then you need to bind an event handler to the container div i.e. the bit which doesn't change.
Like this
$(".container").on("click", ".magic-link", function(){
alert("Magic link clicked");
return false;
});
The event bubbles up to the event handler and fires the event. This has another advantage that one event handler and potentially handle events from hundreds of objects.
As a guideline try to bind the listener to the nearest parent object that will not change. In the case of the example this is the Container div. This keeps the bubbling to a minimum.
I have a model that has several fields and contains a list. I need a view that allows the user to input the Parent fields and then input mutlple child fields. The problem I have is that I don't know how many child objects they are going to add. I need the view to allow them to add as many child objects as they need.
I'm assuming I need a partial view for the child object, but how do I allow them to add the partial view multiple times to the page?
edit
here's what I have so far but it just renders the code in the append method as text on the screen.
$(document).ready(function () {
$("#AddProgramTrainingButton").click(function (e) {
$("#ProgramTraining").append('##{Html.RenderPartial("_ProgramTrainingDetailsCreate",new Online.Models.ProgramTrainingDetailsViewModel());}</br></br>');
e.preventDefault();
});
});
---------2nd edit
I've tried using jquery to load the partial view by calling the partial view in a controller, but this is not working either.
$(document).ready(function () {
$("#AddProgramTrainingButton").click(function (e) {
alert("button clicked!");
$('#ProgramTraining').load('#Url.Action("GetCreatePartialView","PGTController")');
return false;
});
});
// controller method
public ActionResult GetCreatePartialView()
{
return PartialView("_ProgramTrainingDetailsCreate.cshtml",new PGTProgramTrainingDetailsViewModel());
}
i needed to remove the file extention and was missing some closing characters in the jquery
Ronald, take a look to this blog post... I use it and it is perfect.
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
I got this to work. I wrapped the partial views in a div
$(document).ready(function () {
// This section is to remove a Dynamically added Training section when a button is clicked
$("#RemoveTrainingButton").live('click', function (e) {
e.preventDefault();
$(this).closest('div').remove();
});
// This section adds a Training section to the page when a button is clicked
$("#AddProgramTrainingButton").click(function (e) {
e.preventDefault();
var url = '#Url.Content("~/PGT/GetCreatePartialView")';
$.get(url, null, function (data) {
$('#ProgramTraining').append(data);
}, 'html').error(function (error) {
alert(error);
});
});
});
[HttpGet]
public ActionResult GetCreatePartialView()
{
return PartialView("_ProgramTrainingDetailsCreate",new PGTProgramTrainingDetailsViewModel());
}
I would suggest having an image / button indicating field addition, and then onclick, you can write a simple handler to insert a partial view or any other form field in the form. If you keep the Name of the inserted fields same, then they will be submitted as an array in server, from there you can parse and find out.
You can use jQuery to retrieve your partial view and insert it into the DOM of the main page. Check out the load and ajax functions. You'll need to wire up some sort of control to trigger the asynchronous load. You partial view will be returned from a controller action (different than the full view, e.g. /Controller/MyPageAction and /Controll/MySubformAction where MyPageAction is a full result and MySubformAction is a partial).
You could either rely on an explicit user action (button click), or automatically provide a new set of child fields as soon as the user starts to fill out the last available set of child fields.
I have a view, say show.js.erb. And I have a link in another view such that
link_to "MyLink", my_object_path, :remote => true
successfully returns the show.js.erb view. My question is, from within that view, is there any way to access the element that triggered the AJAX call without having to resort to generating an id specific to individual elements a la ...
I want to be able to use this view callback to open a small dialog next to whatever element was clicked on, but I can't seem to find a way to access the triggering element.
I tried using $(this) but that doesn't work.
I'd like to do something along the lines of
$(this).after("some new html here");
My solution was to bind a pre-submit class to the element, in my case a popup modal window. It's a similar solution to the post linked to above in that it uses the pre-submit bindings, but tailored to use classes instead.
In public/javascripts/application.rb:
jQuery(function($) {
$(".poppable").bind("ajax:loading", function() { $(this).addClass("popped"); });
});
Then in my view for the popup content (e.g. app/views/mymodel/popup.js.erb):
var p = $(".poppable.popped");
p.removeClass("popped");
/* Do what I need to with p ... */
If this doesn't look kosher, I'm all ears but it works for now.
http://jqueryui.com/demos/accordion/#event-changestart
I'm trying to have an JQuery ajax request get some data and populate the body of a div inside each of my JQueryUI accordion rows when the row is expanded. My intention is to have a hidden field, or some such, within the clickable h3's of the accordion and when the changestart event fires the ajax will go off and get a unique page for that accordion row and fill it with useful html.
My problem is that I can't seem to find any information about the properties or values attached to the objects returned in the changestart event function parameters. Does anyone know how to do this or get those values?
The code I have right now is this:
$("#accordion").accordion({
collapsible: true,
active: false,
changestart: function(event, ui) {
alert('hello:' + event.target.id + ':' + ui.id);
}
});
Which throws up an alert displaying the message hello:accordion:undefined
I've seen this post which seems to be along the lines of what I'm trying to figure out...
jQuery UI object type for "ui" object passed to the callback function?
Thanks,
Matt.
Looks like ui holds this:
$('.ui-accordion').bind('accordionchangestart', function(event, ui) {
ui.newHeader // jQuery object, activated header
ui.oldHeader // jQuery object, previous header
ui.newContent // jQuery object, activated content
ui.oldContent // jQuery object, previous content
});
You can access the contents of those ui.new|old elements easily.
They are jQuery elements, that is why they look a bit odd.
jQuery way
ui.newHeader.first().html()
And if you need access to the dom element use .get()
ui.newHeader.get().first()