Pass data-attr in Materialize's modal (leanModal) - javascript

I am using Materialize framework in my rails app. I have this element that launch a modal on click:
<div data-target="modal1" class="modal-trigger" data-code="<%=code%>">lalala</div>
I want to catch the data-code in js and save it to variable. I've done something like this following the official documentation:
$('.modal-trigger').leanModal({
ready: function() {
var a = $(this).attr("data-code");
},
}
The variable "a" is undefined. How I can pass data-attr in Materialize modal? What is the best way? Thanks.
Update: I'd like to then display the value of data-code in the modal. This is the code:
<div id="modal1" class="modal bottom-sheet">
<div class="modal-content">
<p>The Code</p>
</div>
</div>
Update1: I eventually solved it with clickOn method and append the data attr to a particular div but wondering if it is possible to pass it also through modal.

Related

How to adjust this jQuery code to target div?

I have a reusable modal code that I use to easily load multiple modals. The problem I ran into was I had the div I use to display my errors set using an id. when I tried displaying errors in the second modal, obviously it didn't work because you can't have more than one element with the same id.
I would like to adjust my jQuery code in that erases any errors when the modal window opens.
Here is my code for the modals.
function loadModal($modalNum, $modalTitle, $modalFile) {
echo '<!-- The Modal -->
<div id="'.$modalNum.'" class="modal">
<!-- Modal content -->
<div class="modalContent">
<div class="modalHeader">
<span class="close">×</span>
<h2>'.$modalTitle.'</h2>
</div>
<div class="modalBody">
<!-- Error section -->
<div class="errors"></div>
<!-- include form to show -->';
include($modalFile);
echo ' </div>
</div>
</div>';
}
The piece of above code that I'm targeting.
<!-- Error section -->
<div class="errors"></div>
Here is my script that loads the window.
$('.openModal').on('click', function(){
$('#'+$(this).data('modal')).css('display','block');
$("#form")[0].reset();
while ($('.errors').firstChild) {
$('.errors').removeChild($('.errors').firstChild);
}
})
Here is the portion of code that I cannot figure out.
while ($('.errors').firstChild) {
$('.errors').removeChild($('.errors').firstChild);
}
Prior to changing it to try and read a class it looked like this. This was also when my html for the modal had the div as an id <div id='errors'></div>.
while (errors.firstChild) {
errors.removeChild(errors.firstChild);
}
How can I change this section of code to target my error div using the class
?
You can either scope your search or find the element inside the modal, both will return the same element. Also, the empty method is more convenient. And you can use the same approach for your other elements too, like the form you are targeting:
$('.openModal').on('click', function(){
targetModal = $('#'+$(this).data('modal'));
$("#form")[0].reset();
// Both are equivalent
errors = $(".errors", targetModal);
errors = targetModal.find(".errors");
errors.empty();
targetModal.css('display','block');
});

Javascript modal that displays list that closes and returns to main html

Rather new to javascript, jquery and bootstrap, etc., so bear with me. I have a situation where I want to present a list of errors in a model dialog after the user hits a "validate" button. Got all the working - I am generating a list of objects that indicate to the user they need more work to the exact spot that needs additional data entry. I have the the DIV "id" that represents the field that needs more data (and each item will jump someplace different).I do not want a drop down list since there are be lots and lots of these items.
A few questions:
How do I go about jumping from the modal to the main html. I believe I have seen scrollIntoView mentioned in a few other posts as I was looking but will that hop to the DIV and also close the modal?
What construct should I use for the list? A list of scrolling button? The size of this can be quite large (hundreds) so it will need a scroll capability.
Finally, the app is "paged" with a next and prev buttons. I assume that will not be a problem from the aspect of jumping to a page not already displayed?
Here is the current modal code:
<script id="template-validation-error" type="text/x-handlebars-template">
<div id="validationErrorModal" class="modal">
<div class="message-container">
<div class="header">
Validation Errors
</div>
<div class="message">
The following fields are required:
</div>
<div class="center">
<input type="button" class="btn btn-solid-green btn-sm" onclick="fffdevice.validationErrorOk();" value="Done" />
</div>
</div>
</div>
</script>
and
showValidationError: function (fieldlist) {
settings.focusedField = $(':focus');
$("#validationErrorModal").detach();
$(".device-container").append(templates.validationerror({ fieldlist }));
$(".message-container input").focus();
},
validationErrorOk: function () {
$("#validationErrorModal").detach();
if (settings.focusedField) {
settings.focusedField.focus();
}
},
The field list is a list of objects that contain the id (field.id) of the DIV and also a description (field.fieldName) that I want to display.
Here is something I mocked up in paint...I am not sold on it but it show in a general sense what I am looking for:
I don't need a full solution rather, just want mechanisms I can use.
UPDATE
Just to help out anyone else in the future, using the info provided in the correct answer below I have a new code as follows:
<script id="template-validation-error" type="text/x-handlebars-template">
<div id="validationErrorModal" class="modal">
<div class="validation-container">
<div class="header" align="center">
Validation Errors
</div>
<div class="message">
<div class="scrolling-container" style="background-color: rgb(238, 238, 238); height:660px">
<div class="grid grid-pad">
{{#each fieldlist}}
<div class="row click-row" onclick="fffdevice.validationErrorFix('{{id}}');">
<div class="col-7-8 field-name">{{fieldName}}</div>
<div class="col-1-8">
<img class="pull-right" src="/mysite/Content/device/images/fix.png" style="width: 40px; position:relative; top: -5px;">
</div>
</div>
{{/each}}
</div>
</div>
</div>
<div><br/></div>
<div class="center">
<input type="button" class="btn btn-solid-green btn-sm" onclick="fffdevice.validationErrorOk();" value="Done" />
</div>
</div>
</div>
Then the Javascript for the onClick is:
validationErrorFix: function (id) {
$("#validationErrorModal").detach();
var x = document.getElementById(id);
x.scrollIntoView({
behavior: "smooth", // or "auto" or "instant"
block: "start" // or "end"
});
},
Which closes the dialog and jumps to the field. It looks like (I know this is ugly and I will clean it up later):
Bind the modal event to the validation code and show the modal if error(s) are found.
Display the modal with the list of errors using an html unordered list, inside the li element an anchor tag where the href attribute will have a value with the id that corresponds to the input field, all this done dynamically from your validation code.
Once an error in the list is clicked hide the modal using bootstrap $('#your-error-modal').modal('hide'); so the code would be something like this:
$('#your-error-modal').on('click', 'a.error-item', function(){
$('#your-error-modal').modal('hide');
});
I haven't tested this code, but if you're having issues with scrolling to the section of the input and closing the modal you can probably do something like this too:
$('#your-error-modal').on('click', 'a.error-item', function(e){ // use this method of onclick because your list will be created dynamically
e.preventDefault(); // prevent the default anchor tag action
var href = $(this).attr('href'); // grab the href value
$('#your-error-modal').modal('hide'); // close the modal first
scrollToDiv(href); // then take the user to the div with error with a nice smooth scroll animation
});
function scrollToDiv(location) {
$('html, body').animate({
scrollTop: $(location).offset().top
}, 2000);
}
Again this is untested code, but the idea is there.
For UX reasons you might also want to create a floating div or something where users can click on it and go back to the modal to continue reading your list of errors.

Is it possible for me to make my controller return data for my modal window? MVC5 ASP.NET

Im busy making my ASP.NET web-app.
I will start with explaining the flow of my application.
User submits form
Form data gets posted to controller
Controller generates table with numbers in it using tagbuilder, returning it as mvcHtmlString.
Every number in this table is surrounded by an anchor tag (a).
When this number is clicked i want to open a modal window that shows data relevant to the number being clicked.
Clicking this number currently has an url.action as href so it jumps into my controller, passing the number to the controller.
Showing the modal is not a problem since i can just pass a data-toggle and a data-target into my anchor tag, but i want to show data that the controller returns in it's body.
What i am currently doing is in my view which contains the form i do
#{Html.RenderPartial("_Details");}
_Details contains the whole modal code:
<div class="modal fade" id="competenceModal" tabindex="-1" role="dialog" aria-labelledby="competenceModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>Competence details</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
My anchor tag being returned to the view containg the form:
UrlHelper url = new UrlHelper(HttpContext.Request.RequestContext);
var url2 = url.Action("LevelDetails", "Knowledge", new { level = level.Value });
var anchor = new TagBuilder("a");
anchor.Attributes.Add("href", url2);
anchor.Attributes.Add("data-target", "#competenceModal");
anchor.Attributes.Add("data-toggle", "modal");
This is correctly acessing my controller, but my big question is:
Is it possible to make the controller return data, such as a mvcHtmlString or any other content and put it in the body of my modal window? If so, what would be the best way to do so?
I would like to suggest you following things,
1. Use data-id field while building your modal link in controller. Like data-id="1".
2. In your partial view use this id to call an ajax method like "getData"
3. Return your data in json format from "getData".
4. Now bind that returned data to your form controls using jquery.
Hope this helps you !

How to create a ViewModel event pattern

I have a web application built using Knockout.js but the one thing I have failed to implement is proper reusable HTML. Right now even if I have a view such as a dialog which is shared by multiple other views I have to copy and paste the HTML code and nest it in the parent in order to achieve proper binding communication between the child and parent.
Here's an example:
<div class="person-view"> <!-- PersonViewModel -->
<div class="person-details">
<!-- Person details -->
</div>
<button type="button" data-bind="click: EditAddress">Edit address</button>
<div class="modal hide fade" role="dialog" data-bind="modal: ShowEditAddressModal, with: Address"> <!-- AddressViewModel -->
<div class="modal-header">
<h3>Edit address</h3>
</div>
<div class="modal-body">
<!-- Address details -->
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-danger" data-dismiss="modal" data-bind="click: function() { $parent.SetAddress($data); }">Save</button>
</div>
</div>
</div>
In this case I have a sub-ViewModel which I am setting as the DataContext for the modal div. When the user clicks the Save button I am calling a method on the parent DataContext.
I know how to break the modal out to a separate HTML template and to generate the template dynamically supplying the ViewModel. That would work for showing and hiding the modal because I would simply need to do the following from within the code of the parent:
this.Address().IsShown(true);
In this case the modal would simply bind its visibility to a property on itself and the parent just needs to change it. That's fine.
However, what about when I click the Save button? I do not see how to have the parent respond to this occurrence using the MVVM pattern of Knockout.js. The button would still need a click binding which would bind to arbitrary code on the AddressViewModel, but how would it signal an event to its parent using Knockout?
Is there no way of doing this with Knockout and do I need to implement a separate library such as Underscore.js for events?
This is not a direct answer to your question, but the problem you're trying to solve is eliminated by using a library like DurandalJS which is built on top of knockout and handles view composition. There are a lot of features that Durandal provides to enable the kind of code reuse you're looking for, without having to reinvent the wheel. It's not the right fit for every project, but it might fit your needs.

Load a page fragment into a Twitter bootstrap Modal

Is it possible to load a page fragment using Twitter bootstrap's modal components? I want to load a page into the modal, but I only want a section of it. For example, I want the form on the page without the wrapping navigation. I've done this type of thing before using jquery tools overlays and jquery's .load function. But the modal stuff doesn't allow for this type of information to be passed in.
Here is some example text I'm working with:
<a tabindex="-1"
href="metadata.html"
id="metadata-link"
data-target="#modal"
data-toggle="modal">Metadata</a>
<div id="modal" class="modal hide fade in" style="display:none;">
<div class="modal-header">header<a class="close" data-dismiss="modal">x</a></div>
<div class="modal-body"></div>
<div class="model-footer">footer</div>
</div>
<script>
$(document).ready(function() {
$('#metadata-link').modal({show:false});
});
</script>
The 'metadata.html' page is a full html document. The contents of this page get loaded into the '.modal-body' element as expected. But the nothing displays...
If I switch the 'metadata.html' page for a page that contains only a 'div' contents, the modal displays.
Does anyone have any idea why this would happen?
You can do it manually:
<script>
$(document).ready(function() {
$('#metadata-link').click(function(){
$.ajax(
{
url:'url-to-load-page',
success: function(response){
//do what ever you want here to extract the part you want
$('#modal-div-content').html(adapted-response);
$('#modal').modal('show');
}
});
});
});
</script>
bootstrap uses the jquery load method which allows a URL and a fragment selector to be specified:
The .load() method, unlike $.get(), allows us to specify a portion of
the remote document to be inserted. This is achieved with a special
syntax for the url parameter. If one or more space characters are
included in the string, the portion of the string following the first
space is assumed to be a jQuery selector that determines the content
to be loaded.
So in my case (adding a musician) i could use a normal link tag like this:
</i> Add
Which extracts the form element from the container div and shows it in the newItemModal modal. This approach allows me to re-use the modal for other items
Declaring the fragment id using data-remote worked for me:
<a href="remote.html" data-remote="remote.html #fragment" data-toggle="modal" data-target="#modal">

Categories

Resources