MVC3 - jQuery datepicker when multiple elements have the same ID - javascript

I have a weird situation (don't we all?) with datepickers and want to get some advice.
I have a screen with a list of Locations, and for each Location, they can click Edit and edit that location. The Edit displays below the Edit link, and they can edit multiple locations at one time. This means the same View is rendered on the screen multiple times, and therefore multiple fields will exist with the same id (editing 4 locations will result in 4 "DateOpened" fields).
So, when I load my View, javascript adds datepickers to any fields that need it like so:
$(document).ready(function () {
var elements = $(".NeedsDatePicker > td > input");
$(".NeedsDatePicker > td > input").datepicker();
$(".NeedsDatePicker").removeClass("NeedsDatePicker");
});
Works fine, but, as you've probably already figured out, when I click a date on the calender, it populates the first "DateOpened" field when multiple Edit windows are open.
Is there a way to tell the datepicker to use the field WITHIN a certain parent, like you can for general jQuery selects?
$("#DateOpened", "Location-134").doWhatever...
...or is there a way to give the fields different id's without breaking MVC's UpdateModel() function? Or any other advice?

You should definitely keep IDs unique within an HTML DOM. Most, if not all, DOM manipulation libraries/frameworks, including jQuery, have this assumption built-in.
There are a few questions on SO WRT to avoid the same IDs in the form:
two forms with same input id in asp.net mvc
how to prevent html input id duplication on asp.net mvc 3 when a model contains multiple elements

Related

How do I iterate over a container with KendoUI widgets and get their values using jQuery?

I'm working with jQuery and KendoUI for MVC. I have a ul called #overview and each list item has a different kind of KendoUI widget in it. Those widgets are the like of text boxes, multi select, ranger sliders and dropdown lists. There is a button that the user can click which runs a jQuery function to gather the content of all these widgets.
The problem I have is that these widgets have Kendo specific code to access their values and text attributes such as $("MyControl").data("kendoDropDownList).text();, I am using a .each loop to iterate over the li and I need a way to grab the data from the varying controls and I was wondering if there was a clean way to do that?
With so many controls available it will make for a complex piece of code to check for every possible control that may be there.
Any help is appreciated.
This is kinda tricky. There is an obscure method called kendo.widgetInstance() that whatever element you pass intto it, it will check for a widget and return it's instance.
var $date = $("#date").kendoDatePicker({ value: (new Date()) });
console.log(kendo.widgetInstance($date).value());
Demo

Rerender Dynamic Elements when using jQuery Plugin Selectize and Bootstrap-Switch

I am new to jQuery so please go easy, I have a form that will represent an Advanced Search. Users will be able to add rows to refine their specific search.
Each row has 3 elements: A Checkbox & 2 x Select boxes.
As can be seen in the fiddle I am using jquery to clone the row and place the cloned row after the last row.
Everything is working fine except visually I would like the checkbox to use Bootstrap-Switch http://www.bootstrap-switch.org/
And the select boxes to use Selectize https://github.com/brianreavis/selectize.js
Now, when I clone the row with these plugins not active, everything works.
I have NO idea how to re-render or re activate them once a new row is inserted.
Is this something that is plugin specific? Or kind of universal to jquery?
I have read HEAPS of answers on here about similar things but I cannot seem to get it right.
Here is the jquery snippet:
$adSearchForm = $('#adSearchForm');
$adSearchForm.on('click', 'button, input, select, option', function (event) {
console.log("Button Clicked", event)
});
$('#addSearchRow').click(function(event){
$('[data-content=adSearch-3]:first').clone().insertAfter('[data-content=adSearch-3]:last');
// $('.searchByField,.searchOperator').selectize({refreshItems: true});
// $('[data-toggle=switch]').bootstrapSwitch({refreshItems: true});
});
Here is the fiddle, hope its ok. http://jsfiddle.net/CkVQr/6/
Thankyou very much for your help.
Cheers
Plugins change your HTML
There are two major problems you may not be fully aware of with your code:
Whenever you do a .clone() it merely deep clones your DOM element subtree, but not any event handlers bound to cloned elements.
Your .selectize() plugin changes HTML of your form quite considerably, converting input elements to other things. So whenever you clone your already converted select filter row, and subsequently want to run .selectize() on it again, this particular plugin won't find any suitable input elements to convert. Hence it won't work. Everything will just look as it should but won't work.
What can be done?
The main idea is that whenever you clone your search filter row, you have to clone your original HTML and not after it was converted using your plugins.
HTML Templates to the rescue
One of the possibilities is to change you page (and functionality) a bit and put your search filter row in a template and always use that. When you create your first row, you should read the template (and cache it) and add+convert it on your page. When you'd add an additional row, just use the same cached template and add+convert it again.
HTML template
<script id="filterRow" type="text/x-template">
<!-- Your filter rown HTML goes in here -->
</script>
Some Javascript
var cachedTemplate = cachedTemplate || $("#filterRow").html();
...
$('#addSearchRow').click(function(evt) {
var newRow = cachedTemplate.clone(); // clone for reusability
newRow.insertAfter('[data-content=adSearch-3]:last');
newRow.selectize();
...
});

Multy-filter page with transitions - Isotope & Quicksand JS problems

(note: edited since I've just realized the question are somehow correlated, at least in my mind!)
I want to create a multi-filter page in which the result will be animated...
I'm trying with 2 different plugin (quicksand and Isotope) and with both solution I'm having problems...
---ISOTOPE--- (original)
With Isotope I need to filter data based on active class, or based on IDs of filters, which I've already stored in JS, does anyone know how can I do that?
I set up a page with 2 different filter like 'color' (red, blue, orange...) and 'type' (square, round...)
I already have a Javascript that assign class active to the 2 filtering lu based on selection, if all color are selected shift the 'active' class to 'all', and more than one sub-filter can be activated. And this also save the list of the id of the active li items in a string for color filter and another string for shape filter
I also already set up the page like the combination filter Isotope demo at this link: http://isotope.metafizzy.co/demos/combination-filters.html and it is working fine but doesn't allow to select more than one sub-filter at the same time.
I saw the demo at this link http://fiddle.jshell.net/desandro/JB45z/ with filtering combination, but it is based on radio button that I'd like to avoid.
I'm not sure if what I'm trying to do is easy or not... is like, how to tell to Isotope to filter based on the sub-filter that have active class or based on the sum of the li with the ID saved in my two string?
Thanks for any help, as you can easily understand I'm not skilled in js at all and english is not my first language!
--- QUICKSAND --- (edited)
I've just realized that I didn't explain why I stored the IDs of the selected items in the js string. And this is also about the different js question.
I was trying to set up the same system with Quicksand instead of Isotope.
But since quicksand need to have a starting li and a destination li to display the animation I set up the js to pass an array to a different temporary php page that use the array to display a destination li.
All until here is working fine but I'm not able to get back the li data in the original page to let Quicksand perform the animation. The last part of my js appear to have problems that I'm not able to fix (too many days trying with no success), the last part of the js is:
$.post( 'destination_li_filtered.php', {
colorString,
shapeString,
$('#ids').attr('val')
},
function(data) { // should contains the resulting data from the request (?)
$('.list').quicksand( $(data).find('li'),
{ adjustHeight: 'auto' },
function() {
callbackCode();
}
);
e.preventDefault();
});
the external page destination-li-filtered is displaying the results but the original page is not able to take back the data...
Obviously I need to set op the page with isotope or quicksand, not both.
but I'm also wondering witch is the best plugin to display 100's of results with about 20 filters (without considering the combinations). And of course, which is the easiest to use!
You should see the radio button and the change in view as separate things.
It's a common misconception that you should store all your state in the DOM (ie. which checkbox is checked). The DOM is a view, you don't keep state in a view.
You should have a state that lives in your JavaScript.
Like:
var state = "all_selected"; // green, red, blue
Then, when you check the radio button, it will set the appropriate state and update the list (show/hide elements based on state).
This allows you to make any control you want, be it a radio button, a checkbox or something completely custom.

Show/Hide multiple div classes independently based on checkbox value

I've seen several questions similar to mine, but I can't seem to find a solution.
I'm working on a calendar with JavaScript powered by FullCalendar using Google XML URLs. My objective is to show/hide events on the calendar based on a checkbox value corresponding to the events on the calendar. Such events are grouped by type (they're on separate Google calendars with separate XML URLs but are rendered on the same calendar display on the webpage) and have different div class names. I have 11 different classes total and need a way to toggle their visibility independently of the other classes based on a checkbox value.
I'm in the process of learning JQuery/JavaScript and hence much of it is still Greek to me. I found a solution that works for a single class, but is dependent on all of the other checkboxes' values if other checkboxes are present. This is the JS I'm using currently:
<script type="text/javascript">
function doInputs(obj){
var checkbox = $("input[type=checkbox]:checked");
var i =0, box;
$('.className').fadeOut('fast');
while(box = checkbox[i++]){
if(!box.checked)continue;
$('.className').fadeIn('fast');
break;
}
}
</script>
And the corresponding mark-up:
<input type="checkbox" checked="checked" name="className" onclick="doInputs(this)"> Class Name Text
This works quite well; however, I can't figure out how to make it work with multiple div classes. Any suggestions?
I found a different solution, one that works much better and uses existing FullCalendar JS actions. Instead of using div classes and their class names as the determining factor of their display status, I used FullCalendar's removeEventSource and addEventSource actions to show/hide each of the 11 calendars being toggled.
The original JS is here. A little more picking around and I would have found this much sooner.
Thanks to those that commented and answered.
You can pass class name of div along with JS function e.g.
doInputs(this,'classname')
and according to that class name you can toggle that class
E.G
function doInputs(obj,cc){
......
$('.' + cc).fadeOut('fast');
......
}

Auto Complete Fields in Rails that Display Something Different Than What They Select

I'm trying to create an auto complete field (using the script.aculo.us plugin) in a form for a category select, but I want the auto complete list to display a number next to each category (the number of other things in the same category). This is similar to the Tags field on stack overflow.
Right now I can display the number I want, but when I select any field the extra number gets dumped into the text field with the category. Currently I'm simply appending the number to each item on the array before I display it. How can I make it so when you select something from the list the number (enclosed in parentheses) does not get put into the text field. Thank you.
I finally solved my problem, I just needed to figure out what some of the plugin's options were. It turns out there is an option for the auto_complete_field helper called :select. The value you provide to this tells the JavaScript which part of the <li> element (the HTML tags the results are displayed in) to return to the text box.
The solution was a simple matter of enclosing the name of the category in a span with a special class and leaving the number part I didn't want outside of this class. This was easy since I was already using my own partial to display the results.

Categories